Skip to content

Commit 2881814

Browse files
authored
Prevent BitAnd for facet types from matching non-type values (#5111)
Currently this test fails with trying to access a comptime function with runtime values: ``` fn F() { let a: J = {} as J; let b: J = {} as J; // CHECK:STDERR: fail_bit_and_values_no_impl.carbon:[[@line+7]]:3: error: non-constant call to compile-time-only function [NonConstantCallToCompTimeOnlyFunction] // CHECK:STDERR: a & b; // CHECK:STDERR: ^~~~~ // CHECK:STDERR: core/prelude/operators/bitwise.carbon:96:3: note: compile-time-only function declared here [CompTimeOnlyFunctionHere] // CHECK:STDERR: fn Op[self: Self](other: Self) -> Self = "type.and"; // CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CHECK:STDERR: a & b; } ``` The issue is that the BitAnd impl for facet types is matching on any value of any type: ``` impl forall [T:! type] T as BitAnd ``` What we really want is for it to match on facet types (which are type values), which is written as: ``` impl type as BitAnd ``` After this change, the error makes more sense in the above test: ``` fn F() { let a: J = {} as J; let b: J = {} as J; // CHECK:STDERR: fail_bit_and_values_no_impl.carbon:[[@line+4]]:3: error: cannot access member of interface `Core.BitAnd` in type `J` that does not implement that interface [MissingImplInMemberAccess] // CHECK:STDERR: a & b; // CHECK:STDERR: ^~~~~ // CHECK:STDERR: a & b; } ```
1 parent 6fd139b commit 2881814

File tree

15 files changed

+157
-149
lines changed

15 files changed

+157
-149
lines changed

core/prelude/operators/bitwise.carbon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,6 @@ impl IntLiteral() as RightShift {
9292
// associated library of its own.
9393

9494
// Facet type combination.
95-
impl forall [T:! type] T as BitAnd {
95+
impl type as BitAnd {
9696
fn Op[self: Self](other: Self) -> Self = "type.and";
9797
}

toolchain/check/testdata/builtin_conversions/value_with_type_through_access.carbon

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -646,11 +646,11 @@ fn G() {
646646
// CHECK:STDOUT: constants {
647647
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete]
648648
// CHECK:STDOUT: %array_type: type = array_type %int_1, type [concrete]
649-
// CHECK:STDOUT: %T.eb6: %array_type = bind_symbolic_name T, 0 [symbolic]
650-
// CHECK:STDOUT: %T.patt.226: %array_type = symbolic_binding_pattern T, 0 [symbolic]
649+
// CHECK:STDOUT: %T: %array_type = bind_symbolic_name T, 0 [symbolic]
650+
// CHECK:STDOUT: %T.patt: %array_type = symbolic_binding_pattern T, 0 [symbolic]
651651
// CHECK:STDOUT: %HoldsType.type: type = generic_class_type @HoldsType [concrete]
652652
// CHECK:STDOUT: %HoldsType.generic: %HoldsType.type = struct_value () [concrete]
653-
// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T.eb6) [symbolic]
653+
// CHECK:STDOUT: %HoldsType: type = class_type @HoldsType, @HoldsType(%T) [symbolic]
654654
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
655655
// CHECK:STDOUT: %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
656656
// CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
@@ -696,16 +696,16 @@ fn G() {
696696
// CHECK:STDOUT: }
697697
// CHECK:STDOUT: %Core.import = import Core
698698
// CHECK:STDOUT: %HoldsType.decl: %HoldsType.type = class_decl @HoldsType [concrete = constants.%HoldsType.generic] {
699-
// CHECK:STDOUT: %T.patt.loc4_17.1: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_17.2 (constants.%T.patt.226)]
699+
// CHECK:STDOUT: %T.patt.loc4_17.1: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_17.2 (constants.%T.patt)]
700700
// CHECK:STDOUT: } {
701701
// CHECK:STDOUT: %.loc4: type = splice_block %array_type [concrete = constants.%array_type] {
702702
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
703703
// CHECK:STDOUT: %array_type: type = array_type %int_1, type [concrete = constants.%array_type]
704704
// CHECK:STDOUT: }
705-
// CHECK:STDOUT: %T.loc4_17.1: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.2 (constants.%T.eb6)]
705+
// CHECK:STDOUT: %T.loc4_17.1: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.2 (constants.%T)]
706706
// CHECK:STDOUT: }
707707
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
708-
// CHECK:STDOUT: %T.patt.loc12_6.1: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt.226)]
708+
// CHECK:STDOUT: %T.patt.loc12_6.1: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt)]
709709
// CHECK:STDOUT: %x.patt: @F.%HoldsType.loc12_40.2 (%HoldsType) = binding_pattern x
710710
// CHECK:STDOUT: %x.param_patt: @F.%HoldsType.loc12_40.2 (%HoldsType) = value_param_pattern %x.patt, call_param0
711711
// CHECK:STDOUT: %a.patt: <error> = binding_pattern a
@@ -715,17 +715,17 @@ fn G() {
715715
// CHECK:STDOUT: %int_1: Core.IntLiteral = int_value 1 [concrete = constants.%int_1]
716716
// CHECK:STDOUT: %array_type: type = array_type %int_1, type [concrete = constants.%array_type]
717717
// CHECK:STDOUT: }
718-
// CHECK:STDOUT: %T.loc12_6.1: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc12_6.2 (constants.%T.eb6)]
718+
// CHECK:STDOUT: %T.loc12_6.1: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc12_6.2 (constants.%T)]
719719
// CHECK:STDOUT: %x.param: @F.%HoldsType.loc12_40.2 (%HoldsType) = value_param call_param0
720720
// CHECK:STDOUT: %.loc12_40: type = splice_block %HoldsType.loc12_40.1 [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)] {
721721
// CHECK:STDOUT: %HoldsType.ref: %HoldsType.type = name_ref HoldsType, file.%HoldsType.decl [concrete = constants.%HoldsType.generic]
722-
// CHECK:STDOUT: %T.ref.loc12_39: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T.eb6)]
723-
// CHECK:STDOUT: %HoldsType.loc12_40.1: type = class_type @HoldsType, @HoldsType(constants.%T.eb6) [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)]
722+
// CHECK:STDOUT: %T.ref.loc12_39: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)]
723+
// CHECK:STDOUT: %HoldsType.loc12_40.1: type = class_type @HoldsType, @HoldsType(constants.%T) [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)]
724724
// CHECK:STDOUT: }
725725
// CHECK:STDOUT: %x: @F.%HoldsType.loc12_40.2 (%HoldsType) = bind_name x, %x.param
726726
// CHECK:STDOUT: %a.param: <error> = value_param call_param1
727727
// CHECK:STDOUT: %.1: <error> = splice_block <error> [concrete = <error>] {
728-
// CHECK:STDOUT: %T.ref.loc12_46: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T.eb6)]
728+
// CHECK:STDOUT: %T.ref.loc12_46: %array_type = name_ref T, %T.loc12_6.1 [symbolic = %T.loc12_6.2 (constants.%T)]
729729
// CHECK:STDOUT: %int_0: Core.IntLiteral = int_value 0 [concrete = constants.%int_0.5c6]
730730
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
731731
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
@@ -747,8 +747,8 @@ fn G() {
747747
// CHECK:STDOUT: }
748748
// CHECK:STDOUT:
749749
// CHECK:STDOUT: generic class @HoldsType(%T.loc4_17.1: %array_type) {
750-
// CHECK:STDOUT: %T.loc4_17.2: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.2 (constants.%T.eb6)]
751-
// CHECK:STDOUT: %T.patt.loc4_17.2: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_17.2 (constants.%T.patt.226)]
750+
// CHECK:STDOUT: %T.loc4_17.2: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc4_17.2 (constants.%T)]
751+
// CHECK:STDOUT: %T.patt.loc4_17.2: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc4_17.2 (constants.%T.patt)]
752752
// CHECK:STDOUT:
753753
// CHECK:STDOUT: !definition:
754754
// CHECK:STDOUT:
@@ -770,8 +770,8 @@ fn G() {
770770
// CHECK:STDOUT: }
771771
// CHECK:STDOUT:
772772
// CHECK:STDOUT: generic fn @F(%T.loc12_6.1: %array_type) {
773-
// CHECK:STDOUT: %T.loc12_6.2: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc12_6.2 (constants.%T.eb6)]
774-
// CHECK:STDOUT: %T.patt.loc12_6.2: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt.226)]
773+
// CHECK:STDOUT: %T.loc12_6.2: %array_type = bind_symbolic_name T, 0 [symbolic = %T.loc12_6.2 (constants.%T)]
774+
// CHECK:STDOUT: %T.patt.loc12_6.2: %array_type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc12_6.2 (constants.%T.patt)]
775775
// CHECK:STDOUT: %HoldsType.loc12_40.2: type = class_type @HoldsType, @HoldsType(%T.loc12_6.2) [symbolic = %HoldsType.loc12_40.2 (constants.%HoldsType)]
776776
// CHECK:STDOUT:
777777
// CHECK:STDOUT: !definition:
@@ -804,16 +804,16 @@ fn G() {
804804
// CHECK:STDOUT: return
805805
// CHECK:STDOUT: }
806806
// CHECK:STDOUT:
807-
// CHECK:STDOUT: specific @HoldsType(constants.%T.eb6) {
808-
// CHECK:STDOUT: %T.loc4_17.2 => constants.%T.eb6
809-
// CHECK:STDOUT: %T.patt.loc4_17.2 => constants.%T.eb6
807+
// CHECK:STDOUT: specific @HoldsType(constants.%T) {
808+
// CHECK:STDOUT: %T.loc4_17.2 => constants.%T
809+
// CHECK:STDOUT: %T.patt.loc4_17.2 => constants.%T
810810
// CHECK:STDOUT:
811811
// CHECK:STDOUT: !definition:
812812
// CHECK:STDOUT: }
813813
// CHECK:STDOUT:
814-
// CHECK:STDOUT: specific @F(constants.%T.eb6) {
815-
// CHECK:STDOUT: %T.loc12_6.2 => constants.%T.eb6
816-
// CHECK:STDOUT: %T.patt.loc12_6.2 => constants.%T.eb6
814+
// CHECK:STDOUT: specific @F(constants.%T) {
815+
// CHECK:STDOUT: %T.loc12_6.2 => constants.%T
816+
// CHECK:STDOUT: %T.patt.loc12_6.2 => constants.%T
817817
// CHECK:STDOUT: %HoldsType.loc12_40.2 => constants.%HoldsType
818818
// CHECK:STDOUT: }
819819
// CHECK:STDOUT:

toolchain/check/testdata/class/generic/import.carbon

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,10 @@ class Class(U:! type) {
252252
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(%int_32) [concrete]
253253
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
254254
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
255-
// CHECK:STDOUT: %require_complete.4ae: <witness> = require_complete_type %T [symbolic]
256255
// CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete]
257256
// CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete]
258257
// CHECK:STDOUT: %Class: type = class_type @Class, @Class(%T) [symbolic]
258+
// CHECK:STDOUT: %require_complete.4ae: <witness> = require_complete_type %T [symbolic]
259259
// CHECK:STDOUT: %Class.elem: type = unbound_element_type %Class, %T [symbolic]
260260
// CHECK:STDOUT: %struct_type.x: type = struct_type {.x: %T} [symbolic]
261261
// CHECK:STDOUT: %complete_type.433: <witness> = complete_type_witness %struct_type.x [symbolic]
@@ -776,12 +776,12 @@ class Class(U:! type) {
776776
// CHECK:STDOUT: --- fail_foo.impl.carbon
777777
// CHECK:STDOUT:
778778
// CHECK:STDOUT: constants {
779-
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
780-
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
781779
// CHECK:STDOUT: %U: type = bind_symbolic_name U, 0 [symbolic]
782780
// CHECK:STDOUT: %U.patt: type = symbolic_binding_pattern U, 0 [symbolic]
783781
// CHECK:STDOUT: %Class.type: type = generic_class_type @Class [concrete]
784782
// CHECK:STDOUT: %Class.generic: %Class.type = struct_value () [concrete]
783+
// CHECK:STDOUT: %T: type = bind_symbolic_name T, 0 [symbolic]
784+
// CHECK:STDOUT: %T.patt: type = symbolic_binding_pattern T, 0 [symbolic]
785785
// CHECK:STDOUT: %.type: type = generic_class_type @.1 [concrete]
786786
// CHECK:STDOUT: %.generic: %.type = struct_value () [concrete]
787787
// CHECK:STDOUT: %.e41: type = class_type @.1, @.1(%U) [symbolic]

toolchain/check/testdata/class/import.carbon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,5 +364,5 @@ fn Run() {
364364
// CHECK:STDOUT:
365365
// CHECK:STDOUT: fn @F[%self.param_patt: %ForwardDeclared.7b34f2.1]() [from "a.carbon"];
366366
// CHECK:STDOUT:
367-
// CHECK:STDOUT: fn @G[addr <unexpected>.inst1158: %ptr.6cf]() [from "a.carbon"];
367+
// CHECK:STDOUT: fn @G[addr <unexpected>.inst1134: %ptr.6cf]() [from "a.carbon"];
368368
// CHECK:STDOUT:

toolchain/check/testdata/facet/min_prelude/combine.carbon

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -11,74 +11,6 @@
1111
// TIP: To dump output, run:
1212
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/facet/min_prelude/combine.carbon
1313

14-
// --- fail_combine_with_non_facet_type.carbon
15-
library "[[@TEST_NAME]]";
16-
17-
interface A {}
18-
class C {}
19-
20-
// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:11: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator]
21-
// CHECK:STDERR: fn AC[T:! A & C](t: T) {}
22-
// CHECK:STDERR: ^~~~~
23-
// CHECK:STDERR:
24-
fn AC[T:! A & C](t: T) {}
25-
// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:11: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator]
26-
// CHECK:STDERR: fn CA[T:! C & A](t: T) {}
27-
// CHECK:STDERR: ^~~~~
28-
// CHECK:STDERR:
29-
fn CA[T:! C & A](t: T) {}
30-
// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+8]]:11: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator]
31-
// CHECK:STDERR: fn CC[T:! C & C](t: T) {}
32-
// CHECK:STDERR: ^~~~~
33-
// CHECK:STDERR:
34-
// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:11: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator]
35-
// CHECK:STDERR: fn CC[T:! C & C](t: T) {}
36-
// CHECK:STDERR: ^~~~~
37-
// CHECK:STDERR:
38-
fn CC[T:! C & C](t: T) {}
39-
40-
fn F() {
41-
// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:23: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator]
42-
// CHECK:STDERR: ({} as C) as (C as (A & C));
43-
// CHECK:STDERR: ^~~~~
44-
// CHECK:STDERR:
45-
({} as C) as (C as (A & C));
46-
// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:23: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator]
47-
// CHECK:STDERR: ({} as C) as (C as (C & A));
48-
// CHECK:STDERR: ^~~~~
49-
// CHECK:STDERR:
50-
({} as C) as (C as (C & A));
51-
// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+8]]:23: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator]
52-
// CHECK:STDERR: ({} as C) as (C as (C & C));
53-
// CHECK:STDERR: ^~~~~
54-
// CHECK:STDERR:
55-
// CHECK:STDERR: fail_combine_with_non_facet_type.carbon:[[@LINE+4]]:23: error: non-facet type `C` combined with `&` operator [FacetTypeRequiredForTypeAndOperator]
56-
// CHECK:STDERR: ({} as C) as (C as (C & C));
57-
// CHECK:STDERR: ^~~~~
58-
// CHECK:STDERR:
59-
({} as C) as (C as (C & C));
60-
61-
AC({} as C);
62-
CA({} as C);
63-
CC({} as C);
64-
}
65-
66-
// --- same.carbon
67-
library "[[@TEST_NAME]]";
68-
69-
interface A {}
70-
71-
class C {}
72-
impl C as A {}
73-
74-
fn AA[T:! A & A](t: T) {}
75-
76-
fn F() {
77-
({} as C) as (C as (A & A));
78-
79-
AA({} as C);
80-
}
81-
8214
// --- fail_name_collision.carbon
8315
library "[[@TEST_NAME]]";
8416

toolchain/check/testdata/function/generic/undefined.carbon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ fn CallUndefined() -> i32 {
185185
// CHECK:STDOUT: %int_0.5c6: Core.IntLiteral = int_value 0 [concrete]
186186
// CHECK:STDOUT: %As.type.fd4: type = facet_type <@As, @As(%i32)> [concrete]
187187
// CHECK:STDOUT: %Convert.type.99b: type = fn_type @Convert.1, @As(%i32) [concrete]
188-
// CHECK:STDOUT: %require_complete.4ae: <witness> = require_complete_type %T [symbolic]
189188
// CHECK:STDOUT: %impl_witness.882: <witness> = impl_witness (imports.%Core.import_ref.78a), @impl.686(%int_32) [concrete]
190189
// CHECK:STDOUT: %Convert.type.4fd: type = fn_type @Convert.5, @impl.686(%int_32) [concrete]
191190
// CHECK:STDOUT: %Convert.197: %Convert.type.4fd = struct_value () [concrete]
@@ -196,6 +195,7 @@ fn CallUndefined() -> i32 {
196195
// CHECK:STDOUT: %bound_method: <bound method> = bound_method %int_0.5c6, %Convert.specific_fn [concrete]
197196
// CHECK:STDOUT: %int_0.6a9: %i32 = int_value 0 [concrete]
198197
// CHECK:STDOUT: %Defined.specific_fn: <specific function> = specific_function %Defined, @Defined(%i32) [concrete]
198+
// CHECK:STDOUT: %require_complete.4ae: <witness> = require_complete_type %T [symbolic]
199199
// CHECK:STDOUT: }
200200
// CHECK:STDOUT:
201201
// CHECK:STDOUT: imports {

toolchain/check/testdata/if_expr/fail_not_in_function.carbon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class C {
9494
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [concrete = constants.%int_32]
9595
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [concrete = constants.%i32]
9696
// CHECK:STDOUT: }
97-
// CHECK:STDOUT: %x: %i32 = bind_name x, <unexpected>.inst1080.loc27_14
97+
// CHECK:STDOUT: %x: %i32 = bind_name x, <unexpected>.inst1056.loc27_14
9898
// CHECK:STDOUT: name_binding_decl {
9999
// CHECK:STDOUT: %y.patt: %i32 = binding_pattern y
100100
// CHECK:STDOUT: %.loc37: %i32 = var_pattern %y.patt

0 commit comments

Comments
 (0)