Caution

You’re reading a draft of the Ferrocene Language Specification. Some parts of this document might be missing, incomplete or incorrect. Our aim is to have the specification ready by the end of 2022.

5. Patterns

5.1. Patterns

Syntax

Pattern ::=
    |? PatternWithoutAlternation (| PatternWithoutAlternation)*

PatternList ::=
    Pattern (, Pattern)* ,?

PatternWithoutAlternation ::=
    PatternWithoutRange
  | RangePattern

PatternWithoutRange ::=
    IdentifierPattern
  | LiteralPattern
  | MacroInvocation
  | ParenthesizedPattern
  | PathPattern
  | ReferencePattern
  | RestPattern
  | SlicePattern
  | StructPattern
  | TuplePattern
  | UnderscorePattern

Legality Rules

5.1:1 A pattern is a construct that matches a value which satisfies all the criteria of the pattern.

5.1:2 A pattern-without-alternation is a pattern that cannot be alternated.

5.1:3 A pattern-without-range is a pattern-without-alternation that excludes range patterns.

5.1:4 A subpattern is a pattern nested within another pattern.

5.1:5 A pattern has a type, with the exception of the rest pattern if it is not the inner pattern of a slice pattern or the pattern of a possibly nested identifier pattern of a slice pattern.

5.1:6 The expected type of a pattern is the type of the value the pattern is being matched against.

5.1:7 It is a static error when lexical elements match multiple alternations of a PatternWithoutRange, except for when the pattern is &mut Identifier. Such a pattern is interpreted as a reference pattern with keyword mut containing an identifier pattern.

5.1:8 Any two pattern-without-alternations that are or-ed using character 0x7C (vertical line) are subject to the following restrictions:

5.1.1. Identifier Patterns

Syntax

IdentifierPattern ::=
    ref? mut? Binding BoundPattern?

BoundPattern ::=
    @ Pattern

Legality Rules

5.1.1:1 An identifier pattern is a pattern that binds the value it matches to a binding.

5.1.1:2 A bound pattern is a pattern that imposes a constraint on a related identifier pattern.

5.1.1:3 An identifier pattern yields a binding. An identifier pattern with keyword mut yields a mutable binding.

5.1.1:4 An identifier pattern with keyword ref is a reference identifier pattern.

5.1.1:5 The identifier pattern enters its binding into pattern scope in the value namespace if it does not resolve to a constant, a unit struct constant or a unit enum variant.

5.1.1:6 It is a static error if the identifier pattern consists of anything other than a binding when the binding resolves to a constant, a unit struct constant or a unit enum variant.

5.1.1:7 It is a static error if the binding of an identifier pattern resolves to a tuple struct or a tuple enum variant.

5.1.1:8 An identifier pattern is irrefutable when:

5.1.1:12 If the identifier pattern does not have a bound pattern, then the type of its binding is determined as follows:

5.1.1:16 If the identifier pattern has a bound pattern, then the type of its binding is determined as follows:

Examples

5.1.1:20 An identifier pattern in the context of a let expression.

let x = 42;

5.1.1:21 An identifier pattern with a bound pattern in the context of a match expression.

match x {
    small @ 1 ..= 5 => (),
    _ => (),
}

5.1.2. Literal Patterns

Syntax

LiteralPattern ::=
    BooleanLiteral
  | ByteLiteral
  | ByteStringLiteral
  | CharacterLiteral
  | -? NumericLiteral
  | RawByteStringLiteral
  | RawStringLiteral
  | SimpleStringLiteral

Legality Rules

5.1.2:1 A literal pattern is a pattern that matches a literal.

5.1.2:2 A literal pattern is always refutable.

5.1.2:3 The type of a literal pattern is the type of the specified literal.

Examples

5.1.2:4 Two literal patterns in the context of a match expression. See Paragraph 5.1.1. for the declaration of x.

match x {
    -2 => (),
    36 => (),
    _  => (),
}

5.1.3. Parenthesized Patterns

Syntax

ParenthesizedPattern ::=
    ( Pattern )

Legality Rules

5.1.3:1 A parenthesized pattern is a pattern that controls the precedence of its subpatterns.

5.1.3:2 A parenthesized pattern is irrefutable when its nested pattern is irrefutable.

5.1.3:3 The type of a parenthesized pattern is the type of its nested pattern.

Examples

5.1.3:4 See Paragraph 5.1.1. for the declaration of x.

let ref_x = &x;

5.1.3:5 A parenthesized pattern inside a reference pattern in the context of a match expression.

match ref_x {
    &(1 ..= 5) => (),
    _ => (),
}

5.1.4. Path Patterns

Syntax

PathPattern ::=
    PathInExpression
  | QualifiedPathInExpression

Legality Rules

5.1.4:1 A path pattern is a pattern that matches a constant, a unit enum variant, or a unit struct constant indicated by a path.

5.1.4:2 A path pattern expressed as a path-in-expression shall refer to either an associated constant, or a constant.

5.1.4:3 When a path pattern refers to an associated constant or a constant, the associated constant or constant shall not be of a union type.

5.1.4:4 When a path pattern refers to an associated constant or a constant, the type of the associated constant or constant shall be structurally equal.

5.1.4:5 When the type of the path pattern is of an enum type or struct type, then the enum type or struct type shall be subject to attribute derive with arguments core::cmp::Eq and core::cmp::PartialEq.

5.1.4:6 A path pattern expressed as a qualified path-in-expression shall refer to an associated constant.

5.1.4:7 A path pattern is irrefutable when it refers to:

5.1.4:11 The type of a path pattern is the type of the constant, unit enum variant, or unit struct constant the path resolved to.

Examples

mod module {
     pub const ZERO: i32 = 0;
}

enum Enum { Variant }

5.1.4:12 See Paragraph 5.1.1. for the declaration of x.

match x {
    module::ZERO => (),
    Enum::Variant => (),
    _  => (),
}

5.1.5. Range Patterns

Syntax

RangePattern ::=
    HalfOpenRangePattern
  | InclusiveRangePattern
  | ObsoleteRangePattern

HalfOpenRangePattern ::=
    RangePatternLowBound ..

InclusiveRangePattern ::=
    RangePatternLowBound ..= RangePatternHighBound

ObsoleteRangePattern ::=
    RangePatternLowBound ... RangePatternHighBound

RangePatternLowBound ::=
    RangePatternBound

RangePatternHighBound ::=
    RangePatternBound

RangePatternBound ::=
    ByteLiteral
  | CharacterLiteral
  | -? NumericLiteral
  | PathInExpression
  | QualifiedPathInExpression

Legality Rules

5.1.5:1 A range pattern is a pattern that matches values which fall within a range.

5.1.5:2 A half-open range pattern is a range pattern with only a range pattern low bound.

5.1.5:3 An inclusive range pattern is a range pattern with both a range pattern low bound and a range pattern high bound.

5.1.5:4 An obsolete range pattern is a range pattern that uses obsolete syntax to express an inclusive range pattern.

5.1.5:5 A range pattern bound is a constraint on the range of a range pattern.

5.1.5:6 A range pattern low bound is a range pattern bound that specifies the start of a range.

5.1.5:7 A range pattern high bound is a range pattern bound that specifies the end of a range.

5.1.5:8 A half-open range pattern shall appear within a parenthesized pattern when context is a slice pattern.

5.1.5:9 The range pattern low bound of an inclusive range pattern shall be less than or equal to its range pattern high bound.

5.1.5:10 An obsolete range pattern is equivalent to an inclusive range pattern.

5.1.5:11 A range pattern is irrefutable only when it spans the entire set of possible values of a type.

5.1.5:12 The types of the range pattern low bound and the range pattern high bound of a range pattern shall be unifiable.

5.1.5:13 The type of a range pattern is determined as follows:

5.1.5:16 A path-in-expression of a range pattern shall refer to a constant of a scalar type.

5.1.5:17 A qualified path-in-expression of a range pattern shall refer to an associated constant of a scalar type.

Examples

5.1.5:18 Two range patterns in the context of a match expression. See Paragraph 5.1.1. for the declaration of x.

match x {
    -30 ..= 2 => (),
    57 .. => (),
    _ => (),
}

5.1.6. Reference Patterns

Syntax

ReferencePattern ::=
    & mut? PatternWithoutRange

Legality Rules

5.1.6:1 A reference pattern is a pattern that dereferences a pointer that is being matched.

5.1.6:2 A reference pattern is always irrefutable.

5.1.6:3 The type of a reference pattern is determined as follows:

Examples

5.1.6:6 A reference pattern in the context of a match expression. See Paragraph 5.1.3. for the declaration of ref_x.

match ref_x {
    &23 => (),
    _ => (),
}

5.1.7. Rest Patterns

Syntax

RestPattern ::=
    ..

Legality Rules

5.1.7:1 A rest pattern is a pattern that matches zero or more elements that have not already been matched.

5.1.7:2 A rest pattern shall appear at most once within a slice pattern, an identifier pattern of a slice pattern, a tuple pattern, and a tuple struct pattern.

5.1.7:3 A rest pattern is always irrefutable.

5.1.7:4 If a rest pattern appears within a slice pattern or the identifier pattern of a slice pattern, then the type of the rest pattern is determined as follows:

Examples

5.1.7:7 A rest pattern in an identifier pattern of a slice pattern, followed by a rest pattern in a slice pattern.

match slice {
    [1, 5, .., 7] => (),
    [start, end @ ..] => (),
}

5.1.7:8 Rest patterns in tuple patterns.

match tuple {
    (1, .., y) => (),
    (.., 5) => (),
    (..) => (),
}

5.1.8. Slice Patterns

Syntax

SlicePattern ::=
    [ PatternList? ]

Legality Rules

5.1.8:1 A slice pattern is a pattern that matches arrays of fixed size and slices of dynamic size.

5.1.8:2 A slice pattern is irrefutable when it refers to:

5.1.8:5 The type of a slice pattern is the same as the expected type.

Examples

let v = vec![1, 2, 3];

5.1.8:6 A slice pattern in the context of a match expression.

match v {
    [a, b, c] => (),
    _ => ()
}

5.2. Struct Patterns

Syntax

StructPattern ::=
    RecordStructPattern
  | TupleStructPattern

Deconstructee ::=
    PathInExpression

Legality Rules

5.2:1 A struct pattern is a pattern that matches an enum value, a struct value, or a union value.

5.2:2 A deconstructee indicates the enum variant or type that is being deconstructed by a struct pattern.

5.2:3 A struct pattern is interpreted based on the deconstructee. It is a static error if a struct pattern cannot be interpreted.

5.2:4 A struct pattern is irrefutable when all of its subpatterns are irrefutable.

5.2.1. Record Struct Patterns

Syntax

RecordStructPattern ::=
    Deconstructee { RecordStructPatternContent? }

RecordStructPatternContent ::=
    RecordStructRestPattern
  | FieldDeconstructorList (, RecordStructRestPattern | ,?)

RecordStructRestPattern ::=
    OuterAttributeOrDoc* RestPattern

FieldDeconstructorList ::=
    FieldDeconstructor (, FieldDeconstructor)*

FieldDeconstructor ::=
    OuterAttributeOrDoc* (
        IndexedDeconstructor
      | NamedDeconstructor
      | ShorthandDeconstructor
    )

IndexedDeconstructor ::=
    FieldIndex : Pattern

NamedDeconstructor ::=
    Identifier : Pattern

ShorthandDeconstructor ::=
    ref? mut? Binding

FieldIndex ::=
    DecimalLiteral

Legality Rules

5.2.1:1 A record struct pattern is a pattern that matches a enum variant value, a struct value, or a union value.

5.2.1:2 The deconstructee of a record struct pattern shall resolve to an enum variant, a struct type, or a union type.

5.2.1:3 An indexed deconstructor is a construct that matches the position of a field.

5.2.1:4 An indexed deconstructor matches a field of the deconstructee when its field index and the position of the field in the deconstructee are the same. Such an indexed deconstructor is a matched indexed deconstructor.

5.2.1:5 The type of a matched indexed deconstructor and the type of the matched field shall be unifiable.

5.2.1:6 A named deconstructor is a construct that matches the name of a field.

5.2.1:7 A named deconstructor matches a field of the deconstructee when its identifier and the name of the field are the same. Such a named deconstructor is a matched named deconstructor.

5.2.1:8 The type of a matched named deconstructor and the type of the matched field shall be unifiable.

5.2.1:9 A shorthand deconstructor is a construct that matches the name of a field and binds the value of the matched field to a binding.

5.2.1:10 A shorthand deconstructor with keyword mut yields a mutable binding.

5.2.1:11 It is a static error if a shorthand deconstructor has only keyword ref or keywords ref mut, and its binding shadows a constant, a unit enum variant, or a unit struct constant.

5.2.1:12 A shorthand deconstructor is equivalent to a named deconstructor where the name of the shorthand deconstructor denotes the identifier of the named deconstructor and the entire content of the shorthand deconstructor denotes the pattern of the named deconstructor.

5.2.1:13 A shorthand deconstructor matches a field of the deconstructee when its name and the name of the field are the same. Such a shorthand deconstructor is a matched shorthand deconstructor.

5.2.1:14 The type of a matched shorthand deconstructor and the type of the matched field shall be unifiable.

5.2.1:15 If the deconstructee of a record struct pattern is a record enum variant or a record struct, then

5.2.1:21 If the deconstructee of a record struct pattern is a tuple enum variant or a tuple struct type, then

5.2.1:26 If the deconstructee of a record struct pattern is a union type, then

5.2.1:33 If the deconstructee of a record struct pattern is a unit enum variant or a unit struct, then the record struct pattern shall have at most one RecordStructRestPattern.

Examples

struct RecordStruct {
    first : u32,
    second: u32,
}

let record_struct_value = RecordStruct { first: 11, second: 22 };

match record_struct_value {
    RecordStruct { second: 33, ref first } => (),
    RecordStruct { first: 44, .. } => (),
    RecordStruct { .. } => (),
}

struct TupleStruct (
    u32,
    u32,
);

let tuple_struct_value = TupleStruct { 0: 11, 1: 22 };

match tuple_struct_value {
    TupleStruct { 1: 33, 0: 44 } => (),
    TupleStruct { 0: 55, .. } => (),
    TupleStruct { .. } => (),
}

union Union {
    first : u32,
    second: u32,
}

let union_value = Union { second: 11 };

unsafe {
    match union_value {
        Union { first: 22 } => (),
        Union { second: 33 } => (),
        _ => (),
    }
}

5.2.2. Tuple Struct Patterns

Syntax

TupleStructPattern ::=
    Deconstructee ( PatternList? )

Legality Rules

5.2.2:1 A tuple struct pattern is a pattern that matches a tuple enum variant value or a tuple struct value.

5.2.2:2 The deconstructee of a tuple struct pattern shall resolve to a tuple enum variant or a tuple struct type.

5.2.2:3 A subpattern of a tuple struct pattern matches a field of the deconstructee when its position and the position of the field in the deconstructee are the same. Such a subpattern is a matched tuple struct subpattern.

5.2.2:4 The position of a subpattern is determined as follows:

5.2.2:9 The type of the subpattern of a tuple struct pattern and the type of the matched field shall be unifiable.

5.2.2:10 For each field of the deconstructee, the tuple struct pattern shall either:

5.2.2:13 A RecordStructRestPattern is allowed even if all fields of the deconstructee have been matched.

Examples

5.2.2:14 See Paragraph 5.1.9.1. for the declarations of TupleStruct and tuple_struct_value.

match tuple_struct_value {
    TupleStruct ( 11, 22 ) => (),
    TupleStruct ( 33, .., 44 ) => (),
    TupleStruct ( .., 55 ) => (),
    TupleStruct ( 66, .. ) => (),
    TupleStruct ( .. ) => (),
}

5.2.3. Tuple Patterns

Syntax

TuplePattern ::=
    ( PatternList? )

Legality Rules

5.2.3:1 A tuple pattern is a pattern that matches a tuple which satisfies all criteria defined by its subpatterns.

5.2.3:2 A tuple pattern is irrefutable when all of its subpatterns are irrefutable.

5.2.3:3 The type of a tuple pattern is the type of the tuple being destructured.

5.2.3:4 A subpattern of a tuple pattern matches a tuple field of the tuple type when its position and the position of the tuple field in the tuple type are the same. Such a subpattern is a matched tuple subpattern.

5.2.3:5 The position of a subpattern is determined as follows:

5.2.3:10 The type of the subpattern of a tuple pattern and the type of the matched tuple field shall be unifiable.

5.2.3:11 For each tuple field of the tuple type, the tuple pattern shall either:

5.2.3:14 A RestPattern is allowed even if all tuple fields of the tuple type have been matched.

Examples

let pair = (1, "two");

5.2.3:15 A tuple pattern in the context of a let statement.

let (first, second) = pair;

5.2.4. Underscore Patterns

Syntax

UnderscorePattern ::=
    _

Legality Rules

5.2.4:1 An underscore pattern is a pattern that matches any single value.

5.2.4:2 An underscore pattern is always irrefutable.

5.2.4:3 The type of an underscore pattern is the type of the value it matches.

Examples

5.2.4:4 An underscore pattern in the context of a let statement. See Paragraph 5.1.10. for the declaration of pair.

let (first, _) = pair;

5.3. Refutability

Legality Rules

5.3:1 Refutability is a property of patterns that expresses the ability to match all possible values of a type.

5.3:2 An irrefutable pattern is a pattern that always matches the value it is being matched against.

5.3:3 A refutable pattern is a pattern that has a possibility of not matching the value it is being matched against.

5.3:4 An irrefutable type is a type that has at most one value.

5.3:5 A refutable type is a type that has more than one value.

5.3:6 An irrefutable constant is a constant of an irrefutable type.

5.3:7 A refutable constant is a constant of a refutable type.

Examples

5.3:8 x is an irrefutable pattern because it always matches 42.

let x = 42;

5.3:9 y is a refutable pattern because it does not match value when value denotes core::option::Option::None.

if let core::option::Option::Some(y) = value {

5.4. Binding Modes

Syntax

Binding ::=
    Name

Legality Rules

5.4:1 A binding pattern is either an identifier pattern or a shorthand deconstructor.

5.4:2 A binding of a binding pattern binds a matched value to a name.

5.4:3 A non-reference pattern is any pattern except non-binding patterns, path patterns, reference patterns, and underscore patterns.

5.4:4 If a binding pattern does not explicitly specify keyword ref, keyword mut, or keywords ref mut, then its binding mode uses the current binding mode of pattern matching.

5.4:5 Initially, the binding mode of a binding is by value.

5.4:6 During the process of pattern matching, each time a reference is matched against a non-reference pattern, the reference is dereferenced and the binding mode is updated as follows:

5.4:9 The process repeats if the dereferenced value is a reference.

Dynamic Semantics

5.4:10 A binding patterns binds its binding to a matched value as follows:

5.5. Pattern Matching

Dynamic Semantics

5.5:1 Pattern matching that involves a pattern and a context value proceeds as follows:

  1. 5.5:2 For each pattern-without-alternation of the pattern

    1. 5.5:3 If the pattern-without-alternation is an identifier pattern, then perform identifier pattern matching.

    2. 5.5:4 If the pattern-without-alternation is a literal pattern, then perform literal pattern matching.

    3. 5.5:5 If the pattern-without-alternation is a parenthesized pattern, then perform parenthesized pattern matching.

    4. 5.5:6 If the pattern-without-alternation is a path pattern, then perform path pattern matching.

    5. 5.5:7 If the pattern-without-alternation is a range pattern, then perform range pattern matching.

    6. 5.5:8 If the pattern-without-alternation is a reference pattern, then perform reference pattern matching.

    7. 5.5:9 If the pattern-without-alternation is a slice pattern, then perform slice pattern matching.

    8. 5.5:10 If the pattern-without-alternation is a struct pattern, then perform struct pattern matching.

    9. 5.5:11 If the pattern-without-alternation is a tuple pattern, then perform tuple pattern matching.

    10. 5.5:12 If the pattern-without-alternation is a tuple struct pattern, then perform tuple struct pattern matching.

    11. 5.5:13 If the pattern-without-alternation is an underscore pattern, then perform underscore pattern matching.

    12. 5.5:14 Otherwise pattern matching fails.

5.5:15 Only the bindings of a matched pattern-without-alternation are introduced to the corresponding scope.

5.5.1. Identifier Pattern Matching

Legality Rules

5.5.1:1 An identifier pattern with keyword mut shall require that the context value is a mutable place expression.

Dynamic Semantics

5.5.1:2 Identifier pattern matching proceeds as follows:

  1. 5.5.1:3 If the identifier pattern has a bound pattern, then

    1. 5.5.1:4 Performed pattern matching with the bound pattern and the same context value.

    2. 5.5.1:5 If matching the bound pattern fails, then matching fails.

  2. 5.5.1:6 The context value is bound to the binding of the identifier pattern according to the binding mode.

  3. 5.5.1:7 Matching succeeds.

5.5.2. Literal Pattern Matching

Dynamic Semantics

5.5.2:1 Literal pattern matching proceeds as follows:

  1. 5.5.2:2 If the literal of the literal pattern and the context value are equal, then matching succeeds.

  2. 5.5.2:3 Otherwise matching fails.

5.5.3. Parenthesized Pattern Matching

Dynamic Semantics

5.5.3:1 Parenthesized pattern matching performs pattern matching with its subpattern and the same context value.

5.5.4. Path Pattern Matching

Dynamic Semantics

5.5.4:1 Path pattern matching proceeds as follows:

  1. 5.5.4:2 If the constant, unit enum variant or unit struct the path of the path pattern resolved to and the context value are equal, then matching succeeds.

  2. 5.5.4:3 Otherwise matching fails.

5.5.5. Range Pattern Matching

Dynamic Semantics

5.5.5:1 Range pattern matching proceeds as follows:

  1. 5.5.5:2 If the range pattern is expressed as a half-open range pattern and the context value is in the inclusive range from the range pattern low bound to the maximum value of the range pattern low bound's type, then matching succeeds.

  2. 5.5.5:3 If the range pattern is expressed as either an inclusive range pattern or an obsolete range pattern and the context value is in the inclusive range from the range pattern low bound to the range pattern high bound, then matching succeeds.

  3. 5.5.5:4 Otherwise matching fails.

5.5.6. Reference Pattern Matching

Dynamic Semantics

5.5.6:1 Reference pattern matching proceeds as follows:

  1. 5.5.6:2 Dereference the context value.

  2. 5.5.6:3 Perform pattern matching with its subpattern and the dereferenced value.

5.5.7. Slice Pattern Matching

Dynamic Semantics

5.5.7:1 Slice pattern matching proceeds as follows:

  1. 5.5.7:2 If the expected type is a slice type then,

    1. 5.5.7:3 If the number of subpatterns of the slice pattern is greater than the length of the context value, then matching fails.

    2. 5.5.7:4 If the number of subpatterns of the slice pattern is less than the size of the context value and one of those subpatterns is not a rest pattern, then matching fails.

    3. 5.5.7:5 For each subpattern of the slice pattern

      1. 5.5.7:6 Perform pattern matching with the subpattern and the corresponding value from the context value, ignoring rest patterns.

      2. 5.5.7:7 If matching the subpattern fails, then matching fails.

  2. 5.5.7:8 Otherwise if the expected type is an array type

    1. 5.5.7:9 For each subpattern of the slice pattern

      1. 5.5.7:10 Perform pattern matching with the subpattern and the corresponding value from the context value, ignoring rest patterns.

      2. 5.5.7:11 If matching the subpattern fails, then matching fails.

5.5.8. Struct Pattern Matching

Dynamic Semantics

5.5.8:1 Struct pattern matching proceeds as follows:

  1. 5.5.8:2 If the number of subpatterns of the struct pattern is less than the number of fields of the context value and one of those subpatterns is not a rest pattern, then matching fails.

  2. 5.5.8:3 For each subpattern of the struct pattern

    1. 5.5.8:4 If the subpattern is a shorthand deconstructor, then the corresponding field of the context value is bound to the binding of the shorthand deconstructor according to the binding mode.

    2. 5.5.8:5 Otherwise perform pattern matching with the subpattern and the corresponding field from the context value, ignoring rest patterns.

    3. 5.5.8:6 If matching the subpattern fails, then matching fails.

5.5.9. Tuple Pattern Matching

Dynamic Semantics

5.5.9:1 Tuple pattern matching proceeds as follows:

  1. 5.5.9:2 For each subpattern of the tuple pattern

    1. 5.5.9:3 Perform pattern matching with the subpattern and the corresponding field from the context value, ignoring rest patterns.

    2. 5.5.9:4 If matching the subpattern fails, then matching fails.

5.5.10. Tuple Struct Pattern Matching

Dynamic Semantics

5.5.10:1 Tuple struct pattern matching proceeds as follows:

  1. 5.5.10:2 For each subpattern of the tuple struct pattern

    1. 5.5.10:3 Otherwise perform pattern matching with the subpattern and the corresponding field from the context value, ignoring rest patterns.

    2. 5.5.10:4 If matching the subpattern fails, then matching fails.

5.5.11. Underscore Pattern Matching

Dynamic Semantics

5.5.11:1 Underscore pattern matching proceeds as follows:

  1. 5.5.11:2 The context value is matched unconditionally.

  2. 5.5.11:3 Matching succeeds.