mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-27 15:20:09 +01:00
This is in addition to finding a `where` on the RHS of another `where`. Since a generic binding introduces `.Self`, any `where` expression that isn't part of a facet type modifying the binding itself would introduce an ambiguous `.Self`. Add virtual parse nodes for let, var, and form bindings, which goes before the type. This allows us to track if `where` appears in the binding's type. We only need to look for an invalid `where` if any appeared in the type. We combine these three nodes together into a single node kind, which requires us to remove the name from it as a child. We move it up to the Pattern node again, and rename the PatternStart nodes to PatternTypeStart as they are now located in the middle of the Pattern nodes, just before the type. And we only need to thaw `.Self` in generic bindings. Non-generic bindings can only have `.Self` through a `where` expression, since the name is not provided otherwise to non-generic bindings. And `where` expressions thaw their `.Self` independently. So the binding only needs to thaw a `.Self` that it introduced, which is only for generic bindings.
186 lines
9.9 KiB
Plaintext
186 lines
9.9 KiB
Plaintext
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
// AUTOUPDATE
|
|
// TIP: To test this file alone, run:
|
|
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/parse/testdata/generics/impl/fail_impl.carbon
|
|
// TIP: To dump output, run:
|
|
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/parse/testdata/generics/impl/fail_impl.carbon
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:10: error: expected `as` in `impl` declaration [ImplExpectedAs]
|
|
// CHECK:STDERR: impl foo bar;
|
|
// CHECK:STDERR: ^~~
|
|
// CHECK:STDERR:
|
|
impl foo bar;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:12: error: expected expression [ExpectedExpr]
|
|
// CHECK:STDERR: impl i32 as;
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
impl i32 as;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:18: error: `impl` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition]
|
|
// CHECK:STDERR: impl bool as bar unexpected;
|
|
// CHECK:STDERR: ^~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
impl bool as bar unexpected;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:6: error: expected expression [ExpectedExpr]
|
|
// CHECK:STDERR: impl return as A;
|
|
// CHECK:STDERR: ^~~~~~
|
|
// CHECK:STDERR:
|
|
impl return as A;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:6: error: expected expression [ExpectedExpr]
|
|
// CHECK:STDERR: impl return B;
|
|
// CHECK:STDERR: ^~~~~~
|
|
// CHECK:STDERR:
|
|
impl return B;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+8]]:13: error: expected `[` after `forall` in `impl` declaration [ImplExpectedAfterForall]
|
|
// CHECK:STDERR: impl forall f32;
|
|
// CHECK:STDERR: ^~~
|
|
// CHECK:STDERR:
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:16: error: expected `as` in `impl` declaration [ImplExpectedAs]
|
|
// CHECK:STDERR: impl forall f32;
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
impl forall f32;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:19: error: expected `as` in `impl` declaration [ImplExpectedAs]
|
|
// CHECK:STDERR: impl forall [] u32;
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
impl forall [] u32;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:25: error: expected `as` in `impl` declaration [ImplExpectedAs]
|
|
// CHECK:STDERR: impl forall [invalid] i8;
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
impl forall [invalid] i8;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:13: error: expected `[` after `forall` in `impl` declaration [ImplExpectedAfterForall]
|
|
// CHECK:STDERR: impl forall f16 as Quux;
|
|
// CHECK:STDERR: ^~~
|
|
// CHECK:STDERR:
|
|
impl forall f16 as Quux;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:26: error: expected `as` in `impl` declaration [ImplExpectedAs]
|
|
// CHECK:STDERR: impl forall [T: type] str;
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
impl forall [T: type] str;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:25: error: expected `as` in `impl` declaration [ImplExpectedAs]
|
|
// CHECK:STDERR: impl forall [T: type] T missing_as;
|
|
// CHECK:STDERR: ^~~~~~~~~~
|
|
// CHECK:STDERR:
|
|
impl forall [T: type] T missing_as;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:38: error: `impl` declarations must either end with a `;` or have a `{ ... }` block for a definition [ExpectedDeclSemiOrDefinition]
|
|
// CHECK:STDERR: impl forall [T: type] T as Interface extra;
|
|
// CHECK:STDERR: ^~~~~
|
|
// CHECK:STDERR:
|
|
impl forall [T: type] T as Interface extra;
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+4]]:5: error: expected expression [ExpectedExpr]
|
|
// CHECK:STDERR: impl;
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
impl;
|
|
|
|
impl
|
|
|
|
// CHECK:STDERR: fail_impl.carbon:[[@LINE+90]]:21: error: expected expression [ExpectedExpr]
|
|
// CHECK:STDERR: // CHECK:STDOUT: ]
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
// CHECK:STDOUT: - filename: fail_impl.carbon
|
|
// CHECK:STDOUT: parse_tree: [
|
|
// CHECK:STDOUT: {kind: 'FileStart', text: ''},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'foo'},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 3},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i32'},
|
|
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
|
// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 5},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'BoolTypeLiteral', text: 'bool'},
|
|
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'bar'},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 5},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'InvalidParse', text: 'return', has_error: yes},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 3},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'InvalidParse', text: 'return', has_error: yes},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 3},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
|
|
// CHECK:STDOUT: {kind: 'InvalidParse', text: 'f32', has_error: yes},
|
|
// CHECK:STDOUT: {kind: 'FloatTypeLiteral', text: 'f32'},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 5},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 2},
|
|
// CHECK:STDOUT: {kind: 'UnsignedIntTypeLiteral', text: 'u32'},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 6},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'invalid'},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 3},
|
|
// CHECK:STDOUT: {kind: 'IntTypeLiteral', text: 'i8'},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 7},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
|
|
// CHECK:STDOUT: {kind: 'InvalidParse', text: 'f16', has_error: yes},
|
|
// CHECK:STDOUT: {kind: 'FloatTypeLiteral', text: 'f16'},
|
|
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Quux'},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 7},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
|
|
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
|
|
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
|
|
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
|
|
// CHECK:STDOUT: {kind: 'StringTypeLiteral', text: 'str'},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 10},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
|
|
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
|
|
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
|
|
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'T'},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 10},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
|
|
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
|
|
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
|
|
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
|
|
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'T'},
|
|
// CHECK:STDOUT: {kind: 'ImplTypeAs', text: 'as', subtree_size: 2},
|
|
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 12},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'InvalidParse', text: ';', has_error: yes},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: ';', has_error: yes, subtree_size: 3},
|
|
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
|
|
// CHECK:STDOUT: {kind: 'InvalidParse', text: '', has_error: yes},
|
|
// CHECK:STDOUT: {kind: 'ImplDecl', text: 'impl', has_error: yes, subtree_size: 3},
|
|
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
|
|
// CHECK:STDOUT: ]
|