mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 12:11:04 +01:00
Treat the empty inst block as being canonical. (#4199)
TryEvalInst was assuming this to be the case when forming canonical constants, but it previously wasn't. This fixes an issue where we can end up with two identical-looking constants for an empty struct value: one with an `Empty` block and another with the canonical empty block.
This commit is contained in:
+5
-6
@@ -198,9 +198,8 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
|
||||
// CHECK:STDOUT: %U: type = bind_symbolic_name U 1 [symbolic]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F, @C(%Self) [symbolic]
|
||||
// CHECK:STDOUT: %.2: type = tuple_type () [template]
|
||||
// CHECK:STDOUT: %F.1: %F.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.3: type = struct_type {} [template]
|
||||
// CHECK:STDOUT: %F.2: %F.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.4: type = ptr_type %.3 [template]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -223,7 +222,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Core.import = import Core
|
||||
// CHECK:STDOUT: %Interface.decl: type = interface_decl @Interface [template = constants.%.1] {}
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [symbolic = constants.%F.1] {
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [symbolic = constants.%F] {
|
||||
// CHECK:STDOUT: %.loc20: type = specific_constant constants.%C.2, @C(constants.%Self) [symbolic = constants.%C.2]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc20 [symbolic = constants.%C.2]
|
||||
// CHECK:STDOUT: %self.loc20_18.1: %C.2 = param self
|
||||
@@ -252,10 +251,10 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Self: %.1 = bind_symbolic_name Self 0 [symbolic = %Self (constants.%Self)]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F, @C(%Self) [symbolic = %F.type (constants.%F.type)]
|
||||
// CHECK:STDOUT: %F: @C.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F.1)]
|
||||
// CHECK:STDOUT: %F: @C.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: class {
|
||||
// CHECK:STDOUT: %F.decl: @C.%F.type (%F.type) = fn_decl @F [symbolic = %F (constants.%F.1)] {
|
||||
// CHECK:STDOUT: %F.decl: @C.%F.type (%F.type) = fn_decl @F [symbolic = %F (constants.%F)] {
|
||||
// CHECK:STDOUT: %.loc14: type = specific_constant constants.%C.2, @C(constants.%Self) [symbolic = @F.%C (constants.%C.2)]
|
||||
// CHECK:STDOUT: %Self.ref: type = name_ref Self, %.loc14 [symbolic = @F.%C (constants.%C.2)]
|
||||
// CHECK:STDOUT: %self.loc14_10.1: @F.%C (%C.2) = param self
|
||||
@@ -293,7 +292,7 @@ fn Interface.C.F[self: Self](U:! type, u: U) -> U { return u; }
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %Self => constants.%Self
|
||||
// CHECK:STDOUT: %F.type => constants.%F.type
|
||||
// CHECK:STDOUT: %F => constants.%F.2
|
||||
// CHECK:STDOUT: %F => constants.%F
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @C(@F.%Self) {}
|
||||
|
||||
+1
-2
@@ -46,7 +46,6 @@ interface Outer {
|
||||
// CHECK:STDOUT: %Self.3: %.5 = bind_symbolic_name Self 1 [symbolic]
|
||||
// CHECK:STDOUT: %.type: type = fn_type @.1, @Inner(%Self.2) [symbolic]
|
||||
// CHECK:STDOUT: %.6: %.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.7: %.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %F.type.2: type = fn_type @F.2, @Inner(%Self.2) [symbolic]
|
||||
// CHECK:STDOUT: %F.2: %F.type.2 = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -127,7 +126,7 @@ interface Outer {
|
||||
// CHECK:STDOUT: %.1 => constants.%.5
|
||||
// CHECK:STDOUT: %Self.3 => constants.%Self.3
|
||||
// CHECK:STDOUT: %.type => constants.%.type
|
||||
// CHECK:STDOUT: %.2 => constants.%.7
|
||||
// CHECK:STDOUT: %.2 => constants.%.6
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @.1(constants.%Self.2, constants.%Self.3) {}
|
||||
|
||||
+4
-5
@@ -31,10 +31,9 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
|
||||
// CHECK:STDOUT: %.2: type = interface_type @I, @I(%T) [symbolic]
|
||||
// CHECK:STDOUT: %Self: %.2 = bind_symbolic_name Self 1 [symbolic]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T) [symbolic]
|
||||
// CHECK:STDOUT: %F.1: %F.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.3: type = assoc_entity_type %.2, %F.type [symbolic]
|
||||
// CHECK:STDOUT: %.4: %.3 = assoc_entity element0, @I.%F.decl [symbolic]
|
||||
// CHECK:STDOUT: %F.2: %F.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: %.type: type = fn_type @.1, @I(%T) [symbolic]
|
||||
// CHECK:STDOUT: %.5: %.type = struct_value () [symbolic]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -71,13 +70,13 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
|
||||
// CHECK:STDOUT: %.1: type = interface_type @I, @I(%T) [symbolic = %.1 (constants.%.2)]
|
||||
// CHECK:STDOUT: %Self.2: %.2 = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F, @I(%T) [symbolic = %F.type (constants.%F.type)]
|
||||
// CHECK:STDOUT: %F: @I.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F.1)]
|
||||
// CHECK:STDOUT: %F: @I.%F.type (%F.type) = struct_value () [symbolic = %F (constants.%F)]
|
||||
// CHECK:STDOUT: %.2: type = assoc_entity_type @I.%.1 (%.2), @I.%F.type (%F.type) [symbolic = %.2 (constants.%.3)]
|
||||
// CHECK:STDOUT: %.3: @I.%.2 (%.3) = assoc_entity element0, %F.decl [symbolic = %.3 (constants.%.4)]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: interface {
|
||||
// CHECK:STDOUT: %Self.1: @I.%.1 (%.2) = bind_symbolic_name Self 1 [symbolic = %Self.2 (constants.%Self)]
|
||||
// CHECK:STDOUT: %F.decl: @I.%F.type (%F.type) = fn_decl @F [symbolic = %F (constants.%F.1)] {
|
||||
// CHECK:STDOUT: %F.decl: @I.%F.type (%F.type) = fn_decl @F [symbolic = %F (constants.%F)] {
|
||||
// CHECK:STDOUT: %.loc13_14.1: @F.%.1 (%.2) = specific_constant %Self.1, @I(constants.%T) [symbolic = @F.%Self (constants.%Self)]
|
||||
// CHECK:STDOUT: %Self.ref.loc13_14: @F.%.1 (%.2) = name_ref Self, %.loc13_14.1 [symbolic = @F.%Self (constants.%Self)]
|
||||
// CHECK:STDOUT: %.loc13_14.2: type = facet_type_access %Self.ref.loc13_14 [symbolic = @F.%Self (constants.%Self)]
|
||||
@@ -128,7 +127,7 @@ fn I(T:! type).F[self: Self]() -> Self { return self; }
|
||||
// CHECK:STDOUT: %.1 => constants.%.2
|
||||
// CHECK:STDOUT: %Self.2 => constants.%Self
|
||||
// CHECK:STDOUT: %F.type => constants.%F.type
|
||||
// CHECK:STDOUT: %F => constants.%F.2
|
||||
// CHECK:STDOUT: %F => constants.%F
|
||||
// CHECK:STDOUT: %.2 => constants.%.3
|
||||
// CHECK:STDOUT: %.3 => constants.%.4
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
Reference in New Issue
Block a user