Model var as a pattern operator (#4720)

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
Geoff Romer
2025-01-17 17:51:34 +00:00
committed by GitHub
co-authored by Richard Smith
parent 6572da7314
commit 13434f0e8a
510 changed files with 11819 additions and 3352 deletions
@@ -10,9 +10,9 @@
fn F(T:! type, U:! type) {
var p: T*;
// CHECK:STDERR: fail_type_param_mismatch.carbon:[[@LINE+4]]:3: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
// CHECK:STDERR: fail_type_param_mismatch.carbon:[[@LINE+4]]:14: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
// CHECK:STDERR: let n: U = *p;
// CHECK:STDERR: ^~~~~~~~~~~~~~
// CHECK:STDERR: ^~
// CHECK:STDERR:
let n: U = *p;
}
@@ -55,18 +55,30 @@ fn F(T:! type, U:! type) {
// CHECK:STDOUT: %U.patt.loc11_16.2: type = symbolic_binding_pattern U, 1 [symbolic = %U.patt.loc11_16.2 (constants.%U.patt)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %ptr: type = ptr_type @F.%T.loc11_6.2 (%T) [symbolic = %ptr (constants.%ptr)]
// CHECK:STDOUT: %require_complete.loc12: <witness> = require_complete_type @F.%ptr (%ptr) [symbolic = %require_complete.loc12 (constants.%require_complete.6e5)]
// CHECK:STDOUT: %ptr.loc12_11.2: type = ptr_type @F.%T.loc11_6.2 (%T) [symbolic = %ptr.loc12_11.2 (constants.%ptr)]
// CHECK:STDOUT: %require_complete.loc12: <witness> = require_complete_type @F.%ptr.loc12_11.2 (%ptr) [symbolic = %require_complete.loc12 (constants.%require_complete.6e5)]
// CHECK:STDOUT: %require_complete.loc17: <witness> = require_complete_type @F.%U.loc11_16.2 (%U) [symbolic = %require_complete.loc17 (constants.%require_complete.b54)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%T.param_patt: type, %U.param_patt: type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %p.var: ref @F.%ptr (%ptr) = var p
// CHECK:STDOUT: %p: ref @F.%ptr (%ptr) = bind_name p, %p.var
// CHECK:STDOUT: %p.ref: ref @F.%ptr (%ptr) = name_ref p, %p
// CHECK:STDOUT: %.loc17_15: @F.%ptr (%ptr) = bind_value %p.ref
// CHECK:STDOUT: %.loc17_14: ref @F.%T.loc11_6.2 (%T) = deref %.loc17_15
// CHECK:STDOUT: %.loc17_16: @F.%U.loc11_16.2 (%U) = converted %.loc17_14, <error> [template = <error>]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %p.patt: @F.%ptr.loc12_11.2 (%ptr) = binding_pattern p
// CHECK:STDOUT: %.loc12_3: @F.%ptr.loc12_11.2 (%ptr) = var_pattern %p.patt
// CHECK:STDOUT: }
// CHECK:STDOUT: %p.var: ref @F.%ptr.loc12_11.2 (%ptr) = var p
// CHECK:STDOUT: %.loc12_11: type = splice_block %ptr.loc12_11.1 [symbolic = %ptr.loc12_11.2 (constants.%ptr)] {
// CHECK:STDOUT: %T.ref: type = name_ref T, %T.loc11_6.1 [symbolic = %T.loc11_6.2 (constants.%T)]
// CHECK:STDOUT: %ptr.loc12_11.1: type = ptr_type %T [symbolic = %ptr.loc12_11.2 (constants.%ptr)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %p: ref @F.%ptr.loc12_11.2 (%ptr) = bind_name p, %p.var
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %n.patt: @F.%U.loc11_16.2 (%U) = binding_pattern n
// CHECK:STDOUT: }
// CHECK:STDOUT: %p.ref: ref @F.%ptr.loc12_11.2 (%ptr) = name_ref p, %p
// CHECK:STDOUT: %.loc17_15: @F.%ptr.loc12_11.2 (%ptr) = bind_value %p.ref
// CHECK:STDOUT: %.loc17_14.1: ref @F.%T.loc11_6.2 (%T) = deref %.loc17_15
// CHECK:STDOUT: %U.ref: type = name_ref U, %U.loc11_16.1 [symbolic = %U.loc11_16.2 (constants.%U)]
// CHECK:STDOUT: %.loc17_14.2: @F.%U.loc11_16.2 (%U) = converted %.loc17_14.1, <error> [template = <error>]
// CHECK:STDOUT: %n: @F.%U.loc11_16.2 (%U) = bind_name n, <error>
// CHECK:STDOUT: return
// CHECK:STDOUT: }
@@ -43,19 +43,30 @@ fn F(T:! type) {
// CHECK:STDOUT: %T.patt.loc11_6.2: type = symbolic_binding_pattern T, 0 [symbolic = %T.patt.loc11_6.2 (constants.%T.patt)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %ptr: type = ptr_type @F.%T.loc11_6.2 (%T) [symbolic = %ptr (constants.%ptr)]
// CHECK:STDOUT: %require_complete.loc12: <witness> = require_complete_type @F.%ptr (%ptr) [symbolic = %require_complete.loc12 (constants.%require_complete.6e5)]
// CHECK:STDOUT: %ptr.loc12_11.2: type = ptr_type @F.%T.loc11_6.2 (%T) [symbolic = %ptr.loc12_11.2 (constants.%ptr)]
// CHECK:STDOUT: %require_complete.loc12: <witness> = require_complete_type @F.%ptr.loc12_11.2 (%ptr) [symbolic = %require_complete.loc12 (constants.%require_complete.6e5)]
// CHECK:STDOUT: %require_complete.loc13: <witness> = require_complete_type @F.%T.loc11_6.2 (%T) [symbolic = %require_complete.loc13 (constants.%require_complete.4ae)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%T.param_patt: type) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %p.var: ref @F.%ptr (%ptr) = var p
// CHECK:STDOUT: %p: ref @F.%ptr (%ptr) = bind_name p, %p.var
// CHECK:STDOUT: %p.ref: ref @F.%ptr (%ptr) = name_ref p, %p
// CHECK:STDOUT: %.loc13_15: @F.%ptr (%ptr) = bind_value %p.ref
// CHECK:STDOUT: %.loc13_14.1: ref @F.%T.loc11_6.2 (%T) = deref %.loc13_15
// CHECK:STDOUT: %.loc13_14.2: @F.%T.loc11_6.2 (%T) = bind_value %.loc13_14.1
// CHECK:STDOUT: %n: @F.%T.loc11_6.2 (%T) = bind_name n, %.loc13_14.2
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %p.patt: @F.%ptr.loc12_11.2 (%ptr) = binding_pattern p
// CHECK:STDOUT: %.loc12_3: @F.%ptr.loc12_11.2 (%ptr) = var_pattern %p.patt
// CHECK:STDOUT: }
// CHECK:STDOUT: %p.var: ref @F.%ptr.loc12_11.2 (%ptr) = var p
// CHECK:STDOUT: %.loc12_11: type = splice_block %ptr.loc12_11.1 [symbolic = %ptr.loc12_11.2 (constants.%ptr)] {
// CHECK:STDOUT: %T.ref.loc12: type = name_ref T, %T.loc11_6.1 [symbolic = %T.loc11_6.2 (constants.%T)]
// CHECK:STDOUT: %ptr.loc12_11.1: type = ptr_type %T [symbolic = %ptr.loc12_11.2 (constants.%ptr)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %p: ref @F.%ptr.loc12_11.2 (%ptr) = bind_name p, %p.var
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %n.patt: @F.%T.loc11_6.2 (%T) = binding_pattern n
// CHECK:STDOUT: }
// CHECK:STDOUT: %p.ref: ref @F.%ptr.loc12_11.2 (%ptr) = name_ref p, %p
// CHECK:STDOUT: %.loc13_15: @F.%ptr.loc12_11.2 (%ptr) = bind_value %p.ref
// CHECK:STDOUT: %.loc13_14: ref @F.%T.loc11_6.2 (%T) = deref %.loc13_15
// CHECK:STDOUT: %T.ref.loc13: type = name_ref T, %T.loc11_6.1 [symbolic = %T.loc11_6.2 (constants.%T)]
// CHECK:STDOUT: %n: ref @F.%T.loc11_6.2 (%T) = bind_name n, %.loc13_14
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -55,7 +55,11 @@ fn F(T:! type, n: T) -> T {
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%T.param_patt: type, %n.param_patt: @F.%T.loc11_6.2 (%T)) -> @F.%T.loc11_6.2 (%T) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %m.patt: @F.%T.loc11_6.2 (%T) = binding_pattern m
// CHECK:STDOUT: }
// CHECK:STDOUT: %n.ref: @F.%T.loc11_6.2 (%T) = name_ref n, %n
// CHECK:STDOUT: %T.ref.loc12: type = name_ref T, %T.loc11_6.1 [symbolic = %T.loc11_6.2 (constants.%T)]
// CHECK:STDOUT: %m: @F.%T.loc11_6.2 (%T) = bind_name m, %n.ref
// CHECK:STDOUT: %m.ref: @F.%T.loc11_6.2 (%T) = name_ref m, %m
// CHECK:STDOUT: return %m.ref
@@ -44,6 +44,8 @@ fn CallNegative() {
// CHECK:STDOUT: %N.patt: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic]
// CHECK:STDOUT: %ErrorIfNIsZero.type: type = fn_type @ErrorIfNIsZero [template]
// CHECK:STDOUT: %ErrorIfNIsZero: %ErrorIfNIsZero.type = struct_value () [template]
// CHECK:STDOUT: %Int.type: type = generic_class_type @Int [template]
// CHECK:STDOUT: %Int.generic: %Int.type = struct_value () [template]
// CHECK:STDOUT: %Int: type = class_type @Int, @Int(%N) [symbolic]
// CHECK:STDOUT: %require_complete.b4f: <witness> = require_complete_type %Int [symbolic]
// CHECK:STDOUT: %CallNegative.type: type = fn_type @CallNegative [template]
@@ -62,6 +64,7 @@ fn CallNegative() {
// CHECK:STDOUT: import Core//prelude/...
// CHECK:STDOUT: }
// CHECK:STDOUT: %import_ref.72f: %IntLiteral.type = import_ref Core//prelude/types/int_literal, IntLiteral, loaded [template = constants.%IntLiteral]
// CHECK:STDOUT: %import_ref.485: %Int.type = import_ref Core//prelude/types/int, Int, loaded [template = constants.%Int.generic]
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
@@ -77,7 +80,7 @@ fn CallNegative() {
// CHECK:STDOUT: } {
// CHECK:STDOUT: %N.param: Core.IntLiteral = value_param runtime_param<invalid>
// CHECK:STDOUT: %.loc4_39.1: type = splice_block %.loc4_39.3 [template = Core.IntLiteral] {
// CHECK:STDOUT: %Core.ref: <namespace> = name_ref Core, imports.%Core [template = imports.%Core]
// CHECK:STDOUT: %Core.ref.loc4: <namespace> = name_ref Core, imports.%Core [template = imports.%Core]
// CHECK:STDOUT: %IntLiteral.ref: %IntLiteral.type = name_ref IntLiteral, imports.%import_ref.72f [template = constants.%IntLiteral]
// CHECK:STDOUT: %int_literal.make_type: init type = call %IntLiteral.ref() [template = Core.IntLiteral]
// CHECK:STDOUT: %.loc4_39.2: type = value_of_initializer %int_literal.make_type [template = Core.IntLiteral]
@@ -93,13 +96,23 @@ fn CallNegative() {
// CHECK:STDOUT: %N.patt.loc4_19.2: Core.IntLiteral = symbolic_binding_pattern N, 0 [symbolic = %N.patt.loc4_19.2 (constants.%N.patt)]
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %Int: type = class_type @Int, @Int(%N.loc4_19.2) [symbolic = %Int (constants.%Int)]
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type @ErrorIfNIsZero.%Int (%Int) [symbolic = %require_complete (constants.%require_complete.b4f)]
// CHECK:STDOUT: %Int.loc15_20.2: type = class_type @Int, @Int(%N.loc4_19.2) [symbolic = %Int.loc15_20.2 (constants.%Int)]
// CHECK:STDOUT: %require_complete: <witness> = require_complete_type @ErrorIfNIsZero.%Int.loc15_20.2 (%Int) [symbolic = %require_complete (constants.%require_complete.b4f)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%N.param_patt: Core.IntLiteral) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %v.var: ref @ErrorIfNIsZero.%Int (%Int) = var v
// CHECK:STDOUT: %v: ref @ErrorIfNIsZero.%Int (%Int) = bind_name v, %v.var
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %v.patt: @ErrorIfNIsZero.%Int.loc15_20.2 (%Int) = binding_pattern v
// CHECK:STDOUT: %.loc15_3: @ErrorIfNIsZero.%Int.loc15_20.2 (%Int) = var_pattern %v.patt
// CHECK:STDOUT: }
// CHECK:STDOUT: %v.var: ref @ErrorIfNIsZero.%Int.loc15_20.2 (%Int) = var v
// CHECK:STDOUT: %.loc15_20: type = splice_block %Int.loc15_20.1 [symbolic = %Int.loc15_20.2 (constants.%Int)] {
// CHECK:STDOUT: %Core.ref.loc15: <namespace> = name_ref Core, imports.%Core [template = imports.%Core]
// CHECK:STDOUT: %Int.ref: %Int.type = name_ref Int, imports.%import_ref.485 [template = constants.%Int.generic]
// CHECK:STDOUT: %N.ref: Core.IntLiteral = name_ref N, %N.loc4_19.1 [symbolic = %N.loc4_19.2 (constants.%N)]
// CHECK:STDOUT: %Int.loc15_20.1: type = class_type @Int, @Int(constants.%N) [symbolic = %Int.loc15_20.2 (constants.%Int)]
// CHECK:STDOUT: }
// CHECK:STDOUT: %v: ref @ErrorIfNIsZero.%Int.loc15_20.2 (%Int) = bind_name v, %v.var
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -123,7 +136,7 @@ fn CallNegative() {
// CHECK:STDOUT: %N.patt.loc4_19.2 => constants.%int_0
// CHECK:STDOUT:
// CHECK:STDOUT: !definition:
// CHECK:STDOUT: %Int => constants.%i0
// CHECK:STDOUT: %Int.loc15_20.2 => constants.%i0
// CHECK:STDOUT: %require_complete => constants.%complete_type.d94
// CHECK:STDOUT: }
// CHECK:STDOUT:
+36 -11
View File
@@ -111,7 +111,11 @@ fn G() {
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: class @C {
// CHECK:STDOUT: %.loc15: %C.elem = field_decl arr, element0 [template]
// CHECK:STDOUT: %.loc15_18: %C.elem = field_decl arr, element0 [template]
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %.loc15_11: %C.elem = var_pattern %.loc15_18
// CHECK:STDOUT: }
// CHECK:STDOUT: %.var: ref %C.elem = var <invalid>
// CHECK:STDOUT: %complete_type: <witness> = complete_type_witness %struct_type.arr.5f2 [template = constants.%complete_type.22a]
// CHECK:STDOUT: complete_type_witness = %complete_type
// CHECK:STDOUT: }
@@ -139,19 +143,30 @@ fn G() {
// CHECK:STDOUT:
// CHECK:STDOUT: fn @G() {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %a.patt: %i32 = binding_pattern a
// CHECK:STDOUT: %.loc18_3: %i32 = var_pattern %a.patt
// CHECK:STDOUT: }
// CHECK:STDOUT: %a.var: ref %i32 = var a
// CHECK:STDOUT: %a: ref %i32 = bind_name a, %a.var
// CHECK:STDOUT: %Wrap.ref.loc18: %Wrap.type = name_ref Wrap, file.%Wrap.decl [template = constants.%Wrap.generic]
// CHECK:STDOUT: %int_32: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %int_32.loc18_21: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc18_21: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: %Wrap.loc18: type = class_type @Wrap, @Wrap(constants.%i32) [template = constants.%Wrap.f84]
// CHECK:STDOUT: %.loc18: %Make.type.572 = specific_constant @Wrap.%Make.decl, @Wrap(constants.%i32) [template = constants.%Make.2c5]
// CHECK:STDOUT: %Make.ref.loc18: %Make.type.572 = name_ref Make, %.loc18 [template = constants.%Make.2c5]
// CHECK:STDOUT: %.loc18_25: %Make.type.572 = specific_constant @Wrap.%Make.decl, @Wrap(constants.%i32) [template = constants.%Make.2c5]
// CHECK:STDOUT: %Make.ref.loc18: %Make.type.572 = name_ref Make, %.loc18_25 [template = constants.%Make.2c5]
// CHECK:STDOUT: %Make.specific_fn.loc18: <specific function> = specific_function %Make.ref.loc18, @Make(constants.%i32) [template = constants.%Make.specific_fn.f29]
// CHECK:STDOUT: %Make.call.loc18: init %i32 = call %Make.specific_fn.loc18()
// CHECK:STDOUT: assign %a.var, %Make.call.loc18
// CHECK:STDOUT: %.loc18_10: type = splice_block %i32.loc18_10 [template = constants.%i32] {
// CHECK:STDOUT: %int_32.loc18_10: Core.IntLiteral = int_value 32 [template = constants.%int_32]
// CHECK:STDOUT: %i32.loc18_10: type = class_type @Int, @Int(constants.%int_32) [template = constants.%i32]
// CHECK:STDOUT: }
// CHECK:STDOUT: %a: ref %i32 = bind_name a, %a.var
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %b.patt: %empty_tuple.type = binding_pattern b
// CHECK:STDOUT: %.loc19_3: %empty_tuple.type = var_pattern %b.patt
// CHECK:STDOUT: }
// CHECK:STDOUT: %b.var: ref %empty_tuple.type = var b
// CHECK:STDOUT: %b: ref %empty_tuple.type = bind_name b, %b.var
// CHECK:STDOUT: %Wrap.ref.loc19: %Wrap.type = name_ref Wrap, file.%Wrap.decl [template = constants.%Wrap.generic]
// CHECK:STDOUT: %.loc19_21: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc19_22: type = converted %.loc19_21, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
@@ -161,17 +176,27 @@ fn G() {
// CHECK:STDOUT: %Make.specific_fn.loc19: <specific function> = specific_function %Make.ref.loc19, @Make(constants.%empty_tuple.type) [template = constants.%Make.specific_fn.e43]
// CHECK:STDOUT: %Make.call.loc19: init %empty_tuple.type = call %Make.specific_fn.loc19()
// CHECK:STDOUT: assign %b.var, %Make.call.loc19
// CHECK:STDOUT: %.loc19_11.1: type = splice_block %.loc19_11.3 [template = constants.%empty_tuple.type] {
// CHECK:STDOUT: %.loc19_11.2: %empty_tuple.type = tuple_literal ()
// CHECK:STDOUT: %.loc19_11.3: type = converted %.loc19_11.2, constants.%empty_tuple.type [template = constants.%empty_tuple.type]
// CHECK:STDOUT: }
// CHECK:STDOUT: %b: ref %empty_tuple.type = bind_name b, %b.var
// CHECK:STDOUT: name_binding_decl {
// CHECK:STDOUT: %c.patt: %C = binding_pattern c
// CHECK:STDOUT: %.loc20_3.1: %C = var_pattern %c.patt
// CHECK:STDOUT: }
// CHECK:STDOUT: %c.var: ref %C = var c
// CHECK:STDOUT: %c: ref %C = bind_name c, %c.var
// CHECK:STDOUT: %Wrap.ref.loc20: %Wrap.type = name_ref Wrap, file.%Wrap.decl [template = constants.%Wrap.generic]
// CHECK:STDOUT: %C.ref: type = name_ref C, file.%C.decl [template = constants.%C]
// CHECK:STDOUT: %C.ref.loc20_19: type = name_ref C, file.%C.decl [template = constants.%C]
// CHECK:STDOUT: %Wrap.loc20: type = class_type @Wrap, @Wrap(constants.%C) [template = constants.%Wrap.2eb]
// CHECK:STDOUT: %.loc20_21: %Make.type.708 = specific_constant @Wrap.%Make.decl, @Wrap(constants.%C) [template = constants.%Make.e4b]
// CHECK:STDOUT: %Make.ref.loc20: %Make.type.708 = name_ref Make, %.loc20_21 [template = constants.%Make.e4b]
// CHECK:STDOUT: %Make.specific_fn.loc20: <specific function> = specific_function %Make.ref.loc20, @Make(constants.%C) [template = constants.%Make.specific_fn.834]
// CHECK:STDOUT: %.loc20_7: ref %C = splice_block %c.var {}
// CHECK:STDOUT: %Make.call.loc20: init %C = call %Make.specific_fn.loc20() to %.loc20_7
// CHECK:STDOUT: %.loc20_3.2: ref %C = splice_block %c.var {}
// CHECK:STDOUT: %Make.call.loc20: init %C = call %Make.specific_fn.loc20() to %.loc20_3.2
// CHECK:STDOUT: assign %c.var, %Make.call.loc20
// CHECK:STDOUT: %C.ref.loc20_10: type = name_ref C, file.%C.decl [template = constants.%C]
// CHECK:STDOUT: %c: ref %C = bind_name c, %c.var
// CHECK:STDOUT: return
// CHECK:STDOUT: }
// CHECK:STDOUT: