From 010efd2e40b6511c65ba4033b40e9d98af7fbb88 Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Mon, 12 May 2025 14:10:36 -0400 Subject: [PATCH] Preserve the `is_final` bit when importing an `impl` declaration (#5461) We were importing all impls as non-final, since we forgot to set the new field when constructing the imported Impl. Adds a test that fails before this PR, since the imported Impl is treated as non-final. --- toolchain/check/import_ref.cpp | 3 +- .../lookup/min_prelude/final_placement.carbon | 2 +- .../lookup/min_prelude/import_final.carbon | 33 +++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 toolchain/check/testdata/impl/lookup/min_prelude/import_final.carbon diff --git a/toolchain/check/import_ref.cpp b/toolchain/check/import_ref.cpp index 86edbe85ef5f..ced1d3e0c965 100644 --- a/toolchain/check/import_ref.cpp +++ b/toolchain/check/import_ref.cpp @@ -2126,7 +2126,8 @@ static auto MakeImplDeclaration(ImportContext& context, {.self_id = SemIR::TypeInstId::None, .constraint_id = SemIR::TypeInstId::None, .interface = SemIR::SpecificInterface::None, - .witness_id = witness_id}}); + .witness_id = witness_id, + .is_final = import_impl.is_final}}); // Write the impl ID into the ImplDecl. auto impl_const_id = diff --git a/toolchain/check/testdata/impl/lookup/min_prelude/final_placement.carbon b/toolchain/check/testdata/impl/lookup/min_prelude/final_placement.carbon index 713e7101042c..99fcd88c8253 100644 --- a/toolchain/check/testdata/impl/lookup/min_prelude/final_placement.carbon +++ b/toolchain/check/testdata/impl/lookup/min_prelude/final_placement.carbon @@ -67,4 +67,4 @@ import library "type_d"; import library "interface_z"; // TODO: Can not write a final impl on `D` outside the file where `D` is defined. -final impl D as Z(()) where .X = () {} +final impl D as Z({}) where .X = () {} diff --git a/toolchain/check/testdata/impl/lookup/min_prelude/import_final.carbon b/toolchain/check/testdata/impl/lookup/min_prelude/import_final.carbon new file mode 100644 index 000000000000..a97512520381 --- /dev/null +++ b/toolchain/check/testdata/impl/lookup/min_prelude/import_final.carbon @@ -0,0 +1,33 @@ +// 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 +// +// INCLUDE-FILE: toolchain/testing/min_prelude/facet_types.carbon +// EXTRA-ARGS: --no-dump-sem-ir --custom-core +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/lookup/min_prelude/import_final.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/lookup/min_prelude/import_final.carbon + +// --- interface_z.carbon +library "[[@TEST_NAME]]"; + +interface Z { + let X:! type; +} + +class C {} +final impl forall [T:! type] T as Z where .X = C {} + +// --- import_final.carbon +library "[[@TEST_NAME]]"; + +import library "interface_z"; + +fn F[U:! type](T:! Z) { + // The value of `.X` can be known to be `C` here when the impl `T as Z(C)` is + // final. + let a: T.X = {} as C; +}