diff --git a/toolchain/check/decl_name_stack.cpp b/toolchain/check/decl_name_stack.cpp index b328800a6d40..5ed6aee3ebd9 100644 --- a/toolchain/check/decl_name_stack.cpp +++ b/toolchain/check/decl_name_stack.cpp @@ -366,8 +366,9 @@ auto DeclNameStack::ResolveAsScope(const NameContext& name_context, return InvalidResult; } - auto new_params = - DeclParams(name.name_loc_id, name.implicit_params_id, name.params_id); + auto new_params = DeclParams(name.name_loc_id, name.first_param_node_id, + name.last_param_node_id, name.implicit_params_id, + name.params_id); // Find the scope corresponding to the resolved instruction. CARBON_KIND_SWITCH(context_->insts().Get(name_context.resolved_inst_id)) { @@ -404,10 +405,11 @@ auto DeclNameStack::ResolveAsScope(const NameContext& name_context, case CARBON_KIND(SemIR::Namespace resolved_inst): { auto scope_id = resolved_inst.name_scope_id; auto& scope = context_->name_scopes().Get(scope_id); - if (!CheckRedeclParamsMatch(*context_, new_params, - DeclParams(name_context.resolved_inst_id, - SemIR::InstBlockId::Invalid, - SemIR::InstBlockId::Invalid))) { + if (!CheckRedeclParamsMatch( + *context_, new_params, + DeclParams(name_context.resolved_inst_id, Parse::NodeId::Invalid, + Parse::NodeId::Invalid, SemIR::InstBlockId::Invalid, + SemIR::InstBlockId::Invalid))) { return InvalidResult; } if (scope.is_closed_import) { diff --git a/toolchain/check/function.cpp b/toolchain/check/function.cpp index 7aafb42b18b9..eeecf30c58e8 100644 --- a/toolchain/check/function.cpp +++ b/toolchain/check/function.cpp @@ -13,9 +13,11 @@ namespace Carbon::Check { auto CheckFunctionTypeMatches(Context& context, const SemIR::Function& new_function, const SemIR::Function& prev_function, - Substitutions substitutions) -> bool { + Substitutions substitutions, bool check_syntax) + -> bool { if (!CheckRedeclParamsMatch(context, DeclParams(new_function), - DeclParams(prev_function), substitutions)) { + DeclParams(prev_function), substitutions, + check_syntax)) { return false; } diff --git a/toolchain/check/function.h b/toolchain/check/function.h index f7de8352ba32..44de24bc0928 100644 --- a/toolchain/check/function.h +++ b/toolchain/check/function.h @@ -29,12 +29,11 @@ struct SuspendedFunction { // Checks that `new_function` has the same parameter types and return type as // `prev_function`, applying the specified set of substitutions to the // previous function. Prints a suitable diagnostic and returns false if not. -// Note that this doesn't include the syntactic check that's performed for -// redeclarations. auto CheckFunctionTypeMatches(Context& context, const SemIR::Function& new_function, const SemIR::Function& prev_function, - Substitutions substitutions) -> bool; + Substitutions substitutions, bool check_syntax) + -> bool; // Checks that the return type of the specified function is complete, issuing an // error if not. This computes the return slot usage for the function if diff --git a/toolchain/check/global_init.cpp b/toolchain/check/global_init.cpp index 56995b1d06d5..0c5b4c781bfe 100644 --- a/toolchain/check/global_init.cpp +++ b/toolchain/check/global_init.cpp @@ -39,6 +39,8 @@ auto GlobalInit::Finalize() -> void { .parent_scope_id = SemIR::NameScopeId::Package, .decl_id = SemIR::InstId::Invalid, .generic_id = SemIR::GenericId::Invalid, + .first_param_node_id = Parse::NodeId::Invalid, + .last_param_node_id = Parse::NodeId::Invalid, .implicit_param_refs_id = SemIR::InstBlockId::Invalid, .param_refs_id = SemIR::InstBlockId::Empty, .return_storage_id = SemIR::InstId::Invalid, diff --git a/toolchain/check/handle_class.cpp b/toolchain/check/handle_class.cpp index e14ecbf4818c..a460b80e155f 100644 --- a/toolchain/check/handle_class.cpp +++ b/toolchain/check/handle_class.cpp @@ -93,6 +93,8 @@ static auto MergeClassRedecl(Context& context, SemIRLoc new_loc, } if (new_is_definition) { + prev_class.first_param_node_id = new_class.first_param_node_id; + prev_class.last_param_node_id = new_class.last_param_node_id; prev_class.implicit_param_refs_id = new_class.implicit_param_refs_id; prev_class.param_refs_id = new_class.param_refs_id; prev_class.definition_id = new_class.definition_id; @@ -225,6 +227,8 @@ static auto BuildClassDecl(Context& context, Parse::AnyClassDeclId node_id, .name_id = name_context.name_id_for_new_inst(), .parent_scope_id = name_context.parent_scope_id_for_new_inst(), .generic_id = SemIR::GenericId::Invalid, + .first_param_node_id = name.first_param_node_id, + .last_param_node_id = name.last_param_node_id, .implicit_param_refs_id = name.implicit_params_id, .param_refs_id = name.params_id, // `.self_type_id` depends on the ClassType, so is set below. diff --git a/toolchain/check/handle_function.cpp b/toolchain/check/handle_function.cpp index 2d5e6a50abf1..69b035f1be17 100644 --- a/toolchain/check/handle_function.cpp +++ b/toolchain/check/handle_function.cpp @@ -99,7 +99,8 @@ static auto MergeFunctionRedecl(Context& context, SemIRLoc new_loc, SemIR::ImportIRId prev_import_ir_id) -> bool { auto& prev_function = context.functions().Get(prev_function_id); - if (!CheckFunctionTypeMatches(context, new_function, prev_function, {})) { + if (!CheckFunctionTypeMatches(context, new_function, prev_function, {}, + /*check_syntax=*/true)) { return false; } @@ -118,6 +119,8 @@ static auto MergeFunctionRedecl(Context& context, SemIRLoc new_loc, // Track the signature from the definition, so that IDs in the body // match IDs in the signature. prev_function.definition_id = new_function.definition_id; + prev_function.first_param_node_id = new_function.first_param_node_id; + prev_function.last_param_node_id = new_function.last_param_node_id; prev_function.implicit_param_refs_id = new_function.implicit_param_refs_id; prev_function.param_refs_id = new_function.param_refs_id; prev_function.return_storage_id = new_function.return_storage_id; @@ -252,6 +255,8 @@ static auto BuildFunctionDecl(Context& context, .parent_scope_id = name_context.parent_scope_id_for_new_inst(), .decl_id = decl_id, .generic_id = SemIR::GenericId::Invalid, + .first_param_node_id = name.first_param_node_id, + .last_param_node_id = name.last_param_node_id, .implicit_param_refs_id = name.implicit_params_id, .param_refs_id = name.params_id, .return_storage_id = return_storage_id, diff --git a/toolchain/check/handle_impl.cpp b/toolchain/check/handle_impl.cpp index 1626c0f1e7e7..f501d74bef92 100644 --- a/toolchain/check/handle_impl.cpp +++ b/toolchain/check/handle_impl.cpp @@ -36,6 +36,8 @@ auto HandleParseNode(Context& context, Parse::ImplIntroducerId node_id) auto HandleParseNode(Context& context, Parse::ImplForallId node_id) -> bool { auto params_id = context.node_stack().Pop(); + context.node_stack() + .PopAndDiscardSoloNodeId(); context.node_stack().Push(node_id, params_id); return true; } diff --git a/toolchain/check/handle_interface.cpp b/toolchain/check/handle_interface.cpp index 0bbc33ebb255..c7e8c57f6d7e 100644 --- a/toolchain/check/handle_interface.cpp +++ b/toolchain/check/handle_interface.cpp @@ -62,7 +62,8 @@ static auto BuildInterfaceDecl(Context& context, // now we just check the generic parameters match. if (CheckRedeclParamsMatch( context, - DeclParams(interface_decl_id, name.implicit_params_id, + DeclParams(interface_decl_id, name.first_param_node_id, + name.last_param_node_id, name.implicit_params_id, name.params_id), DeclParams(context.interfaces().Get( existing_interface_decl->interface_id)))) { @@ -90,6 +91,8 @@ static auto BuildInterfaceDecl(Context& context, .name_id = name_context.name_id_for_new_inst(), .parent_scope_id = name_context.parent_scope_id_for_new_inst(), .generic_id = generic_id, + .first_param_node_id = name.first_param_node_id, + .last_param_node_id = name.last_param_node_id, .implicit_param_refs_id = name.implicit_params_id, .param_refs_id = name.params_id, .decl_id = interface_decl_id}; diff --git a/toolchain/check/handle_pattern_list.cpp b/toolchain/check/handle_pattern_list.cpp index 6ee4b79c4162..44dbb4a36840 100644 --- a/toolchain/check/handle_pattern_list.cpp +++ b/toolchain/check/handle_pattern_list.cpp @@ -16,10 +16,10 @@ auto HandleParseNode(Context& context, Parse::ImplicitParamListStartId node_id) auto HandleParseNode(Context& context, Parse::ImplicitParamListId node_id) -> bool { + // Note the Start node remains on the stack, where the param list handler can + // make use of it. auto refs_id = context.param_and_arg_refs_stack().EndAndPop( Parse::NodeKind::ImplicitParamListStart); - context.node_stack() - .PopAndDiscardSoloNodeId(); context.node_stack().Push(node_id, refs_id); // The implicit parameter list's scope extends to the end of the following // parameter list. @@ -40,10 +40,10 @@ auto HandleParseNode(Context& context, Parse::PatternListCommaId /*node_id*/) } auto HandleParseNode(Context& context, Parse::TuplePatternId node_id) -> bool { + // Note the Start node remains on the stack, where the param list handler can + // make use of it. auto refs_id = context.param_and_arg_refs_stack().EndAndPop( Parse::NodeKind::TuplePatternStart); - context.node_stack() - .PopAndDiscardSoloNodeId(); context.node_stack().Push(node_id, refs_id); return true; } diff --git a/toolchain/check/impl.cpp b/toolchain/check/impl.cpp index 9aeadc285ec9..18fd57028d73 100644 --- a/toolchain/check/impl.cpp +++ b/toolchain/check/impl.cpp @@ -54,7 +54,8 @@ static auto CheckAssociatedFunctionImplementation( // synthesize a suitable thunk. if (!CheckFunctionTypeMatches( context, context.functions().Get(impl_function_decl->function_id), - context.functions().Get(interface_function_id), substitutions)) { + context.functions().Get(interface_function_id), substitutions, + /*check_syntax=*/false)) { return SemIR::InstId::BuiltinError; } return impl_decl_id; diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 369114020197..289ccfc1c658 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -909,6 +909,8 @@ class ImportRefResolver { // importing the parameters. .parent_scope_id = SemIR::NameScopeId::Invalid, .generic_id = generic_id, + .first_param_node_id = Parse::NodeId::Invalid, + .last_param_node_id = Parse::NodeId::Invalid, .implicit_param_refs_id = import_class.implicit_param_refs_id.is_valid() ? SemIR::InstBlockId::Empty : SemIR::InstBlockId::Invalid, @@ -1143,6 +1145,8 @@ class ImportRefResolver { .parent_scope_id = parent_scope_id, .decl_id = function_decl_id, .generic_id = generic_id, + .first_param_node_id = Parse::NodeId::Invalid, + .last_param_node_id = Parse::NodeId::Invalid, .implicit_param_refs_id = GetLocalParamRefsId( function.implicit_param_refs_id, implicit_param_const_ids), .param_refs_id = @@ -1249,6 +1253,8 @@ class ImportRefResolver { // importing the parameters. .parent_scope_id = SemIR::NameScopeId::Invalid, .generic_id = generic_id, + .first_param_node_id = Parse::NodeId::Invalid, + .last_param_node_id = Parse::NodeId::Invalid, .implicit_param_refs_id = import_interface.implicit_param_refs_id.is_valid() ? SemIR::InstBlockId::Empty diff --git a/toolchain/check/merge.cpp b/toolchain/check/merge.cpp index de85034f8f23..e93966755da7 100644 --- a/toolchain/check/merge.cpp +++ b/toolchain/check/merge.cpp @@ -268,9 +268,79 @@ static auto CheckRedeclParams(Context& context, SemIRLoc new_decl_loc, return true; } +// Returns true if the two nodes represent the same syntax. +// TODO: Detect raw identifiers (will require token changes). +static auto IsNodeSyntaxEqual(Context& context, Parse::NodeId new_node_id, + Parse::NodeId prev_node_id) -> bool { + if (context.parse_tree().node_kind(new_node_id) != + context.parse_tree().node_kind(prev_node_id)) { + return false; + } + + // TODO: Should there be a trivial way to check if we need to check spellings? + // Identifiers and literals need their text checked for cross-file matching, + // but not intra-file. Keywords and operators shouldn't need the token text + // examined at all. + auto new_spelling = context.tokens().GetTokenText( + context.parse_tree().node_token(new_node_id)); + auto prev_spelling = context.tokens().GetTokenText( + context.parse_tree().node_token(prev_node_id)); + return new_spelling == prev_spelling; +} + +// Returns false if redeclaration parameter syntax doesn't match. +static auto CheckRedeclParamSyntax(Context& context, + Parse::NodeId new_first_param_node_id, + Parse::NodeId new_last_param_node_id, + Parse::NodeId prev_first_param_node_id, + Parse::NodeId prev_last_param_node_id) + -> bool { + // Parse nodes may not always be available to compare. + // TODO: Support cross-file syntax checks. Right now imports provide invalid + // nodes, and we'll need to follow the declaration to its original file to + // get the parse tree. + if (!new_first_param_node_id.is_valid() || + !prev_first_param_node_id.is_valid()) { + return true; + } + CARBON_CHECK(new_last_param_node_id.is_valid()) + << "new_last_param_node_id.is_valid should match " + "new_first_param_node_id.is_valid"; + CARBON_CHECK(prev_last_param_node_id.is_valid()) + << "prev_last_param_node_id.is_valid should match " + "prev_first_param_node_id.is_valid"; + + auto new_range = context.parse_tree().postorder(new_first_param_node_id, + new_last_param_node_id); + auto prev_range = context.parse_tree().postorder(prev_first_param_node_id, + prev_last_param_node_id); + + // zip is using the shortest range. If they differ in length, there should be + // some difference inside the range because the range includes parameter + // brackets. As a consequence, we don't explicitly handle different range + // sizes here. + for (auto [new_node_id, prev_node_id] : llvm::zip(new_range, prev_range)) { + if (!IsNodeSyntaxEqual(context, new_node_id, prev_node_id)) { + CARBON_DIAGNOSTIC(RedeclParamSyntaxDiffers, Error, + "Redeclaration syntax differs here."); + CARBON_DIAGNOSTIC(RedeclParamSyntaxPrevious, Note, + "Comparing with previous declaration here."); + context.emitter() + .Build(new_node_id, RedeclParamSyntaxDiffers) + .Note(prev_node_id, RedeclParamSyntaxPrevious) + .Emit(); + + return false; + } + } + + return true; +} + auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity, const DeclParams& prev_entity, - Substitutions substitutions) -> bool { + Substitutions substitutions, bool check_syntax) + -> bool { if (EntityHasParamError(context, new_entity) || EntityHasParamError(context, prev_entity)) { return false; @@ -278,12 +348,21 @@ auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity, if (!CheckRedeclParams(context, new_entity.loc, new_entity.implicit_param_refs_id, prev_entity.loc, prev_entity.implicit_param_refs_id, "implicit ", - substitutions) || - !CheckRedeclParams(context, new_entity.loc, new_entity.param_refs_id, + substitutions)) { + return false; + } + if (!CheckRedeclParams(context, new_entity.loc, new_entity.param_refs_id, prev_entity.loc, prev_entity.param_refs_id, "", substitutions)) { return false; } + if (check_syntax && + !CheckRedeclParamSyntax(context, new_entity.first_param_node_id, + new_entity.last_param_node_id, + prev_entity.first_param_node_id, + prev_entity.last_param_node_id)) { + return false; + } return true; } diff --git a/toolchain/check/merge.h b/toolchain/check/merge.h index d7a96b9a94d8..121af502edc7 100644 --- a/toolchain/check/merge.h +++ b/toolchain/check/merge.h @@ -47,17 +47,30 @@ struct DeclParams { template explicit DeclParams(const Entity& entity) : loc(entity.decl_id), + first_param_node_id(entity.first_param_node_id), + last_param_node_id(entity.last_param_node_id), implicit_param_refs_id(entity.implicit_param_refs_id), param_refs_id(entity.param_refs_id) {} - DeclParams(SemIRLoc loc, SemIR::InstBlockId implicit_params_id, + DeclParams(SemIRLoc loc, Parse::NodeId first_param_node_id, + Parse::NodeId last_param_node_id, + SemIR::InstBlockId implicit_params_id, SemIR::InstBlockId params_id) : loc(loc), + first_param_node_id(first_param_node_id), + last_param_node_id(last_param_node_id), implicit_param_refs_id(implicit_params_id), param_refs_id(params_id) {} // The location of the declaration of the entity. SemIRLoc loc; + + // Parse tree bounds for the parameters, including both implicit and explicit + // parameters. These will be compared to match between declaration and + // definition. + Parse::NodeId first_param_node_id; + Parse::NodeId last_param_node_id; + // The implicit parameters of the entity. Can be Invalid if there is no // implicit parameter list. SemIR::InstBlockId implicit_param_refs_id; @@ -71,8 +84,8 @@ struct DeclParams { // returns false. auto CheckRedeclParamsMatch(Context& context, const DeclParams& new_entity, const DeclParams& prev_entity, - Substitutions substitutions = Substitutions()) - -> bool; + Substitutions substitutions = Substitutions(), + bool check_syntax = true) -> bool; } // namespace Carbon::Check diff --git a/toolchain/check/name_component.cpp b/toolchain/check/name_component.cpp index b5c785132af8..7c92754303cd 100644 --- a/toolchain/check/name_component.cpp +++ b/toolchain/check/name_component.cpp @@ -9,15 +9,40 @@ namespace Carbon::Check { auto PopNameComponent(Context& context) -> NameComponent { + Parse::NodeId first_param_node_id = Parse::InvalidNodeId(); + Parse::NodeId last_param_node_id = Parse::InvalidNodeId(); + + // Explicit params. auto [params_loc_id, params_id] = context.node_stack().PopWithNodeIdIf(); + if (params_id) { + first_param_node_id = + context.node_stack() + .PopForSoloNodeId(); + last_param_node_id = params_loc_id; + } + + // Implicit params. auto [implicit_params_loc_id, implicit_params_id] = context.node_stack() .PopWithNodeIdIf(); + if (implicit_params_id) { + // Implicit params always come before explicit params. + first_param_node_id = + context.node_stack() + .PopForSoloNodeId(); + // Only use the end of implicit params if there weren't explicit params. + if (last_param_node_id.is_valid()) { + last_param_node_id = params_loc_id; + } + } + auto [name_loc_id, name_id] = context.node_stack().PopNameWithNodeId(); return { .name_loc_id = name_loc_id, .name_id = name_id, + .first_param_node_id = first_param_node_id, + .last_param_node_id = last_param_node_id, .implicit_params_loc_id = implicit_params_loc_id, .implicit_params_id = implicit_params_id.value_or(SemIR::InstBlockId::Invalid), diff --git a/toolchain/check/name_component.h b/toolchain/check/name_component.h index 4adecac7ce82..e058e52eacf0 100644 --- a/toolchain/check/name_component.h +++ b/toolchain/check/name_component.h @@ -20,6 +20,12 @@ struct NameComponent { Parse::NodeId name_loc_id; SemIR::NameId name_id; + // Parse tree bounds for the parameters, including both implicit and explicit + // parameters. These will be compared to match between declaration and + // definition. + Parse::NodeId first_param_node_id; + Parse::NodeId last_param_node_id; + // The implicit parameter list. Parse::NodeId implicit_params_loc_id; SemIR::InstBlockId implicit_params_id; diff --git a/toolchain/check/testdata/class/base_method.carbon b/toolchain/check/testdata/class/base_method.carbon index 81b297de859a..edb7a0c87c9e 100644 --- a/toolchain/check/testdata/class/base_method.carbon +++ b/toolchain/check/testdata/class/base_method.carbon @@ -14,7 +14,7 @@ base class Base { fn F[addr self: Self*](); } -fn Base.F[addr self: Base*]() { +fn Base.F[addr self: Self*]() { (*self).a = 1; } @@ -73,7 +73,7 @@ fn Call(p: Derived*) { // CHECK:STDOUT: } // CHECK:STDOUT: %Base.decl: type = class_decl @Base [template = constants.%Base] {} // CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] { -// CHECK:STDOUT: %Base.ref: type = name_ref Base, %Base.decl [template = constants.%Base] +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [template = constants.%Base] // CHECK:STDOUT: %.loc17_26: type = ptr_type %Base [template = constants.%.3] // CHECK:STDOUT: %self.loc17_16.1: %.3 = param self // CHECK:STDOUT: @F.%self: %.3 = bind_name self, %self.loc17_16.1 diff --git a/toolchain/check/testdata/class/no_prelude/syntactic_merge.carbon b/toolchain/check/testdata/class/no_prelude/syntactic_merge.carbon new file mode 100644 index 000000000000..5c1c4135c9c3 --- /dev/null +++ b/toolchain/check/testdata/class/no_prelude/syntactic_merge.carbon @@ -0,0 +1,794 @@ +// 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/class/no_prelude/syntactic_merge.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/no_prelude/syntactic_merge.carbon + +// --- basic.carbon + +library "basic"; + +class C {} +alias D = C; + +class Foo(a: C); +class Foo(a: C) {} + +class Bar(a: D); +class Bar(a: D) {} + +// --- spacing.carbon + +library "spacing"; + +class C {} + +class Foo [ ] ( a : C ); +class Foo[](a: C) {} + +// --- fail_parens.carbon + +library "parens"; + +class C {} + +class Foo(a: C); +// CHECK:STDERR: fail_parens.carbon:[[@LINE+7]]:14: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: class Foo(a: (C)) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_parens.carbon:[[@LINE-4]]:14: Comparing with previous declaration here. +// CHECK:STDERR: class Foo(a: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +class Foo(a: (C)) {} + +// --- todo_fail_raw_identifier.carbon + +library "raw_identifier"; + +class C {} + +class Foo(a: C); +class Foo(a: r#C) {} + +// --- two_file.carbon + +library "two_file"; + +class C {} +alias D = C; + +class Foo(a: C); +class Bar(a: D); + +// --- two_file.impl.carbon + +impl library "two_file"; + +class Foo(a: C) {} +class Bar(a: D) {} + +// --- fail_name_mismatch.carbon + +library "name_mismatch"; + +class C {} +alias D = C; + +class Foo(a: C); +// CHECK:STDERR: fail_name_mismatch.carbon:[[@LINE+7]]:11: ERROR: Redeclaration differs at parameter 1. +// CHECK:STDERR: class Foo(b: D) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_name_mismatch.carbon:[[@LINE-4]]:11: Previous declaration's corresponding parameter here. +// CHECK:STDERR: class Foo(a: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +class Foo(b: D) {} + +// --- fail_alias.carbon + +library "alias"; + +class C {} +alias D = C; + +class Foo(a: C); +// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:14: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: class Foo(a: D) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_alias.carbon:[[@LINE-4]]:14: Comparing with previous declaration here. +// CHECK:STDERR: class Foo(a: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +class Foo(a: D) {} + +// --- fail_deduced_alias.carbon + +library "deduced_alias"; + +class C {} +alias D = C; + +class Foo[a: C](); +// CHECK:STDERR: fail_deduced_alias.carbon:[[@LINE+7]]:14: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: class Foo[a: D]() {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_deduced_alias.carbon:[[@LINE-4]]:14: Comparing with previous declaration here. +// CHECK:STDERR: class Foo[a: C](); +// CHECK:STDERR: ^ +// CHECK:STDERR: +class Foo[a: D]() {} + +// --- alias_two_file.carbon + +library "alias_two_file"; + +class C {} + +class Foo(a: C); + +// --- todo_fail_alias_two_file.impl.carbon + +impl library "alias_two_file"; + +alias D = C; + +class Foo(a: D) {} + +// --- fail_repeat_const.carbon + +library "repeat_const"; + +class C {} + +class Foo(a: const C); +// CHECK:STDERR: fail_repeat_const.carbon:[[@LINE+11]]:14: WARNING: `const` applied repeatedly to the same type has no additional effect. +// CHECK:STDERR: class Foo(a: const (const C)) {} +// CHECK:STDERR: ^~~~~~~~~~~~~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_repeat_const.carbon:[[@LINE+7]]:20: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: class Foo(a: const (const C)) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_repeat_const.carbon:[[@LINE-8]]:20: Comparing with previous declaration here. +// CHECK:STDERR: class Foo(a: const C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +class Foo(a: const (const C)) {} + +// --- fail_self_type.carbon + +library "self_type"; + +base class Base { + var a: (); + + fn F[addr self: Self*](); +} + +// CHECK:STDERR: fail_self_type.carbon:[[@LINE+6]]:22: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: fn Base.F[addr self: Base*]() { +// CHECK:STDERR: ^~~~ +// CHECK:STDERR: fail_self_type.carbon:[[@LINE-6]]:19: Comparing with previous declaration here. +// CHECK:STDERR: fn F[addr self: Self*](); +// CHECK:STDERR: ^~~~ +fn Base.F[addr self: Base*]() { + (*self).a = (); +} + +// CHECK:STDOUT: --- basic.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: %Bar.type: type = generic_class_type @Bar [template] +// CHECK:STDOUT: %Bar.1: %Bar.type = struct_value () [template] +// CHECK:STDOUT: %Bar.2: type = class_type @Bar [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl.loc7 +// CHECK:STDOUT: .Bar = %Bar.decl.loc10 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_11.1: %C = param a +// CHECK:STDOUT: %a.loc7_11.2: %C = bind_name a, %a.loc7_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc8: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc8_11.1: %C = param a +// CHECK:STDOUT: %a.loc8_11.2: %C = bind_name a, %a.loc8_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl.loc10: %Bar.type = class_decl @Bar [template = constants.%Bar.1] { +// CHECK:STDOUT: %D.ref.loc10: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc10_11.1: %C = param a +// CHECK:STDOUT: %a.loc10_11.2: %C = bind_name a, %a.loc10_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl.loc11: %Bar.type = class_decl @Bar [template = constants.%Bar.1] { +// CHECK:STDOUT: %D.ref.loc11: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc11_11.1: %C = param a +// CHECK:STDOUT: %a.loc11_11.2: %C = bind_name a, %a.loc11_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Foo.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Bar { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Bar.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- spacing.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl.loc6 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl.loc6: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_17.1: %C = param a +// CHECK:STDOUT: %a.loc6_17.2: %C = bind_name a, %a.loc6_17.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_13.1: %C = param a +// CHECK:STDOUT: %a.loc7_13.2: %C = bind_name a, %a.loc7_13.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Foo.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_parens.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: %.type: type = generic_class_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = class_type @.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_11.1: %C = param a +// CHECK:STDOUT: %a.loc6_11.2: %C = bind_name a, %a.loc6_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = class_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %C.ref.loc14: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc14_11.1: %C = param a +// CHECK:STDOUT: %a.loc14_11.2: %C = bind_name a, %a.loc14_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: class @.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- todo_fail_raw_identifier.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl.loc6 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl.loc6: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_11.1: %C = param a +// CHECK:STDOUT: %a.loc6_11.2: %C = bind_name a, %a.loc6_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_11.1: %C = param a +// CHECK:STDOUT: %a.loc7_11.2: %C = bind_name a, %a.loc7_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Foo.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- two_file.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: %Bar.type: type = generic_class_type @Bar [template] +// CHECK:STDOUT: %Bar.1: %Bar.type = struct_value () [template] +// CHECK:STDOUT: %Bar.2: type = class_type @Bar [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: .Bar = %Bar.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_11.1: %C = param a +// CHECK:STDOUT: %a.loc7_11.2: %C = bind_name a, %a.loc7_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl: %Bar.type = class_decl @Bar [template = constants.%Bar.1] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc8_11.1: %C = param a +// CHECK:STDOUT: %a.loc8_11.2: %C = bind_name a, %a.loc8_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: class @Bar; +// CHECK:STDOUT: +// CHECK:STDOUT: --- two_file.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: %Bar.type: type = generic_class_type @Bar [template] +// CHECK:STDOUT: %Bar.1: %Bar.type = struct_value () [template] +// CHECK:STDOUT: %Bar.2: type = class_type @Bar [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//two_file, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//two_file, inst+5, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.3: %Foo.type = import_ref Main//two_file, inst+9, loaded [template = constants.%Foo.1] +// CHECK:STDOUT: %import_ref.4: %Bar.type = import_ref Main//two_file, inst+17, loaded [template = constants.%Bar.1] +// CHECK:STDOUT: %import_ref.5 = import_ref Main//two_file, inst+2, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = imports.%import_ref.1 +// CHECK:STDOUT: .D = imports.%import_ref.2 +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: .Bar = %Bar.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %Foo.decl: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %a.loc4_11.1: %C = param a +// CHECK:STDOUT: %a.loc4_11.2: %C = bind_name a, %a.loc4_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl: %Bar.type = class_decl @Bar [template = constants.%Bar.1] { +// CHECK:STDOUT: %D.ref: type = name_ref D, imports.%import_ref.2 [template = constants.%C] +// CHECK:STDOUT: %a.loc5_11.1: %C = param a +// CHECK:STDOUT: %a.loc5_11.2: %C = bind_name a, %a.loc5_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Foo.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Bar { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Bar.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_name_mismatch.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: %.type: type = generic_class_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = class_type @.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_11.1: %C = param a +// CHECK:STDOUT: %a.loc7_11.2: %C = bind_name a, %a.loc7_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = class_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %b.loc15_11.1: %C = param b +// CHECK:STDOUT: %b.loc15_11.2: %C = bind_name b, %b.loc15_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: class @.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: %.type: type = generic_class_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = class_type @.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_11.1: %C = param a +// CHECK:STDOUT: %a.loc7_11.2: %C = bind_name a, %a.loc7_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = class_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc15_11.1: %C = param a +// CHECK:STDOUT: %a.loc15_11.2: %C = bind_name a, %a.loc15_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: class @.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_deduced_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: %.type: type = generic_class_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = class_type @.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_11.1: %C = param a +// CHECK:STDOUT: %a.loc7_11.2: %C = bind_name a, %a.loc7_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = class_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc15_11.1: %C = param a +// CHECK:STDOUT: %a.loc15_11.2: %C = bind_name a, %a.loc15_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: class @.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- alias_two_file.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_11.1: %C = param a +// CHECK:STDOUT: %a.loc6_11.2: %C = bind_name a, %a.loc6_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: --- todo_fail_alias_two_file.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//alias_two_file, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: %Foo.type = import_ref Main//alias_two_file, inst+7, loaded [template = constants.%Foo.1] +// CHECK:STDOUT: %import_ref.3 = import_ref Main//alias_two_file, inst+2, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = imports.%import_ref.1 +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, imports.%import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc6_11.1: %C = param a +// CHECK:STDOUT: %a.loc6_11.2: %C = bind_name a, %a.loc6_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Foo.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_repeat_const.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %.2: type = const_type %C [template] +// CHECK:STDOUT: %Foo.type: type = generic_class_type @Foo [template] +// CHECK:STDOUT: %.3: type = tuple_type () [template] +// CHECK:STDOUT: %Foo.1: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Foo.2: type = class_type @Foo [template] +// CHECK:STDOUT: %.type: type = generic_class_type @.1 [template] +// CHECK:STDOUT: %.4: %.type = struct_value () [template] +// CHECK:STDOUT: %.5: type = class_type @.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl: %Foo.type = class_decl @Foo [template = constants.%Foo.1] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %.loc6: type = const_type %C [template = constants.%.2] +// CHECK:STDOUT: %a.loc6_11.1: %.2 = param a +// CHECK:STDOUT: %a.loc6_11.2: %.2 = bind_name a, %a.loc6_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = class_decl @.1 [template = constants.%.4] { +// CHECK:STDOUT: %C.ref.loc18: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %.loc18_21: type = const_type %C [template = constants.%.2] +// CHECK:STDOUT: %.loc18_14: type = const_type %.2 [template = constants.%.2] +// CHECK:STDOUT: %a.loc18_11.1: %.2 = param a +// CHECK:STDOUT: %a.loc18_11.2: %.2 = bind_name a, %a.loc18_11.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: class @.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_self_type.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Base: type = class_type @Base [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %.2: type = unbound_element_type %Base, %.1 [template] +// CHECK:STDOUT: %.3: type = ptr_type %Base [template] +// CHECK:STDOUT: %F.type: type = fn_type @F [template] +// CHECK:STDOUT: %F: %F.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = struct_type {.a: %.1} [template] +// CHECK:STDOUT: %.type: type = fn_type @.1 [template] +// CHECK:STDOUT: %.5: %.type = struct_value () [template] +// CHECK:STDOUT: %.6: type = ptr_type %.4 [template] +// CHECK:STDOUT: %tuple: %.1 = tuple_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Base = %Base.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Base.decl: type = class_decl @Base [template = constants.%Base] {} +// CHECK:STDOUT: %.decl: %.type = fn_decl @.1 [template = constants.%.5] { +// CHECK:STDOUT: %Base.ref: type = name_ref Base, %Base.decl [template = constants.%Base] +// CHECK:STDOUT: %.loc16_26: type = ptr_type %Base [template = constants.%.3] +// CHECK:STDOUT: %self.loc16_16.1: %.3 = param self +// CHECK:STDOUT: @.1.%self: %.3 = bind_name self, %self.loc16_16.1 +// CHECK:STDOUT: @.1.%.loc16: %.3 = addr_pattern @.1.%self +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @Base { +// CHECK:STDOUT: %.loc5_11.1: %.1 = tuple_literal () +// CHECK:STDOUT: %.loc5_11.2: type = converted %.loc5_11.1, constants.%.1 [template = constants.%.1] +// CHECK:STDOUT: %.loc5_8: %.2 = field_decl a, element0 [template] +// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [template = constants.%F] { +// CHECK:STDOUT: %Self.ref: type = name_ref Self, constants.%Base [template = constants.%Base] +// CHECK:STDOUT: %.loc7_23: type = ptr_type %Base [template = constants.%.3] +// CHECK:STDOUT: %self.loc7_13.1: %.3 = param self +// CHECK:STDOUT: %self.loc7_13.3: %.3 = bind_name self, %self.loc7_13.1 +// CHECK:STDOUT: %.loc7_8: %.3 = addr_pattern %self.loc7_13.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%Base +// CHECK:STDOUT: .a = %.loc5_8 +// CHECK:STDOUT: .F = %F.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @F[addr @Base.%self.loc7_13.3: %.3](); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @.1[addr %self: %.3]() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %self.ref: %.3 = name_ref self, %self +// CHECK:STDOUT: %.loc17_4: ref %Base = deref %self.ref +// CHECK:STDOUT: %a.ref: %.2 = name_ref a, @Base.%.loc5_8 [template = @Base.%.loc5_8] +// CHECK:STDOUT: %.loc17_10: ref %.1 = class_element_access %.loc17_4, element0 +// CHECK:STDOUT: %.loc17_16.1: %.1 = tuple_literal () +// CHECK:STDOUT: %.loc17_16.2: init %.1 = tuple_init () to %.loc17_10 [template = constants.%tuple] +// CHECK:STDOUT: %.loc17_13: init %.1 = converted %.loc17_16.1, %.loc17_16.2 [template = constants.%tuple] +// CHECK:STDOUT: assign %.loc17_10, %.loc17_13 +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/class/syntactic_merge_literal.carbon b/toolchain/check/testdata/class/syntactic_merge_literal.carbon new file mode 100644 index 000000000000..a5504a4c37e6 --- /dev/null +++ b/toolchain/check/testdata/class/syntactic_merge_literal.carbon @@ -0,0 +1,191 @@ +// 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/class/syntactic_merge_literal.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/class/syntactic_merge_literal.carbon +// CHECK:STDERR: fail_int_mismatch.carbon: ERROR: Main//default previously provided by `int_match.carbon`. +// CHECK:STDERR: + +// --- int_match.carbon + +class C(a: i32) {} +class D(b: C(1_000)); +class D(b: C(1_000)) {} + +// --- fail_int_mismatch.carbon + +class C(a: i32) {} +class D(b: C(1000)); +// CHECK:STDERR: fail_int_mismatch.carbon:[[@LINE+6]]:14: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: class D(b: C(1_000)) {} +// CHECK:STDERR: ^~~~~ +// CHECK:STDERR: fail_int_mismatch.carbon:[[@LINE-4]]:14: Comparing with previous declaration here. +// CHECK:STDERR: class D(b: C(1000)); +// CHECK:STDERR: ^~~~ +class D(b: C(1_000)) {} + +// CHECK:STDOUT: --- int_match.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [template] +// CHECK:STDOUT: %C.1: %C.type = struct_value () [template] +// CHECK:STDOUT: %C.2: type = class_type @C [template] +// CHECK:STDOUT: %.2: type = struct_type {} [template] +// CHECK:STDOUT: %.3: i32 = int_literal 1000 [template] +// CHECK:STDOUT: %C.3: type = class_type @C, (%.3) [template] +// CHECK:STDOUT: %D.type: type = generic_class_type @D [template] +// CHECK:STDOUT: %D.1: %D.type = struct_value () [template] +// CHECK:STDOUT: %D.2: type = class_type @D [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = %Core +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D.decl.loc3 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Core: = namespace %Core.import, [template] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/operators +// CHECK:STDOUT: import Core//prelude/types +// CHECK:STDOUT: import Core//prelude/operators/arithmetic +// CHECK:STDOUT: import Core//prelude/operators/bitwise +// CHECK:STDOUT: import Core//prelude/operators/comparison +// CHECK:STDOUT: import Core//prelude/types/bool +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: %C.type = class_decl @C [template = constants.%C.1] { +// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32] +// CHECK:STDOUT: %.loc2_12.1: type = value_of_initializer %int.make_type_32 [template = i32] +// CHECK:STDOUT: %.loc2_12.2: type = converted %int.make_type_32, %.loc2_12.1 [template = i32] +// CHECK:STDOUT: %a.loc2_9.1: i32 = param a +// CHECK:STDOUT: %a.loc2_9.2: i32 = bind_name a, %a.loc2_9.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %D.decl.loc3: %D.type = class_decl @D [template = constants.%D.1] { +// CHECK:STDOUT: %C.ref.loc3: %C.type = name_ref C, %C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc3_14: i32 = int_literal 1000 [template = constants.%.3] +// CHECK:STDOUT: %.loc3_13: init type = call %C.ref.loc3(%.loc3_14) [template = constants.%C.3] +// CHECK:STDOUT: %.loc3_19.1: type = value_of_initializer %.loc3_13 [template = constants.%C.3] +// CHECK:STDOUT: %.loc3_19.2: type = converted %.loc3_13, %.loc3_19.1 [template = constants.%C.3] +// CHECK:STDOUT: %b.loc3_9.1: %C.3 = param b +// CHECK:STDOUT: %b.loc3_9.2: %C.3 = bind_name b, %b.loc3_9.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %D.decl.loc4: %D.type = class_decl @D [template = constants.%D.1] { +// CHECK:STDOUT: %C.ref.loc4: %C.type = name_ref C, %C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc4_14: i32 = int_literal 1000 [template = constants.%.3] +// CHECK:STDOUT: %.loc4_13: init type = call %C.ref.loc4(%.loc4_14) [template = constants.%C.3] +// CHECK:STDOUT: %.loc4_19.1: type = value_of_initializer %.loc4_13 [template = constants.%C.3] +// CHECK:STDOUT: %.loc4_19.2: type = converted %.loc4_13, %.loc4_19.1 [template = constants.%C.3] +// CHECK:STDOUT: %b.loc4_9.1: %C.3 = param b +// CHECK:STDOUT: %b.loc4_9.2: %C.3 = bind_name b, %b.loc4_9.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @D { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%D.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32"; +// CHECK:STDOUT: +// CHECK:STDOUT: specific (constants.%.3); +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_int_mismatch.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %Int32.type: type = fn_type @Int32 [template] +// CHECK:STDOUT: %.1: type = tuple_type () [template] +// CHECK:STDOUT: %Int32: %Int32.type = struct_value () [template] +// CHECK:STDOUT: %C.type: type = generic_class_type @C [template] +// CHECK:STDOUT: %C.1: %C.type = struct_value () [template] +// CHECK:STDOUT: %C.2: type = class_type @C [template] +// CHECK:STDOUT: %.2: type = struct_type {} [template] +// CHECK:STDOUT: %.3: i32 = int_literal 1000 [template] +// CHECK:STDOUT: %C.3: type = class_type @C, (%.3) [template] +// CHECK:STDOUT: %D.type: type = generic_class_type @D [template] +// CHECK:STDOUT: %D.1: %D.type = struct_value () [template] +// CHECK:STDOUT: %D.2: type = class_type @D [template] +// CHECK:STDOUT: %.type: type = generic_class_type @.1 [template] +// CHECK:STDOUT: %.4: %.type = struct_value () [template] +// CHECK:STDOUT: %.5: type = class_type @.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref: %Int32.type = import_ref Core//prelude/types, inst+4, loaded [template = constants.%Int32] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .Core = %Core +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %Core.import = import Core +// CHECK:STDOUT: %Core: = namespace %Core.import, [template] { +// CHECK:STDOUT: import Core//prelude +// CHECK:STDOUT: import Core//prelude/operators +// CHECK:STDOUT: import Core//prelude/types +// CHECK:STDOUT: import Core//prelude/operators/arithmetic +// CHECK:STDOUT: import Core//prelude/operators/bitwise +// CHECK:STDOUT: import Core//prelude/operators/comparison +// CHECK:STDOUT: import Core//prelude/types/bool +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: %C.type = class_decl @C [template = constants.%C.1] { +// CHECK:STDOUT: %int.make_type_32: init type = call constants.%Int32() [template = i32] +// CHECK:STDOUT: %.loc2_12.1: type = value_of_initializer %int.make_type_32 [template = i32] +// CHECK:STDOUT: %.loc2_12.2: type = converted %int.make_type_32, %.loc2_12.1 [template = i32] +// CHECK:STDOUT: %a.loc2_9.1: i32 = param a +// CHECK:STDOUT: %a.loc2_9.2: i32 = bind_name a, %a.loc2_9.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %D.decl: %D.type = class_decl @D [template = constants.%D.1] { +// CHECK:STDOUT: %C.ref.loc3: %C.type = name_ref C, %C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc3_14: i32 = int_literal 1000 [template = constants.%.3] +// CHECK:STDOUT: %.loc3_13: init type = call %C.ref.loc3(%.loc3_14) [template = constants.%C.3] +// CHECK:STDOUT: %.loc3_18.1: type = value_of_initializer %.loc3_13 [template = constants.%C.3] +// CHECK:STDOUT: %.loc3_18.2: type = converted %.loc3_13, %.loc3_18.1 [template = constants.%C.3] +// CHECK:STDOUT: %b.loc3_9.1: %C.3 = param b +// CHECK:STDOUT: %b.loc3_9.2: %C.3 = bind_name b, %b.loc3_9.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = class_decl @.1 [template = constants.%.4] { +// CHECK:STDOUT: %C.ref.loc10: %C.type = name_ref C, %C.decl [template = constants.%C.1] +// CHECK:STDOUT: %.loc10_14: i32 = int_literal 1000 [template = constants.%.3] +// CHECK:STDOUT: %.loc10_13: init type = call %C.ref.loc10(%.loc10_14) [template = constants.%C.3] +// CHECK:STDOUT: %.loc10_19.1: type = value_of_initializer %.loc10_13 [template = constants.%C.3] +// CHECK:STDOUT: %.loc10_19.2: type = converted %.loc10_13, %.loc10_19.1 [template = constants.%C.3] +// CHECK:STDOUT: %b.loc10_9.1: %C.3 = param b +// CHECK:STDOUT: %b.loc10_9.2: %C.3 = bind_name b, %b.loc10_9.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C.2 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @D; +// CHECK:STDOUT: +// CHECK:STDOUT: class @.1 { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Int32() -> type = "int.make_type_32"; +// CHECK:STDOUT: +// CHECK:STDOUT: specific (constants.%.3); +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/function/definition/no_prelude/syntactic_merge.carbon b/toolchain/check/testdata/function/definition/no_prelude/syntactic_merge.carbon new file mode 100644 index 000000000000..bc081cd81500 --- /dev/null +++ b/toolchain/check/testdata/function/definition/no_prelude/syntactic_merge.carbon @@ -0,0 +1,754 @@ +// 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/function/definition/no_prelude/syntactic_merge.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/function/definition/no_prelude/syntactic_merge.carbon + +// --- basic.carbon + +library "basic"; + +class C {} +alias D = C; + +fn Foo(a: C); +fn Foo(a: C) {} + +fn Bar(a: D); +fn Bar(a: D) {} + +// --- spacing.carbon + +library "spacing"; + +class C {} + +fn Foo [ ] ( a : C ); +fn Foo[](a: C) {} + +// --- fail_parens.carbon + +library "parens"; + +class C {} + +fn Foo(a: C); +// CHECK:STDERR: fail_parens.carbon:[[@LINE+7]]:11: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: fn Foo(a: (C)) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_parens.carbon:[[@LINE-4]]:11: Comparing with previous declaration here. +// CHECK:STDERR: fn Foo(a: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn Foo(a: (C)) {} + +// --- todo_fail_raw_identifier.carbon + +library "raw_identifier"; + +class C {} + +fn Foo(a: C); +fn Foo(a: r#C) {} + +// --- two_file.carbon + +library "two_file"; + +class C {} +alias D = C; + +fn Foo(a: C); +fn Bar(a: D); + +// --- two_file.impl.carbon + +impl library "two_file"; + +fn Foo(a: C) {} +fn Bar(a: D) {} + +// --- fail_name_mismatch.carbon + +library "name_mismatch"; + +class C {} +alias D = C; + +fn Foo(a: C); +// CHECK:STDERR: fail_name_mismatch.carbon:[[@LINE+7]]:8: ERROR: Redeclaration differs at parameter 1. +// CHECK:STDERR: fn Foo(b: D) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_name_mismatch.carbon:[[@LINE-4]]:8: Previous declaration's corresponding parameter here. +// CHECK:STDERR: fn Foo(a: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn Foo(b: D) {} + +// --- fail_alias.carbon + +library "alias"; + +class C {} +alias D = C; + +fn Foo(a: C); +// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:11: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: fn Foo(a: D) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_alias.carbon:[[@LINE-4]]:11: Comparing with previous declaration here. +// CHECK:STDERR: fn Foo(a: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn Foo(a: D) {} + +// --- fail_deduced_alias.carbon + +library "deduced_alias"; + +class C {} +alias D = C; + +fn Foo[a: C](); +// CHECK:STDERR: fail_deduced_alias.carbon:[[@LINE+7]]:11: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: fn Foo[a: D]() {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_deduced_alias.carbon:[[@LINE-4]]:11: Comparing with previous declaration here. +// CHECK:STDERR: fn Foo[a: C](); +// CHECK:STDERR: ^ +// CHECK:STDERR: +fn Foo[a: D]() {} + +// --- todo_fail_alias_in_return.carbon + +library "alias_in_return"; + +class C {} +alias D = C; + +fn Foo() -> C; +fn Foo() -> D { return {}; } + +// --- alias_two_file.carbon + +library "alias_two_file"; + +class C {} + +fn Foo(a: C); + +// --- todo_fail_alias_two_file.impl.carbon + +impl library "alias_two_file"; + +alias D = C; + +fn Foo(a: D) {} + +// --- fail_repeat_const.carbon + +library "repeat_const"; + +class C {} + +fn Foo(a: const C); +// CHECK:STDERR: fail_repeat_const.carbon:[[@LINE+10]]:11: WARNING: `const` applied repeatedly to the same type has no additional effect. +// CHECK:STDERR: fn Foo(a: const (const C)) {} +// CHECK:STDERR: ^~~~~~~~~~~~~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_repeat_const.carbon:[[@LINE+6]]:17: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: fn Foo(a: const (const C)) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_repeat_const.carbon:[[@LINE-8]]:17: Comparing with previous declaration here. +// CHECK:STDERR: fn Foo(a: const C); +// CHECK:STDERR: ^ +fn Foo(a: const (const C)) {} + +// CHECK:STDOUT: --- basic.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.3: type = ptr_type %.1 [template] +// CHECK:STDOUT: %Bar.type: type = fn_type @Bar [template] +// CHECK:STDOUT: %Bar: %Bar.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl.loc7 +// CHECK:STDOUT: .Bar = %Bar.decl.loc10 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_8.1: %C = param a +// CHECK:STDOUT: %a.loc7_8.2: %C = bind_name a, %a.loc7_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc8: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc8_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc8_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl.loc10: %Bar.type = fn_decl @Bar [template = constants.%Bar] { +// CHECK:STDOUT: %D.ref.loc10: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc10_8.1: %C = param a +// CHECK:STDOUT: %a.loc10_8.2: %C = bind_name a, %a.loc10_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl.loc11: %Bar.type = fn_decl @Bar [template = constants.%Bar] { +// CHECK:STDOUT: %D.ref.loc11: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc11_8.1: %C = param a +// CHECK:STDOUT: @Bar.%a: %C = bind_name a, %a.loc11_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Bar(%a: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- spacing.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.3: type = ptr_type %.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl.loc6 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl.loc6: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_14.1: %C = param a +// CHECK:STDOUT: %a.loc6_14.2: %C = bind_name a, %a.loc6_14.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_10.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc7_10.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo[](%a: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_parens.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = fn_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = ptr_type %.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc6_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = fn_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %C.ref.loc14: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc14_8.1: %C = param a +// CHECK:STDOUT: @.1.%a: %C = bind_name a, %a.loc14_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %C); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @.1(%a: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- todo_fail_raw_identifier.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.3: type = ptr_type %.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl.loc6 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl.loc6: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_8.1: %C = param a +// CHECK:STDOUT: %a.loc6_8.2: %C = bind_name a, %a.loc6_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc7_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- two_file.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Bar.type: type = fn_type @Bar [template] +// CHECK:STDOUT: %Bar: %Bar.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: .Bar = %Bar.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc7_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl: %Bar.type = fn_decl @Bar [template = constants.%Bar] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc8_8.1: %C = param a +// CHECK:STDOUT: @Bar.%a: %C = bind_name a, %a.loc8_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %C); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Bar(%a: %C); +// CHECK:STDOUT: +// CHECK:STDOUT: --- two_file.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.3: type = ptr_type %.1 [template] +// CHECK:STDOUT: %Bar.type: type = fn_type @Bar [template] +// CHECK:STDOUT: %Bar: %Bar.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//two_file, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//two_file, inst+5, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.3: %Foo.type = import_ref Main//two_file, inst+9, loaded [template = constants.%Foo] +// CHECK:STDOUT: %import_ref.4: %Bar.type = import_ref Main//two_file, inst+16, loaded [template = constants.%Bar] +// CHECK:STDOUT: %import_ref.5 = import_ref Main//two_file, inst+2, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = imports.%import_ref.1 +// CHECK:STDOUT: .D = imports.%import_ref.2 +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: .Bar = %Bar.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %Foo.decl: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %a.loc4_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc4_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl: %Bar.type = fn_decl @Bar [template = constants.%Bar] { +// CHECK:STDOUT: %D.ref: type = name_ref D, imports.%import_ref.2 [template = constants.%C] +// CHECK:STDOUT: %a.loc5_8.1: %C = param a +// CHECK:STDOUT: @Bar.%a: %C = bind_name a, %a.loc5_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Bar(%a: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_name_mismatch.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = fn_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = ptr_type %.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc7_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = fn_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %b.loc15_8.1: %C = param b +// CHECK:STDOUT: @.1.%b: %C = bind_name b, %b.loc15_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %C); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @.1(%b: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = fn_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = ptr_type %.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc7_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = fn_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc15_8.1: %C = param a +// CHECK:STDOUT: @.1.%a: %C = bind_name a, %a.loc15_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %C); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @.1(%a: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_deduced_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = fn_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = ptr_type %.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc7_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = fn_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc15_8.1: %C = param a +// CHECK:STDOUT: @.1.%a: %C = bind_name a, %a.loc15_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo[%a: %C](); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @.1[%a: %C]() { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- todo_fail_alias_in_return.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.3: type = ptr_type %.1 [template] +// CHECK:STDOUT: %struct: %C = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl.loc7 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %return.var.loc7: ref %C = var +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc8: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: @Foo.%return: ref %C = var +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo() -> %return: %C { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: %.loc8_25.1: %.1 = struct_literal () +// CHECK:STDOUT: %.loc8_25.2: init %C = class_init (), %return [template = constants.%struct] +// CHECK:STDOUT: %.loc8_26: init %C = converted %.loc8_25.1, %.loc8_25.2 [template = constants.%struct] +// CHECK:STDOUT: return %.loc8_26 to %return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- alias_two_file.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc6_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %C); +// CHECK:STDOUT: +// CHECK:STDOUT: --- todo_fail_alias_two_file.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.3: type = ptr_type %.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//alias_two_file, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: %Foo.type = import_ref Main//alias_two_file, inst+7, loaded [template = constants.%Foo] +// CHECK:STDOUT: %import_ref.3 = import_ref Main//alias_two_file, inst+2, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = imports.%import_ref.1 +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, imports.%import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc6_8.1: %C = param a +// CHECK:STDOUT: @Foo.%a: %C = bind_name a, %a.loc6_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %C) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_repeat_const.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %.2: type = const_type %C [template] +// CHECK:STDOUT: %Foo.type: type = fn_type @Foo [template] +// CHECK:STDOUT: %.3: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = fn_type @.1 [template] +// CHECK:STDOUT: %.4: %.type = struct_value () [template] +// CHECK:STDOUT: %.5: type = ptr_type %.1 [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl: %Foo.type = fn_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %.loc6: type = const_type %C [template = constants.%.2] +// CHECK:STDOUT: %a.loc6_8.1: %.2 = param a +// CHECK:STDOUT: @Foo.%a: %.2 = bind_name a, %a.loc6_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = fn_decl @.1 [template = constants.%.4] { +// CHECK:STDOUT: %C.ref.loc17: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %.loc17_18: type = const_type %C [template = constants.%.2] +// CHECK:STDOUT: %.loc17_11: type = const_type %.2 [template = constants.%.2] +// CHECK:STDOUT: %a.loc17_8.1: %.2 = param a +// CHECK:STDOUT: @.1.%a: %.2 = bind_name a, %a.loc17_8.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Foo(%a: %.2); +// CHECK:STDOUT: +// CHECK:STDOUT: fn @.1(%a: %.2) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: return +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/interface/no_prelude/syntactic_merge.carbon b/toolchain/check/testdata/interface/no_prelude/syntactic_merge.carbon new file mode 100644 index 000000000000..2b74b35a2266 --- /dev/null +++ b/toolchain/check/testdata/interface/no_prelude/syntactic_merge.carbon @@ -0,0 +1,795 @@ +// 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/interface/no_prelude/syntactic_merge.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interface/no_prelude/syntactic_merge.carbon + +// --- basic.carbon + +library "basic"; + +class C {} +alias D = C; + +interface Foo(a: C); +interface Foo(a: C) {} + +interface Bar(a: D); +interface Bar(a: D) {} + +// --- spacing.carbon + +library "spacing"; + +class C {} + +interface Foo [ ] ( a : C ); +interface Foo[](a: C) {} + +// --- fail_parens.carbon + +library "parens"; + +class C {} + +interface Foo(a: C); +// CHECK:STDERR: fail_parens.carbon:[[@LINE+7]]:18: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: interface Foo(a: (C)) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_parens.carbon:[[@LINE-4]]:18: Comparing with previous declaration here. +// CHECK:STDERR: interface Foo(a: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface Foo(a: (C)) {} + +// --- todo_fail_raw_identifier.carbon + +library "raw_identifier"; + +class C {} + +interface Foo(a: C); +interface Foo(a: r#C) {} + +// --- two_file.carbon + +library "two_file"; + +class C {} +alias D = C; + +interface Foo(a: C); +interface Bar(a: D); + +// --- fail_todo_two_file.impl.carbon + +impl library "two_file"; + +// CHECK:STDERR: fail_todo_two_file.impl.carbon:[[@LINE+10]]:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: interface Foo(a: C) {} +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_todo_two_file.impl.carbon:[[@LINE-5]]:6: In import. +// CHECK:STDERR: impl library "two_file"; +// CHECK:STDERR: ^~~~~~~ +// CHECK:STDERR: two_file.carbon:7:1: Name is previously declared here. +// CHECK:STDERR: interface Foo(a: C); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +interface Foo(a: C) {} +// CHECK:STDERR: fail_todo_two_file.impl.carbon:[[@LINE+10]]:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: interface Bar(a: D) {} +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_todo_two_file.impl.carbon:[[@LINE-16]]:6: In import. +// CHECK:STDERR: impl library "two_file"; +// CHECK:STDERR: ^~~~~~~ +// CHECK:STDERR: two_file.carbon:8:1: Name is previously declared here. +// CHECK:STDERR: interface Bar(a: D); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +interface Bar(a: D) {} + +// --- fail_name_mismatch.carbon + +library "name_mismatch"; + +class C {} +alias D = C; + +interface Foo(a: C); +// CHECK:STDERR: fail_name_mismatch.carbon:[[@LINE+7]]:15: ERROR: Redeclaration differs at parameter 1. +// CHECK:STDERR: interface Foo(b: D) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_name_mismatch.carbon:[[@LINE-4]]:15: Previous declaration's corresponding parameter here. +// CHECK:STDERR: interface Foo(a: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface Foo(b: D) {} + +// --- fail_alias.carbon + +library "alias"; + +class C {} +alias D = C; + +interface Foo(a: C); +// CHECK:STDERR: fail_alias.carbon:[[@LINE+7]]:18: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: interface Foo(a: D) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_alias.carbon:[[@LINE-4]]:18: Comparing with previous declaration here. +// CHECK:STDERR: interface Foo(a: C); +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface Foo(a: D) {} + +// --- fail_deduced_alias.carbon + +library "deduced_alias"; + +class C {} +alias D = C; + +interface Foo[a: C](); +// CHECK:STDERR: fail_deduced_alias.carbon:[[@LINE+7]]:18: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: interface Foo[a: D]() {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_deduced_alias.carbon:[[@LINE-4]]:18: Comparing with previous declaration here. +// CHECK:STDERR: interface Foo[a: C](); +// CHECK:STDERR: ^ +// CHECK:STDERR: +interface Foo[a: D]() {} + +// --- alias_two_file.carbon + +library "alias_two_file"; + +class C {} + +interface Foo(a: C); + +// --- fail_alias_two_file.impl.carbon + +impl library "alias_two_file"; + +alias D = C; + +// TODO: This fails because importing interfaces doesn't work well. It should +// fail due to `C` versus `D`, but may succeed if importing interfaces is fixed +// before syntax matching on imports is supported. +// CHECK:STDERR: fail_alias_two_file.impl.carbon:[[@LINE+10]]:1: ERROR: Duplicate name being declared in the same scope. +// CHECK:STDERR: interface Foo(a: D) {} +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: fail_alias_two_file.impl.carbon:[[@LINE-10]]:6: In import. +// CHECK:STDERR: impl library "alias_two_file"; +// CHECK:STDERR: ^~~~~~~ +// CHECK:STDERR: alias_two_file.carbon:6:1: Name is previously declared here. +// CHECK:STDERR: interface Foo(a: C); +// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~ +// CHECK:STDERR: +interface Foo(a: D) {} + +// --- fail_repeat_const.carbon + +library "repeat_const"; + +class C {} + +interface Foo(a: const C); +// CHECK:STDERR: fail_repeat_const.carbon:[[@LINE+10]]:18: WARNING: `const` applied repeatedly to the same type has no additional effect. +// CHECK:STDERR: interface Foo(a: const (const C)) {} +// CHECK:STDERR: ^~~~~~~~~~~~~~~ +// CHECK:STDERR: +// CHECK:STDERR: fail_repeat_const.carbon:[[@LINE+6]]:24: ERROR: Redeclaration syntax differs here. +// CHECK:STDERR: interface Foo(a: const (const C)) {} +// CHECK:STDERR: ^ +// CHECK:STDERR: fail_repeat_const.carbon:[[@LINE-8]]:24: Comparing with previous declaration here. +// CHECK:STDERR: interface Foo(a: const C); +// CHECK:STDERR: ^ +interface Foo(a: const (const C)) {} + +// CHECK:STDOUT: --- basic.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.3: type = interface_type @Foo [template] +// CHECK:STDOUT: %Self.1: %.3 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: %Bar.type: type = generic_interface_type @Bar [template] +// CHECK:STDOUT: %Bar: %Bar.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = interface_type @Bar [template] +// CHECK:STDOUT: %Self.2: %.4 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl.loc7 +// CHECK:STDOUT: .Bar = %Bar.decl.loc10 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_15.1: %C = param a +// CHECK:STDOUT: %a.loc7_15.2: %C = bind_name a, %a.loc7_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc8: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc8: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc8_15.1: %C = param a +// CHECK:STDOUT: %a.loc8_15.2: %C = bind_name a, %a.loc8_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl.loc10: %Bar.type = interface_decl @Bar [template = constants.%Bar] { +// CHECK:STDOUT: %D.ref.loc10: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc10_15.1: %C = param a +// CHECK:STDOUT: %a.loc10_15.2: %C = bind_name a, %a.loc10_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl.loc11: %Bar.type = interface_decl @Bar [template = constants.%Bar] { +// CHECK:STDOUT: %D.ref.loc11: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc11_15.1: %C = param a +// CHECK:STDOUT: %a.loc11_15.2: %C = bind_name a, %a.loc11_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo { +// CHECK:STDOUT: %Self: %.3 = 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 @Bar { +// CHECK:STDOUT: %Self: %.4 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- spacing.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.3: type = interface_type @Foo [template] +// CHECK:STDOUT: %Self: %.3 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl.loc6 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl.loc6: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_21.1: %C = param a +// CHECK:STDOUT: %a.loc6_21.2: %C = bind_name a, %a.loc6_21.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_17.1: %C = param a +// CHECK:STDOUT: %a.loc7_17.2: %C = bind_name a, %a.loc7_17.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo { +// CHECK:STDOUT: %Self: %.3 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_parens.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = generic_interface_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = interface_type @.1 [template] +// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_15.1: %C = param a +// CHECK:STDOUT: %a.loc6_15.2: %C = bind_name a, %a.loc6_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = interface_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %C.ref.loc14: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc14_15.1: %C = param a +// CHECK:STDOUT: %a.loc14_15.2: %C = bind_name a, %a.loc14_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @.1 { +// CHECK:STDOUT: %Self: %.4 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- todo_fail_raw_identifier.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.3: type = interface_type @Foo [template] +// CHECK:STDOUT: %Self: %.3 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl.loc6 +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl.loc6: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_15.1: %C = param a +// CHECK:STDOUT: %a.loc6_15.2: %C = bind_name a, %a.loc6_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Foo.decl.loc7: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_15.1: %C = param a +// CHECK:STDOUT: %a.loc7_15.2: %C = bind_name a, %a.loc7_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo { +// CHECK:STDOUT: %Self: %.3 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- two_file.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %Bar.type: type = generic_interface_type @Bar [template] +// CHECK:STDOUT: %Bar: %Bar.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: .Bar = %Bar.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_15.1: %C = param a +// CHECK:STDOUT: %a.loc7_15.2: %C = bind_name a, %a.loc7_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %Bar.decl: %Bar.type = interface_decl @Bar [template = constants.%Bar] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc8_15.1: %C = param a +// CHECK:STDOUT: %a.loc8_15.2: %C = bind_name a, %a.loc8_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Bar; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_todo_two_file.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type.1: type = generic_interface_type @.1 [template] +// CHECK:STDOUT: %.3: %.type.1 = struct_value () [template] +// CHECK:STDOUT: %.4: type = interface_type @.1 [template] +// CHECK:STDOUT: %Self.1: %.4 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: %Bar.type: type = generic_interface_type @Bar [template] +// CHECK:STDOUT: %Bar: %Bar.type = struct_value () [template] +// CHECK:STDOUT: %.type.2: type = generic_interface_type @.2 [template] +// CHECK:STDOUT: %.5: %.type.2 = struct_value () [template] +// CHECK:STDOUT: %.6: type = interface_type @.2 [template] +// CHECK:STDOUT: %Self.2: %.6 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//two_file, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: type = import_ref Main//two_file, inst+5, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.3: %Foo.type = import_ref Main//two_file, inst+9, loaded [template = constants.%Foo] +// CHECK:STDOUT: %import_ref.4: %Bar.type = import_ref Main//two_file, inst+16, loaded [template = constants.%Bar] +// CHECK:STDOUT: %import_ref.5 = import_ref Main//two_file, inst+2, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = imports.%import_ref.1 +// CHECK:STDOUT: .D = imports.%import_ref.2 +// CHECK:STDOUT: .Foo = imports.%import_ref.3 +// CHECK:STDOUT: .Bar = imports.%import_ref.4 +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %.decl.loc14: %.type.1 = interface_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %a.loc14_15.1: %C = param a +// CHECK:STDOUT: %a.loc14_15.2: %C = bind_name a, %a.loc14_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl.loc25: %.type.2 = interface_decl @.2 [template = constants.%.5] { +// CHECK:STDOUT: %D.ref: type = name_ref D, imports.%import_ref.2 [template = constants.%C] +// CHECK:STDOUT: %a.loc25_15.1: %C = param a +// CHECK:STDOUT: %a.loc25_15.2: %C = bind_name a, %a.loc25_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @.1 { +// CHECK:STDOUT: %Self: %.4 = 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 @Bar; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @.2 { +// CHECK:STDOUT: %Self: %.6 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.5 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_name_mismatch.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = generic_interface_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = interface_type @.1 [template] +// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_15.1: %C = param a +// CHECK:STDOUT: %a.loc7_15.2: %C = bind_name a, %a.loc7_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = interface_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %b.loc15_15.1: %C = param b +// CHECK:STDOUT: %b.loc15_15.2: %C = bind_name b, %b.loc15_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @.1 { +// CHECK:STDOUT: %Self: %.4 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = generic_interface_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = interface_type @.1 [template] +// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_15.1: %C = param a +// CHECK:STDOUT: %a.loc7_15.2: %C = bind_name a, %a.loc7_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = interface_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc15_15.1: %C = param a +// CHECK:STDOUT: %a.loc15_15.2: %C = bind_name a, %a.loc15_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @.1 { +// CHECK:STDOUT: %Self: %.4 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_deduced_alias.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = generic_interface_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = interface_type @.1 [template] +// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %C.ref.loc5: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, %C.decl [template = constants.%C] +// CHECK:STDOUT: %Foo.decl: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc7: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc7_15.1: %C = param a +// CHECK:STDOUT: %a.loc7_15.2: %C = bind_name a, %a.loc7_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = interface_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc15_15.1: %C = param a +// CHECK:STDOUT: %a.loc15_15.2: %C = bind_name a, %a.loc15_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @.1 { +// CHECK:STDOUT: %Self: %.4 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- alias_two_file.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %a.loc6_15.1: %C = param a +// CHECK:STDOUT: %a.loc6_15.2: %C = bind_name a, %a.loc6_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_alias_two_file.impl.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.2: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = generic_interface_type @.1 [template] +// CHECK:STDOUT: %.3: %.type = struct_value () [template] +// CHECK:STDOUT: %.4: type = interface_type @.1 [template] +// CHECK:STDOUT: %Self: %.4 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: %import_ref.1: type = import_ref Main//alias_two_file, inst+1, loaded [template = constants.%C] +// CHECK:STDOUT: %import_ref.2: %Foo.type = import_ref Main//alias_two_file, inst+7, loaded [template = constants.%Foo] +// CHECK:STDOUT: %import_ref.3 = import_ref Main//alias_two_file, inst+2, unloaded +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = imports.%import_ref.1 +// CHECK:STDOUT: .Foo = imports.%import_ref.2 +// CHECK:STDOUT: .D = %D +// CHECK:STDOUT: } +// CHECK:STDOUT: %default.import.loc2_6.1 = import +// CHECK:STDOUT: %default.import.loc2_6.2 = import +// CHECK:STDOUT: %C.ref: type = name_ref C, imports.%import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %D: type = bind_alias D, imports.%import_ref.1 [template = constants.%C] +// CHECK:STDOUT: %.decl: %.type = interface_decl @.1 [template = constants.%.3] { +// CHECK:STDOUT: %D.ref: type = name_ref D, %D [template = constants.%C] +// CHECK:STDOUT: %a.loc19_15.1: %C = param a +// CHECK:STDOUT: %a.loc19_15.2: %C = bind_name a, %a.loc19_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @.1 { +// CHECK:STDOUT: %Self: %.4 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = imports.%import_ref.3 +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: --- fail_repeat_const.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %C: type = class_type @C [template] +// CHECK:STDOUT: %.1: type = struct_type {} [template] +// CHECK:STDOUT: %.2: type = const_type %C [template] +// CHECK:STDOUT: %Foo.type: type = generic_interface_type @Foo [template] +// CHECK:STDOUT: %.3: type = tuple_type () [template] +// CHECK:STDOUT: %Foo: %Foo.type = struct_value () [template] +// CHECK:STDOUT: %.type: type = generic_interface_type @.1 [template] +// CHECK:STDOUT: %.4: %.type = struct_value () [template] +// CHECK:STDOUT: %.5: type = interface_type @.1 [template] +// CHECK:STDOUT: %Self: %.5 = bind_symbolic_name Self 0 [symbolic] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: file { +// CHECK:STDOUT: package: = namespace [template] { +// CHECK:STDOUT: .C = %C.decl +// CHECK:STDOUT: .Foo = %Foo.decl +// CHECK:STDOUT: } +// CHECK:STDOUT: %C.decl: type = class_decl @C [template = constants.%C] {} +// CHECK:STDOUT: %Foo.decl: %Foo.type = interface_decl @Foo [template = constants.%Foo] { +// CHECK:STDOUT: %C.ref.loc6: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %.loc6: type = const_type %C [template = constants.%.2] +// CHECK:STDOUT: %a.loc6_15.1: %.2 = param a +// CHECK:STDOUT: %a.loc6_15.2: %.2 = bind_name a, %a.loc6_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: %.decl: %.type = interface_decl @.1 [template = constants.%.4] { +// CHECK:STDOUT: %C.ref.loc17: type = name_ref C, %C.decl [template = constants.%C] +// CHECK:STDOUT: %.loc17_25: type = const_type %C [template = constants.%.2] +// CHECK:STDOUT: %.loc17_18: type = const_type %.2 [template = constants.%.2] +// CHECK:STDOUT: %a.loc17_15.1: %.2 = param a +// CHECK:STDOUT: %a.loc17_15.2: %.2 = bind_name a, %a.loc17_15.1 +// CHECK:STDOUT: } +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: interface @Foo; +// CHECK:STDOUT: +// CHECK:STDOUT: interface @.1 { +// CHECK:STDOUT: %Self: %.5 = 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: class @C { +// CHECK:STDOUT: !members: +// CHECK:STDOUT: .Self = constants.%C +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/diagnostics/diagnostic_kind.def b/toolchain/diagnostics/diagnostic_kind.def index dbe4896a3ae6..2012fd5acd54 100644 --- a/toolchain/diagnostics/diagnostic_kind.def +++ b/toolchain/diagnostics/diagnostic_kind.def @@ -165,6 +165,8 @@ CARBON_DIAGNOSTIC_KIND(RedeclParamCountDiffers) CARBON_DIAGNOSTIC_KIND(RedeclParamCountPrevious) CARBON_DIAGNOSTIC_KIND(RedeclParamDiffers) CARBON_DIAGNOSTIC_KIND(RedeclParamPrevious) +CARBON_DIAGNOSTIC_KIND(RedeclParamSyntaxDiffers) +CARBON_DIAGNOSTIC_KIND(RedeclParamSyntaxPrevious) // Function call checking. CARBON_DIAGNOSTIC_KIND(AddrSelfIsNonRef) diff --git a/toolchain/parse/tree.cpp b/toolchain/parse/tree.cpp index 6fbf54d27cb5..8423e8de6162 100644 --- a/toolchain/parse/tree.cpp +++ b/toolchain/parse/tree.cpp @@ -32,6 +32,13 @@ auto Tree::postorder(NodeId n) const PostorderIterator(NodeId(end_index))); } +auto Tree::postorder(NodeId begin, NodeId end) const + -> llvm::iterator_range { + CARBON_CHECK(begin.is_valid() && end.is_valid()); + return llvm::iterator_range( + PostorderIterator(begin), PostorderIterator(NodeId(end.index + 1))); +} + auto Tree::children(NodeId n) const -> llvm::iterator_range { CARBON_CHECK(n.is_valid()); int end_index = n.index - node_impls_[n.index].subtree_size; diff --git a/toolchain/parse/tree.h b/toolchain/parse/tree.h index a67f4473a6d5..8a204d952d15 100644 --- a/toolchain/parse/tree.h +++ b/toolchain/parse/tree.h @@ -118,6 +118,11 @@ class Tree : public Printable { // descendants in depth-first postorder. auto postorder(NodeId n) const -> llvm::iterator_range; + // Returns an iterable range between the two parse tree nodes, in depth-first + // postorder. The range is inclusive of the bounds: [begin, end]. + auto postorder(NodeId begin, NodeId end) const + -> llvm::iterator_range; + // Returns an iterable range over the direct children of a node in the parse // tree. This is a forward range, but is constant time to increment. The order // of children is the same as would be found in a reverse postorder traversal. diff --git a/toolchain/sem_ir/class.h b/toolchain/sem_ir/class.h index 96a6aac66810..9ddf535936e4 100644 --- a/toolchain/sem_ir/class.h +++ b/toolchain/sem_ir/class.h @@ -42,6 +42,11 @@ struct Class : public Printable { NameScopeId parent_scope_id; // If this is a generic function, information about the generic. GenericId generic_id; + // Parse tree bounds for the parameters, including both implicit and explicit + // parameters. These will be compared to match between declaration and + // definition. + Parse::NodeId first_param_node_id; + Parse::NodeId last_param_node_id; // A block containing a single reference instruction per implicit parameter. InstBlockId implicit_param_refs_id; // A block containing a single reference instruction per parameter. diff --git a/toolchain/sem_ir/function.h b/toolchain/sem_ir/function.h index 5e45ee710cd4..c9bbff17c561 100644 --- a/toolchain/sem_ir/function.h +++ b/toolchain/sem_ir/function.h @@ -86,6 +86,11 @@ struct Function : public Printable { InstId decl_id; // If this is a generic function, information about the generic. GenericId generic_id; + // Parse tree bounds for the parameters, including both implicit and explicit + // parameters. These will be compared to match between declaration and + // definition. + Parse::NodeId first_param_node_id; + Parse::NodeId last_param_node_id; // A block containing a single reference instruction per implicit parameter. InstBlockId implicit_param_refs_id; // A block containing a single reference instruction per parameter. diff --git a/toolchain/sem_ir/interface.h b/toolchain/sem_ir/interface.h index 89fbe93a0360..67e595a34ebf 100644 --- a/toolchain/sem_ir/interface.h +++ b/toolchain/sem_ir/interface.h @@ -39,6 +39,11 @@ struct Interface : public Printable { NameScopeId parent_scope_id; // If this is a generic function, information about the generic. GenericId generic_id; + // Parse tree bounds for the parameters, including both implicit and explicit + // parameters. These will be compared to match between declaration and + // definition. + Parse::NodeId first_param_node_id; + Parse::NodeId last_param_node_id; // A block containing a single reference instruction per implicit parameter. InstBlockId implicit_param_refs_id; // A block containing a single reference instruction per parameter.