未验证 提交 ec484126 编写于 作者: M msftbot[bot] 提交者: GitHub

Merge pull request #45104 from...

Merge pull request #45104 from dotnet/merges/release/dev16.7-preview3-to-release/dev16.7-preview3-vs-deps

Merge release/dev16.7-preview3 to release/dev16.7-preview3-vs-deps
......@@ -36,7 +36,7 @@ private BoundExpression BindIsPatternExpression(IsPatternExpressionSyntax node,
Debug.Assert(expression.Type is { });
uint inputValEscape = GetValEscape(expression, LocalScopeDepth);
BoundPattern pattern = BindPattern(node.Pattern, expression.Type, inputValEscape, permitDesignations: true, hasErrors, diagnostics);
BoundPattern pattern = BindPattern(node.Pattern, expression.Type, inputValEscape, permitDesignations: true, hasErrors, diagnostics, underIsPattern: true);
hasErrors |= pattern.HasErrors;
return MakeIsPatternExpression(
node, expression, pattern, GetSpecialType(SpecialType.System_Boolean, diagnostics, node),
......@@ -140,7 +140,8 @@ private BoundExpression BindSwitchExpression(SwitchExpressionSyntax node, Diagno
uint inputValEscape,
bool permitDesignations,
bool hasErrors,
DiagnosticBag diagnostics)
DiagnosticBag diagnostics,
bool underIsPattern = false)
{
return node switch
{
......@@ -149,9 +150,9 @@ private BoundExpression BindSwitchExpression(SwitchExpressionSyntax node, Diagno
ConstantPatternSyntax p => BindConstantPatternWithFallbackToTypePattern(p, inputType, hasErrors, diagnostics),
RecursivePatternSyntax p => BindRecursivePattern(p, inputType, inputValEscape, permitDesignations, hasErrors, diagnostics),
VarPatternSyntax p => BindVarPattern(p, inputType, inputValEscape, permitDesignations, hasErrors, diagnostics),
ParenthesizedPatternSyntax p => BindPattern(p.Pattern, inputType, inputValEscape, permitDesignations, hasErrors, diagnostics),
ParenthesizedPatternSyntax p => BindPattern(p.Pattern, inputType, inputValEscape, permitDesignations, hasErrors, diagnostics, underIsPattern),
BinaryPatternSyntax p => BindBinaryPattern(p, inputType, inputValEscape, permitDesignations, hasErrors, diagnostics),
UnaryPatternSyntax p => BindUnaryPattern(p, inputType, inputValEscape, hasErrors, diagnostics),
UnaryPatternSyntax p => BindUnaryPattern(p, inputType, inputValEscape, hasErrors, diagnostics, underIsPattern),
RelationalPatternSyntax p => BindRelationalPattern(p, inputType, hasErrors, diagnostics),
TypePatternSyntax p => BindTypePattern(p, inputType, hasErrors, diagnostics),
_ => throw ExceptionUtilities.UnexpectedValue(node.Kind()),
......@@ -1315,10 +1316,11 @@ void addSubpatternsForTuple(ImmutableArray<TypeWithAnnotations> elementTypes)
TypeSymbol inputType,
uint inputValEscape,
bool hasErrors,
DiagnosticBag diagnostics)
DiagnosticBag diagnostics,
bool underIsPattern)
{
const bool permitDesignations = false; // prevent designators under 'not'
var subPattern = BindPattern(node.Pattern, inputType, inputValEscape, permitDesignations, hasErrors, diagnostics);
bool permitDesignations = underIsPattern; // prevent designators under 'not' except under an is-pattern
var subPattern = BindPattern(node.Pattern, inputType, inputValEscape, permitDesignations, hasErrors, diagnostics, underIsPattern);
return new BoundNegatedPattern(node, subPattern, inputType: inputType, convertedType: inputType, hasErrors);
}
......
......@@ -959,7 +959,16 @@ public override BoundNode VisitIsPatternExpression(BoundIsPatternExpression node
{
Debug.Assert(!IsConditionalState);
VisitRvalue(node.Expression);
VisitPattern(node.Pattern);
var pattern = node.Pattern;
bool negated = false;
while (pattern is BoundNegatedPattern n)
{
negated = !negated;
pattern = n.Negated;
}
VisitPattern(pattern);
var reachableLabels = node.DecisionDag.ReachableLabels;
if (!reachableLabels.Contains(node.WhenTrueLabel))
{
......@@ -972,6 +981,11 @@ public override BoundNode VisitIsPatternExpression(BoundIsPatternExpression node
SetConditionalState(this.State, UnreachableState());
}
if (negated)
{
SetConditionalState(this.StateWhenFalse, this.StateWhenTrue);
}
return node;
}
......
......@@ -154,14 +154,15 @@ public void DeeplyNestedGeneric()
{
int nestingLevel = (ExecutionConditionUtil.Architecture, ExecutionConditionUtil.Configuration) switch
{
(ExecutionArchitecture.x64, ExecutionConfiguration.Debug) when ExecutionConditionUtil.IsMacOS => 200,
(ExecutionArchitecture.x64, ExecutionConfiguration.Release) when ExecutionConditionUtil.IsMacOS => 520,
_ when ExecutionConditionUtil.IsCoreClrUnix => 1200,
_ when ExecutionConditionUtil.IsMonoDesktop => 730,
(ExecutionArchitecture.x86, ExecutionConfiguration.Debug) => 460,
(ExecutionArchitecture.x86, ExecutionConfiguration.Release) => 1350,
(ExecutionArchitecture.x64, ExecutionConfiguration.Debug) => 260,
(ExecutionArchitecture.x64, ExecutionConfiguration.Release) => 750,
// Legacy baselines are indicated by comments
(ExecutionArchitecture.x64, ExecutionConfiguration.Debug) when ExecutionConditionUtil.IsMacOS => 200, // 100
(ExecutionArchitecture.x64, ExecutionConfiguration.Release) when ExecutionConditionUtil.IsMacOS => 520, // 100
_ when ExecutionConditionUtil.IsCoreClrUnix => 1200, // 1200
_ when ExecutionConditionUtil.IsMonoDesktop => 730, // 730
(ExecutionArchitecture.x86, ExecutionConfiguration.Debug) => 460, // 270
(ExecutionArchitecture.x86, ExecutionConfiguration.Release) => 1320, // 1290
(ExecutionArchitecture.x64, ExecutionConfiguration.Debug) => 260, // 170
(ExecutionArchitecture.x64, ExecutionConfiguration.Release) => 750, // 730
_ => throw new Exception($"Unexpected configuration {ExecutionConditionUtil.Architecture} {ExecutionConditionUtil.Configuration}")
};
......
......@@ -1950,6 +1950,9 @@ void Good(object o)
if (o is 1 and int x3) { }
if (o is (1 or 2) and int x4) { }
if (o is not (1 or 2) and int x5) { }
if (o is not int x6) { }
if (o is not (1 and int x7)) { }
}
void Bad(object o)
......@@ -1958,11 +1961,9 @@ void Bad(object o)
if (o is int y2 or (1 or 2)) { }
if (o is 1 or int y3) { }
if (o is (1 or 2) or int y4) { }
if (o is not int y5) { }
if (o is not (1 and int y6)) { }
if (o is Point { X: var y7 } or Animal _) { }
if (o is Point(var y8, _) or Animal _) { }
if (o is object or (1 or var y9)) { }
if (o is Point { X: var y5 } or Animal _) { }
if (o is Point(var y6, _) or Animal _) { }
if (o is object or (1 or var y7)) { }
}
void NotBad(object o)
......@@ -1984,36 +1985,30 @@ class Animal { }
";
var compilation = CreateCompilation(source, parseOptions: TestOptions.RegularPreview);
compilation.VerifyDiagnostics(
// (16,22): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// (19,22): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is int y1 or 1) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y1").WithLocation(16, 22),
// (17,22): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y1").WithLocation(19, 22),
// (20,22): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is int y2 or (1 or 2)) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y2").WithLocation(17, 22),
// (18,27): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y2").WithLocation(20, 22),
// (21,27): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is 1 or int y3) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y3").WithLocation(18, 27),
// (19,34): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y3").WithLocation(21, 27),
// (22,34): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is (1 or 2) or int y4) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y4").WithLocation(19, 34),
// (20,26): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is not int y5) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y5").WithLocation(20, 26),
// (21,33): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is not (1 and int y6)) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y6").WithLocation(21, 33),
// (22,33): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is Point { X: var y7 } or Animal _) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y7").WithLocation(22, 33),
// (23,28): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is Point(var y8, _) or Animal _) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y8").WithLocation(23, 28),
// (24,13): warning CS8794: An expression of type 'object' always matches the provided pattern.
// if (o is object or (1 or var y9)) { }
Diagnostic(ErrorCode.WRN_IsPatternAlways, "o is object or (1 or var y9)").WithArguments("object").WithLocation(24, 13),
// (24,38): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is object or (1 or var y9)) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y9").WithLocation(24, 38)
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y4").WithLocation(22, 34),
// (23,33): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is Point { X: var y5 } or Animal _) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y5").WithLocation(23, 33),
// (24,28): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is Point(var y6, _) or Animal _) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y6").WithLocation(24, 28),
// (25,13): warning CS8794: An expression of type 'object' always matches the provided pattern.
// if (o is object or (1 or var y7)) { }
Diagnostic(ErrorCode.WRN_IsPatternAlways, "o is object or (1 or var y7)").WithArguments("object").WithLocation(25, 13),
// (25,38): error CS8780: A variable may not be declared within a 'not' or 'or' pattern.
// if (o is object or (1 or var y7)) { }
Diagnostic(ErrorCode.ERR_DesignatorBeneathPatternCombinator, "y7").WithLocation(25, 38)
);
}
......@@ -5641,5 +5636,203 @@ public void ErrorRecovery_04()
Diagnostic(ErrorCode.ERR_IntDivByZero, "0/0").WithLocation(4, 22)
);
}
[Fact]
public void IsNot_01()
{
var source =
@"using System;
class C
{
static void Main()
{
object o = ""s"";
if (o is not string s) return;
Console.WriteLine(s);
}
}";
string expectedOutput = "s";
var compilation = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularWithPatternCombinators);
compilation.VerifyDiagnostics(
);
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
}
[Fact]
public void IsNot_02()
{
var source =
@"using System;
class C
{
static void Main()
{
object o = ""s"";
if (o is (not (string s))) return;
Console.WriteLine(s);
}
}";
string expectedOutput = "s";
var compilation = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularWithPatternCombinators);
compilation.VerifyDiagnostics(
);
var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput);
}
[Fact]
public void IsNot_03()
{
var source =
@"class C
{
static void Main()
{
object o = ""s"";
{
if (o is string s)
_ = s;
else
_ = s; // 1
}
{
if (o is not string s)
_ = s; // 2
else
_ = s;
}
{
if (o is not not string s)
_ = s;
else
_ = s; // 3
}
{
if (o is not not not string s)
_ = s; // 4
else
_ = s;
}
}
}";
var compilation = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularWithPatternCombinators);
compilation.VerifyDiagnostics(
// (10,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 1
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(10, 21),
// (14,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 2
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(14, 21),
// (22,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 3
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(22, 21),
// (26,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 4
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(26, 21)
);
}
[Fact]
public void IsNot_04()
{
var source =
@"class C
{
static void Main()
{
object o = ""s"";
{
if (o is (string s))
_ = s;
else
_ = s; // 1
}
{
if (o is (not (string s)))
_ = s; // 2
else
_ = s;
}
{
if (o is (not (not (string s))))
_ = s;
else
_ = s; // 3
}
{
if (o is (not (not (not (string s)))))
_ = s; // 4
else
_ = s;
}
}
}";
var compilation = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularWithPatternCombinators);
compilation.VerifyDiagnostics(
// (10,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 1
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(10, 21),
// (14,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 2
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(14, 21),
// (22,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 3
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(22, 21),
// (26,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 4
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(26, 21)
);
}
[Fact]
public void IsNot_05()
{
var source =
@"class C
{
static void Main()
{
(object, object) o = (1, 2);
{
if (o is (1, string s))
_ = s;
else
_ = s; // 1
}
{
if (o is (not (1, string s)))
_ = s; // 2
else
_ = s;
}
{
if (o is (not (not (1, string s))))
_ = s;
else
_ = s; // 3
}
{
if (o is (not (not (not (1, string s)))))
_ = s; // 4
else
_ = s;
}
}
}";
var compilation = CreateCompilation(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.RegularWithPatternCombinators);
compilation.VerifyDiagnostics(
// (10,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 1
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(10, 21),
// (14,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 2
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(14, 21),
// (22,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 3
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(22, 21),
// (26,21): error CS0165: Use of unassigned local variable 's'
// _ = s; // 4
Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(26, 21)
);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册