Преглед изворни кода

Add min_prelude/convert.carbon to tests missing ImplicitAs (#5677)

import_use_generic.carbon has the comment "// We're just checking that
this doesn't crash. It's not expected to compile." Because it involves
import behavior by name, I'm not touching it. Other than that, while
maybe it's better to test with less, the `ImplicitAs` errors at best
feel difficult to understand, and at worst could be masking an issue.
Jon Ross-Perkins пре 10 месеци
родитељ
комит
1c09de9b87

+ 20 - 2
toolchain/check/testdata/array/basics.carbon

@@ -2,7 +2,7 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-// EXTRA-ARGS: --no-prelude-import
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
 //
 // AUTOUPDATE
 // TIP: To test this file alone, run:
@@ -96,7 +96,10 @@ var p: Incomplete* = &a[0];
 
 library "[[@TEST_NAME]]";
 
-// CHECK:STDERR: fail_invalid_element.carbon:[[@LINE+4]]:14: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
+// CHECK:STDERR: fail_invalid_element.carbon:[[@LINE+7]]:14: error: cannot implicitly convert non-type value of type `Core.IntLiteral` to `type` [ConversionFailureNonTypeToFacet]
+// CHECK:STDERR: var a: array(1, 1);
+// CHECK:STDERR:              ^
+// CHECK:STDERR: fail_invalid_element.carbon:[[@LINE+4]]:14: note: type `Core.IntLiteral` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: var a: array(1, 1);
 // CHECK:STDERR:              ^
 // CHECK:STDERR:
@@ -120,6 +123,9 @@ var a: array(1, 1);
 // CHECK:STDOUT:   %array: %array_type = tuple_value (%empty_tuple, %empty_tuple, %empty_tuple) [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %b.patt: %pattern_type.035 = binding_pattern b [concrete]
@@ -175,6 +181,9 @@ var a: array(1, 1);
 // CHECK:STDOUT:   %int_1: Core.IntLiteral = int_value 1 [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   name_binding_decl {
@@ -222,6 +231,9 @@ var a: array(1, 1);
 // CHECK:STDOUT:   %pattern_type.8c1: type = pattern_type %tuple.type [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @G() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   name_binding_decl {
@@ -270,6 +282,9 @@ var a: array(1, 1);
 // CHECK:STDOUT:   %array: %array_type = tuple_value (%empty_tuple) [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: fn @Run() {
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   name_binding_decl {
@@ -329,6 +344,9 @@ var a: array(1, 1);
 // CHECK:STDOUT:   %array: %array_type = tuple_value (%empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple, %empty_tuple) [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   name_binding_decl {
 // CHECK:STDOUT:     %b.patt: %pattern_type.3db = binding_pattern b [concrete]

+ 5 - 2
toolchain/check/testdata/array/element_mismatches.carbon

@@ -2,7 +2,7 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-// EXTRA-ARGS: --no-prelude-import
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
 //
 // AUTOUPDATE
 // TIP: To test this file alone, run:
@@ -16,7 +16,10 @@ library "[[@TEST_NAME]]";
 
 class C {}
 
-// CHECK:STDERR: fail_arg_wrong_type.carbon:[[@LINE+4]]:22: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
+// CHECK:STDERR: fail_arg_wrong_type.carbon:[[@LINE+7]]:22: error: cannot implicitly convert expression of type `String` to `C` [ConversionFailure]
+// CHECK:STDERR: var a: array(C, 3) = ({}, "Hello", "World");
+// CHECK:STDERR:                      ^~~~~~~~~~~~~~~~~~~~~~
+// CHECK:STDERR: fail_arg_wrong_type.carbon:[[@LINE+4]]:22: note: type `String` does not implement interface `Core.ImplicitAs(C)` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: var a: array(C, 3) = ({}, "Hello", "World");
 // CHECK:STDERR:                      ^~~~~~~~~~~~~~~~~~~~~~
 // CHECK:STDERR:

+ 35 - 9
toolchain/check/testdata/function/generic/fail_type_param_mismatch.carbon

@@ -4,7 +4,7 @@
 //
 // TODO: Add ranges and switch to "--dump-sem-ir-ranges=only".
 // EXTRA-ARGS: --dump-sem-ir-ranges=if-present
-// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/destroy.carbon
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
 //
 // AUTOUPDATE
 // TIP: To test this file alone, run:
@@ -14,7 +14,10 @@
 
 fn F(T:! type, U:! type) {
   var p: T*;
-  // CHECK:STDERR: fail_type_param_mismatch.carbon:[[@LINE+4]]:14: error: name `Core.ImplicitAs` implicitly referenced here, but not found [CoreNameNotFound]
+  // CHECK:STDERR: fail_type_param_mismatch.carbon:[[@LINE+7]]:14: error: cannot implicitly convert expression of type `T` to `U` [ConversionFailure]
+  // CHECK:STDERR:   let n: U = *p;
+  // CHECK:STDERR:              ^~
+  // CHECK:STDERR: fail_type_param_mismatch.carbon:[[@LINE+4]]:14: note: type `T` does not implement interface `Core.ImplicitAs(U)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   let n: U = *p;
   // CHECK:STDERR:              ^~
   // CHECK:STDERR:
@@ -34,13 +37,29 @@ fn F(T:! type, U:! type) {
 // CHECK:STDOUT:   %pattern_type.afe: type = pattern_type %ptr [symbolic]
 // CHECK:STDOUT:   %require_complete.b54: <witness> = require_complete_type %U [symbolic]
 // CHECK:STDOUT:   %pattern_type.a32: type = pattern_type %U [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete]
+// CHECK:STDOUT:   %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete]
+// CHECK:STDOUT:   %Dest: type = bind_symbolic_name Dest, 0 [symbolic]
+// CHECK:STDOUT:   %Convert.type.275: type = fn_type @Convert, @ImplicitAs(%Dest) [symbolic]
+// CHECK:STDOUT:   %Convert.42e: %Convert.type.275 = struct_value () [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.ca0: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%Dest) [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.type.d88: type = facet_type <@ImplicitAs, @ImplicitAs(%U)> [symbolic]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type.5fe: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%U) [symbolic]
+// CHECK:STDOUT:   %assoc0.a0b: %ImplicitAs.assoc_type.5fe = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic]
+// CHECK:STDOUT:   %require_complete.6c8: <witness> = require_complete_type %ImplicitAs.type.d88 [symbolic]
+// CHECK:STDOUT:   %assoc0.dc0: %ImplicitAs.assoc_type.ca0 = assoc_entity element0, imports.%Core.import_ref.207 [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: imports {
 // CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [concrete] {
-// CHECK:STDOUT:     .ImplicitAs = <poisoned>
+// CHECK:STDOUT:     .ImplicitAs = %Core.ImplicitAs
 // CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
+// CHECK:STDOUT:   %Core.import_ref.492: @ImplicitAs.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.ca0) = import_ref Core//prelude/parts/as, loc10_35, loaded [symbolic = @ImplicitAs.%assoc0 (constants.%assoc0.dc0)]
+// CHECK:STDOUT:   %Core.import_ref.1c7: @ImplicitAs.%Convert.type (%Convert.type.275) = import_ref Core//prelude/parts/as, loc10_35, loaded [symbolic = @ImplicitAs.%Convert (constants.%Convert.42e)]
+// CHECK:STDOUT:   %Core.import_ref.207 = import_ref Core//prelude/parts/as, loc10_35, unloaded
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
@@ -66,8 +85,12 @@ fn F(T:! type, U:! type) {
 // CHECK:STDOUT:   %ptr.loc16_11.2: type = ptr_type %T.loc15_6.2 [symbolic = %ptr.loc16_11.2 (constants.%ptr)]
 // CHECK:STDOUT:   %require_complete.loc16: <witness> = require_complete_type %ptr.loc16_11.2 [symbolic = %require_complete.loc16 (constants.%require_complete.6e5)]
 // CHECK:STDOUT:   %pattern_type.loc16: type = pattern_type %ptr.loc16_11.2 [symbolic = %pattern_type.loc16 (constants.%pattern_type.afe)]
-// CHECK:STDOUT:   %require_complete.loc21: <witness> = require_complete_type %U.loc15_16.2 [symbolic = %require_complete.loc21 (constants.%require_complete.b54)]
-// CHECK:STDOUT:   %pattern_type.loc21: type = pattern_type %U.loc15_16.2 [symbolic = %pattern_type.loc21 (constants.%pattern_type.a32)]
+// CHECK:STDOUT:   %require_complete.loc24_10: <witness> = require_complete_type %U.loc15_16.2 [symbolic = %require_complete.loc24_10 (constants.%require_complete.b54)]
+// CHECK:STDOUT:   %pattern_type.loc24: type = pattern_type %U.loc15_16.2 [symbolic = %pattern_type.loc24 (constants.%pattern_type.a32)]
+// CHECK:STDOUT:   %ImplicitAs.type.loc24_14.2: type = facet_type <@ImplicitAs, @ImplicitAs(%U.loc15_16.2)> [symbolic = %ImplicitAs.type.loc24_14.2 (constants.%ImplicitAs.type.d88)]
+// CHECK:STDOUT:   %require_complete.loc24_14: <witness> = require_complete_type %ImplicitAs.type.loc24_14.2 [symbolic = %require_complete.loc24_14 (constants.%require_complete.6c8)]
+// CHECK:STDOUT:   %ImplicitAs.assoc_type: type = assoc_entity_type @ImplicitAs, @ImplicitAs(%U.loc15_16.2) [symbolic = %ImplicitAs.assoc_type (constants.%ImplicitAs.assoc_type.5fe)]
+// CHECK:STDOUT:   %assoc0: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.5fe) = assoc_entity element0, imports.%Core.import_ref.1c7 [symbolic = %assoc0 (constants.%assoc0.a0b)]
 // CHECK:STDOUT:
 // CHECK:STDOUT:   fn() {
 // CHECK:STDOUT:   !entry:
@@ -82,13 +105,16 @@ fn F(T:! type, U:! type) {
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %p: ref @F.%ptr.loc16_11.2 (%ptr) = bind_name p, %p.var
 // CHECK:STDOUT:     name_binding_decl {
-// CHECK:STDOUT:       %n.patt: @F.%pattern_type.loc21 (%pattern_type.a32) = binding_pattern n [concrete]
+// CHECK:STDOUT:       %n.patt: @F.%pattern_type.loc24 (%pattern_type.a32) = binding_pattern n [concrete]
 // CHECK:STDOUT:     }
 // CHECK:STDOUT:     %p.ref: ref @F.%ptr.loc16_11.2 (%ptr) = name_ref p, %p
-// CHECK:STDOUT:     %.loc21_15: @F.%ptr.loc16_11.2 (%ptr) = bind_value %p.ref
-// CHECK:STDOUT:     %.loc21_14.1: ref @F.%T.loc15_6.2 (%T) = deref %.loc21_15
+// CHECK:STDOUT:     %.loc24_15: @F.%ptr.loc16_11.2 (%ptr) = bind_value %p.ref
+// CHECK:STDOUT:     %.loc24_14.1: ref @F.%T.loc15_6.2 (%T) = deref %.loc24_15
 // CHECK:STDOUT:     %U.ref: type = name_ref U, %U.loc15_16.1 [symbolic = %U.loc15_16.2 (constants.%U)]
-// CHECK:STDOUT:     %.loc21_14.2: @F.%U.loc15_16.2 (%U) = converted %.loc21_14.1, <error> [concrete = <error>]
+// CHECK:STDOUT:     %ImplicitAs.type.loc24_14.1: type = facet_type <@ImplicitAs, @ImplicitAs(constants.%U)> [symbolic = %ImplicitAs.type.loc24_14.2 (constants.%ImplicitAs.type.d88)]
+// CHECK:STDOUT:     %.loc24_14.2: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.5fe) = specific_constant imports.%Core.import_ref.492, @ImplicitAs(constants.%U) [symbolic = %assoc0 (constants.%assoc0.a0b)]
+// CHECK:STDOUT:     %Convert.ref: @F.%ImplicitAs.assoc_type (%ImplicitAs.assoc_type.5fe) = name_ref Convert, %.loc24_14.2 [symbolic = %assoc0 (constants.%assoc0.a0b)]
+// CHECK:STDOUT:     %.loc24_14.3: @F.%U.loc15_16.2 (%U) = converted %.loc24_14.1, <error> [concrete = <error>]
 // CHECK:STDOUT:     %n: @F.%U.loc15_16.2 (%U) = bind_name n, <error> [concrete = <error>]
 // CHECK:STDOUT:     return
 // CHECK:STDOUT:   }

+ 22 - 5
toolchain/check/testdata/impl/fail_impl_bad_type.carbon

@@ -3,7 +3,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 // TODO: Add ranges and switch to "--dump-sem-ir-ranges=only".
-// EXTRA-ARGS: --no-prelude-import --dump-sem-ir-ranges=if-present
+// EXTRA-ARGS: --dump-sem-ir-ranges=if-present
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
 //
 // AUTOUPDATE
 // TIP: To test this file alone, run:
@@ -13,7 +14,10 @@
 
 interface I {}
 
-// CHECK:STDERR: fail_impl_bad_type.carbon:[[@LINE+4]]:6: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
+// CHECK:STDERR: fail_impl_bad_type.carbon:[[@LINE+7]]:6: error: cannot implicitly convert non-type value of type `bool` to `type` [ConversionFailureNonTypeToFacet]
+// CHECK:STDERR: impl true as I {}
+// CHECK:STDERR:      ^~~~
+// CHECK:STDERR: fail_impl_bad_type.carbon:[[@LINE+4]]:6: note: type `bool` does not implement interface `Core.ImplicitAs(type)` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: impl true as I {}
 // CHECK:STDERR:      ^~~~
 // CHECK:STDERR:
@@ -23,24 +27,37 @@ impl true as I {}
 // CHECK:STDOUT:
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %I.type: type = facet_type <@I> [concrete]
-// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic]
+// CHECK:STDOUT:   %Self.826: %I.type = bind_symbolic_name Self, 0 [symbolic]
 // CHECK:STDOUT:   %true: bool = bool_literal true [concrete]
+// CHECK:STDOUT:   %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete]
+// CHECK:STDOUT:   %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [concrete] {
+// CHECK:STDOUT:     .ImplicitAs = %Core.ImplicitAs
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [concrete] {
+// CHECK:STDOUT:     .Core = imports.%Core
 // CHECK:STDOUT:     .I = %I.decl
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   %I.decl: type = interface_decl @I [concrete = constants.%I.type] {} {}
 // CHECK:STDOUT:   impl_decl @impl [concrete] {} {
 // CHECK:STDOUT:     %true: bool = bool_literal true [concrete = constants.%true]
-// CHECK:STDOUT:     %.loc20: type = converted %true, <error> [concrete = <error>]
+// CHECK:STDOUT:     %.loc24: type = converted %true, <error> [concrete = <error>]
 // CHECK:STDOUT:     %I.ref: type = name_ref I, file.%I.decl [concrete = constants.%I.type]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: interface @I {
-// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self]
+// CHECK:STDOUT:   %Self: %I.type = bind_symbolic_name Self, 0 [symbolic = constants.%Self.826]
 // CHECK:STDOUT:
 // CHECK:STDOUT: !members:
 // CHECK:STDOUT:   .Self = %Self

+ 40 - 7
toolchain/check/testdata/impl/impl_thunk.carbon

@@ -2,7 +2,7 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-// EXTRA-ARGS: --no-prelude-import
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
 //
 // AUTOUPDATE
 // TIP: To test this file alone, run:
@@ -119,7 +119,10 @@ impl A as X {
 library "[[@TEST_NAME]]";
 
 interface I {
-  // CHECK:STDERR: fail_param_type_mismatch.carbon:[[@LINE+3]]:8: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
+  // CHECK:STDERR: fail_param_type_mismatch.carbon:[[@LINE+6]]:8: error: cannot implicitly convert expression of type `A` to `B` [ConversionFailure]
+  // CHECK:STDERR:   fn F(a: Self);
+  // CHECK:STDERR:        ^~~~~~~
+  // CHECK:STDERR: fail_param_type_mismatch.carbon:[[@LINE+3]]:8: note: type `A` does not implement interface `Core.ImplicitAs(B)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   fn F(a: Self);
   // CHECK:STDERR:        ^~~~~~~
   fn F(a: Self);
@@ -151,10 +154,13 @@ class A {}
 class B {}
 
 impl A as I {
-  // CHECK:STDERR: fail_return_mismatch.carbon:[[@LINE+7]]:3: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
+  // CHECK:STDERR: fail_return_mismatch.carbon:[[@LINE+10]]:3: error: cannot implicitly convert expression of type `B` to `A` [ConversionFailure]
+  // CHECK:STDERR:   fn F() -> B;
+  // CHECK:STDERR:   ^~~~~~~~~~~~
+  // CHECK:STDERR: fail_return_mismatch.carbon:[[@LINE+7]]:3: note: type `B` does not implement interface `Core.ImplicitAs(A)` [MissingImplInMemberAccessNote]
   // CHECK:STDERR:   fn F() -> B;
   // CHECK:STDERR:   ^~~~~~~~~~~~
-  // CHECK:STDERR: fail_return_mismatch.carbon:[[@LINE-10]]:3: note: while building thunk to match the signature of this function [ThunkSignature]
+  // CHECK:STDERR: fail_return_mismatch.carbon:[[@LINE-13]]:3: note: while building thunk to match the signature of this function [ThunkSignature]
   // CHECK:STDERR:   fn F() -> Self;
   // CHECK:STDERR:   ^~~~~~~~~~~~~~~
   // CHECK:STDERR:
@@ -233,17 +239,20 @@ class B;
 
 class C {
   impl as I(B) {
-    // CHECK:STDERR: fail_param_type_incomplete.carbon:[[@LINE+14]]:5: note: while building thunk calling this function [ThunkCallee]
+    // CHECK:STDERR: fail_param_type_incomplete.carbon:[[@LINE+17]]:5: note: while building thunk calling this function [ThunkCallee]
     // CHECK:STDERR:     fn F(c: C);
     // CHECK:STDERR:     ^~~~~~~~~~~
     // CHECK:STDERR:
-    // CHECK:STDERR: fail_param_type_incomplete.carbon:[[@LINE-14]]:8: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
+    // CHECK:STDERR: fail_param_type_incomplete.carbon:[[@LINE-14]]:8: error: cannot implicitly convert expression of type `B` to `C` [ConversionFailure]
+    // CHECK:STDERR:   fn F(a: T);
+    // CHECK:STDERR:        ^~~~
+    // CHECK:STDERR: fail_param_type_incomplete.carbon:[[@LINE-17]]:8: note: type `B` does not implement interface `Core.ImplicitAs(C)` [MissingImplInMemberAccessNote]
     // CHECK:STDERR:   fn F(a: T);
     // CHECK:STDERR:        ^~~~
     // CHECK:STDERR: fail_param_type_incomplete.carbon:[[@LINE+7]]:10: note: initializing function parameter [InCallToFunctionParam]
     // CHECK:STDERR:     fn F(c: C);
     // CHECK:STDERR:          ^~~~
-    // CHECK:STDERR: fail_param_type_incomplete.carbon:[[@LINE-20]]:3: note: while building thunk to match the signature of this function [ThunkSignature]
+    // CHECK:STDERR: fail_param_type_incomplete.carbon:[[@LINE-23]]:3: note: while building thunk to match the signature of this function [ThunkSignature]
     // CHECK:STDERR:   fn F(a: T);
     // CHECK:STDERR:   ^~~~~~~~~~~
     // CHECK:STDERR:
@@ -322,6 +331,9 @@ impl () as I({}) {
 // CHECK:STDOUT:   %struct: %struct_type.c.d.15a = struct_value (%empty_tuple, %empty_struct) [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc8_7.2 as %I.ref {
 // CHECK:STDOUT:   %F.decl.loc10_48.1: %F.type.39e918.1 = fn_decl @F.2 [concrete = constants.%F.c04b92.1] {
 // CHECK:STDOUT:     %y.patt: %pattern_type.231 = binding_pattern y [concrete]
@@ -398,6 +410,9 @@ impl () as I({}) {
 // CHECK:STDOUT:   %F.5161e9.2: %F.type.f1b0b1.2 = struct_value () [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %B.ref as %X.ref {
 // CHECK:STDOUT:   %F.decl.loc14_39.1: %F.type.f1b0b1.1 = fn_decl @F.2 [concrete = constants.%F.5161e9.1] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.5f8 = binding_pattern self [concrete]
@@ -469,6 +484,9 @@ impl () as I({}) {
 // CHECK:STDOUT:   %F.5161e9.2: %F.type.f1b0b1.2 = struct_value () [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %B.ref as %X.ref {
 // CHECK:STDOUT:   %F.decl.loc13_26.1: %F.type.f1b0b1.1 = fn_decl @F.2 [concrete = constants.%F.5161e9.1] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.c10 = binding_pattern self [concrete]
@@ -525,6 +543,9 @@ impl () as I({}) {
 // CHECK:STDOUT:   %F.5161e9.2: %F.type.f1b0b1.2 = struct_value () [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %B.ref as %X.ref {
 // CHECK:STDOUT:   %F.decl.loc14_39.1: %F.type.f1b0b1.1 = fn_decl @F.2 [concrete = constants.%F.5161e9.1] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.5f8 = binding_pattern self [concrete]
@@ -595,6 +616,9 @@ impl () as I({}) {
 // CHECK:STDOUT:   %F.77e9d5.2: %F.type.b24d6f.2 = struct_value () [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %A.ref as %X.ref {
 // CHECK:STDOUT:   %F.decl.loc20_14.1: %F.type.b24d6f.1 = fn_decl @F.2 [concrete = constants.%F.77e9d5.1] {
 // CHECK:STDOUT:     %return.patt: %pattern_type.049 = return_slot_pattern [concrete]
@@ -649,6 +673,9 @@ impl () as I({}) {
 // CHECK:STDOUT:   %F.specific_fn: <specific function> = specific_function %F.c04b92.1, @F.2(%ptr.79f) [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc8_7.2 as %I.ref {
 // CHECK:STDOUT:   %F.decl.loc10_29.1: %F.type.39e918.1 = fn_decl @F.2 [concrete = constants.%F.c04b92.1] {
 // CHECK:STDOUT:     %U.patt: %pattern_type.98f = symbolic_binding_pattern U, 0 [concrete]
@@ -746,6 +773,9 @@ impl () as I({}) {
 // CHECK:STDOUT:   %require_complete.4ae: <witness> = require_complete_type %U [symbolic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc10_7.2 as %I.ref {
 // CHECK:STDOUT:   %F.decl.loc19_39.1: %F.type.39e918.1 = fn_decl @F.2 [concrete = constants.%F.c04b92.1] {
 // CHECK:STDOUT:     %self.patt: %pattern_type.cb1 = binding_pattern self [concrete]
@@ -834,6 +864,9 @@ impl () as I({}) {
 // CHECK:STDOUT:   %struct: %struct_type.a.b.f95 = struct_value (%empty_struct, %empty_struct) [concrete]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
 // CHECK:STDOUT: impl @impl: %.loc8_7.2 as %I.type {
 // CHECK:STDOUT:   %F.decl.loc10_29.1: %F.type.29ab63.1 = fn_decl @F.2 [concrete = constants.%F.975709.1] {
 // CHECK:STDOUT:     %return.patt: %pattern_type.914 = return_slot_pattern [concrete]

+ 8 - 5
toolchain/check/testdata/interop/cpp/class.carbon

@@ -2,7 +2,7 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-// EXTRA-ARGS: --no-prelude-import
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
 //
 // AUTOUPDATE
 // TIP: To test this file alone, run:
@@ -262,10 +262,13 @@ import Cpp library "inheritance_pointers.h";
 //@dump-sem-ir-begin
 fn MyF1(bar : Cpp.Bar1*);
 // TODO: Support C++ inheritance.
-// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE+7]]:33: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
+// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE+10]]:33: error: cannot implicitly convert expression of type `Cpp.Bar2*` to `Cpp.Bar1*` [ConversionFailure]
 // CHECK:STDERR: fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
 // CHECK:STDERR:                                 ^~~
-// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE-5]]:9: note: initializing function parameter [InCallToFunctionParam]
+// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE+7]]:33: note: type `Cpp.Bar2*` does not implement interface `Core.ImplicitAs(Cpp.Bar1*)` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
+// CHECK:STDERR:                                 ^~~
+// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE-8]]:9: note: initializing function parameter [InCallToFunctionParam]
 // CHECK:STDERR: fn MyF1(bar : Cpp.Bar1*);
 // CHECK:STDERR:         ^~~~~~~~~~~~~~~
 // CHECK:STDERR:
@@ -731,7 +734,7 @@ fn MyF(bar: Cpp.Bar*);
 // CHECK:STDOUT:     %bar.param_patt: %pattern_type.92a = value_param_pattern %bar.patt, call_param0 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %bar.param: %ptr.eca = value_param call_param0
-// CHECK:STDOUT:     %.loc16_23: type = splice_block %ptr [concrete = constants.%ptr.eca] {
+// CHECK:STDOUT:     %.loc19_23: type = splice_block %ptr [concrete = constants.%ptr.eca] {
 // CHECK:STDOUT:       %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
 // CHECK:STDOUT:       <elided>
 // CHECK:STDOUT:       %Bar2.ref: type = name_ref Bar2, imports.%Bar2.decl [concrete = constants.%Bar2]
@@ -747,7 +750,7 @@ fn MyF(bar: Cpp.Bar*);
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %MyF1.ref: %MyF1.type = name_ref MyF1, file.%MyF1.decl [concrete = constants.%MyF1]
 // CHECK:STDOUT:   %bar.ref: %ptr.eca = name_ref bar, %bar
-// CHECK:STDOUT:   %.loc16_33: %ptr.f68 = converted %bar.ref, <error> [concrete = <error>]
+// CHECK:STDOUT:   %.loc19_33: %ptr.f68 = converted %bar.ref, <error> [concrete = <error>]
 // CHECK:STDOUT:   %MyF1.call: init %empty_tuple.type = call %MyF1.ref(<error>)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 8 - 5
toolchain/check/testdata/interop/cpp/struct.carbon

@@ -2,7 +2,7 @@
 // Exceptions. See /LICENSE for license information.
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
-// EXTRA-ARGS: --no-prelude-import
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
 //
 // AUTOUPDATE
 // TIP: To test this file alone, run:
@@ -256,10 +256,13 @@ import Cpp library "inheritance_pointers.h";
 //@dump-sem-ir-begin
 fn MyF1(bar : Cpp.Bar1*);
 // TODO: Support C++ inheritance.
-// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE+7]]:33: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
+// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE+10]]:33: error: cannot implicitly convert expression of type `Cpp.Bar2*` to `Cpp.Bar1*` [ConversionFailure]
 // CHECK:STDERR: fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
 // CHECK:STDERR:                                 ^~~
-// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE-5]]:9: note: initializing function parameter [InCallToFunctionParam]
+// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE+7]]:33: note: type `Cpp.Bar2*` does not implement interface `Core.ImplicitAs(Cpp.Bar1*)` [MissingImplInMemberAccessNote]
+// CHECK:STDERR: fn MyF2(bar : Cpp.Bar2*) { MyF1(bar); }
+// CHECK:STDERR:                                 ^~~
+// CHECK:STDERR: fail_todo_import_inheritance_pointers.carbon:[[@LINE-8]]:9: note: initializing function parameter [InCallToFunctionParam]
 // CHECK:STDERR: fn MyF1(bar : Cpp.Bar1*);
 // CHECK:STDERR:         ^~~~~~~~~~~~~~~
 // CHECK:STDERR:
@@ -721,7 +724,7 @@ fn MyF(bar: Cpp.Bar*);
 // CHECK:STDOUT:     %bar.param_patt: %pattern_type.92a = value_param_pattern %bar.patt, call_param0 [concrete]
 // CHECK:STDOUT:   } {
 // CHECK:STDOUT:     %bar.param: %ptr.eca = value_param call_param0
-// CHECK:STDOUT:     %.loc16_23: type = splice_block %ptr [concrete = constants.%ptr.eca] {
+// CHECK:STDOUT:     %.loc19_23: type = splice_block %ptr [concrete = constants.%ptr.eca] {
 // CHECK:STDOUT:       %Cpp.ref: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
 // CHECK:STDOUT:       <elided>
 // CHECK:STDOUT:       %Bar2.ref: type = name_ref Bar2, imports.%Bar2.decl [concrete = constants.%Bar2]
@@ -737,7 +740,7 @@ fn MyF(bar: Cpp.Bar*);
 // CHECK:STDOUT: !entry:
 // CHECK:STDOUT:   %MyF1.ref: %MyF1.type = name_ref MyF1, file.%MyF1.decl [concrete = constants.%MyF1]
 // CHECK:STDOUT:   %bar.ref: %ptr.eca = name_ref bar, %bar
-// CHECK:STDOUT:   %.loc16_33: %ptr.f68 = converted %bar.ref, <error> [concrete = <error>]
+// CHECK:STDOUT:   %.loc19_33: %ptr.f68 = converted %bar.ref, <error> [concrete = <error>]
 // CHECK:STDOUT:   %MyF1.call: init %empty_tuple.type = call %MyF1.ref(<error>)
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }

+ 27 - 13
toolchain/check/testdata/var/fail_init_type_mismatch.carbon

@@ -3,7 +3,8 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 // TODO: Add ranges and switch to "--dump-sem-ir-ranges=only".
-// EXTRA-ARGS: --no-prelude-import --dump-sem-ir-ranges=if-present
+// EXTRA-ARGS: --dump-sem-ir-ranges=if-present
+// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon
 //
 // AUTOUPDATE
 // TIP: To test this file alone, run:
@@ -11,7 +12,10 @@
 // TIP: To dump output, run:
 // TIP:   bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/var/fail_init_type_mismatch.carbon
 
-// CHECK:STDERR: fail_init_type_mismatch.carbon:[[@LINE+4]]:1: error: `Core.ImplicitAs` implicitly referenced here, but package `Core` not found [CoreNotFound]
+// CHECK:STDERR: fail_init_type_mismatch.carbon:[[@LINE+7]]:1: error: cannot implicitly convert expression of type `()` to `{}` [ConversionFailure]
+// CHECK:STDERR: var x: {} = ();
+// CHECK:STDERR: ^~~~~~~~~
+// CHECK:STDERR: fail_init_type_mismatch.carbon:[[@LINE+4]]:1: note: type `()` does not implement interface `Core.ImplicitAs({})` [MissingImplInMemberAccessNote]
 // CHECK:STDERR: var x: {} = ();
 // CHECK:STDERR: ^~~~~~~~~
 // CHECK:STDERR:
@@ -22,32 +26,42 @@ var x: {} = ();
 // CHECK:STDOUT: constants {
 // CHECK:STDOUT:   %empty_struct_type: type = struct_type {} [concrete]
 // CHECK:STDOUT:   %empty_tuple.type: type = tuple_type () [concrete]
-// CHECK:STDOUT:   %pattern_type: type = pattern_type %empty_struct_type [concrete]
-// CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete]
+// CHECK:STDOUT:   %pattern_type.a96: type = pattern_type %empty_struct_type [concrete]
+// CHECK:STDOUT:   %ImplicitAs.type.cc7: type = generic_interface_type @ImplicitAs [concrete]
+// CHECK:STDOUT:   %ImplicitAs.generic: %ImplicitAs.type.cc7 = struct_value () [concrete]
+// CHECK:STDOUT: }
+// CHECK:STDOUT:
+// CHECK:STDOUT: imports {
+// CHECK:STDOUT:   %Core: <namespace> = namespace file.%Core.import, [concrete] {
+// CHECK:STDOUT:     .ImplicitAs = %Core.ImplicitAs
+// CHECK:STDOUT:     import Core//prelude
+// CHECK:STDOUT:     import Core//prelude/...
+// CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.ImplicitAs: %ImplicitAs.type.cc7 = import_ref Core//prelude/parts/as, ImplicitAs, loaded [concrete = constants.%ImplicitAs.generic]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: file {
 // CHECK:STDOUT:   package: <namespace> = namespace [concrete] {
+// CHECK:STDOUT:     .Core = imports.%Core
 // CHECK:STDOUT:     .x = %x
 // CHECK:STDOUT:   }
+// CHECK:STDOUT:   %Core.import = import Core
 // CHECK:STDOUT:   name_binding_decl {
-// CHECK:STDOUT:     %x.patt: %pattern_type = binding_pattern x [concrete]
-// CHECK:STDOUT:     %x.var_patt: %pattern_type = var_pattern %x.patt [concrete]
+// CHECK:STDOUT:     %x.patt: %pattern_type.a96 = binding_pattern x [concrete]
+// CHECK:STDOUT:     %x.var_patt: %pattern_type.a96 = var_pattern %x.patt [concrete]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %x.var: ref %empty_struct_type = var %x.var_patt [concrete]
-// CHECK:STDOUT:   %.loc18_9.1: type = splice_block %.loc18_9.3 [concrete = constants.%empty_struct_type] {
-// CHECK:STDOUT:     %.loc18_9.2: %empty_struct_type = struct_literal ()
-// CHECK:STDOUT:     %.loc18_9.3: type = converted %.loc18_9.2, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
+// CHECK:STDOUT:   %.loc22_9.1: type = splice_block %.loc22_9.3 [concrete = constants.%empty_struct_type] {
+// CHECK:STDOUT:     %.loc22_9.2: %empty_struct_type = struct_literal ()
+// CHECK:STDOUT:     %.loc22_9.3: type = converted %.loc22_9.2, constants.%empty_struct_type [concrete = constants.%empty_struct_type]
 // CHECK:STDOUT:   }
 // CHECK:STDOUT:   %x: ref %empty_struct_type = bind_name x, %x.var [concrete = %x.var]
 // CHECK:STDOUT: }
 // CHECK:STDOUT:
 // CHECK:STDOUT: fn @__global_init() {
 // CHECK:STDOUT: !entry:
-// CHECK:STDOUT:   %.loc18_14.1: %empty_tuple.type = tuple_literal ()
-// CHECK:STDOUT:   %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc18_14.2: %empty_tuple.type = converted %.loc18_14.1, %empty_tuple [concrete = constants.%empty_tuple]
-// CHECK:STDOUT:   %.loc18_1: %empty_struct_type = converted %.loc18_14.1, <error> [concrete = <error>]
+// CHECK:STDOUT:   %.loc22_14: %empty_tuple.type = tuple_literal ()
+// CHECK:STDOUT:   %.loc22_1: %empty_struct_type = converted %.loc22_14, <error> [concrete = <error>]
 // CHECK:STDOUT:   assign file.%x.var, <error>
 // CHECK:STDOUT:   return
 // CHECK:STDOUT: }