-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Diagnose explicit Self in extend in the parse node handler (Refactor Impl construction 1/7)
#6465
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "toolchain/check/inst.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "toolchain/check/modifiers.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "toolchain/check/name_lookup.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "toolchain/check/name_scope.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "toolchain/check/pattern_match.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "toolchain/check/type.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "toolchain/check/type_completion.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -24,6 +25,16 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace Carbon::Check { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Returns the implicit `Self` type for an `impl` when it's in a `class` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // declaration. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO: Mixin scopes also have a default `Self` type. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static auto GetImplDefaultSelfType(Context& context, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const ClassScope& class_scope) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -> SemIR::TypeId { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return context.classes().Get(class_scope.class_decl.class_id).self_type_id; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto HandleParseNode(Context& context, Parse::ImplIntroducerId node_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -> bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // This might be a generic impl. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -56,23 +67,57 @@ auto HandleParseNode(Context& context, Parse::ForallId /*node_id*/) -> bool { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto HandleParseNode(Context& context, Parse::ImplTypeAsId node_id) -> bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto [self_node, self_id] = context.node_stack().PopExprWithNodeId(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto self_type_inst_id = ExprAsType(context, self_node, self_id).inst_id; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| context.node_stack().Push(node_id, self_type_inst_id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto self_type = ExprAsType(context, self_node, self_id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const auto& introducer = context.decl_introducer_state_stack().innermost(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO: Also handle the parent scope being a mixin. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto class_scope = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TryAsClassScope(context, context.decl_name_stack().PeekParentScopeId()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (class_scope) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If we're not inside a class at all, that will be diagnosed against the | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // `extend` elsewhere. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto extend_node = introducer.modifier_node_id(ModifierOrder::Extend); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CARBON_DIAGNOSTIC(ExtendImplSelfAs, Error, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "cannot `extend` an `impl` with an explicit self type"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto diag = context.emitter().Build(extend_node, ExtendImplSelfAs); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (self_type.type_id == GetImplDefaultSelfType(context, *class_scope)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If the explicit self type is the default, suggest removing it with a | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // diagnostic, but continue as if no error occurred since the self-type | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // is semantically valid. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CARBON_DIAGNOSTIC(ExtendImplSelfAsDefault, Note, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "remove the explicit `Self` type here"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| diag.Note(self_node, ExtendImplSelfAsDefault); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (self_type.type_id != SemIR::ErrorInst::TypeId) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| diag.Emit(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (self_type.type_id != SemIR::ErrorInst::TypeId) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Otherwise, the self-type is an error. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| diag.Emit(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class_scope->name_scope->set_has_error(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self_type.inst_id = SemIR::ErrorInst::TypeInstId; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+83
to
+101
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should also call
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Introduce `Self`. Note that we add this name lexically rather than adding | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // to the `NameScopeId` of the `impl`, because this happens before we enter | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // the `impl` scope or even identify which `impl` we're declaring. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO: Revisit this once #3714 is resolved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AddNameToLookup(context, SemIR::NameId::SelfType, self_type_inst_id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AddNameToLookup(context, SemIR::NameId::SelfType, self_type.inst_id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| context.node_stack().Push(node_id, self_type.inst_id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto HandleParseNode(Context& context, Parse::ImplDefaultSelfAsId node_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -> bool { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto self_inst_id = SemIR::TypeInstId::None; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (auto self_type_id = GetImplDefaultSelfType(context); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self_type_id.has_value()) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto class_scope = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TryAsClassScope(context, context.decl_name_stack().PeekParentScopeId()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (class_scope) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+117
to
+119
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto self_type_id = GetImplDefaultSelfType(context, *class_scope); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Build the implicit access to the enclosing `Self`. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // TODO: Consider calling `HandleNameAsExpr` to build this implicit `Self` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // expression. We've already done the work to check that the enclosing | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -75,6 +75,7 @@ auto HandleParseNode(Context& context, Parse::RequireDefaultSelfImplsId node_id) | |
| } | ||
|
|
||
| CARBON_CHECK(context.types().Is<SemIR::FacetType>(self_type_id)); | ||
| // TODO: We could simplify with a call to ExprAsType, like below? | ||
| auto self_facet_as_type = AddTypeInst<SemIR::FacetAccessType>( | ||
| context, node_id, | ||
| {.type_id = SemIR::TypeType::TypeId, | ||
|
|
@@ -86,16 +87,21 @@ auto HandleParseNode(Context& context, Parse::RequireDefaultSelfImplsId node_id) | |
| auto HandleParseNode(Context& context, Parse::RequireTypeImplsId node_id) | ||
| -> bool { | ||
| auto [self_node_id, self_inst_id] = context.node_stack().PopExprWithNodeId(); | ||
| auto self_type = ExprAsType(context, self_node_id, self_inst_id); | ||
|
|
||
| auto introducer = context.decl_introducer_state_stack().innermost(); | ||
| const auto& introducer = context.decl_introducer_state_stack().innermost(); | ||
| if (introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extend)) { | ||
| CARBON_DIAGNOSTIC(RequireImplsExtendWithExplicitSelf, Error, | ||
| "`extend require impls` with explicit type"); | ||
| context.emitter().Emit(self_node_id, RequireImplsExtendWithExplicitSelf); | ||
| self_inst_id = SemIR::ErrorInst::InstId; | ||
| if (self_type.type_id != SemIR::ErrorInst::TypeId) { | ||
| CARBON_DIAGNOSTIC(RequireImplsExtendWithExplicitSelf, Error, | ||
| "`extend require impls` with explicit type"); | ||
| // TODO: If the explicit self-type matches a lookup of NameId::SelfType, | ||
| // add a note to the diagnostic: "remove the explicit `Self` type here", | ||
| // and continue without an ErrorInst. See ExtendImplSelfAsDefault. | ||
| context.emitter().Emit(self_node_id, RequireImplsExtendWithExplicitSelf); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems a bit inconsistent to be diagnosing this here but diagnosing the class case when handling the |
||
| } | ||
| self_type.inst_id = SemIR::ErrorInst::TypeInstId; | ||
|
Comment on lines
+101
to
+102
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we set the scope to be invalid here too? |
||
| } | ||
|
|
||
| auto self_type = ExprAsType(context, self_node_id, self_inst_id); | ||
| context.node_stack().Push(node_id, self_type.inst_id); | ||
| return true; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // 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 | ||
|
|
||
| #include "toolchain/check/name_scope.h" | ||
|
|
||
| namespace Carbon::Check { | ||
|
|
||
| auto TryAsClassScope(Context& context, SemIR::NameScopeId scope_id) | ||
| -> std::optional<ClassScope> { | ||
| if (!scope_id.has_value()) { | ||
| return std::nullopt; | ||
| } | ||
| auto& scope = context.name_scopes().Get(scope_id); | ||
| if (!scope.inst_id().has_value()) { | ||
| return std::nullopt; | ||
| } | ||
| auto class_decl = context.insts().TryGetAs<SemIR::ClassDecl>(scope.inst_id()); | ||
| if (!class_decl) { | ||
| return std::nullopt; | ||
| } | ||
| return {{.class_decl = *class_decl, .name_scope = &scope}}; | ||
| } | ||
|
|
||
| } // namespace Carbon::Check |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| // 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 | ||
|
|
||
| #ifndef CARBON_TOOLCHAIN_CHECK_NAME_SCOPE_H_ | ||
| #define CARBON_TOOLCHAIN_CHECK_NAME_SCOPE_H_ | ||
|
|
||
| #include <optional> | ||
|
|
||
| #include "toolchain/check/context.h" | ||
| #include "toolchain/sem_ir/ids.h" | ||
| #include "toolchain/sem_ir/typed_insts.h" | ||
|
|
||
| namespace Carbon::Check { | ||
|
|
||
| struct ClassScope { | ||
| SemIR::ClassDecl class_decl; | ||
| SemIR::NameScope* name_scope; | ||
| }; | ||
|
|
||
| // If the specified name scope corresponds to a class, returns the corresponding | ||
| // class declaration. | ||
| auto TryAsClassScope(Context& context, SemIR::NameScopeId scope_id) | ||
| -> std::optional<ClassScope>; | ||
|
|
||
| } // namespace Carbon::Check | ||
|
|
||
| #endif // CARBON_TOOLCHAIN_CHECK_NAME_SCOPE_H_ |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -123,3 +123,29 @@ interface Z { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CHECK:STDERR: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| extend require () impls Y; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // --- fail_extend_require_with_nonexistant_type.carbon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| library "[[@TEST_NAME]]"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface Y {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface Z { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CHECK:STDERR: fail_extend_require_with_nonexistant_type.carbon:[[@LINE+4]]:18: error: name `nonexistant` not found [NameNotFound] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CHECK:STDERR: extend require nonexistant impls Y; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CHECK:STDERR: ^~~~~~~~~~~ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CHECK:STDERR: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| extend require nonexistant impls Y; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // --- fail_extend_require_with_nonexistant_type_pointer.carbon | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| library "[[@TEST_NAME]]"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface Y {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface Z { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CHECK:STDERR: fail_extend_require_with_nonexistant_type_pointer.carbon:[[@LINE+4]]:18: error: name `nonexistant` not found [NameNotFound] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CHECK:STDERR: extend require nonexistant* impls Y; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CHECK:STDERR: ^~~~~~~~~~~ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // CHECK:STDERR: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| extend require nonexistant* impls Y; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+127
to
+151
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.