Require all impls constraints in impl as to be satisfied (#7531)

We checked that requirements inside the impl-as target interface were
satisfied. But we also need to check that requirements coming from the
constraint facet type, or named constraints that it targets, are
satisfied.
This commit is contained in:
Dana Jansens
2026-07-21 19:31:54 +00:00
committed by GitHub
parent 2e61685658
commit 63757d281e
9 changed files with 375 additions and 133 deletions
+1 -2
View File
@@ -421,8 +421,6 @@ auto HandleParseNode(Context& context, Parse::ImplDefinitionStartId node_id)
auto [impl_id, impl_decl_id] = BuildImplDecl(context, node_id, true);
auto& impl = context.impls().Get(impl_id);
CheckRequireDeclsSatisfied(context, node_id, impl);
impl.scope_id =
context.name_scopes().Add(impl_decl_id, SemIR::NameId::None,
context.decl_name_stack().PeekParentScopeId());
@@ -434,6 +432,7 @@ auto HandleParseNode(Context& context, Parse::ImplDefinitionStartId node_id)
context.generics().GetSelfSpecific(impl.generic_id));
StartGenericDefinition(context, impl.generic_id);
ImplWitnessStartDefinition(context, impl);
CheckRequireDeclsSatisfied(context, node_id, impl);
context.inst_block_stack().Push();
context.node_stack().Push(node_id, impl_id);
+70 -33
View File
@@ -762,15 +762,59 @@ auto CheckRequireDeclsSatisfied(Context& context, SemIR::LocId loc_id,
return;
}
const auto& interface = context.interfaces().Get(impl.interface.interface_id);
if (!interface.is_complete()) {
// This will be diagnosed later. We check for required decls before starting
// the definition to avoid inserting these lookups into the definition, as
// the lookups can end up looking for the impl being defined, which creates
// a cycle.
return;
// TODO: Check other kinds of constraints too: rewrites into targets other
// than `Self.(TargetInterface.__)` and same-type constraints. Consider maybe
// building a facet type that just excludes anything about the impl-as target
// interface, and then just perform lookup of Self as that facet type, so we
// don't have to re-implement all of the validation of impl lookup?
// The IdentifiedFacetType canonicalizes the self facets, so we do the same
// for comparing with it.
auto self_const_id = GetCanonicalFacetOrTypeValue(
context, context.constant_values().Get(impl.self_id));
auto canon_constraint_id =
context.constant_values().GetConstantTypeInstId(impl.constraint_id);
// TODO: Consider a function that just forms the key and returns the ID for an
// already-identified facet type? Or plumb through the IdentifiedFacetType?
auto identified_id = TryToIdentifyFacetType(
context, loc_id, self_const_id, canon_constraint_id,
/*allow_partially_identified=*/false);
CARBON_CHECK(identified_id.has_value());
const auto& identified = context.identified_facet_types().Get(identified_id);
for (auto req : identified.required_impls()) {
if (req.self_facet_value == self_const_id &&
req.specific_interface == identified.impl_as_target_interface()) {
// This is what the impl is implementing, so it's not already satisfied.
continue;
}
auto result = LookupImplWitness(
context, loc_id, req.self_facet_value,
GetInterfaceType(context, req.specific_interface.interface_id,
req.specific_interface.specific_id)
.AsConstantId());
if (!result.has_value()) {
CARBON_DIAGNOSTIC(IdentifiedRequireImplsNotImplemented, Error,
"constraint {0} being implemented requires that {1} "
"implements `{2}`",
SemIR::DeclaredFacetTypeId, InstIdAsConstant,
SemIR::SpecificInterface);
context.emitter().Emit(
loc_id, IdentifiedRequireImplsNotImplemented,
context.insts()
.GetAs<SemIR::FacetType>(canon_constraint_id)
.declared_facet_type_id,
context.constant_values().GetInstId(req.self_facet_value),
req.specific_interface);
}
if (!result.has_value() || result.has_error_value()) {
FillImplWitnessWithErrors(context, impl);
return;
}
}
const auto& interface = context.interfaces().Get(impl.interface.interface_id);
auto require_ids =
context.require_impls_blocks().Get(interface.require_impls_block_id);
if (require_ids.empty()) {
@@ -792,41 +836,34 @@ auto CheckRequireDeclsSatisfied(Context& context, SemIR::LocId loc_id,
auto require_specific_id = CopySpecificToGeneric(
context, SemIR::LocId(require.decl_id), interface_with_self_specific_id,
require.generic_id);
auto self_const_id = GetConstantValueInSpecific(
auto req_self_const_id = GetConstantValueInSpecific(
context.sem_ir(), require_specific_id, require.self_id);
auto facet_type_const_id = GetConstantValueInSpecific(
auto req_facet_type_const_id = GetConstantValueInSpecific(
context.sem_ir(), require_specific_id, require.facet_type_inst_id);
if (self_const_id == SemIR::ErrorInst::ConstantId ||
facet_type_const_id == SemIR::ErrorInst::ConstantId) {
if (req_self_const_id == SemIR::ErrorInst::ConstantId ||
req_facet_type_const_id == SemIR::ErrorInst::ConstantId) {
FillImplWitnessWithErrors(context, impl);
break;
return;
}
auto result =
LookupImplWitness(context, loc_id, self_const_id, facet_type_const_id);
// TODO: If the facet type contains 2 interfaces, and one is not `impl`ed,
// it would be nice to diagnose which one was not `impl`ed, but that
// requires LookupImplWitness to return a partial result, or take a
// diagnostic lambda or something.
auto result = LookupImplWitness(context, loc_id, req_self_const_id,
req_facet_type_const_id);
if (!result.has_value()) {
if (!result.has_error_value() &&
facet_type_const_id != SemIR::ErrorInst::ConstantId) {
CARBON_DIAGNOSTIC(RequireImplsNotImplemented, Error,
"interface `{0}` being implemented requires that {1} "
"implements {2}",
SemIR::SpecificInterface, SemIR::TypeId,
SemIR::DeclaredFacetTypeId);
context.emitter().Emit(
loc_id, RequireImplsNotImplemented, impl.interface,
context.types().GetTypeIdForTypeConstantId(self_const_id),
context.constant_values()
.GetInstAs<SemIR::FacetType>(facet_type_const_id)
.declared_facet_type_id);
}
CARBON_DIAGNOSTIC(InterfaceRequireImplsNotImplemented, Error,
"interface `{0}` being implemented requires that {1} "
"implements {2}",
SemIR::SpecificInterface, SemIR::TypeId,
SemIR::DeclaredFacetTypeId);
context.emitter().Emit(
loc_id, InterfaceRequireImplsNotImplemented, impl.interface,
context.types().GetTypeIdForTypeConstantId(req_self_const_id),
context.constant_values()
.GetInstAs<SemIR::FacetType>(req_facet_type_const_id)
.declared_facet_type_id);
}
if (!result.has_value() || result.has_error_value()) {
FillImplWitnessWithErrors(context, impl);
break;
return;
}
}
}
+3 -1
View File
@@ -406,6 +406,8 @@ library "[[@TEST_NAME]]";
interface I { let X: type; }
interface J {}
impl () as J {}
// Test that we avoid an infinite impl lookup cycle from an LookupImplWitness
// instruction in the impl declaration. When matching this impl during impl
// lookup, we deduce and replace `T` with a specific argument, and resolve that
@@ -413,7 +415,7 @@ interface J {}
// `.X`. If that lookup found this impl (since it's a final impl, eval can find
// it), we would deduce and produce an infinite cycle. Instructions inside the
// impl decl should not be able to find the impl.
final impl forall [T: type] T as I where .X impls J and .X = () {}
final impl forall [T: type] T as I where .X = () and .X impls J {}
fn F(unused generic T: I where .X = ()) {}
fn G() {
+9 -9
View File
@@ -349,10 +349,10 @@ impl forall [T: type] D as N(T*) {}
// CHECK:STDOUT: %Self.as_type: type = facet_access_type %Self.9f1 [symbolic]
// CHECK:STDOUT: %J.type.80f: type = facet_type <@J, @J(%empty_struct_type)> [concrete]
// CHECK:STDOUT: %J.impl_witness: <witness> = impl_witness @C.as.J.impl.%J.impl_witness_table [concrete]
// CHECK:STDOUT: %Self.043: %J.type.80f = symbolic_binding Self, 1 [symbolic]
// CHECK:STDOUT: %complete_type.7da: <witness> = complete_type_witness %I.type.81d [concrete]
// CHECK:STDOUT: %type: type = facet_type <type> [concrete]
// CHECK:STDOUT: %C.type.facet: %type = facet_value %C, () [concrete]
// CHECK:STDOUT: %complete_type.7da: <witness> = complete_type_witness %I.type.81d [concrete]
// CHECK:STDOUT: %Self.043: %J.type.80f = symbolic_binding Self, 1 [symbolic]
// CHECK:STDOUT: %J.facet: %J.type.80f = facet_value %C, (%J.impl_witness) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -521,6 +521,13 @@ impl forall [T: type] D as N(T*) {}
// CHECK:STDOUT: %Self => constants.%Self.043
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @J.WithSelf(constants.%empty_struct_type, constants.%Self.9f1) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %T => constants.%empty_struct_type
// CHECK:STDOUT: %I.type => constants.%I.type.81d
// CHECK:STDOUT: %require_complete => constants.%complete_type.7da
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @J.WithSelf(constants.%empty_struct_type, constants.%C.type.facet) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %T => constants.%empty_struct_type
@@ -536,13 +543,6 @@ impl forall [T: type] D as N(T*) {}
// CHECK:STDOUT: %I.type => constants.%I.type.81d
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @J.WithSelf(constants.%empty_struct_type, constants.%Self.9f1) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %T => constants.%empty_struct_type
// CHECK:STDOUT: %I.type => constants.%I.type.81d
// CHECK:STDOUT: %require_complete => constants.%complete_type.7da
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @J.WithSelf(constants.%empty_struct_type, constants.%J.facet) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %T => constants.%empty_struct_type
+266 -75
View File
@@ -98,9 +98,14 @@ class C {}
interface I {}
interface Incomplete;
impl C as I where .Self impls Incomplete;
interface Incomplete {}
impl C as Incomplete {}
impl C as I where .Self impls Incomplete {}
// --- declaration_incomplete_where_rewrite.carbon
// --- incomplete_where_rewrite.carbon
library "[[@TEST_NAME]]";
class C {}
@@ -110,8 +115,25 @@ interface Incomplete;
impl C as J where .Self impls Incomplete and .T = ();
interface Incomplete {}
impl C as Incomplete {}
impl C as J where .Self impls Incomplete and .T = () {}
// --- fail_incomplete_where_definition.carbon
library "[[@TEST_NAME]]";
class C {}
interface I {}
interface Incomplete;
// CHECK:STDERR: fail_incomplete_where_definition.carbon:[[@LINE+4]]:1: error: constraint `I where .Self impls Incomplete` being implemented requires that `C` implements `Incomplete` [IdentifiedRequireImplsNotImplemented]
// CHECK:STDERR: impl C as I where .Self impls Incomplete {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
impl C as I where .Self impls Incomplete {}
// --- fail_declaration_lookup_into_incomplete.carbon
library "[[@TEST_NAME]]";
@@ -120,11 +142,15 @@ class C {}
interface I {}
interface Incomplete;
// CHECK:STDERR: fail_declaration_lookup_into_incomplete.carbon:[[@LINE+4]]:1: error: constraint `I where .Self impls Incomplete` being implemented requires that `C` implements `Incomplete` [IdentifiedRequireImplsNotImplemented]
// CHECK:STDERR: impl C as I where .Self impls Incomplete {
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
impl C as I where .Self impls Incomplete {
// CHECK:STDERR: fail_declaration_lookup_into_incomplete.carbon:[[@LINE+7]]:19: error: member access into incomplete facet type `Incomplete` [QualifiedExprInIncompleteFacetTypeScope]
// CHECK:STDERR: fn F() -> Self.(Incomplete.T);
// CHECK:STDERR: ^~~~~~~~~~~~
// CHECK:STDERR: fail_declaration_lookup_into_incomplete.carbon:[[@LINE-6]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere]
// CHECK:STDERR: fail_declaration_lookup_into_incomplete.carbon:[[@LINE-10]]:1: note: interface was forward declared here [InterfaceForwardDeclaredHere]
// CHECK:STDERR: interface Incomplete;
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -386,7 +412,7 @@ interface B {
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete]
// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %Self.37e: %I.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %Incomplete.type: type = facet_type <@Incomplete> [concrete]
// CHECK:STDOUT: %.Self.frozen: %I.type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %.Self.frozen.as_type: type = facet_access_type %.Self.frozen [symbolic_self]
@@ -394,6 +420,9 @@ interface B {
// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
// CHECK:STDOUT: %I_where.type: type = facet_type <@I where .Self impls @Incomplete> [concrete]
// CHECK:STDOUT: %I.impl_witness: <witness> = impl_witness @C.as.I.impl.%I.impl_witness_table [concrete]
// CHECK:STDOUT: %Self.d08: %Incomplete.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %Incomplete.impl_witness: <witness> = impl_witness @C.as.Incomplete.impl.%Incomplete.impl_witness_table [concrete]
// CHECK:STDOUT: %Incomplete.facet: %Incomplete.type = facet_value %C, (%Incomplete.impl_witness) [concrete]
// CHECK:STDOUT: %I.facet: %I.type = facet_value %C, (%I.impl_witness) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -401,35 +430,60 @@ interface B {
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
// CHECK:STDOUT: .C = %C.decl
// CHECK:STDOUT: .I = %I.decl
// CHECK:STDOUT: .Incomplete = %Incomplete.decl
// CHECK:STDOUT: .Incomplete = %Incomplete.decl.loc6
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {}
// CHECK:STDOUT: %Incomplete.decl: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {}
// CHECK:STDOUT: %Incomplete.decl.loc6: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {}
// CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} {
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
// CHECK:STDOUT: %.Self.frozen: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %base_facet_type = requirement_base_facet_type %I.ref [concrete]
// CHECK:STDOUT: %.Self.ref.loc8_19.1: %I.type = name_ref .Self, %.Self.frozen [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %I.ref.loc8: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
// CHECK:STDOUT: %.Self.frozen.loc8: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %base_facet_type.loc8 = requirement_base_facet_type %I.ref.loc8 [concrete]
// CHECK:STDOUT: %.Self.ref.loc8_19.1: %I.type = name_ref .Self, %.Self.frozen.loc8 [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %Incomplete.ref.loc8: type = name_ref Incomplete, file.%Incomplete.decl.loc6 [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: %.Self.as_type.loc8_19.1: type = facet_access_type %.Self.ref.loc8_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc8_19.1: type = converted %.Self.ref.loc8_19.1, %.Self.as_type.loc8_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %impls.loc8_25.1 = requirement_impls %.loc8_19.1, %Incomplete.ref [concrete]
// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.ref.loc8_19.2: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %impls.loc8_25.1 = requirement_impls %.loc8_19.1, %Incomplete.ref.loc8 [concrete]
// CHECK:STDOUT: %.Self.loc8: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.ref.loc8_19.2: %I.type = name_ref .Self, %.Self.loc8 [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.as_type.loc8_19.2: type = facet_access_type %.Self.ref.loc8_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %.loc8_19.2: type = converted %.Self.ref.loc8_19.1, %.Self.as_type.loc8_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %impls.loc8_25.2 = requirement_impls %.loc8_19.2, %Incomplete.ref [concrete]
// CHECK:STDOUT: %impls.loc8_25.2 = requirement_impls %.loc8_19.2, %Incomplete.ref.loc8 [concrete]
// CHECK:STDOUT: %.loc8_13: type = where_expr [concrete = constants.%I_where.type] {
// CHECK:STDOUT: %base_facet_type = requirement_base_facet_type %I.ref [concrete]
// CHECK:STDOUT: %impls.loc8_25.2 = requirement_impls %.loc8_19.2, %Incomplete.ref [concrete]
// CHECK:STDOUT: %base_facet_type.loc8 = requirement_base_facet_type %I.ref.loc8 [concrete]
// CHECK:STDOUT: %impls.loc8_25.2 = requirement_impls %.loc8_19.2, %Incomplete.ref.loc8 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: %Incomplete.decl.loc10: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {}
// CHECK:STDOUT: impl_decl @C.as.Incomplete.impl [concrete] {} {
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl.loc6 [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} {
// CHECK:STDOUT: %C.ref.loc13: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %I.ref.loc13: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
// CHECK:STDOUT: %.Self.frozen.loc13: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %base_facet_type.loc13 = requirement_base_facet_type %I.ref.loc13 [concrete]
// CHECK:STDOUT: %.Self.ref.loc13_19.1: %I.type = name_ref .Self, %.Self.frozen.loc13 [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %Incomplete.ref.loc13: type = name_ref Incomplete, file.%Incomplete.decl.loc6 [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: %.Self.as_type.loc13_19.1: type = facet_access_type %.Self.ref.loc13_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc13_19.1: type = converted %.Self.ref.loc13_19.1, %.Self.as_type.loc13_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %impls.loc13_25.1 = requirement_impls %.loc13_19.1, %Incomplete.ref.loc13 [concrete]
// CHECK:STDOUT: %.Self.loc13: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.ref.loc13_19.2: %I.type = name_ref .Self, %.Self.loc13 [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.as_type.loc13_19.2: type = facet_access_type %.Self.ref.loc13_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %.loc13_19.2: type = converted %.Self.ref.loc13_19.1, %.Self.as_type.loc13_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %impls.loc13_25.2 = requirement_impls %.loc13_19.2, %Incomplete.ref.loc13 [concrete]
// CHECK:STDOUT: %.loc13_13: type = where_expr [concrete = constants.%I_where.type] {
// CHECK:STDOUT: %base_facet_type.loc13 = requirement_base_facet_type %I.ref.loc13 [concrete]
// CHECK:STDOUT: %impls.loc13_25.2 = requirement_impls %.loc13_19.2, %Incomplete.ref.loc13 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @I {
// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic = constants.%Self]
// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic = constants.%Self.37e]
// CHECK:STDOUT: %I.WithSelf.decl = interface_with_self_decl @I [concrete]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
@@ -439,9 +493,18 @@ interface B {
// CHECK:STDOUT: !requires:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @Incomplete;
// CHECK:STDOUT: interface @Incomplete {
// CHECK:STDOUT: %Self: %Incomplete.type = symbolic_binding Self, 0 [symbolic = constants.%Self.d08]
// CHECK:STDOUT: %Incomplete.WithSelf.decl = interface_with_self_decl @Incomplete [concrete]
// CHECK:STDOUT:
// CHECK:STDOUT: impl @C.as.I.impl: %C.ref as %.loc8_13 {
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT:
// CHECK:STDOUT: !requires:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: impl @C.as.I.impl: %C.ref.loc8 as %.loc8_13 {
// CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @C.as.I.impl [concrete]
// CHECK:STDOUT: %I.impl_witness: <witness> = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness]
// CHECK:STDOUT:
@@ -450,6 +513,15 @@ interface B {
// CHECK:STDOUT: witness = %I.impl_witness
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: impl @C.as.Incomplete.impl: %C.ref as %Incomplete.ref {
// CHECK:STDOUT: %Incomplete.impl_witness_table = impl_witness_table (), @C.as.Incomplete.impl [concrete]
// CHECK:STDOUT: %Incomplete.impl_witness: <witness> = impl_witness %Incomplete.impl_witness_table [concrete = constants.%Incomplete.impl_witness]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: extend %Incomplete.ref
// CHECK:STDOUT: witness = %Incomplete.impl_witness
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type]
// CHECK:STDOUT: complete_type_witness = %complete_type
@@ -458,7 +530,15 @@ interface B {
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @I.WithSelf(constants.%Self) {
// CHECK:STDOUT: specific @I.WithSelf(constants.%Self.37e) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Incomplete.WithSelf(constants.%Self.d08) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Incomplete.WithSelf(constants.%Incomplete.facet) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -466,14 +546,14 @@ interface B {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- declaration_incomplete_where_rewrite.carbon
// CHECK:STDOUT: --- incomplete_where_rewrite.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
// CHECK:STDOUT: %J.type: type = facet_type <@J> [concrete]
// CHECK:STDOUT: %Self: %J.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %Self.653: %J.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %J.assoc_type: type = assoc_entity_type @J [concrete]
// CHECK:STDOUT: %assoc0: %J.assoc_type = assoc_entity element0, @J.WithSelf.%T [concrete]
// CHECK:STDOUT: %Incomplete.type: type = facet_type <@Incomplete> [concrete]
@@ -489,6 +569,9 @@ interface B {
// CHECK:STDOUT: %impl.elem0.bbd: type = impl_witness_access %J.lookup_impl_witness.df8, element0 [symbolic_self]
// CHECK:STDOUT: %J_where.type: type = facet_type <@J where .Self impls @Incomplete and %impl.elem0.bbd = %empty_tuple.type> [concrete]
// CHECK:STDOUT: %J.impl_witness: <witness> = impl_witness @C.as.J.impl.%J.impl_witness_table [concrete]
// CHECK:STDOUT: %Self.d08: %Incomplete.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %Incomplete.impl_witness: <witness> = impl_witness @C.as.Incomplete.impl.%Incomplete.impl_witness_table [concrete]
// CHECK:STDOUT: %Incomplete.facet: %Incomplete.type = facet_value %C, (%Incomplete.impl_witness) [concrete]
// CHECK:STDOUT: %J.facet: %J.type = facet_value %C, (%J.impl_witness) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -496,18 +579,18 @@ interface B {
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
// CHECK:STDOUT: .C = %C.decl
// CHECK:STDOUT: .J = %J.decl
// CHECK:STDOUT: .Incomplete = %Incomplete.decl
// CHECK:STDOUT: .Incomplete = %Incomplete.decl.loc6
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
// CHECK:STDOUT: %J.decl: type = interface_decl @J [concrete = constants.%J.type] {} {}
// CHECK:STDOUT: %Incomplete.decl: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {}
// CHECK:STDOUT: %Incomplete.decl.loc6: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {}
// CHECK:STDOUT: impl_decl @C.as.J.impl [concrete] {} {
// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %J.ref.loc8: type = name_ref J, file.%J.decl [concrete = constants.%J.type]
// CHECK:STDOUT: %.Self.frozen.loc8: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %base_facet_type.loc8 = requirement_base_facet_type %J.ref.loc8 [concrete]
// CHECK:STDOUT: %.Self.ref.loc8_19.1: %J.type = name_ref .Self, %.Self.frozen.loc8 [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %Incomplete.ref.loc8: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: %Incomplete.ref.loc8: type = name_ref Incomplete, file.%Incomplete.decl.loc6 [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: %.Self.as_type.loc8_19.1: type = facet_access_type %.Self.ref.loc8_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc8_19.1: type = converted %.Self.ref.loc8_19.1, %.Self.as_type.loc8_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %impls.loc8_25.1 = requirement_impls %.loc8_19.1, %Incomplete.ref.loc8 [concrete]
@@ -532,41 +615,46 @@ interface B {
// CHECK:STDOUT: %rewrite.loc8_49.2 = requirement_rewrite %impl.elem0.loc8_46.2, %.loc8_52.2 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: %Incomplete.decl.loc10: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {}
// CHECK:STDOUT: impl_decl @C.as.Incomplete.impl [concrete] {} {
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl.loc6 [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: impl_decl @C.as.J.impl [concrete] {} {
// CHECK:STDOUT: %C.ref.loc10: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %J.ref.loc10: type = name_ref J, file.%J.decl [concrete = constants.%J.type]
// CHECK:STDOUT: %.Self.frozen.loc10: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %base_facet_type.loc10 = requirement_base_facet_type %J.ref.loc10 [concrete]
// CHECK:STDOUT: %.Self.ref.loc10_19.1: %J.type = name_ref .Self, %.Self.frozen.loc10 [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %Incomplete.ref.loc10: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: %.Self.as_type.loc10_19.1: type = facet_access_type %.Self.ref.loc10_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc10_19.1: type = converted %.Self.ref.loc10_19.1, %.Self.as_type.loc10_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %impls.loc10_25.1 = requirement_impls %.loc10_19.1, %Incomplete.ref.loc10 [concrete]
// CHECK:STDOUT: %.Self.ref.loc10_46: %J.type = name_ref .Self, %.Self.frozen.loc10 [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %.Self.as_type.loc10_46: type = facet_access_type %.Self.ref.loc10_46 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc10_46: type = converted %.Self.ref.loc10_46, %.Self.as_type.loc10_46 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %T.ref.loc10: %J.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0]
// CHECK:STDOUT: %impl.elem0.loc10_46.1: type = impl_witness_access constants.%J.lookup_impl_witness.cb1, element0 [symbolic_self = constants.%impl.elem0.221]
// CHECK:STDOUT: %.loc10_52.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc10_52.2: type = converted %.loc10_52.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: %rewrite.loc10_49.1 = requirement_rewrite %impl.elem0.loc10_46.1, %.loc10_52.2 [concrete]
// CHECK:STDOUT: %.Self.loc10: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.ref.loc10_19.2: %J.type = name_ref .Self, %.Self.loc10 [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.as_type.loc10_19.2: type = facet_access_type %.Self.ref.loc10_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %.loc10_19.2: type = converted %.Self.ref.loc10_19.1, %.Self.as_type.loc10_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %impls.loc10_25.2 = requirement_impls %.loc10_19.2, %Incomplete.ref.loc10 [concrete]
// CHECK:STDOUT: %impl.elem0.loc10_46.2: type = impl_witness_access constants.%J.lookup_impl_witness.df8, element0 [symbolic_self = constants.%impl.elem0.bbd]
// CHECK:STDOUT: %rewrite.loc10_49.2 = requirement_rewrite %impl.elem0.loc10_46.2, %.loc10_52.2 [concrete]
// CHECK:STDOUT: %.loc10_13: type = where_expr [concrete = constants.%J_where.type] {
// CHECK:STDOUT: %base_facet_type.loc10 = requirement_base_facet_type %J.ref.loc10 [concrete]
// CHECK:STDOUT: %impls.loc10_25.2 = requirement_impls %.loc10_19.2, %Incomplete.ref.loc10 [concrete]
// CHECK:STDOUT: %rewrite.loc10_49.2 = requirement_rewrite %impl.elem0.loc10_46.2, %.loc10_52.2 [concrete]
// CHECK:STDOUT: %C.ref.loc13: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %J.ref.loc13: type = name_ref J, file.%J.decl [concrete = constants.%J.type]
// CHECK:STDOUT: %.Self.frozen.loc13: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %base_facet_type.loc13 = requirement_base_facet_type %J.ref.loc13 [concrete]
// CHECK:STDOUT: %.Self.ref.loc13_19.1: %J.type = name_ref .Self, %.Self.frozen.loc13 [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %Incomplete.ref.loc13: type = name_ref Incomplete, file.%Incomplete.decl.loc6 [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: %.Self.as_type.loc13_19.1: type = facet_access_type %.Self.ref.loc13_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc13_19.1: type = converted %.Self.ref.loc13_19.1, %.Self.as_type.loc13_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %impls.loc13_25.1 = requirement_impls %.loc13_19.1, %Incomplete.ref.loc13 [concrete]
// CHECK:STDOUT: %.Self.ref.loc13_46: %J.type = name_ref .Self, %.Self.frozen.loc13 [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %.Self.as_type.loc13_46: type = facet_access_type %.Self.ref.loc13_46 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc13_46: type = converted %.Self.ref.loc13_46, %.Self.as_type.loc13_46 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %T.ref.loc13: %J.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0]
// CHECK:STDOUT: %impl.elem0.loc13_46.1: type = impl_witness_access constants.%J.lookup_impl_witness.cb1, element0 [symbolic_self = constants.%impl.elem0.221]
// CHECK:STDOUT: %.loc13_52.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc13_52.2: type = converted %.loc13_52.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: %rewrite.loc13_49.1 = requirement_rewrite %impl.elem0.loc13_46.1, %.loc13_52.2 [concrete]
// CHECK:STDOUT: %.Self.loc13: %J.type = symbolic_binding .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.ref.loc13_19.2: %J.type = name_ref .Self, %.Self.loc13 [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.as_type.loc13_19.2: type = facet_access_type %.Self.ref.loc13_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %.loc13_19.2: type = converted %.Self.ref.loc13_19.1, %.Self.as_type.loc13_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %impls.loc13_25.2 = requirement_impls %.loc13_19.2, %Incomplete.ref.loc13 [concrete]
// CHECK:STDOUT: %impl.elem0.loc13_46.2: type = impl_witness_access constants.%J.lookup_impl_witness.df8, element0 [symbolic_self = constants.%impl.elem0.bbd]
// CHECK:STDOUT: %rewrite.loc13_49.2 = requirement_rewrite %impl.elem0.loc13_46.2, %.loc13_52.2 [concrete]
// CHECK:STDOUT: %.loc13_13: type = where_expr [concrete = constants.%J_where.type] {
// CHECK:STDOUT: %base_facet_type.loc13 = requirement_base_facet_type %J.ref.loc13 [concrete]
// CHECK:STDOUT: %impls.loc13_25.2 = requirement_impls %.loc13_19.2, %Incomplete.ref.loc13 [concrete]
// CHECK:STDOUT: %rewrite.loc13_49.2 = requirement_rewrite %impl.elem0.loc13_46.2, %.loc13_52.2 [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @J {
// CHECK:STDOUT: %Self: %J.type = symbolic_binding Self, 0 [symbolic = constants.%Self]
// CHECK:STDOUT: %Self: %J.type = symbolic_binding Self, 0 [symbolic = constants.%Self.653]
// CHECK:STDOUT: %J.WithSelf.decl = interface_with_self_decl @J [concrete]
// CHECK:STDOUT:
// CHECK:STDOUT: !with Self:
@@ -582,7 +670,16 @@ interface B {
// CHECK:STDOUT: !requires:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @Incomplete;
// CHECK:STDOUT: interface @Incomplete {
// CHECK:STDOUT: %Self: %Incomplete.type = symbolic_binding Self, 0 [symbolic = constants.%Self.d08]
// CHECK:STDOUT: %Incomplete.WithSelf.decl = interface_with_self_decl @Incomplete [concrete]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT:
// CHECK:STDOUT: !requires:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: impl @C.as.J.impl: %C.ref.loc8 as %.loc8_13 {
// CHECK:STDOUT: %J.impl_witness_table = impl_witness_table (%impl_witness_assoc_constant), @C.as.J.impl [concrete]
@@ -594,6 +691,15 @@ interface B {
// CHECK:STDOUT: witness = %J.impl_witness
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: impl @C.as.Incomplete.impl: %C.ref as %Incomplete.ref {
// CHECK:STDOUT: %Incomplete.impl_witness_table = impl_witness_table (), @C.as.Incomplete.impl [concrete]
// CHECK:STDOUT: %Incomplete.impl_witness: <witness> = impl_witness %Incomplete.impl_witness_table [concrete = constants.%Incomplete.impl_witness]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: extend %Incomplete.ref
// CHECK:STDOUT: witness = %Incomplete.impl_witness
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type]
// CHECK:STDOUT: complete_type_witness = %complete_type
@@ -602,7 +708,7 @@ interface B {
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @J.WithSelf(constants.%Self) {
// CHECK:STDOUT: specific @J.WithSelf(constants.%Self.653) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -610,10 +716,100 @@ interface B {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Incomplete.WithSelf(constants.%Self.d08) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Incomplete.WithSelf(constants.%Incomplete.facet) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @J.WithSelf(constants.%J.facet) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_incomplete_where_definition.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
// CHECK:STDOUT: %C: type = class_type @C [concrete]
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %empty_struct_type [concrete]
// CHECK:STDOUT: %I.type: type = facet_type <@I> [concrete]
// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic]
// CHECK:STDOUT: %Incomplete.type: type = facet_type <@Incomplete> [concrete]
// CHECK:STDOUT: %.Self.frozen: %I.type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %.Self.frozen.as_type: type = facet_access_type %.Self.frozen [symbolic_self]
// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self]
// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self [symbolic_self]
// CHECK:STDOUT: %I_where.type: type = facet_type <@I where .Self impls @Incomplete> [concrete]
// CHECK:STDOUT: %I.impl_witness: <witness> = impl_witness @C.as.I.impl.%I.impl_witness_table [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
// CHECK:STDOUT: .C = %C.decl
// CHECK:STDOUT: .I = %I.decl
// CHECK:STDOUT: .Incomplete = %Incomplete.decl
// CHECK:STDOUT: }
// CHECK:STDOUT: %C.decl: type = class_decl @C [concrete = constants.%C] {} {}
// CHECK:STDOUT: %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {}
// CHECK:STDOUT: %Incomplete.decl: type = interface_decl @Incomplete [concrete = constants.%Incomplete.type] {} {}
// CHECK:STDOUT: impl_decl @C.as.I.impl [concrete] {} {
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [concrete = constants.%C]
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
// CHECK:STDOUT: %.Self.frozen: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %base_facet_type = requirement_base_facet_type %I.ref [concrete]
// CHECK:STDOUT: %.Self.ref.loc12_19.1: %I.type = name_ref .Self, %.Self.frozen [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: %.Self.as_type.loc12_19.1: type = facet_access_type %.Self.ref.loc12_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc12_19.1: type = converted %.Self.ref.loc12_19.1, %.Self.as_type.loc12_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %impls.loc12_25.1 = requirement_impls %.loc12_19.1, %Incomplete.ref [concrete]
// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.ref.loc12_19.2: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.as_type.loc12_19.2: type = facet_access_type %.Self.ref.loc12_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %.loc12_19.2: type = converted %.Self.ref.loc12_19.1, %.Self.as_type.loc12_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %impls.loc12_25.2 = requirement_impls %.loc12_19.2, %Incomplete.ref [concrete]
// CHECK:STDOUT: %.loc12_13: type = where_expr [concrete = constants.%I_where.type] {
// CHECK:STDOUT: %base_facet_type = requirement_base_facet_type %I.ref [concrete]
// CHECK:STDOUT: %impls.loc12_25.2 = requirement_impls %.loc12_19.2, %Incomplete.ref [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @I {
// CHECK:STDOUT: %Self: %I.type = symbolic_binding Self, 0 [symbolic = constants.%Self]
// CHECK:STDOUT: %I.WithSelf.decl = interface_with_self_decl @I [concrete]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = %Self
// CHECK:STDOUT: witness = ()
// CHECK:STDOUT:
// CHECK:STDOUT: !requires:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: interface @Incomplete;
// CHECK:STDOUT:
// CHECK:STDOUT: impl @C.as.I.impl: %C.ref as %.loc12_13 {
// CHECK:STDOUT: %I.impl_witness_table = impl_witness_table (), @C.as.I.impl [concrete]
// CHECK:STDOUT: %I.impl_witness: <witness> = impl_witness %I.impl_witness_table [concrete = constants.%I.impl_witness]
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: extend %.loc12_13
// CHECK:STDOUT: witness = <error>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness constants.%empty_struct_type [concrete = constants.%complete_type]
// CHECK:STDOUT: complete_type_witness = %complete_type
// CHECK:STDOUT:
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Self = constants.%C
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @I.WithSelf(constants.%Self) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_declaration_lookup_into_incomplete.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -631,7 +827,6 @@ interface B {
// CHECK:STDOUT: %I.impl_witness: <witness> = impl_witness @C.as.I.impl.%I.impl_witness_table [concrete]
// CHECK:STDOUT: %C.as.I.impl.F.type: type = fn_type @C.as.I.impl.F [concrete]
// CHECK:STDOUT: %C.as.I.impl.F: %C.as.I.impl.F.type = struct_value () [concrete]
// CHECK:STDOUT: %I.facet: %I.type = facet_value %C, (%I.impl_witness) [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -648,19 +843,19 @@ interface B {
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
// CHECK:STDOUT: %.Self.frozen: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %base_facet_type = requirement_base_facet_type %I.ref [concrete]
// CHECK:STDOUT: %.Self.ref.loc8_19.1: %I.type = name_ref .Self, %.Self.frozen [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %.Self.ref.loc12_19.1: %I.type = name_ref .Self, %.Self.frozen [symbolic_self = constants.%.Self.frozen]
// CHECK:STDOUT: %Incomplete.ref: type = name_ref Incomplete, file.%Incomplete.decl [concrete = constants.%Incomplete.type]
// CHECK:STDOUT: %.Self.as_type.loc8_19.1: type = facet_access_type %.Self.ref.loc8_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc8_19.1: type = converted %.Self.ref.loc8_19.1, %.Self.as_type.loc8_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %impls.loc8_25.1 = requirement_impls %.loc8_19.1, %Incomplete.ref [concrete]
// CHECK:STDOUT: %.Self.as_type.loc12_19.1: type = facet_access_type %.Self.ref.loc12_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %.loc12_19.1: type = converted %.Self.ref.loc12_19.1, %.Self.as_type.loc12_19.1 [symbolic_self = constants.%.Self.frozen.as_type]
// CHECK:STDOUT: %impls.loc12_25.1 = requirement_impls %.loc12_19.1, %Incomplete.ref [concrete]
// CHECK:STDOUT: %.Self: %I.type = symbolic_binding .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.ref.loc8_19.2: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.as_type.loc8_19.2: type = facet_access_type %.Self.ref.loc8_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %.loc8_19.2: type = converted %.Self.ref.loc8_19.1, %.Self.as_type.loc8_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %impls.loc8_25.2 = requirement_impls %.loc8_19.2, %Incomplete.ref [concrete]
// CHECK:STDOUT: %.loc8_13: type = where_expr [concrete = constants.%I_where.type] {
// CHECK:STDOUT: %.Self.ref.loc12_19.2: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.as_type.loc12_19.2: type = facet_access_type %.Self.ref.loc12_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %.loc12_19.2: type = converted %.Self.ref.loc12_19.1, %.Self.as_type.loc12_19.2 [symbolic_self = constants.%.Self.as_type]
// CHECK:STDOUT: %impls.loc12_25.2 = requirement_impls %.loc12_19.2, %Incomplete.ref [concrete]
// CHECK:STDOUT: %.loc12_13: type = where_expr [concrete = constants.%I_where.type] {
// CHECK:STDOUT: %base_facet_type = requirement_base_facet_type %I.ref [concrete]
// CHECK:STDOUT: %impls.loc8_25.2 = requirement_impls %.loc8_19.2, %Incomplete.ref [concrete]
// CHECK:STDOUT: %impls.loc12_25.2 = requirement_impls %.loc12_19.2, %Incomplete.ref [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -679,7 +874,7 @@ interface B {
// CHECK:STDOUT:
// CHECK:STDOUT: interface @Incomplete;
// CHECK:STDOUT:
// CHECK:STDOUT: impl @C.as.I.impl: %C.ref as %.loc8_13 {
// CHECK:STDOUT: impl @C.as.I.impl: %C.ref as %.loc12_13 {
// CHECK:STDOUT: %C.as.I.impl.F.decl: %C.as.I.impl.F.type = fn_decl @C.as.I.impl.F [concrete = constants.%C.as.I.impl.F] {
// CHECK:STDOUT: %return.patt: <error> = return_slot_pattern <error>, <error> [concrete = <error>]
// CHECK:STDOUT: } {
@@ -694,8 +889,8 @@ interface B {
// CHECK:STDOUT: !members:
// CHECK:STDOUT: .Incomplete = <poisoned>
// CHECK:STDOUT: .F = %C.as.I.impl.F.decl
// CHECK:STDOUT: extend %.loc8_13
// CHECK:STDOUT: witness = %I.impl_witness
// CHECK:STDOUT: extend %.loc12_13
// CHECK:STDOUT: witness = <error>
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
@@ -712,10 +907,6 @@ interface B {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @I.WithSelf(constants.%I.facet) {
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_unidentified_constraint.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: constants {
@@ -23,7 +23,7 @@ interface Y {
impl () as Y;
// () needs to impl Z at the start of the definition.
// CHECK:STDERR: fail_missing_extend_require_for_concrete_type.carbon:[[@LINE+4]]:1: error: interface `Y` being implemented requires that `()` implements `Z` [RequireImplsNotImplemented]
// CHECK:STDERR: fail_missing_extend_require_for_concrete_type.carbon:[[@LINE+4]]:1: error: interface `Y` being implemented requires that `()` implements `Z` [InterfaceRequireImplsNotImplemented]
// CHECK:STDERR: impl () as Y {}
// CHECK:STDERR: ^~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -42,7 +42,7 @@ interface Y {
impl () as Y;
// () needs to impl Z at the start of the definition.
// CHECK:STDERR: fail_missing_require_for_concrete_type.carbon:[[@LINE+4]]:1: error: interface `Y` being implemented requires that `()` implements `Z` [RequireImplsNotImplemented]
// CHECK:STDERR: fail_missing_require_for_concrete_type.carbon:[[@LINE+4]]:1: error: interface `Y` being implemented requires that `()` implements `Z` [InterfaceRequireImplsNotImplemented]
// CHECK:STDERR: impl () as Y {}
// CHECK:STDERR: ^~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -61,7 +61,7 @@ interface Y {
impl forall [T: type] T as Y;
// T needs to impl Z at the start of the definition.
// CHECK:STDERR: fail_missing_extend_require_for_symbolic_type.carbon:[[@LINE+4]]:1: error: interface `Y` being implemented requires that `T` implements `Z` [RequireImplsNotImplemented]
// CHECK:STDERR: fail_missing_extend_require_for_symbolic_type.carbon:[[@LINE+4]]:1: error: interface `Y` being implemented requires that `T` implements `Z` [InterfaceRequireImplsNotImplemented]
// CHECK:STDERR: impl forall [T: type] T as Y {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -80,7 +80,7 @@ interface Y {
impl forall [T: type] T as Y;
// T needs to impl Z at the start of the definition.
// CHECK:STDERR: fail_missing_require_for_symbolic_type.carbon:[[@LINE+4]]:1: error: interface `Y` being implemented requires that `T` implements `Z` [RequireImplsNotImplemented]
// CHECK:STDERR: fail_missing_require_for_symbolic_type.carbon:[[@LINE+4]]:1: error: interface `Y` being implemented requires that `T` implements `Z` [InterfaceRequireImplsNotImplemented]
// CHECK:STDERR: impl forall [T: type] T as Y {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -99,7 +99,7 @@ interface Y(U: type) {
extend require impls Z1(U) & Z2(B);
}
// CHECK:STDERR: fail_missing_extend_require_double.carbon:[[@LINE+4]]:1: error: interface `Y(A)` being implemented requires that `()` implements `Z1(A) & Z2(B)` [RequireImplsNotImplemented]
// CHECK:STDERR: fail_missing_extend_require_double.carbon:[[@LINE+4]]:1: error: interface `Y(A)` being implemented requires that `()` implements `Z1(A) & Z2(B)` [InterfaceRequireImplsNotImplemented]
// CHECK:STDERR: impl () as Y(A) {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -118,7 +118,7 @@ interface Y(U: type) {
require impls Z1(U) & Z2(B);
}
// CHECK:STDERR: fail_missing_require_double.carbon:[[@LINE+4]]:1: error: interface `Y(A)` being implemented requires that `()` implements `Z1(A) & Z2(B)` [RequireImplsNotImplemented]
// CHECK:STDERR: fail_missing_require_double.carbon:[[@LINE+4]]:1: error: interface `Y(A)` being implemented requires that `()` implements `Z1(A) & Z2(B)` [InterfaceRequireImplsNotImplemented]
// CHECK:STDERR: impl () as Y(A) {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -227,7 +227,7 @@ interface Y(U: type) {
}
// Y requires that C impls Z(Self), but it does not do so.
// CHECK:STDERR: fail_require_non_self_missing.carbon:[[@LINE+4]]:1: error: interface `Y(())` being implemented requires that `C` implements `Z(())` [RequireImplsNotImplemented]
// CHECK:STDERR: fail_require_non_self_missing.carbon:[[@LINE+4]]:1: error: interface `Y(())` being implemented requires that `C` implements `Z(())` [InterfaceRequireImplsNotImplemented]
// CHECK:STDERR: impl () as Y(()) {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
@@ -10,7 +10,7 @@
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/require_satisified_in_named_constraint.carbon
// --- todo_fail_missing_require_for_concrete_type.carbon
// --- fail_missing_require_for_concrete_type.carbon
library "[[@TEST_NAME]]";
interface Y {}
@@ -25,10 +25,13 @@ constraint N {
impl () as N;
// () needs to impl Z at the start of the definition.
// TODO: RequireImplsNotImplemented error that () does not implement Z.
// CHECK:STDERR: fail_missing_require_for_concrete_type.carbon:[[@LINE+4]]:1: error: constraint `N` being implemented requires that `()` implements `Z` [IdentifiedRequireImplsNotImplemented]
// CHECK:STDERR: impl () as N {}
// CHECK:STDERR: ^~~~~~~~~~~~~~
// CHECK:STDERR:
impl () as N {}
// --- todo_fail_missing_require_for_symbolic_type.carbon
// --- fail_missing_require_for_symbolic_type.carbon
library "[[@TEST_NAME]]";
interface Y {}
@@ -43,7 +46,10 @@ constraint N {
impl forall [T: type] T as N;
// T needs to impl Z at the start of the definition.
// TODO: RequireImplsNotImplemented error that () does not implement Z.
// CHECK:STDERR: fail_missing_require_for_symbolic_type.carbon:[[@LINE+4]]:1: error: constraint `N` being implemented requires that `T` implements `Z` [IdentifiedRequireImplsNotImplemented]
// CHECK:STDERR: impl forall [T: type] T as N {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
impl forall [T: type] T as N {}
// --- require_for_concrete_type.carbon
+7 -1
View File
@@ -271,8 +271,14 @@ interface J { let T: type; }
// Interfaces to the right of the `where` don't interfere with the
// "can only impl a facet type with a single interface" rule. Only
// the interface being implemented needs to have all of its
// associated constants set
// associated constants set.
impl {.a: C} as I where .Self impls J;
impl {.b: C} as J where .Self impls I and .T = ();
// The requirements after `where` must be met before we define the above impls.
impl {.a: C} as J where .T = () {}
impl {.a: C} as I where .Self impls J {}
impl {.b: C} as I {}
impl {.b: C} as J where .Self impls I and .T = () {}
// --- impl_with_rewrite_of_interface_not_being_implemented.carbon
+2 -1
View File
@@ -411,7 +411,8 @@ CARBON_DIAGNOSTIC_KIND(RequireImplsMissingSelfEmptyFacetType)
CARBON_DIAGNOSTIC_KIND(RequireImplsIncompleteFacetType)
CARBON_DIAGNOSTIC_KIND(RequireImplsReferenceCycle)
CARBON_DIAGNOSTIC_KIND(RequireImplsUnidentifiedFacetType)
CARBON_DIAGNOSTIC_KIND(RequireImplsNotImplemented)
CARBON_DIAGNOSTIC_KIND(IdentifiedRequireImplsNotImplemented)
CARBON_DIAGNOSTIC_KIND(InterfaceRequireImplsNotImplemented)
CARBON_DIAGNOSTIC_KIND(RequireInWrongScope)
// Observe checking.