-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
323 additions
and
0 deletions.
There are no files selected for viewing
323 changes: 323 additions & 0 deletions
323
toolchain/check/testdata/impl/no_prelude/generic_redeclaration.carbon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,323 @@ | ||
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM | ||
// Exceptions. See /LICENSE for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
// AUTOUPDATE | ||
// TIP: To test this file alone, run: | ||
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/no_prelude/generic_redeclaration.carbon | ||
// TIP: To dump output, run: | ||
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/no_prelude/generic_redeclaration.carbon | ||
|
||
// --- same_self_and_interface.carbon | ||
|
||
library "[[@TEST_NAME]]"; | ||
|
||
interface I {} | ||
interface J {} | ||
interface K {} | ||
|
||
impl forall [T:! I] T as K; | ||
impl forall [T:! J] T as K; | ||
|
||
// These are two different impls, so this is not a redefinition, even though the | ||
// self type and constraint type are the same. | ||
impl forall [T:! I] T as K {} | ||
impl forall [T:! J] T as K {} | ||
|
||
// --- fail_same_self_and_interface_redefined.carbon | ||
|
||
library "[[@TEST_NAME]]"; | ||
|
||
interface I {} | ||
interface J {} | ||
|
||
impl forall [T:! I] T as J {} | ||
// CHECK:STDERR: fail_same_self_and_interface_redefined.carbon:[[@LINE+6]]:1: error: redefinition of `impl T as J` | ||
// CHECK:STDERR: impl forall [T:! I] T as J {} | ||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
// CHECK:STDERR: fail_same_self_and_interface_redefined.carbon:[[@LINE-4]]:1: previous definition was here | ||
// CHECK:STDERR: impl forall [T:! I] T as J {} | ||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
impl forall [T:! I] T as J {} | ||
|
||
// --- same_type_different_spelling.carbon | ||
|
||
library "[[@TEST_NAME]]"; | ||
|
||
class C; | ||
interface I {} | ||
|
||
// We accept this because these two types are spelled differently, even though | ||
// they evaluate to the same type constant. Any use of this impl will be | ||
// ambiguous unless resolved by a `match_first` or similar. | ||
// | ||
// TODO: Produce a warning or maybe an error when this happens in a non-generic | ||
// impl. | ||
impl C as I {} | ||
impl (C, C).0 as I {} | ||
|
||
// CHECK:STDOUT: --- same_self_and_interface.carbon | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: constants { | ||
// CHECK:STDOUT: %.1: type = interface_type @I [template] | ||
// CHECK:STDOUT: %Self.1: %.1 = bind_symbolic_name Self 0 [symbolic] | ||
// CHECK:STDOUT: %.2: type = interface_type @J [template] | ||
// CHECK:STDOUT: %Self.2: %.2 = bind_symbolic_name Self 0 [symbolic] | ||
// CHECK:STDOUT: %.3: type = interface_type @K [template] | ||
// CHECK:STDOUT: %Self.3: %.3 = bind_symbolic_name Self 0 [symbolic] | ||
// CHECK:STDOUT: %T.1: %.1 = bind_symbolic_name T 0 [symbolic] | ||
// CHECK:STDOUT: %T.2: %.2 = bind_symbolic_name T 0 [symbolic] | ||
// CHECK:STDOUT: %.4: type = tuple_type () [template] | ||
// CHECK:STDOUT: %.5: <witness> = interface_witness () [template] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: file { | ||
// CHECK:STDOUT: package: <namespace> = namespace [template] { | ||
// CHECK:STDOUT: .I = %I.decl | ||
// CHECK:STDOUT: .J = %J.decl | ||
// CHECK:STDOUT: .K = %K.decl | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: %I.decl: type = interface_decl @I [template = constants.%.1] {} | ||
// CHECK:STDOUT: %J.decl: type = interface_decl @J [template = constants.%.2] {} | ||
// CHECK:STDOUT: %K.decl: type = interface_decl @K [template = constants.%.3] {} | ||
// CHECK:STDOUT: impl_decl @impl.1 { | ||
// CHECK:STDOUT: %I.ref.loc8: type = name_ref I, %I.decl [template = constants.%.1] | ||
// CHECK:STDOUT: %T.loc8_14.1: %.1 = param T, runtime_param<invalid> | ||
// CHECK:STDOUT: %T.loc8_14.2: %.1 = bind_symbolic_name T 0, %T.loc8_14.1 [symbolic = @impl.1.%T (constants.%T.1)] | ||
// CHECK:STDOUT: %T.ref.loc8: %.1 = name_ref T, %T.loc8_14.2 [symbolic = @impl.1.%T (constants.%T.1)] | ||
// CHECK:STDOUT: %.loc8_21.1: type = facet_type_access %T.ref.loc8 [symbolic = @impl.1.%T (constants.%T.1)] | ||
// CHECK:STDOUT: %.loc8_21.2: type = converted %T.ref.loc8, %.loc8_21.1 [symbolic = @impl.1.%T (constants.%T.1)] | ||
// CHECK:STDOUT: %K.ref.loc8: type = name_ref K, %K.decl [template = constants.%.3] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: impl_decl @impl.2 { | ||
// CHECK:STDOUT: %J.ref.loc9: type = name_ref J, %J.decl [template = constants.%.2] | ||
// CHECK:STDOUT: %T.loc9_14.1: %.2 = param T, runtime_param<invalid> | ||
// CHECK:STDOUT: %T.loc9_14.2: %.2 = bind_symbolic_name T 0, %T.loc9_14.1 [symbolic = @impl.2.%T (constants.%T.2)] | ||
// CHECK:STDOUT: %T.ref.loc9: %.2 = name_ref T, %T.loc9_14.2 [symbolic = @impl.2.%T (constants.%T.2)] | ||
// CHECK:STDOUT: %.loc9_21.1: type = facet_type_access %T.ref.loc9 [symbolic = @impl.2.%T (constants.%T.2)] | ||
// CHECK:STDOUT: %.loc9_21.2: type = converted %T.ref.loc9, %.loc9_21.1 [symbolic = @impl.2.%T (constants.%T.2)] | ||
// CHECK:STDOUT: %K.ref.loc9: type = name_ref K, %K.decl [template = constants.%.3] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: impl_decl @impl.3 { | ||
// CHECK:STDOUT: %I.ref.loc13: type = name_ref I, %I.decl [template = constants.%.1] | ||
// CHECK:STDOUT: %T.loc13_14.1: %.1 = param T, runtime_param<invalid> | ||
// CHECK:STDOUT: %T.loc13_14.2: %.1 = bind_symbolic_name T 0, %T.loc13_14.1 [symbolic = @impl.3.%T (constants.%T.1)] | ||
// CHECK:STDOUT: %T.ref.loc13: %.1 = name_ref T, %T.loc13_14.2 [symbolic = @impl.3.%T (constants.%T.1)] | ||
// CHECK:STDOUT: %.loc13_21.1: type = facet_type_access %T.ref.loc13 [symbolic = @impl.3.%T (constants.%T.1)] | ||
// CHECK:STDOUT: %.loc13_21.2: type = converted %T.ref.loc13, %.loc13_21.1 [symbolic = @impl.3.%T (constants.%T.1)] | ||
// CHECK:STDOUT: %K.ref.loc13: type = name_ref K, %K.decl [template = constants.%.3] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: impl_decl @impl.4 { | ||
// CHECK:STDOUT: %J.ref.loc14: type = name_ref J, %J.decl [template = constants.%.2] | ||
// CHECK:STDOUT: %T.loc14_14.1: %.2 = param T, runtime_param<invalid> | ||
// CHECK:STDOUT: %T.loc14_14.2: %.2 = bind_symbolic_name T 0, %T.loc14_14.1 [symbolic = @impl.4.%T (constants.%T.2)] | ||
// CHECK:STDOUT: %T.ref.loc14: %.2 = name_ref T, %T.loc14_14.2 [symbolic = @impl.4.%T (constants.%T.2)] | ||
// CHECK:STDOUT: %.loc14_21.1: type = facet_type_access %T.ref.loc14 [symbolic = @impl.4.%T (constants.%T.2)] | ||
// CHECK:STDOUT: %.loc14_21.2: type = converted %T.ref.loc14, %.loc14_21.1 [symbolic = @impl.4.%T (constants.%T.2)] | ||
// CHECK:STDOUT: %K.ref.loc14: type = name_ref K, %K.decl [template = constants.%.3] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: interface @I { | ||
// CHECK:STDOUT: %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self.1] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: .Self = %Self | ||
// CHECK:STDOUT: witness = () | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: interface @J { | ||
// CHECK:STDOUT: %Self: %.2 = bind_symbolic_name Self 0 [symbolic = constants.%Self.2] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: .Self = %Self | ||
// CHECK:STDOUT: witness = () | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: interface @K { | ||
// CHECK:STDOUT: %Self: %.3 = bind_symbolic_name Self 0 [symbolic = constants.%Self.3] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: .Self = %Self | ||
// CHECK:STDOUT: witness = () | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: generic impl @impl.1(file.%T.loc8_14.2: %.1) { | ||
// CHECK:STDOUT: %T: %.1 = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: impl: %T.1 as %.3; | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: generic impl @impl.2(file.%T.loc9_14.2: %.2) { | ||
// CHECK:STDOUT: %T: %.2 = bind_symbolic_name T 0 [symbolic = %T (constants.%T.2)] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: impl: %T.2 as %.3; | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: generic impl @impl.3(file.%T.loc13_14.2: %.1) { | ||
// CHECK:STDOUT: %T: %.1 = bind_symbolic_name T 0 [symbolic = %T (constants.%T.1)] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: impl: %T.1 as %.3 { | ||
// CHECK:STDOUT: %.loc13: <witness> = interface_witness () [template = constants.%.5] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: witness = %.loc13 | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: generic impl @impl.4(file.%T.loc14_14.2: %.2) { | ||
// CHECK:STDOUT: %T: %.2 = bind_symbolic_name T 0 [symbolic = %T (constants.%T.2)] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: impl: %T.2 as %.3 { | ||
// CHECK:STDOUT: %.loc14: <witness> = interface_witness () [template = constants.%.5] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: witness = %.loc14 | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: specific @impl.1(constants.%T.1) { | ||
// CHECK:STDOUT: %T => constants.%T.1 | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: specific @impl.2(constants.%T.2) { | ||
// CHECK:STDOUT: %T => constants.%T.2 | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: specific @impl.3(constants.%T.1) { | ||
// CHECK:STDOUT: %T => constants.%T.1 | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: specific @impl.4(constants.%T.2) { | ||
// CHECK:STDOUT: %T => constants.%T.2 | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: --- fail_same_self_and_interface_redefined.carbon | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: constants { | ||
// CHECK:STDOUT: %.1: type = interface_type @I [template] | ||
// CHECK:STDOUT: %Self.1: %.1 = bind_symbolic_name Self 0 [symbolic] | ||
// CHECK:STDOUT: %.2: type = interface_type @J [template] | ||
// CHECK:STDOUT: %Self.2: %.2 = bind_symbolic_name Self 0 [symbolic] | ||
// CHECK:STDOUT: %T: %.1 = bind_symbolic_name T 0 [symbolic] | ||
// CHECK:STDOUT: %.3: type = tuple_type () [template] | ||
// CHECK:STDOUT: %.4: <witness> = interface_witness () [template] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: file { | ||
// CHECK:STDOUT: package: <namespace> = namespace [template] { | ||
// CHECK:STDOUT: .I = %I.decl | ||
// CHECK:STDOUT: .J = %J.decl | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: %I.decl: type = interface_decl @I [template = constants.%.1] {} | ||
// CHECK:STDOUT: %J.decl: type = interface_decl @J [template = constants.%.2] {} | ||
// CHECK:STDOUT: impl_decl @impl { | ||
// CHECK:STDOUT: %I.ref.loc7: type = name_ref I, %I.decl [template = constants.%.1] | ||
// CHECK:STDOUT: %T.loc7_14.1: %.1 = param T, runtime_param<invalid> | ||
// CHECK:STDOUT: %T.loc7_14.2: %.1 = bind_symbolic_name T 0, %T.loc7_14.1 [symbolic = @impl.%T (constants.%T)] | ||
// CHECK:STDOUT: %T.ref.loc7: %.1 = name_ref T, %T.loc7_14.2 [symbolic = @impl.%T (constants.%T)] | ||
// CHECK:STDOUT: %.loc7_21.1: type = facet_type_access %T.ref.loc7 [symbolic = @impl.%T (constants.%T)] | ||
// CHECK:STDOUT: %.loc7_21.2: type = converted %T.ref.loc7, %.loc7_21.1 [symbolic = @impl.%T (constants.%T)] | ||
// CHECK:STDOUT: %J.ref.loc7: type = name_ref J, %J.decl [template = constants.%.2] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: impl_decl @impl { | ||
// CHECK:STDOUT: %I.ref.loc14: type = name_ref I, %I.decl [template = constants.%.1] | ||
// CHECK:STDOUT: %T.loc14_14.1: %.1 = param T, runtime_param<invalid> | ||
// CHECK:STDOUT: %T.loc14_14.2: %.1 = bind_symbolic_name T 0, %T.loc14_14.1 [symbolic = constants.%T] | ||
// CHECK:STDOUT: %T.ref.loc14: %.1 = name_ref T, %T.loc14_14.2 [symbolic = constants.%T] | ||
// CHECK:STDOUT: %.loc14_21.1: type = facet_type_access %T.ref.loc14 [symbolic = constants.%T] | ||
// CHECK:STDOUT: %.loc14_21.2: type = converted %T.ref.loc14, %.loc14_21.1 [symbolic = constants.%T] | ||
// CHECK:STDOUT: %J.ref.loc14: type = name_ref J, %J.decl [template = constants.%.2] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: interface @I { | ||
// CHECK:STDOUT: %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self.1] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: .Self = %Self | ||
// CHECK:STDOUT: witness = () | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: interface @J { | ||
// CHECK:STDOUT: %Self: %.2 = bind_symbolic_name Self 0 [symbolic = constants.%Self.2] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: .Self = %Self | ||
// CHECK:STDOUT: witness = () | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: generic impl @impl(file.%T.loc7_14.2: %.1) { | ||
// CHECK:STDOUT: %T: %.1 = bind_symbolic_name T 0 [symbolic = %T (constants.%T)] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: impl: %T as %.2 { | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: witness = <unexpected>.inst+20.loc7_28 | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: specific @impl(constants.%T) { | ||
// CHECK:STDOUT: %T => constants.%T | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: --- same_type_different_spelling.carbon | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: constants { | ||
// CHECK:STDOUT: %C: type = class_type @C [template] | ||
// CHECK:STDOUT: %.1: type = interface_type @I [template] | ||
// CHECK:STDOUT: %Self: %.1 = bind_symbolic_name Self 0 [symbolic] | ||
// CHECK:STDOUT: %.2: type = tuple_type () [template] | ||
// CHECK:STDOUT: %.3: <witness> = interface_witness () [template] | ||
// CHECK:STDOUT: %.4: type = tuple_type (type, type) [template] | ||
// CHECK:STDOUT: %.5: i32 = int_literal 0 [template] | ||
// CHECK:STDOUT: %.6: type = ptr_type %.4 [template] | ||
// CHECK:STDOUT: %tuple: %.4 = tuple_value (%C, %C) [template] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: file { | ||
// CHECK:STDOUT: package: <namespace> = namespace [template] { | ||
// CHECK:STDOUT: .C = %C.decl | ||
// CHECK:STDOUT: .I = %I.decl | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} | ||
// CHECK:STDOUT: %I.decl: type = interface_decl @I [template = constants.%.1] {} | ||
// CHECK:STDOUT: impl_decl @impl.1 { | ||
// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] | ||
// CHECK:STDOUT: %I.ref.loc7: type = name_ref I, %I.decl [template = constants.%.1] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: impl_decl @impl.2 { | ||
// CHECK:STDOUT: %C.ref.loc8_7: type = name_ref C, %C.decl [template = constants.%C] | ||
// CHECK:STDOUT: %C.ref.loc8_10: type = name_ref C, %C.decl [template = constants.%C] | ||
// CHECK:STDOUT: %.loc8_11.1: %.4 = tuple_literal (%C.ref.loc8_7, %C.ref.loc8_10) | ||
// CHECK:STDOUT: %.loc8_13: i32 = int_literal 0 [template = constants.%.5] | ||
// CHECK:STDOUT: %tuple: %.4 = tuple_value (%C.ref.loc8_7, %C.ref.loc8_10) [template = constants.%tuple] | ||
// CHECK:STDOUT: %.loc8_11.2: %.4 = converted %.loc8_11.1, %tuple [template = constants.%tuple] | ||
// CHECK:STDOUT: %.loc8_12: type = tuple_access %.loc8_11.2, element0 [template = constants.%C] | ||
// CHECK:STDOUT: %I.ref.loc8: type = name_ref I, %I.decl [template = constants.%.1] | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: interface @I { | ||
// CHECK:STDOUT: %Self: %.1 = bind_symbolic_name Self 0 [symbolic = constants.%Self] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: .Self = %Self | ||
// CHECK:STDOUT: witness = () | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: impl @impl.1: %C as %.1 { | ||
// CHECK:STDOUT: %.loc7: <witness> = interface_witness () [template = constants.%.3] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: witness = %.loc7 | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: impl @impl.2: %C as %.1 { | ||
// CHECK:STDOUT: %.loc8: <witness> = interface_witness () [template = constants.%.3] | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: !members: | ||
// CHECK:STDOUT: witness = %.loc8 | ||
// CHECK:STDOUT: } | ||
// CHECK:STDOUT: | ||
// CHECK:STDOUT: class @C; | ||
// CHECK:STDOUT: |