mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Add an interface-with-self generic to each interface and same for constraints (#6667)
Currently each interface has a `Self` facet internally that becomes a binding to every entity inside the interface: associated constants, functions, and require decls. Each of these has to be independently generic as a result. This makes is challenging in extended name lookup to move into an extended scope of an interface, as we have a specific for the interface, but the names within require a different specific that includes a `Self` facet value. We generalize this relationship by adding a second generic to Interface, called `generic_with_self`. When we want to work with entities inside the interface, we move from the interface-without-specific to the interface-with-self specific by adding a Self to the specific. This is done independently of any particular entity inside the Interface, as those entities are now all members of the interface-with-self generic. Associated constants no longer need a generic of their own, as they do not have separate generic bindings. Functions retain a generic, but if the function has no generic arguments, it will have no bindings of its own now. Require decls retain a generic so that their specific can be instantiated separately from the interface. Requiring the interface to be complete does not require the types in a require decl to be complete unless it is modified by `extend`. So we allow them to be completed later by keeping them in a separate generic. Named constraints look like interfaces and gain the additional inner generic-with-self, with the same relationship to require decls. This removes the need for name lookup to perform Substitution of a Self facet into the extended scope instruction. Instead, the `SpecificConstant` instruction inserted by a `require` decl is part of the interface-with-self generic. When looking through a FacetType for extended scopes, for each interface, we push the scope with the specific for the interface-with-self. Then the constant value of the `SpecificConstant` is correctly modified by the provided self automatically through applying that specific.
This commit is contained in:
+4
-4
@@ -76,8 +76,8 @@ fn Run() {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc37_20.1.temp = alloca i1, align 1, !dbg !23
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc37_20.1.temp), !dbg !23
|
||||
// CHECK:STDOUT: %I.F.call = call i1 @"_CF.X.Main:I.Main"(), !dbg !23
|
||||
// CHECK:STDOUT: %.loc37_20.2 = zext i1 %I.F.call to i8, !dbg !23
|
||||
// CHECK:STDOUT: %I.WithSelf.F.call = call i1 @"_CF.X.Main:I.Main"(), !dbg !23
|
||||
// CHECK:STDOUT: %.loc37_20.2 = zext i1 %I.WithSelf.F.call to i8, !dbg !23
|
||||
// CHECK:STDOUT: store i8 %.loc37_20.2, ptr %.loc37_20.1.temp, align 1, !dbg !23
|
||||
// CHECK:STDOUT: %.loc37_20.3 = load i8, ptr %.loc37_20.1.temp, align 1, !dbg !23
|
||||
// CHECK:STDOUT: %.loc37_20.31 = trunc i8 %.loc37_20.3 to i1, !dbg !23
|
||||
@@ -89,8 +89,8 @@ fn Run() {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %.loc37_20.1.temp = alloca i32, align 4, !dbg !26
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc37_20.1.temp), !dbg !26
|
||||
// CHECK:STDOUT: %I.F.call = call i32 @"_CF.Y.Main:I.Main"(), !dbg !26
|
||||
// CHECK:STDOUT: store i32 %I.F.call, ptr %.loc37_20.1.temp, align 4, !dbg !26
|
||||
// CHECK:STDOUT: %I.WithSelf.F.call = call i32 @"_CF.Y.Main:I.Main"(), !dbg !26
|
||||
// CHECK:STDOUT: store i32 %I.WithSelf.F.call, ptr %.loc37_20.1.temp, align 4, !dbg !26
|
||||
// CHECK:STDOUT: %.loc37_20.3 = load i32, ptr %.loc37_20.1.temp, align 4, !dbg !26
|
||||
// CHECK:STDOUT: ret void, !dbg !27
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -63,8 +63,8 @@ fn G() {
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
// CHECK:STDOUT: define linkonce_odr i32 @_CCallGenericMethod.Main.416a86e385b6ba35(i32 %x) #0 !dbg !17 {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %SomeInterface.F.call = call i32 @"_CF.ImplsSomeInterface.Main:SomeInterface.b88d1103f417c6d4.Main"(i32 %x), !dbg !20
|
||||
// CHECK:STDOUT: ret i32 %SomeInterface.F.call, !dbg !21
|
||||
// CHECK:STDOUT: %SomeInterface.WithSelf.F.call = call i32 @"_CF.ImplsSomeInterface.Main:SomeInterface.b88d1103f417c6d4.Main"(i32 %x), !dbg !20
|
||||
// CHECK:STDOUT: ret i32 %SomeInterface.WithSelf.F.call, !dbg !21
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: attributes #0 = { nounwind }
|
||||
|
||||
@@ -171,10 +171,10 @@ fn F_nested_tuple(a: ((i32, i32), X)) -> ((i32, i32), X) {
|
||||
// CHECK:STDOUT: entry:
|
||||
// CHECK:STDOUT: %_.var = alloca i32, align 4, !dbg !63
|
||||
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %_.var), !dbg !63
|
||||
// CHECK:STDOUT: %Copy.Op.call.loc18 = call i32 @"_COp.Int.be1e879c1ad406d8.Core:Copy.Main"(i32 %a), !dbg !64
|
||||
// CHECK:STDOUT: store i32 %Copy.Op.call.loc18, ptr %_.var, align 4, !dbg !63
|
||||
// CHECK:STDOUT: %Copy.Op.call.loc19 = call i32 @"_COp.Int.be1e879c1ad406d8.Core:Copy.Main"(i32 %a), !dbg !65
|
||||
// CHECK:STDOUT: ret i32 %Copy.Op.call.loc19, !dbg !66
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.call.loc18 = call i32 @"_COp.Int.be1e879c1ad406d8.Core:Copy.Main"(i32 %a), !dbg !64
|
||||
// CHECK:STDOUT: store i32 %Copy.WithSelf.Op.call.loc18, ptr %_.var, align 4, !dbg !63
|
||||
// CHECK:STDOUT: %Copy.WithSelf.Op.call.loc19 = call i32 @"_COp.Int.be1e879c1ad406d8.Core:Copy.Main"(i32 %a), !dbg !65
|
||||
// CHECK:STDOUT: ret i32 %Copy.WithSelf.Op.call.loc19, !dbg !66
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: ; Function Attrs: nounwind
|
||||
|
||||
Reference in New Issue
Block a user