Skip to content

Commit

Permalink
Add extra test.
Browse files Browse the repository at this point in the history
  • Loading branch information
zygoloid committed Sep 24, 2024
1 parent b44a1a5 commit 3780307
Showing 1 changed file with 323 additions and 0 deletions.
323 changes: 323 additions & 0 deletions toolchain/check/testdata/impl/no_prelude/generic_redeclaration.carbon
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:

0 comments on commit 3780307

Please sign in to comment.