Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
fffa9bed
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
fffa9bed
编写于
6月 29, 2018
作者:
C
Charles Stoner
提交者:
GitHub
6月 29, 2018
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Erase nullability from base and interfaces for types from unannotated assemblies (#28028)
上级
cbf4d8a3
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
388 addition
and
112 deletion
+388
-112
src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs
src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs
+2
-2
src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs
.../Portable/Binder/Semantics/Conversions/ConversionsBase.cs
+1
-4
src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs
.../CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs
+36
-29
src/Compilers/CSharp/Portable/Symbols/Metadata/PE/SymbolFactory.cs
...lers/CSharp/Portable/Symbols/Metadata/PE/SymbolFactory.cs
+9
-4
src/Compilers/CSharp/Portable/Symbols/SymbolWithAnnotations.cs
...ompilers/CSharp/Portable/Symbols/SymbolWithAnnotations.cs
+12
-27
src/Compilers/CSharp/Test/Semantic/Semantics/StaticNullChecking.cs
...lers/CSharp/Test/Semantic/Semantics/StaticNullChecking.cs
+328
-46
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder_Symbols.cs
浏览文件 @
fffa9bed
...
...
@@ -343,7 +343,7 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS
TypeSymbolWithAnnotations
constructedType
;
if
(
Compilation
.
IsFeatureEnabled
(
MessageID
.
IDS_FeatureStaticNullChecking
))
{
constructedType
=
typeArgument
.
AsNullableReferenceOrValueType
(
Compilation
,
syntax
.
GetReference
()
);
constructedType
=
typeArgument
.
AsNullableReferenceOrValueType
(
Compilation
);
if
(!
ShouldCheckConstraints
)
{
diagnostics
.
Add
(
new
LazyUseSiteDiagnosticsInfoForNullableType
(
constructedType
),
syntax
.
GetLocation
());
...
...
@@ -433,7 +433,7 @@ internal NamespaceOrTypeOrAliasSymbolWithAnnotations BindNamespaceOrTypeOrAliasS
if
(
a
.
QuestionToken
.
IsKind
(
SyntaxKind
.
QuestionToken
))
{
type
=
TypeSymbolWithAnnotations
.
Create
NullableReferenceType
(
array
);
type
=
TypeSymbolWithAnnotations
.
Create
(
array
,
isNullableIfReferenceType
:
true
);
}
else
{
...
...
src/Compilers/CSharp/Portable/Binder/Semantics/Conversions/ConversionsBase.cs
浏览文件 @
fffa9bed
...
...
@@ -1338,7 +1338,7 @@ private static bool HasIdentityConversionInternal(TypeSymbol type1, TypeSymbol t
// PROTOTYPE(NullableReferenceTypes): If two types differ only by nullability and
// one has IsNullable unset and the other doesn't, which do we choose in inference?
// See
failing test IdentityConversion_ArrayInitializer_IsNullableNull
.
// See
test TypeInference_04
.
var
compareKind
=
includeNullability
?
TypeCompareKind
.
AllIgnoreOptions
|
TypeCompareKind
.
CompareNullableModifiersForReferenceTypes
|
TypeCompareKind
.
UnknownNullableModifierMatchesAny
:
TypeCompareKind
.
AllIgnoreOptions
;
...
...
@@ -1352,9 +1352,6 @@ private bool HasIdentityConversionInternal(TypeSymbol type1, TypeSymbol type2)
internal
static
bool
HasTopLevelNullabilityIdentityConversion
(
TypeSymbolWithAnnotations
source
,
TypeSymbolWithAnnotations
destination
)
{
// PROTOTYPE(NullableReferenceTypes): If two types differ only by nullability and
// one has IsNullable unset and the other doesn't, which do we choose in inference?
// See failing test IdentityConversion_ArrayInitializer_IsNullableNull.
bool
?
sourceIsNullable
=
source
.
IsNullable
;
bool
?
destinationIsNullable
=
destination
.
IsNullable
;
return
sourceIsNullable
==
null
||
destinationIsNullable
==
null
||
sourceIsNullable
==
destinationIsNullable
;
...
...
src/Compilers/CSharp/Portable/Symbols/Metadata/PE/PENamedTypeSymbol.cs
浏览文件 @
fffa9bed
...
...
@@ -65,7 +65,8 @@ internal abstract class PENamedTypeSymbol : NamedTypeSymbol
private
NamedTypeSymbol
_lazyBaseType
=
ErrorTypeSymbol
.
UnknownResultType
;
private
ImmutableArray
<
NamedTypeSymbol
>
_lazyInterfaces
=
default
(
ImmutableArray
<
NamedTypeSymbol
>);
private
NamedTypeSymbol
_lazyDeclaredBaseType
=
ErrorTypeSymbol
.
UnknownResultType
;
private
NamedTypeSymbol
_lazyDeclaredBaseTypeWithoutNullability
=
ErrorTypeSymbol
.
UnknownResultType
;
private
NamedTypeSymbol
_lazyDeclaredBaseTypeWithNullability
=
ErrorTypeSymbol
.
UnknownResultType
;
private
ImmutableArray
<
NamedTypeSymbol
>
_lazyDeclaredInterfaces
=
default
(
ImmutableArray
<
NamedTypeSymbol
>);
private
Tuple
<
CultureInfo
,
string
>
_lazyDocComment
;
...
...
@@ -426,12 +427,32 @@ internal override ImmutableArray<NamedTypeSymbol> GetInterfacesToEmit()
internal
override
NamedTypeSymbol
GetDeclaredBaseType
(
ConsList
<
Symbol
>
basesBeingResolved
)
{
if
(
ReferenceEquals
(
_lazyDeclaredBaseType
,
ErrorTypeSymbol
.
UnknownResultType
))
return
GetDeclaredBaseType
(
ignoreNullability
:
false
);
}
private
NamedTypeSymbol
GetDeclaredBaseType
(
bool
ignoreNullability
)
{
if
(
ReferenceEquals
(
_lazyDeclaredBaseTypeWithoutNullability
,
ErrorTypeSymbol
.
UnknownResultType
))
{
Interlocked
.
CompareExchange
(
ref
_lazyDeclaredBaseTypeWithoutNullability
,
MakeDeclaredBaseType
(),
ErrorTypeSymbol
.
UnknownResultType
);
}
if
(
ignoreNullability
)
{
Interlocked
.
CompareExchange
(
ref
_lazyDeclaredBaseType
,
MakeDeclaredBaseType
(),
ErrorTypeSymbol
.
UnknownResultType
)
;
return
_lazyDeclaredBaseTypeWithoutNullability
;
}
return
_lazyDeclaredBaseType
;
if
(
ReferenceEquals
(
_lazyDeclaredBaseTypeWithNullability
,
ErrorTypeSymbol
.
UnknownResultType
))
{
var
declaredBase
=
_lazyDeclaredBaseTypeWithoutNullability
;
if
((
object
)
declaredBase
!=
null
)
{
declaredBase
=
(
NamedTypeSymbol
)
NullableTypeDecoder
.
TransformOrEraseNullability
(
TypeSymbolWithAnnotations
.
Create
(
declaredBase
),
_handle
,
ContainingPEModule
).
TypeSymbol
;
}
Interlocked
.
CompareExchange
(
ref
_lazyDeclaredBaseTypeWithNullability
,
declaredBase
,
ErrorTypeSymbol
.
UnknownResultType
);
}
return
_lazyDeclaredBaseTypeWithNullability
;
}
internal
override
ImmutableArray
<
NamedTypeSymbol
>
GetDeclaredInterfaces
(
ConsList
<
Symbol
>
basesBeingResolved
)
...
...
@@ -456,8 +477,10 @@ private NamedTypeSymbol MakeDeclaredBaseType()
if
(!
token
.
IsNil
)
{
TypeSymbol
decodedType
=
new
MetadataDecoder
(
moduleSymbol
,
this
).
GetTypeOfToken
(
token
);
var
result
=
(
NamedTypeSymbol
)
DynamicTypeDecoder
.
TransformType
(
decodedType
,
0
,
_handle
,
moduleSymbol
);
return
DecodeBaseAndInterfaceNullableAndTupleTypes
(
result
,
_handle
,
moduleSymbol
);
decodedType
=
DynamicTypeDecoder
.
TransformType
(
decodedType
,
0
,
_handle
,
moduleSymbol
);
return
(
NamedTypeSymbol
)
TupleTypeDecoder
.
DecodeTupleTypesIfApplicable
(
decodedType
,
_handle
,
moduleSymbol
);
}
}
catch
(
BadImageFormatException
mrEx
)
...
...
@@ -485,16 +508,12 @@ private ImmutableArray<NamedTypeSymbol> MakeDeclaredInterfaces()
{
EntityHandle
interfaceHandle
=
moduleSymbol
.
Module
.
MetadataReader
.
GetInterfaceImplementation
(
interfaceImpl
).
Interface
;
TypeSymbol
typeSymbol
=
tokenDecoder
.
GetTypeOfToken
(
interfaceHandle
);
var
result
=
typeSymbol
as
NamedTypeSymbol
;
if
(
result
is
null
)
{
result
=
new
UnsupportedMetadataTypeSymbol
();
// interface list contains a bad type
}
else
{
result
=
DecodeBaseAndInterfaceNullableAndTupleTypes
(
result
,
interfaceImpl
,
moduleSymbol
);
}
symbols
.
Add
(
result
);
typeSymbol
=
TupleTypeDecoder
.
DecodeTupleTypesIfApplicable
(
typeSymbol
,
interfaceImpl
,
moduleSymbol
);
typeSymbol
=
NullableTypeDecoder
.
TransformOrEraseNullability
(
TypeSymbolWithAnnotations
.
Create
(
typeSymbol
),
interfaceImpl
,
moduleSymbol
).
TypeSymbol
;
var
namedTypeSymbol
=
typeSymbol
as
NamedTypeSymbol
??
new
UnsupportedMetadataTypeSymbol
();
// interface list contains a bad type
symbols
.
Add
(
namedTypeSymbol
);
}
return
symbols
.
ToImmutableAndFree
();
...
...
@@ -508,18 +527,6 @@ private ImmutableArray<NamedTypeSymbol> MakeDeclaredInterfaces()
}
}
private
static
NamedTypeSymbol
DecodeBaseAndInterfaceNullableAndTupleTypes
(
NamedTypeSymbol
type
,
EntityHandle
handle
,
PEModuleSymbol
moduleSymbol
)
{
// PROTOTYPE(NullableReferenceTypes): Should call NullableTypeDecoder.TransformOrEraseNullability
// here (see StaticNullChecking.UnannotatedAssemblies_09) but TransformOrEraseNullability results in
// a StackOverflowException when building Roslyn.sln.
if
(
moduleSymbol
.
UtilizesNullableReferenceTypes
)
{
type
=
(
NamedTypeSymbol
)
NullableTypeDecoder
.
TransformType
(
TypeSymbolWithAnnotations
.
Create
(
type
),
handle
,
moduleSymbol
).
TypeSymbol
;
}
return
(
NamedTypeSymbol
)
TupleTypeDecoder
.
DecodeTupleTypesIfApplicable
(
type
,
handle
,
moduleSymbol
);
}
public
override
NamedTypeSymbol
ConstructedFrom
{
get
...
...
@@ -1628,7 +1635,7 @@ public override TypeKind TypeKind
}
else
{
TypeSymbol
@base
=
GetDeclaredBaseType
(
null
);
TypeSymbol
@base
=
GetDeclaredBaseType
(
ignoreNullability
:
true
);
result
=
TypeKind
.
Class
;
...
...
src/Compilers/CSharp/Portable/Symbols/Metadata/PE/SymbolFactory.cs
浏览文件 @
fffa9bed
...
...
@@ -19,7 +19,7 @@ internal sealed class SymbolFactory : SymbolFactory<PEModuleSymbol, TypeSymbol>
return
elementType
;
}
return
ArrayTypeSymbol
.
CreateMDArray
(
moduleSymbol
.
ContainingAssembly
,
TypeSymbolWithAnnotations
.
Create
(
elementType
,
CSharpCustomModifier
.
Convert
(
customModifiers
)
),
rank
,
sizes
,
lowerBounds
);
return
ArrayTypeSymbol
.
CreateMDArray
(
moduleSymbol
.
ContainingAssembly
,
CreateType
(
elementType
,
customModifiers
),
rank
,
sizes
,
lowerBounds
);
}
internal
override
TypeSymbol
GetSpecialType
(
PEModuleSymbol
moduleSymbol
,
SpecialType
specialType
)
...
...
@@ -39,7 +39,7 @@ internal override TypeSymbol MakePointerTypeSymbol(PEModuleSymbol moduleSymbol,
return
type
;
}
return
new
PointerTypeSymbol
(
TypeSymbolWithAnnotations
.
Create
(
type
,
CSharpCustomModifier
.
Convert
(
customModifiers
)
));
return
new
PointerTypeSymbol
(
CreateType
(
type
,
customModifiers
));
}
internal
override
TypeSymbol
GetEnumUnderlyingType
(
PEModuleSymbol
moduleSymbol
,
TypeSymbol
type
)
...
...
@@ -74,7 +74,7 @@ internal override TypeSymbol GetSZArrayTypeSymbol(PEModuleSymbol moduleSymbol, T
return
elementType
;
}
return
ArrayTypeSymbol
.
CreateSZArray
(
moduleSymbol
.
ContainingAssembly
,
TypeSymbolWithAnnotations
.
Create
(
elementType
,
CSharpCustomModifier
.
Convert
(
customModifiers
)
));
return
ArrayTypeSymbol
.
CreateSZArray
(
moduleSymbol
.
ContainingAssembly
,
CreateType
(
elementType
,
customModifiers
));
}
internal
override
TypeSymbol
GetUnsupportedMetadataTypeSymbol
(
PEModuleSymbol
moduleSymbol
,
BadImageFormatException
exception
)
...
...
@@ -152,7 +152,7 @@ internal override TypeSymbol GetUnsupportedMetadataTypeSymbol(PEModuleSymbol mod
return
new
UnsupportedMetadataTypeSymbol
();
}
TypeMap
substitution
=
new
TypeMap
(
typeParameters
,
arguments
.
SelectAsArray
(
arg
=>
TypeSymbolWithAnnotations
.
Create
(
arg
.
Key
,
CSharpCustomModifier
.
Convert
(
arg
.
Value
)
)));
TypeMap
substitution
=
new
TypeMap
(
typeParameters
,
arguments
.
SelectAsArray
(
arg
=>
CreateType
(
arg
.
Key
,
arg
.
Value
)));
NamedTypeSymbol
constructedType
=
substitution
.
SubstituteNamedType
(
genericType
);
...
...
@@ -169,5 +169,10 @@ internal override TypeSymbol MakeUnboundIfGeneric(PEModuleSymbol moduleSymbol, T
var
namedType
=
type
as
NamedTypeSymbol
;
return
((
object
)
namedType
!=
null
&&
namedType
.
IsGenericType
)
?
namedType
.
AsUnboundGenericType
()
:
type
;
}
private
static
TypeSymbolWithAnnotations
CreateType
(
TypeSymbol
type
,
ImmutableArray
<
ModifierInfo
<
TypeSymbol
>>
customModifiers
)
{
return
TypeSymbolWithAnnotations
.
Create
(
type
,
CSharpCustomModifier
.
Convert
(
customModifiers
));
}
}
}
src/Compilers/CSharp/Portable/Symbols/SymbolWithAnnotations.cs
浏览文件 @
fffa9bed
...
...
@@ -196,20 +196,6 @@ public static TypeSymbolWithAnnotations Create(TypeSymbol typeSymbol)
return
Create
(
typeSymbol
,
ImmutableArray
<
CustomModifier
>.
Empty
);
}
// PROTOTYPE(NullableReferenceTypes): Check we are not using this method on type references in
// member signatures visible outside the assembly. Consider overriding, implementing, NoPIA embedding, etc.
public
static
TypeSymbolWithAnnotations
CreateNullableReferenceType
(
TypeSymbol
typeSymbol
)
{
if
(
typeSymbol
is
null
)
{
return
null
;
}
// PROTOTYPE(NullableReferenceTypes): Consider if it makes
// sense to cache and reuse instances, at least for definitions.
return
new
NonLazyType
(
typeSymbol
,
isNullable
:
true
,
ImmutableArray
<
CustomModifier
>.
Empty
);
}
// PROTOTYPE(NullableReferenceTypes): Check we are not using this method on type references in
// member signatures visible outside the assembly. Consider overriding, implementing, NoPIA embedding, etc.
public
static
TypeSymbolWithAnnotations
Create
(
TypeSymbol
typeSymbol
,
ImmutableArray
<
CustomModifier
>
customModifiers
)
...
...
@@ -252,17 +238,18 @@ public static TypeSymbolWithAnnotations Create(TypeSymbol typeSymbol, bool? isNu
return
new
NonLazyType
(
typeSymbol
,
isNullable
,
customModifiers
);
}
public
TypeSymbolWithAnnotations
AsNullableReferenceOrValueType
(
CSharpCompilation
compilation
,
SyntaxReference
nullableTypeSyntax
)
public
TypeSymbolWithAnnotations
AsNullableReferenceOrValueType
(
CSharpCompilation
compilation
)
{
var
typeSymbol
=
this
.
TypeSymbol
;
Debug
.
Assert
(
compilation
.
IsFeatureEnabled
(
MessageID
.
IDS_FeatureStaticNullChecking
));
Debug
.
Assert
(
CustomModifiers
.
IsEmpty
);
var
typeSymbol
=
this
.
TypeSymbol
;
// It is not safe to check if a type parameter is a reference type right away, this can send us into a cycle.
// In this case we delay asking this question as long as possible.
if
(
typeSymbol
.
TypeKind
!=
TypeKind
.
TypeParameter
)
{
if
(
typeSymbol
.
IsReferenceType
&&
((
CSharpParseOptions
)
nullableTypeSyntax
.
SyntaxTree
.
Options
).
IsFeatureEnabled
(
MessageID
.
IDS_FeatureStaticNullChecking
)
)
if
(
typeSymbol
.
IsReferenceType
)
{
return
new
NonLazyType
(
typeSymbol
,
isNullable
:
true
,
this
.
CustomModifiers
);
}
...
...
@@ -272,7 +259,7 @@ public TypeSymbolWithAnnotations AsNullableReferenceOrValueType(CSharpCompilatio
}
}
return
new
LazyNullableType
(
compilation
,
nullableTypeSyntax
,
this
);
return
new
LazyNullableType
(
compilation
,
this
);
}
/// <summary>
...
...
@@ -744,17 +731,16 @@ public override string ToDisplayString(SymbolDisplayFormat format)
private
sealed
class
LazyNullableType
:
TypeSymbolWithAnnotations
{
private
readonly
CSharpCompilation
_compilation
;
private
readonly
SyntaxReference
_nullableTypeSyntax
;
private
readonly
TypeSymbolWithAnnotations
_underlying
;
private
TypeSymbol
_resolved
;
public
LazyNullableType
(
CSharpCompilation
compilation
,
SyntaxReference
nullableTypeSyntax
,
TypeSymbolWithAnnotations
underlying
)
public
LazyNullableType
(
CSharpCompilation
compilation
,
TypeSymbolWithAnnotations
underlying
)
{
Debug
.
Assert
(
compilation
.
IsFeatureEnabled
(
MessageID
.
IDS_FeatureStaticNullChecking
));
Debug
.
Assert
(
underlying
.
IsNullable
!=
true
);
Debug
.
Assert
(
underlying
.
TypeKind
==
TypeKind
.
TypeParameter
);
Debug
.
Assert
(
underlying
.
CustomModifiers
.
IsEmpty
);
_compilation
=
compilation
;
_nullableTypeSyntax
=
nullableTypeSyntax
;
_underlying
=
underlying
;
}
...
...
@@ -769,15 +755,14 @@ public override TypeSymbol TypeSymbol
{
if
((
object
)
_resolved
==
null
)
{
if
(!
_underlying
.
IsValueType
&&
((
CSharpParseOptions
)
_nullableTypeSyntax
.
SyntaxTree
.
Options
).
IsFeatureEnabled
(
MessageID
.
IDS_FeatureStaticNullChecking
)
)
if
(!
_underlying
.
IsValueType
)
{
_resolved
=
_underlying
.
TypeSymbol
;
}
else
{
Interlocked
.
CompareExchange
(
ref
_resolved
,
_compilation
.
GetSpecialType
(
SpecialType
.
System_Nullable_T
).
Construct
(
ImmutableArray
.
Create
(
_underlying
)),
_compilation
.
GetSpecialType
(
SpecialType
.
System_Nullable_T
).
Construct
(
ImmutableArray
.
Create
(
_underlying
)),
null
);
}
}
...
...
@@ -890,7 +875,7 @@ public override TypeSymbolWithAnnotations SubstituteType(AbstractTypeMap typeMap
newUnderlying
.
TypeSymbol
is
IndexedTypeParameterSymbolForOverriding
)
&&
newUnderlying
.
CustomModifiers
.
IsEmpty
)
{
return
new
LazyNullableType
(
_compilation
,
_nullableTypeSyntax
,
newUnderlying
);
return
new
LazyNullableType
(
_compilation
,
newUnderlying
);
}
return
base
.
SubstituteType
(
typeMap
);
...
...
@@ -915,7 +900,7 @@ public override TypeSymbolWithAnnotations SubstituteTypeWithTupleUnification(Abs
newUnderlying
.
TypeSymbol
is
IndexedTypeParameterSymbolForOverriding
)
&&
newUnderlying
.
CustomModifiers
.
IsEmpty
)
{
return
new
LazyNullableType
(
_compilation
,
_nullableTypeSyntax
,
newUnderlying
);
return
new
LazyNullableType
(
_compilation
,
newUnderlying
);
}
return
base
.
SubstituteTypeWithTupleUnification
(
typeMap
);
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/StaticNullChecking.cs
浏览文件 @
fffa9bed
...
...
@@ -819,9 +819,7 @@ static void F(object? x, object y, C2 c)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "((A)c).F(x, y)").WithLocation(27, 9));
}
// PROTOTYPE(NullableReferenceTypes): Should call NullableTypeDecoder.TransformOrEraseNullability
// in PENamedTypeSymbol.MakeDeclaredBaseType.
[Fact(Skip = "TODO")]
[Fact]
public void UnannotatedAssemblies_10()
{
var source0 =
...
...
@@ -15129,55 +15127,87 @@ static void F(IOut<object> x, IOut<object?> y, IOut<object>? z, IOut<object?>? w
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { w, z })[0]").WithLocation(31, 9));
}
// PROTOTYPE(NullableReferenceTypes): Update this method to use types from unannotated assemblies
// rather than `x!`, particularly because `x!` results in IsNullable=false rather than IsNullable=null.
[Fact]
public void IdentityConversion_ArrayInitializer_IsNullableNull()
{
var source =
@"#pragma warning disable 0649
#pragma warning disable 8618
class A<T>
var source0 =
@"#pragma warning disable 8618
public class A<T>
{
internal
T F;
public
T F;
}
class B
public class B : A<object>
{
}";
var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular7);
comp0.VerifyDiagnostics();
var ref0 = comp0.EmitToImageReference();
var source =
@"class C
{
static void F(object? x,
object y
)
static void F(object? x,
B b
)
{
(new[] { x, x! })[0].ToString();
(new[] { x!, x })[0].ToString();
var y = b.F/*T:object*/;
(new[] { x, x! })[0].ToString(); // 1
(new[] { x!, x })[0].ToString(); // 2
(new[] { x!, x! })[0].ToString();
(new[] { y, y! })[0].ToString();
(new[] { y!, y })[0].ToString();
(new[] { x, y })[0].ToString(); // 3
(new[] { x, y! })[0].ToString(); // 4
(new[] { x!, y })[0].ToString();
(new[] { x!, y! })[0].ToString();
}
static void F(A<object?> z,
A<object>
w)
static void F(A<object?> z,
B
w)
{
(new[] { z, z! })[0].F.ToString();
(new[] { z!, z })[0].F.ToString();
(new[] { z!, z! })[0].F.ToString();
(new[] { z, z! })[0].F.ToString();
// 5
(new[] { z!, z })[0].F.ToString();
// 6
(new[] { z!, z! })[0].F.ToString();
// 7
(new[] { w, w! })[0].F.ToString();
(new[] { w!, w })[0].F.ToString();
(new[] { z, w })[0].F.ToString(); // 8
(new[] { z, w! })[0].F.ToString(); // 9
(new[] { z!, w })[0].F.ToString(); // 10
(new[] { z!, w! })[0].F.ToString(); // 11
}
}";
var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8);
var comp = CreateCompilation(source, references: new[] { ref0 }, parseOptions: TestOptions.Regular8);
comp.VerifyTypes();
comp.VerifyDiagnostics(
// (6,9): warning CS8602: Possible dereference of a null reference.
// (new[] { x, x! })[0].ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { x, x! })[0]").WithLocation(6, 9),
// (7,9): warning CS8602: Possible dereference of a null reference.
// (new[] { x!, x })[0].ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { x!, x })[0]").WithLocation(7, 9),
// (11,9): warning CS8602: Possible dereference of a null reference.
// (new[] { x,
x! })[0].ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { x,
x!
})[0]").WithLocation(11, 9),
// (new[] { x,
y })[0].ToString(); // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { x,
y
})[0]").WithLocation(11, 9),
// (12,9): warning CS8602: Possible dereference of a null reference.
// (new[] { x!, x })[0].ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { x!, x })[0]").WithLocation(12, 9),
// (new[] { x, y! })[0].ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { x, y! })[0]").WithLocation(12, 9),
// (18,9): warning CS8602: Possible dereference of a null reference.
// (new[] { z, z! })[0].F.ToString(); // 5
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z, z! })[0].F").WithLocation(18, 9),
// (19,9): warning CS8602: Possible dereference of a null reference.
// (new[] { z
, z! })[0].F.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z
, z!
})[0].F").WithLocation(19, 9),
// (new[] { z
!, z })[0].F.ToString(); // 6
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z
!, z
})[0].F").WithLocation(19, 9),
// (20,9): warning CS8602: Possible dereference of a null reference.
// (new[] { z!, z })[0].F.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z!, z })[0].F").WithLocation(20, 9),
// (21,9): warning CS8602: Possible dereference of a null reference.
// (new[] { z!, z! })[0].F.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z!, z! })[0].F").WithLocation(21, 9)
);
// (new[] { z!, z! })[0].F.ToString(); // 7
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z!, z! })[0].F").WithLocation(20, 9),
// (23,9): warning CS8602: Possible dereference of a null reference.
// (new[] { z, w })[0].F.ToString(); // 8
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z, w })[0].F").WithLocation(23, 9),
// (24,9): warning CS8602: Possible dereference of a null reference.
// (new[] { z, w! })[0].F.ToString(); // 9
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z, w! })[0].F").WithLocation(24, 9),
// (25,9): warning CS8602: Possible dereference of a null reference.
// (new[] { z!, w })[0].F.ToString(); // 10
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z!, w })[0].F").WithLocation(25, 9),
// (26,9): warning CS8602: Possible dereference of a null reference.
// (new[] { z!, w! })[0].F.ToString(); // 11
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(new[] { z!, w! })[0].F").WithLocation(26, 9));
}
[Fact]
...
...
@@ -20920,6 +20950,36 @@ class CL0<T>
);
}
[Fact]
public void MethodGroupConversion_06()
{
var source =
@"delegate void D<T>(T t) where T : A;
class A { }
class B<T>
{
internal void F(T t) { }
}
class C
{
static B<T> Create<T>(T t) => new B<T>();
static void G(A x, A? y)
{
D<A> d;
d = Create(x).F;
d = Create(y).F; // warning
x = y;
d = Create(x).F; // warning
}
}";
var comp = CreateCompilation(source, parseOptions: TestOptions.Regular8);
// PROTOTYPE(NullableReferenceTypes): Report conversion warnings.
comp.VerifyDiagnostics(
// (15,13): warning CS8600: Converting null literal or possible null value to non-nullable type.
// x = y;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "y").WithLocation(15, 13));
}
[Fact]
public void UnaryOperator_01()
{
...
...
@@ -32243,31 +32303,55 @@ static void G(I<string> x, I<string?> y)
[Fact]
public void TypeInference_04()
{
var source0 =
@"public class A
{
}
public class B
{
public A F;
}";
var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular7);
comp0.VerifyDiagnostics();
var ref0 = comp0.EmitToImageReference();
// PROTOTYPE(NullableReferenceTypes): The result of type inference with null-oblivious
// depends on the order possible type arguments are considered. For instance,
// the type inferred for F(x, z) is A? and the type inferred for F(z, x) is A.
// See https://github.com/dotnet/roslyn/issues/27961.
var source =
@"class C
{
static T F<T>(T x, T y) => x;
static void G(
C? x, C y
)
static void G(
A? x, A y, B b
)
{
F(x, x).ToString();
F(x, y).ToString();
F(y, x).ToString();
F(y, y).ToString();
var z = b.F;
F(x, x)/*T:A?*/.ToString(); // 1
F(x, y)/*T:A?*/.ToString(); // 2
F(x, z)/*T:A?*/.ToString(); // 3
F(y, x)/*T:A?*/.ToString(); // 4
F(y, y)/*T:A!*/.ToString();
F(y, z)/*T:A!*/.ToString();
F(z, x)/*T:A*/.ToString(); // 5
F(z, y)/*T:A*/.ToString();
F(z, z)/*T:A*/.ToString();
}
}";
var comp = CreateCompilation(
source,
parseOptions: TestOptions.Regular8);
var comp = CreateCompilation(source, references: new[] { ref0 }, parseOptions: TestOptions.Regular8);
comp.VerifyTypes();
comp.VerifyDiagnostics(
// (6,9): warning CS8602: Possible dereference of a null reference.
// F(x, x).ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "F(x, x)").WithLocation(6, 9),
// (7,9): warning CS8602: Possible dereference of a null reference.
// F(x,
y).ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "F(x,
y
)").WithLocation(7, 9),
// F(x,
x)/*T:A?*/.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "F(x,
x
)").WithLocation(7, 9),
// (8,9): warning CS8602: Possible dereference of a null reference.
// F(y, x).ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "F(y, x)").WithLocation(8, 9));
// F(x, y)/*T:A?*/.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "F(x, y)").WithLocation(8, 9),
// (9,9): warning CS8602: Possible dereference of a null reference.
// F(x, z)/*T:A?*/.ToString(); // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "F(x, z)").WithLocation(9, 9),
// (10,9): warning CS8602: Possible dereference of a null reference.
// F(y, x)/*T:A?*/.ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "F(y, x)").WithLocation(10, 9));
}
[Fact]
...
...
@@ -34985,6 +35069,204 @@ class B2 : A<int>
comp.VerifyDiagnostics();
}
[WorkItem(27967, "https://github.com/dotnet/roslyn/issues/27967")]
[Fact]
public void UnannotatedTypeArgument_Interface()
{
var source0 =
@"public interface I<T>
{
}
public class B : I<object[]>
{
}
public class C : I<C>
{
}";
var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular7);
comp0.VerifyDiagnostics();
var ref0 = comp0.EmitToImageReference();
var source =
@"class Program
{
static void F(B x)
{
I<object[]?> a = x;
I<object[]> b = x;
}
static void F(C y)
{
I<C?> a = y;
I<C> b = y;
}
}";
var comp = CreateCompilation(source, references: new[] { ref0 }, parseOptions: TestOptions.Regular8);
comp.VerifyDiagnostics();
}
[WorkItem(27967, "https://github.com/dotnet/roslyn/issues/27967")]
[Fact]
public void UnannotatedTypeArgument_BaseType()
{
var source0 =
@"public class A<T>
{
}
public class B : A<object[]>
{
}
public class C : A<C>
{
}";
var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular7);
comp0.VerifyDiagnostics();
var ref0 = comp0.EmitToImageReference();
var source =
@"class Program
{
static void F(B x)
{
A<object[]?> a = x;
A<object[]> b = x;
}
static void F(C y)
{
A<C?> a = y;
A<C> b = y;
}
}";
var comp = CreateCompilation(source, references: new[] { ref0 }, parseOptions: TestOptions.Regular8);
comp.VerifyDiagnostics();
}
[Fact]
public void UnannotatedTypeArgument_Interface_Lookup()
{
var source0 =
@"public interface I<T>
{
void F(T t);
}
public interface I1 : I<object>
{
}";
var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular7);
comp0.VerifyDiagnostics();
var ref0 = comp0.EmitToImageReference();
var source =
@"interface I2 : I<object>
{
}
class Program
{
static void F(I1 i1, I2 i2, object x, object? y)
{
i1.F(x);
i1.F(y);
i2.F(x);
i2.F(y); // warn
}
}";
var comp = CreateCompilation(source, references: new[] { ref0 }, parseOptions: TestOptions.Regular8);
comp.VerifyDiagnostics(
// (11,14): warning CS8604: Possible null reference argument for parameter 't' in 'void I<object>.F(object t)'.
// i2.F(y); // warn
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "y").WithArguments("t", "void I<object>.F(object t)").WithLocation(11, 14));
}
[Fact]
public void UnannotatedTypeArgument_BaseType_Lookup()
{
var source0 =
@"public class A<T>
{
public static void F(T t) { }
}
public class B1 : A<object>
{
}";
var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular7);
comp0.VerifyDiagnostics();
var ref0 = comp0.EmitToImageReference();
var source =
@"class B2 : A<object>
{
}
class Program
{
static void F(object x, object? y)
{
B1.F(x);
B1.F(y);
B2.F(x);
B2.F(y); // warn
}
}";
var comp = CreateCompilation(source, references: new[] { ref0 }, parseOptions: TestOptions.Regular8);
comp.VerifyDiagnostics(
// (11,14): warning CS8604: Possible null reference argument for parameter 't' in 'void A<object>.F(object t)'.
// B2.F(y); // warn
Diagnostic(ErrorCode.WRN_NullReferenceArgument, "y").WithArguments("t", "void A<object>.F(object t)").WithLocation(11, 14));
}
[Fact]
public void UnannotatedConstraint_01()
{
var source0 =
@"public class A
{
}
public class B<T> where T : A
{
}";
var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular7);
comp0.VerifyDiagnostics();
var ref0 = comp0.EmitToImageReference();
var source =
@"class Program
{
static void Main()
{
new B<A?>();
new B<A>();
}
}";
var comp = CreateCompilation(source, references: new[] { ref0 }, parseOptions: TestOptions.Regular8);
comp.VerifyDiagnostics();
}
[Fact]
public void UnannotatedConstraint_02()
{
var source0 =
@"public class A<T>
{
}
public class B<T> where T : A<object>
{
}";
var comp0 = CreateCompilation(source0, parseOptions: TestOptions.Regular7);
comp0.VerifyDiagnostics();
var ref0 = comp0.EmitToImageReference();
var source =
@"class Program
{
static void Main()
{
new B<A<object?>>();
new B<A<object>>();
}
}";
var comp = CreateCompilation(source, references: new[] { ref0 }, parseOptions: TestOptions.Regular8);
comp.VerifyDiagnostics();
}
[Fact]
public void Constraint_Oblivious_01()
{
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录