Browse Source

Fix #2860

pull/2993/head
Daniel Grunwald 2 years ago
parent
commit
9bfec8cf98
  1. 28
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullableRefTypes.cs
  2. 3
      ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs
  3. 2
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs
  4. 3
      ICSharpCode.Decompiler/TypeSystem/Implementation/NullabilityAnnotatedType.cs
  5. 2
      ICSharpCode.Decompiler/TypeSystem/SpecialType.cs

28
ICSharpCode.Decompiler.Tests/TestCases/Pretty/NullableRefTypes.cs

@ -111,4 +111,32 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -111,4 +111,32 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
private Entry[]? _entries;
private IEqualityComparer<TKey>? _comparer;
}
public class T05_NullableUnconstrainedGeneric
{
public static TValue? Default<TValue>()
{
return default(TValue);
}
public static void CallDefault()
{
#if OPT
string? format = Default<string>();
#else
// With optimizations it's a stack slot, so ILSpy picks a nullable type.
// Without optimizations it's a local, so the nullability is missing.
string format = Default<string>();
#endif
int num = Default<int>();
#if CS110 && NET70
nint num2 = Default<nint>();
#else
int num2 = Default<int>();
#endif
(object, string) tuple = Default<(object, string)>();
Console.WriteLine("No inlining");
Console.WriteLine(format, num, num2, tuple);
}
}
}

3
ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractType.cs

@ -64,7 +64,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -64,7 +64,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public virtual IType ChangeNullability(Nullability nullability)
{
Debug.Assert(nullability == Nullability.Oblivious);
// Only some types support nullability, in the default implementation
// we just ignore the nullability change.
return this;
}

2
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

@ -308,7 +308,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -308,7 +308,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
public IType ChangeNullability(Nullability nullability)
{
if (nullability == Nullability.Oblivious)
if (nullability == Nullability.Oblivious || IsReferenceType == false)
return this;
else
return new NullabilityAnnotatedType(this, nullability);

3
ICSharpCode.Decompiler/TypeSystem/Implementation/NullabilityAnnotatedType.cs

@ -18,9 +18,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation @@ -18,9 +18,8 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
Debug.Assert(nullability != Nullability.Oblivious);
// Due to IType -> concrete type casts all over the type system, we can insert
// the NullabilityAnnotatedType wrapper only in some limited places.
Debug.Assert(type is ITypeDefinition
Debug.Assert(type is ITypeDefinition { IsReferenceType: not false }
|| type.Kind == TypeKind.Dynamic
|| type.Kind == TypeKind.Unknown
|| (type is ITypeParameter && this is ITypeParameter));
this.nullability = nullability;
}

2
ICSharpCode.Decompiler/TypeSystem/SpecialType.cs

@ -115,7 +115,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -115,7 +115,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
public override IType ChangeNullability(Nullability nullability)
{
if (nullability == base.Nullability)
if (nullability == base.Nullability || Kind is not TypeKind.Dynamic)
return this;
else
return new NullabilityAnnotatedType(this, nullability);

Loading…
Cancel
Save