Implement unused pattern bindings, continued (#6518)

Implementation of unused pattern bindings #2022, continued.

Whereas previous PR #6460 took care of parsing, and PR #6479 prepared
the stage by using _ in some test cases, this PR has the the actual
implementation, using a simple dataflow analysis.

---------

Co-authored-by: Burak Emir <bqe@google.com>
Co-authored-by: jonmeow <jperkins@google.com>
This commit is contained in:
Burak Emir
2026-02-19 23:33:36 +00:00
committed by GitHub
co-authored by Burak Emir jonmeow
parent bea24a8bee
commit fdb188ccfd
366 changed files with 8453 additions and 7996 deletions
+5 -5
View File
@@ -180,7 +180,7 @@ import library "error_in_constraint";
fn F() {
//@dump-sem-ir-begin
let x: () = WithError(());
let unused x: () = WithError(());
//@dump-sem-ir-end
}
@@ -538,10 +538,10 @@ fn F() {
// CHECK:STDOUT: %x.patt: %pattern_type = value_binding_pattern x [concrete]
// CHECK:STDOUT: }
// CHECK:STDOUT: %WithError.ref: %WithError.type = name_ref WithError, imports.%Main.WithError [concrete = constants.%WithError]
// CHECK:STDOUT: %.loc8_26: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_11.1: type = splice_block %.loc8_11.3 [concrete = constants.%empty_tuple.type] {
// CHECK:STDOUT: %.loc8_11.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_11.3: type = converted %.loc8_11.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: %.loc8_33: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_18.1: type = splice_block %.loc8_18.3 [concrete = constants.%empty_tuple.type] {
// CHECK:STDOUT: %.loc8_18.2: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc8_18.3: type = converted %.loc8_18.2, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %x: %empty_tuple.type = value_binding x, <error> [concrete = <error>]
// CHECK:STDOUT: <elided>
+6 -6
View File
@@ -45,7 +45,7 @@ fn PeriodMismatch(W:! J where .Mismatch = {});
library "[[@TEST_NAME]]";
fn Foo() -> () {
var x: ();
var unused x: ();
// CHECK:STDERR: fail_designator_matches_var.carbon:[[@LINE+5]]:10: error: name `.Self` not found [NameNotFound]
// CHECK:STDERR: return .x;
// CHECK:STDERR: ^~
@@ -98,7 +98,7 @@ interface I {}
// TODO: Diagnose that the `where` on `T` does not refer to `.Self` at all.
// See https://docs.carbon-lang.dev/docs/design/generics/details.html#constraints-must-use-a-designator
fn F(U:! type, T:! type where U impls I) {}
fn F(U:! type, unused T:! type where U impls I) {}
// --- todo_fail_equality_constraint_does_not_constrain_self.carbon
library "[[@TEST_NAME]]";
@@ -109,7 +109,7 @@ interface I {
// TODO: Diagnose that the `where` on `T` does not refer to `.Self` at all.
// See https://docs.carbon-lang.dev/docs/design/generics/details.html#constraints-must-use-a-designator
fn F(U:! I, T:! type where U.X == ()) {}
fn F(U:! I, unused T:! type where U.X == ()) {}
// --- todo_fail_combined_constraint_does_not_constrain_self.carbon
library "[[@TEST_NAME]]";
@@ -120,7 +120,7 @@ interface I {
// TODO: Diagnose that the `where` on `T` does not refer to `.Self` at all.
// See https://docs.carbon-lang.dev/docs/design/generics/details.html#constraints-must-use-a-designator
fn F(U:! I, T:! type where U impls I and U.X == ()) {}
fn F(U:! I, unused T:! type where U impls I and U.X == ()) {}
// --- impls_constraint_does_constrain_self.carbon
library "[[@TEST_NAME]]";
@@ -129,9 +129,9 @@ interface I(T:! type) {}
class C(T:! type);
fn F(T:! type where C(.Self) impls I(())) {}
fn F(unused T:! type where C(.Self) impls I(())) {}
fn G(T:! type where C(()) impls I(.Self)) {}
fn G(unused T:! type where C(()) impls I(.Self)) {}
// CHECK:STDOUT: --- success.carbon
// CHECK:STDOUT:
+6 -6
View File
@@ -57,7 +57,7 @@ interface J {
fn INotJ(T:! I where .Self impls J) {
// Gets `T.(I.F)`. Doesn't consider `T.(J.F)`, so no ambiguity.
let x: () = T.F();
let unused x: () = T.F();
}
// --- fail_name_lookup_through_where_self_impls.carbon
@@ -145,7 +145,7 @@ fn INotJ[T:! I where .Self impls J](x: T) {
library "[[@TEST_NAME]]";
class WrapType(T:! type) {}
fn AssertSame[T:! type](a: WrapType(T), b: WrapType(T)) {}
fn AssertSame[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
fn Type(T:! type) -> WrapType(T) { return {}; }
interface I;
@@ -178,7 +178,7 @@ interface K {}
library "[[@TEST_NAME]]";
class WrapType(T:! type) {}
fn AssertSame[T:! type](a: WrapType(T), b: WrapType(T)) {}
fn AssertSame[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
fn Type(T:! type) -> WrapType(T) { return {}; }
interface I { let A:! type; }
@@ -201,7 +201,7 @@ fn Test() {
library "[[@TEST_NAME]]";
class WrapType(T:! type) {}
fn Same[T:! type](a: WrapType(T), b: WrapType(T)) {}
fn Same[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
fn Type(T:! type) -> WrapType(T) { return {}; }
interface I {}
@@ -212,8 +212,8 @@ fn Test() {
// CHECK:STDERR: Same(Type(I where .Self impls J), Type(J where .Self impls I));
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fail_compare_not_equal.carbon:[[@LINE-10]]:1: note: while deducing parameters of generic declared here [DeductionGenericHere]
// CHECK:STDERR: fn Same[T:! type](a: WrapType(T), b: WrapType(T)) {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR: fn Same[T:! type](unused a: WrapType(T), unused b: WrapType(T)) {}
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
Same(Type(I where .Self impls J), Type(J where .Self impls I));
}
+33 -33
View File
@@ -18,7 +18,7 @@ interface Empty(W:! type) {
// .Self has index invalid, not 1
// V has index 1, does not match .Self
//@dump-sem-ir-begin
fn H(T:! type, U: Empty(T) where .A = T*, V:! type) {}
fn H(T:! type, unused U: Empty(T) where .A = T*, unused V:! type) {}
//@dump-sem-ir-end
fn G(U: Empty(i32) where .A = i32*) {
@@ -76,47 +76,47 @@ fn G(U: Empty(i32) where .A = i32*) {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %T.loc21_6.2: type = symbolic_binding T, 0 [symbolic = %T.loc21_6.1 (constants.%T)]
// CHECK:STDOUT: %U.param: @H.%Empty_where.type (%Empty_where.type.2dc) = value_param call_param0
// CHECK:STDOUT: %.loc21_28.1: type = splice_block %.loc21_28.2 [symbolic = %Empty_where.type (constants.%Empty_where.type.2dc)] {
// CHECK:STDOUT: %.loc21_35.1: type = splice_block %.loc21_35.2 [symbolic = %Empty_where.type (constants.%Empty_where.type.2dc)] {
// CHECK:STDOUT: %Empty.ref: %Empty.type.d36 = name_ref Empty, file.%Empty.decl [concrete = constants.%Empty.generic]
// CHECK:STDOUT: %T.ref.loc21_25: type = name_ref T, %T.loc21_6.2 [symbolic = %T.loc21_6.1 (constants.%T)]
// CHECK:STDOUT: %Empty.type.loc21_26.2: type = facet_type <@Empty, @Empty(constants.%T)> [symbolic = %Empty.type.loc21_26.1 (constants.%Empty.type.6f76f1.2)]
// CHECK:STDOUT: %T.ref.loc21_32: type = name_ref T, %T.loc21_6.2 [symbolic = %T.loc21_6.1 (constants.%T)]
// CHECK:STDOUT: %Empty.type.loc21_33.2: type = facet_type <@Empty, @Empty(constants.%T)> [symbolic = %Empty.type.loc21_33.1 (constants.%Empty.type.6f76f1.2)]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.Self.ref: @H.%Empty.type.loc21_26.1 (%Empty.type.6f76f1.2) = name_ref .Self, %.Self.4 [symbolic = %.Self.1 (constants.%.Self.b4b)]
// CHECK:STDOUT: %.Self.ref: @H.%Empty.type.loc21_33.1 (%Empty.type.6f76f1.2) = name_ref .Self, %.Self.4 [symbolic = %.Self.1 (constants.%.Self.b4b)]
// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic = %.Self.binding.as_type (constants.%.Self.binding.as_type.b61)]
// CHECK:STDOUT: %.loc21_34.1: type = converted %.Self.ref, %.Self.as_type [symbolic = %.Self.binding.as_type (constants.%.Self.binding.as_type.b61)]
// CHECK:STDOUT: %.loc21_34.2: @H.%Empty.assoc_type (%Empty.assoc_type.ce4b5a.2) = specific_constant @A.%assoc0, @Empty(constants.%T, constants.%.Self.b4b) [symbolic = %assoc0 (constants.%assoc0.beb632.2)]
// CHECK:STDOUT: %A.ref: @H.%Empty.assoc_type (%Empty.assoc_type.ce4b5a.2) = name_ref A, %.loc21_34.2 [symbolic = %assoc0 (constants.%assoc0.beb632.2)]
// CHECK:STDOUT: %impl.elem0.loc21_34.2: type = impl_witness_access constants.%Empty.lookup_impl_witness.177, element0 [symbolic = %impl.elem0.loc21_34.1 (constants.%impl.elem0.de5)]
// CHECK:STDOUT: %T.ref.loc21_39: type = name_ref T, %T.loc21_6.2 [symbolic = %T.loc21_6.1 (constants.%T)]
// CHECK:STDOUT: %ptr.loc21_40.2: type = ptr_type %T.ref.loc21_39 [symbolic = %ptr.loc21_40.1 (constants.%ptr.e8f)]
// CHECK:STDOUT: %.loc21_28.2: type = where_expr %.Self.4 [symbolic = %Empty_where.type (constants.%Empty_where.type.2dc)] {
// CHECK:STDOUT: %.loc21_41.1: type = converted %.Self.ref, %.Self.as_type [symbolic = %.Self.binding.as_type (constants.%.Self.binding.as_type.b61)]
// CHECK:STDOUT: %.loc21_41.2: @H.%Empty.assoc_type (%Empty.assoc_type.ce4b5a.2) = specific_constant @A.%assoc0, @Empty(constants.%T, constants.%.Self.b4b) [symbolic = %assoc0 (constants.%assoc0.beb632.2)]
// CHECK:STDOUT: %A.ref: @H.%Empty.assoc_type (%Empty.assoc_type.ce4b5a.2) = name_ref A, %.loc21_41.2 [symbolic = %assoc0 (constants.%assoc0.beb632.2)]
// CHECK:STDOUT: %impl.elem0.loc21_41.2: type = impl_witness_access constants.%Empty.lookup_impl_witness.177, element0 [symbolic = %impl.elem0.loc21_41.1 (constants.%impl.elem0.de5)]
// CHECK:STDOUT: %T.ref.loc21_46: type = name_ref T, %T.loc21_6.2 [symbolic = %T.loc21_6.1 (constants.%T)]
// CHECK:STDOUT: %ptr.loc21_47.2: type = ptr_type %T.ref.loc21_46 [symbolic = %ptr.loc21_47.1 (constants.%ptr.e8f)]
// CHECK:STDOUT: %.loc21_35.2: type = where_expr %.Self.4 [symbolic = %Empty_where.type (constants.%Empty_where.type.2dc)] {
// CHECK:STDOUT: requirement_base_facet_type constants.%Empty.type.6f76f1.2
// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc21_34.2, %ptr.loc21_40.2
// CHECK:STDOUT: requirement_rewrite %impl.elem0.loc21_41.2, %ptr.loc21_47.2
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: %U: @H.%Empty_where.type (%Empty_where.type.2dc) = value_binding U, %U.param
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %V.loc21_43.2: type = symbolic_binding V, 1 [symbolic = %V.loc21_43.1 (constants.%V)]
// CHECK:STDOUT: %V.loc21_57.2: type = symbolic_binding V, 1 [symbolic = %V.loc21_57.1 (constants.%V)]
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @H(%T.loc21_6.2: type, %V.loc21_43.2: type) {
// CHECK:STDOUT: generic fn @H(%T.loc21_6.2: type, %V.loc21_57.2: type) {
// CHECK:STDOUT: %T.loc21_6.1: type = symbolic_binding T, 0 [symbolic = %T.loc21_6.1 (constants.%T)]
// CHECK:STDOUT: %Empty.type.loc21_26.1: type = facet_type <@Empty, @Empty(%T.loc21_6.1)> [symbolic = %Empty.type.loc21_26.1 (constants.%Empty.type.6f76f1.2)]
// CHECK:STDOUT: %Empty.type.loc21_33.1: type = facet_type <@Empty, @Empty(%T.loc21_6.1)> [symbolic = %Empty.type.loc21_33.1 (constants.%Empty.type.6f76f1.2)]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %require_complete.loc21_34: <witness> = require_complete_type %Empty.type.loc21_26.1 [symbolic = %require_complete.loc21_34 (constants.%require_complete.8eb)]
// CHECK:STDOUT: %require_complete.loc21_41: <witness> = require_complete_type %Empty.type.loc21_33.1 [symbolic = %require_complete.loc21_41 (constants.%require_complete.8eb)]
// CHECK:STDOUT: %.Self.binding.as_type: type = symbolic_binding_type .Self, %.Self.1 [symbolic = %.Self.binding.as_type (constants.%.Self.binding.as_type.b61)]
// CHECK:STDOUT: %Empty.assoc_type: type = assoc_entity_type @Empty, @Empty(%T.loc21_6.1) [symbolic = %Empty.assoc_type (constants.%Empty.assoc_type.ce4b5a.2)]
// CHECK:STDOUT: %assoc0: @H.%Empty.assoc_type (%Empty.assoc_type.ce4b5a.2) = assoc_entity element0, @Empty.%A [symbolic = %assoc0 (constants.%assoc0.beb632.2)]
// CHECK:STDOUT: %Empty.lookup_impl_witness: <witness> = lookup_impl_witness %.Self.1, @Empty, @Empty(%T.loc21_6.1) [symbolic = %Empty.lookup_impl_witness (constants.%Empty.lookup_impl_witness.177)]
// CHECK:STDOUT: %impl.elem0.loc21_34.1: type = impl_witness_access %Empty.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc21_34.1 (constants.%impl.elem0.de5)]
// CHECK:STDOUT: %ptr.loc21_40.1: type = ptr_type %T.loc21_6.1 [symbolic = %ptr.loc21_40.1 (constants.%ptr.e8f)]
// CHECK:STDOUT: %Empty_where.type: type = facet_type <@Empty, @Empty(%T.loc21_6.1) where %impl.elem0.loc21_34.1 = %ptr.loc21_40.1> [symbolic = %Empty_where.type (constants.%Empty_where.type.2dc)]
// CHECK:STDOUT: %impl.elem0.loc21_41.1: type = impl_witness_access %Empty.lookup_impl_witness, element0 [symbolic = %impl.elem0.loc21_41.1 (constants.%impl.elem0.de5)]
// CHECK:STDOUT: %ptr.loc21_47.1: type = ptr_type %T.loc21_6.1 [symbolic = %ptr.loc21_47.1 (constants.%ptr.e8f)]
// CHECK:STDOUT: %Empty_where.type: type = facet_type <@Empty, @Empty(%T.loc21_6.1) where %impl.elem0.loc21_41.1 = %ptr.loc21_47.1> [symbolic = %Empty_where.type (constants.%Empty_where.type.2dc)]
// CHECK:STDOUT: %pattern_type: type = pattern_type %Empty_where.type [symbolic = %pattern_type (constants.%pattern_type.bb3)]
// CHECK:STDOUT: %V.loc21_43.1: type = symbolic_binding V, 1 [symbolic = %V.loc21_43.1 (constants.%V)]
// CHECK:STDOUT: %V.loc21_57.1: type = symbolic_binding V, 1 [symbolic = %V.loc21_57.1 (constants.%V)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete.loc21_17: <witness> = require_complete_type %Empty_where.type [symbolic = %require_complete.loc21_17 (constants.%require_complete.6bc)]
// CHECK:STDOUT: %require_complete.loc21_24: <witness> = require_complete_type %Empty_where.type [symbolic = %require_complete.loc21_24 (constants.%require_complete.6bc)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%U.param: @H.%Empty_where.type (%Empty_where.type.2dc)) {
// CHECK:STDOUT: !entry:
@@ -126,36 +126,36 @@ fn G(U: Empty(i32) where .A = i32*) {
// CHECK:STDOUT:
// CHECK:STDOUT: specific @H(constants.%T, constants.%V) {
// CHECK:STDOUT: %T.loc21_6.1 => constants.%T
// CHECK:STDOUT: %Empty.type.loc21_26.1 => constants.%Empty.type.6f76f1.2
// CHECK:STDOUT: %Empty.type.loc21_33.1 => constants.%Empty.type.6f76f1.2
// CHECK:STDOUT: %.Self.1 => constants.%.Self.b4b
// CHECK:STDOUT: %require_complete.loc21_34 => constants.%require_complete.8eb
// CHECK:STDOUT: %require_complete.loc21_41 => constants.%require_complete.8eb
// CHECK:STDOUT: %.Self.binding.as_type => constants.%.Self.binding.as_type.b61
// CHECK:STDOUT: %Empty.assoc_type => constants.%Empty.assoc_type.ce4b5a.2
// CHECK:STDOUT: %assoc0 => constants.%assoc0.beb632.2
// CHECK:STDOUT: %Empty.lookup_impl_witness => constants.%Empty.lookup_impl_witness.177
// CHECK:STDOUT: %impl.elem0.loc21_34.1 => constants.%impl.elem0.de5
// CHECK:STDOUT: %ptr.loc21_40.1 => constants.%ptr.e8f
// CHECK:STDOUT: %impl.elem0.loc21_41.1 => constants.%impl.elem0.de5
// CHECK:STDOUT: %ptr.loc21_47.1 => constants.%ptr.e8f
// CHECK:STDOUT: %Empty_where.type => constants.%Empty_where.type.2dc
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.bb3
// CHECK:STDOUT: %V.loc21_43.1 => constants.%V
// CHECK:STDOUT: %V.loc21_57.1 => constants.%V
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @H(constants.%i32, bool) {
// CHECK:STDOUT: %T.loc21_6.1 => constants.%i32
// CHECK:STDOUT: %Empty.type.loc21_26.1 => constants.%Empty.type.4fb
// CHECK:STDOUT: %Empty.type.loc21_33.1 => constants.%Empty.type.4fb
// CHECK:STDOUT: %.Self.1 => constants.%.Self.ec6
// CHECK:STDOUT: %require_complete.loc21_34 => constants.%complete_type.ba8
// CHECK:STDOUT: %require_complete.loc21_41 => constants.%complete_type.ba8
// CHECK:STDOUT: %.Self.binding.as_type => constants.%.Self.binding.as_type.63c
// CHECK:STDOUT: %Empty.assoc_type => constants.%Empty.assoc_type.623
// CHECK:STDOUT: %assoc0 => constants.%assoc0.edc
// CHECK:STDOUT: %Empty.lookup_impl_witness => constants.%Empty.lookup_impl_witness.924
// CHECK:STDOUT: %impl.elem0.loc21_34.1 => constants.%impl.elem0.238
// CHECK:STDOUT: %ptr.loc21_40.1 => constants.%ptr.235
// CHECK:STDOUT: %impl.elem0.loc21_41.1 => constants.%impl.elem0.238
// CHECK:STDOUT: %ptr.loc21_47.1 => constants.%ptr.235
// CHECK:STDOUT: %Empty_where.type => constants.%Empty_where.type.729
// CHECK:STDOUT: %pattern_type => constants.%pattern_type.ee5
// CHECK:STDOUT: %V.loc21_43.1 => bool
// CHECK:STDOUT: %V.loc21_57.1 => bool
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %require_complete.loc21_17 => constants.%complete_type.863
// CHECK:STDOUT: %require_complete.loc21_24 => constants.%complete_type.863
// CHECK:STDOUT: }
// CHECK:STDOUT:
+38 -38
View File
@@ -44,7 +44,7 @@ interface E {
}
//@dump-sem-ir-begin
fn OneRewrite(G:! E where .F = i32) {}
fn OneRewrite(unused G:! E where .F = i32) {}
fn RepeatedRewrite(H:! E where .F = i32 and .F = i32) {
//@dump-sem-ir-end
@@ -65,7 +65,7 @@ interface J {
}
//@dump-sem-ir-begin
fn Alphabetical(M:! J where .K = () and .L = bool) {}
fn Alphabetical(unused M:! J where .K = () and .L = bool) {}
fn Reversed(N:! J where .L = bool and .K = ()) {
//@dump-sem-ir-end
@@ -80,15 +80,15 @@ interface O {
let P:! type;
}
fn WithInteger(Q:! O where .P = i32) {}
fn WithInteger(unused Q:! O where .P = i32) {}
fn WithBool(R:! O where .P = bool) {
// CHECK:STDERR: fail_rewrites_mismatch_right.carbon:[[@LINE+7]]:3: error: cannot convert type `R` that implements `O where .(O.P) = bool` into type implementing `O where .(O.P) = i32` [ConversionFailureFacetToFacet]
// CHECK:STDERR: WithInteger(R);
// CHECK:STDERR: ^~~~~~~~~~~~~~
// CHECK:STDERR: fail_rewrites_mismatch_right.carbon:[[@LINE-6]]:16: note: initializing generic parameter `Q` declared here [InitializingGenericParam]
// CHECK:STDERR: fn WithInteger(Q:! O where .P = i32) {}
// CHECK:STDERR: ^
// CHECK:STDERR: fail_rewrites_mismatch_right.carbon:[[@LINE-6]]:23: note: initializing generic parameter `Q` declared here [InitializingGenericParam]
// CHECK:STDERR: fn WithInteger(unused Q:! O where .P = i32) {}
// CHECK:STDERR: ^
// CHECK:STDERR:
WithInteger(R);
}
@@ -102,15 +102,15 @@ interface S {
let U:! type;
}
fn WithT(V:! S where .T = ()) {}
fn WithT(unused V:! S where .T = ()) {}
fn WithU(W:! S where .U = ()) {
// CHECK:STDERR: fail_rewrites_mismatch_left.carbon:[[@LINE+7]]:3: error: cannot convert type `W` that implements `S where .(S.U) = ()` into type implementing `S where .(S.T) = ()` [ConversionFailureFacetToFacet]
// CHECK:STDERR: WithT(W);
// CHECK:STDERR: ^~~~~~~~
// CHECK:STDERR: fail_rewrites_mismatch_left.carbon:[[@LINE-6]]:10: note: initializing generic parameter `V` declared here [InitializingGenericParam]
// CHECK:STDERR: fn WithT(V:! S where .T = ()) {}
// CHECK:STDERR: ^
// CHECK:STDERR: fail_rewrites_mismatch_left.carbon:[[@LINE-6]]:17: note: initializing generic parameter `V` declared here [InitializingGenericParam]
// CHECK:STDERR: fn WithT(unused V:! S where .T = ()) {}
// CHECK:STDERR: ^
// CHECK:STDERR:
WithT(W);
}
@@ -382,23 +382,23 @@ let K: (E where .F = .Self.G) = bool;
// CHECK:STDOUT: %OneRewrite.decl: %OneRewrite.type = fn_decl @OneRewrite [concrete = constants.%OneRewrite] {
// CHECK:STDOUT: %G.patt: %pattern_type.606 = symbolic_binding_pattern G, 0 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.loc9_21.1: type = splice_block %.loc9_21.2 [concrete = constants.%E_where.type] {
// CHECK:STDOUT: %.loc9_28.1: type = splice_block %.loc9_28.2 [concrete = constants.%E_where.type] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %E.ref: type = name_ref E, file.%E.decl [concrete = constants.%E.type]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.Self.ref: %E.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.7f5]
// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.loc9_27: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.loc9_34: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %F.ref: %E.assoc_type = name_ref F, @F.%assoc0 [concrete = constants.%assoc0]
// CHECK:STDOUT: %impl.elem0: type = impl_witness_access constants.%E.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: %.loc9_21.2: type = where_expr %.Self.2 [concrete = constants.%E_where.type] {
// CHECK:STDOUT: %.loc9_28.2: type = where_expr %.Self.2 [concrete = constants.%E_where.type] {
// CHECK:STDOUT: requirement_base_facet_type constants.%E.type
// CHECK:STDOUT: requirement_rewrite %impl.elem0, %i32
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: %G.loc9_15.2: %E_where.type = symbolic_binding G, 0 [symbolic = %G.loc9_15.1 (constants.%G)]
// CHECK:STDOUT: %G.loc9_22.2: %E_where.type = symbolic_binding G, 0 [symbolic = %G.loc9_22.1 (constants.%G)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %RepeatedRewrite.decl: %RepeatedRewrite.type = fn_decl @RepeatedRewrite [concrete = constants.%RepeatedRewrite] {
// CHECK:STDOUT: %H.patt: %pattern_type.606 = symbolic_binding_pattern H, 0 [concrete]
@@ -432,8 +432,8 @@ let K: (E where .F = .Self.G) = bool;
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @OneRewrite(%G.loc9_15.2: %E_where.type) {
// CHECK:STDOUT: %G.loc9_15.1: %E_where.type = symbolic_binding G, 0 [symbolic = %G.loc9_15.1 (constants.%G)]
// CHECK:STDOUT: generic fn @OneRewrite(%G.loc9_22.2: %E_where.type) {
// CHECK:STDOUT: %G.loc9_22.1: %E_where.type = symbolic_binding G, 0 [symbolic = %G.loc9_22.1 (constants.%G)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
@@ -456,7 +456,7 @@ let K: (E where .F = .Self.G) = bool;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @OneRewrite(constants.%G) {
// CHECK:STDOUT: %G.loc9_15.1 => constants.%G
// CHECK:STDOUT: %G.loc9_22.1 => constants.%G
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @RepeatedRewrite(constants.%H) {
@@ -464,7 +464,7 @@ let K: (E where .F = .Self.G) = bool;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @OneRewrite(constants.%H) {
// CHECK:STDOUT: %G.loc9_15.1 => constants.%H
// CHECK:STDOUT: %G.loc9_22.1 => constants.%H
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
@@ -477,7 +477,7 @@ let K: (E where .F = .Self.G) = bool;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @OneRewrite(constants.%I) {
// CHECK:STDOUT: %G.loc9_15.1 => constants.%I
// CHECK:STDOUT: %G.loc9_22.1 => constants.%I
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
@@ -515,32 +515,32 @@ let K: (E where .F = .Self.G) = bool;
// CHECK:STDOUT: %Alphabetical.decl: %Alphabetical.type = fn_decl @Alphabetical [concrete = constants.%Alphabetical] {
// CHECK:STDOUT: %M.patt: %pattern_type.a2c = symbolic_binding_pattern M, 0 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %.loc10_23.1: type = splice_block %.loc10_23.2 [concrete = constants.%J_where.type] {
// CHECK:STDOUT: %.loc10_30.1: type = splice_block %.loc10_30.2 [concrete = constants.%J_where.type] {
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %J.ref: type = name_ref J, file.%J.decl [concrete = constants.%J.type]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.Self.ref.loc10_29: %J.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.2fa]
// CHECK:STDOUT: %.Self.as_type.loc10_29: type = facet_access_type %.Self.ref.loc10_29 [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.loc10_29: type = converted %.Self.ref.loc10_29, %.Self.as_type.loc10_29 [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.Self.ref.loc10_36: %J.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.2fa]
// CHECK:STDOUT: %.Self.as_type.loc10_36: type = facet_access_type %.Self.ref.loc10_36 [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.loc10_36: type = converted %.Self.ref.loc10_36, %.Self.as_type.loc10_36 [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %K.ref: %J.assoc_type = name_ref K, @K.%assoc0 [concrete = constants.%assoc0]
// CHECK:STDOUT: %impl.elem0: type = impl_witness_access constants.%J.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0]
// CHECK:STDOUT: %.loc10_35.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc10_35.2: type = converted %.loc10_35.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: %.Self.ref.loc10_41: %J.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.2fa]
// CHECK:STDOUT: %.Self.as_type.loc10_41: type = facet_access_type %.Self.ref.loc10_41 [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.loc10_41: type = converted %.Self.ref.loc10_41, %.Self.as_type.loc10_41 [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.loc10_42.1: %empty_tuple.type = tuple_literal () [concrete = constants.%empty_tuple]
// CHECK:STDOUT: %.loc10_42.2: type = converted %.loc10_42.1, constants.%empty_tuple.type [concrete = constants.%empty_tuple.type]
// CHECK:STDOUT: %.Self.ref.loc10_48: %J.type = name_ref .Self, %.Self.2 [symbolic_self = constants.%.Self.2fa]
// CHECK:STDOUT: %.Self.as_type.loc10_48: type = facet_access_type %.Self.ref.loc10_48 [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.loc10_48: type = converted %.Self.ref.loc10_48, %.Self.as_type.loc10_48 [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %L.ref: %J.assoc_type = name_ref L, @L.%assoc1 [concrete = constants.%assoc1]
// CHECK:STDOUT: %impl.elem1: type = impl_witness_access constants.%J.lookup_impl_witness, element1 [symbolic_self = constants.%impl.elem1]
// CHECK:STDOUT: %Bool.call: init type = call constants.%Bool() [concrete = bool]
// CHECK:STDOUT: %.loc10_46.1: type = value_of_initializer %Bool.call [concrete = bool]
// CHECK:STDOUT: %.loc10_46.2: type = converted %Bool.call, %.loc10_46.1 [concrete = bool]
// CHECK:STDOUT: %.loc10_23.2: type = where_expr %.Self.2 [concrete = constants.%J_where.type] {
// CHECK:STDOUT: %.loc10_53.1: type = value_of_initializer %Bool.call [concrete = bool]
// CHECK:STDOUT: %.loc10_53.2: type = converted %Bool.call, %.loc10_53.1 [concrete = bool]
// CHECK:STDOUT: %.loc10_30.2: type = where_expr %.Self.2 [concrete = constants.%J_where.type] {
// CHECK:STDOUT: requirement_base_facet_type constants.%J.type
// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc10_35.2
// CHECK:STDOUT: requirement_rewrite %impl.elem1, %.loc10_46.2
// CHECK:STDOUT: requirement_rewrite %impl.elem0, %.loc10_42.2
// CHECK:STDOUT: requirement_rewrite %impl.elem1, %.loc10_53.2
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: %M.loc10_17.2: %J_where.type = symbolic_binding M, 0 [symbolic = %M.loc10_17.1 (constants.%M)]
// CHECK:STDOUT: %M.loc10_24.2: %J_where.type = symbolic_binding M, 0 [symbolic = %M.loc10_24.1 (constants.%M)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %Reversed.decl: %Reversed.type = fn_decl @Reversed [concrete = constants.%Reversed] {
// CHECK:STDOUT: %N.patt: %pattern_type.a2c = symbolic_binding_pattern N, 0 [concrete]
@@ -574,8 +574,8 @@ let K: (E where .F = .Self.G) = bool;
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: generic fn @Alphabetical(%M.loc10_17.2: %J_where.type) {
// CHECK:STDOUT: %M.loc10_17.1: %J_where.type = symbolic_binding M, 0 [symbolic = %M.loc10_17.1 (constants.%M)]
// CHECK:STDOUT: generic fn @Alphabetical(%M.loc10_24.2: %J_where.type) {
// CHECK:STDOUT: %M.loc10_24.1: %J_where.type = symbolic_binding M, 0 [symbolic = %M.loc10_24.1 (constants.%M)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT:
@@ -598,7 +598,7 @@ let K: (E where .F = .Self.G) = bool;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Alphabetical(constants.%M) {
// CHECK:STDOUT: %M.loc10_17.1 => constants.%M
// CHECK:STDOUT: %M.loc10_24.1 => constants.%M
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Reversed(constants.%N) {
@@ -606,7 +606,7 @@ let K: (E where .F = .Self.G) = bool;
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: specific @Alphabetical(constants.%N) {
// CHECK:STDOUT: %M.loc10_17.1 => constants.%N
// CHECK:STDOUT: %M.loc10_24.1 => constants.%N
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: }
+4 -4
View File
@@ -14,7 +14,7 @@ interface I { let T:! type; }
// Ensure that we don't crash when checking this `where` in a non-generic context.
//@dump-sem-ir-begin
fn NotGenericF(U: I where .T == i32) {}
fn NotGenericF(unused U: I where .T == i32) {}
//@dump-sem-ir-end
// CHECK:STDOUT: --- non_generic.carbon
@@ -44,17 +44,17 @@ fn NotGenericF(U: I where .T == i32) {}
// CHECK:STDOUT: %U.param_patt: %pattern_type.092 = value_param_pattern %U.patt, call_param0 [concrete]
// CHECK:STDOUT: } {
// CHECK:STDOUT: %U.param: %I_where.type = value_param call_param0
// CHECK:STDOUT: %.loc17_21.1: type = splice_block %.loc17_21.2 [concrete = constants.%I_where.type] {
// CHECK:STDOUT: %.loc17_28.1: type = splice_block %.loc17_28.2 [concrete = constants.%I_where.type] {
// CHECK:STDOUT: %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
// CHECK:STDOUT: <elided>
// CHECK:STDOUT: %.Self.ref: %I.type = name_ref .Self, %.Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %.Self.as_type: type = facet_access_type %.Self.ref [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.loc17_27: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %.loc17_34: type = converted %.Self.ref, %.Self.as_type [symbolic_self = constants.%.Self.binding.as_type]
// CHECK:STDOUT: %T.ref: %I.assoc_type = name_ref T, @T.%assoc0 [concrete = constants.%assoc0]
// CHECK:STDOUT: %impl.elem0: type = impl_witness_access constants.%I.lookup_impl_witness, element0 [symbolic_self = constants.%impl.elem0]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
// CHECK:STDOUT: %.loc17_21.2: type = where_expr %.Self [concrete = constants.%I_where.type] {
// CHECK:STDOUT: %.loc17_28.2: type = where_expr %.Self [concrete = constants.%I_where.type] {
// CHECK:STDOUT: requirement_base_facet_type constants.%I.type
// CHECK:STDOUT: requirement_equivalent %impl.elem0, %i32
// CHECK:STDOUT: }