@@ -233,6 +233,21 @@ private PatternSyntax GenerateMatchPattern(
233233
234234 case LiteralPattern literal :
235235 {
236+ // Handle None()/None patterns on Optional scrutinees
237+ var litUnionCase = _context . SemanticInfo ? . GetPatternUnionCase ( literal ) ;
238+ if ( litUnionCase ? . Name == "None" && scrutineeType is OptionalType )
239+ {
240+ // Optional<T>.Deconstruct(out bool hasValue, out T value)
241+ // None → (false, _)
242+ return RecursivePattern ( )
243+ . WithPositionalPatternClause (
244+ PositionalPatternClause ( SeparatedList ( new [ ]
245+ {
246+ Subpattern ( ConstantPattern ( LiteralExpression ( SyntaxKind . FalseLiteralExpression ) ) ) ,
247+ Subpattern ( VarPattern ( DiscardDesignation ( ) ) )
248+ } ) ) ) ;
249+ }
250+
236251 var literalExpr = GenerateExpression ( literal . Literal ) ;
237252 return ConstantPattern ( literalExpr ) ;
238253 }
@@ -402,6 +417,12 @@ a is MemberAccessPattern ma
402417 var unionCase = _context . SemanticInfo ? . GetPatternUnionCase ( positionalPattern ) ;
403418 if ( unionCase != null )
404419 {
420+ // Handle Optional/Result synthetic union cases via Deconstruct
421+ var optResultPattern = TryGenerateOptionalResultPattern (
422+ positionalPattern , unionCase , scrutineeType , memberGuards , ref matchVarCounter ) ;
423+ if ( optResultPattern != null )
424+ return optResultPattern ;
425+
405426 return GenerateUnionCasePositionalPattern (
406427 positionalPattern , unionCase , scrutineeType , memberGuards , ref matchVarCounter ) ;
407428 }
@@ -475,6 +496,93 @@ a is MemberAccessPattern ma
475496 }
476497 }
477498
499+ /// <summary>
500+ /// Generates a C# positional deconstruction pattern for Optional/Result synthetic union cases.
501+ /// Returns null if the union case is not from a synthetic Optional/Result union.
502+ ///
503+ /// Optional[T].Deconstruct(out bool hasValue, out T value):
504+ /// Some(v) → (true, var v)
505+ /// None() → (false, _)
506+ ///
507+ /// Result[T, E].Deconstruct(out bool isOk, out T value, out E error):
508+ /// Ok(v) → (true, var v, _)
509+ /// Err(e) → (false, _, var e)
510+ /// </summary>
511+ private PatternSyntax ? TryGenerateOptionalResultPattern (
512+ PositionalPattern positionalPattern ,
513+ TypeSymbol unionCaseSymbol ,
514+ SemanticType ? scrutineeType ,
515+ List < ExpressionSyntax > memberGuards ,
516+ ref int matchVarCounter )
517+ {
518+ if ( scrutineeType is OptionalType && unionCaseSymbol . Name == "Some" )
519+ {
520+ // Some(v) → (true, var v)
521+ var subPatterns = new List < SubpatternSyntax >
522+ {
523+ Subpattern ( ConstantPattern ( LiteralExpression ( SyntaxKind . TrueLiteralExpression ) ) )
524+ } ;
525+ if ( positionalPattern . Elements . Length == 1 )
526+ {
527+ subPatterns . Add ( Subpattern ( GenerateMatchPattern (
528+ positionalPattern . Elements [ 0 ] , memberGuards , ref matchVarCounter ) ) ) ;
529+ }
530+ else
531+ {
532+ subPatterns . Add ( Subpattern ( VarPattern ( DiscardDesignation ( ) ) ) ) ;
533+ }
534+ return RecursivePattern ( )
535+ . WithPositionalPatternClause (
536+ PositionalPatternClause ( SeparatedList ( subPatterns ) ) ) ;
537+ }
538+
539+ if ( scrutineeType is ResultType && unionCaseSymbol . Name == "Ok" )
540+ {
541+ // Ok(v) → (true, var v, _)
542+ var subPatterns = new List < SubpatternSyntax >
543+ {
544+ Subpattern ( ConstantPattern ( LiteralExpression ( SyntaxKind . TrueLiteralExpression ) ) )
545+ } ;
546+ if ( positionalPattern . Elements . Length == 1 )
547+ {
548+ subPatterns . Add ( Subpattern ( GenerateMatchPattern (
549+ positionalPattern . Elements [ 0 ] , memberGuards , ref matchVarCounter ) ) ) ;
550+ }
551+ else
552+ {
553+ subPatterns . Add ( Subpattern ( VarPattern ( DiscardDesignation ( ) ) ) ) ;
554+ }
555+ subPatterns . Add ( Subpattern ( VarPattern ( DiscardDesignation ( ) ) ) ) ;
556+ return RecursivePattern ( )
557+ . WithPositionalPatternClause (
558+ PositionalPatternClause ( SeparatedList ( subPatterns ) ) ) ;
559+ }
560+
561+ if ( scrutineeType is ResultType && unionCaseSymbol . Name == "Err" )
562+ {
563+ // Err(e) → (false, _, var e)
564+ var subPatterns = new List < SubpatternSyntax >
565+ {
566+ Subpattern ( ConstantPattern ( LiteralExpression ( SyntaxKind . FalseLiteralExpression ) ) ) ,
567+ Subpattern ( VarPattern ( DiscardDesignation ( ) ) )
568+ } ;
569+ if ( positionalPattern . Elements . Length == 1 )
570+ {
571+ subPatterns . Add ( Subpattern ( GenerateMatchPattern (
572+ positionalPattern . Elements [ 0 ] , memberGuards , ref matchVarCounter ) ) ) ;
573+ }
574+ else
575+ {
576+ subPatterns . Add ( Subpattern ( VarPattern ( DiscardDesignation ( ) ) ) ) ;
577+ }
578+ return RecursivePattern ( )
579+ . WithPositionalPatternClause (
580+ PositionalPatternClause ( SeparatedList ( subPatterns ) ) ) ;
581+ }
582+
583+ return null ;
584+ }
585+
478586 /// <summary>
479587 /// Generates a C# positional pattern for a union case with fields.
480588 /// Emits: UnionName{TypeArgs}.CaseName(var field1, var field2)
0 commit comments