Files
carbon-lang/toolchain/check/testdata/impl/lookup/use_impl_from_definition.carbon
T
Dana Jansens d6be20641c Use earlier require decls inside a named constraint to provide witnesses for Self (#6915)
Performing a lookup against `Self` inside the definition of the named
constraint leads to cycles, as described in the document [Self
contradictions in Named
Constraints](https://docs.google.com/document/d/17rn2XmME8o2MM4OJqatSVuMa1iYZ1PAgcNrf0PXR9Q4/edit?tab=t.0).
To prevent those cycles, this change introduces a large refactoring of
impl lookup.

The impl lookup done inside eval is reduced to only performing
monomorphization. That is it:
- Only looks for an provides final witnesses.
- Is not allowed to identify the facet type of the query self.
- Returns either a final witness or None (or an error)

The paths for finding non-final witnesses are now done outside of eval,
directly in the initial `LookupImplWitness()` function. If no final
witness it found through eval, the resulting non-final
`LookupImplWitness` instruction witness is returned. It does not produce
cycles to identify the facet type of query self outside of eval, since
that does not result in repeating the identification when resolving
specifics of the named constraint or require decl.

Move the ArrayStack for Context::require_impls_stack into a new class
which tracks a NamedConstraintId (or InterfaceId) for each frame of
RequireImplsIds, so that in type completion we always can find the
correct frame for a given named constraint which is still being defined,
in order to find the RequireImplsIds in the in-progress definition.
2026-03-26 15:26:56 +00:00

45 lines
1.4 KiB
Plaintext

// 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/testdata/min_prelude/convert.carbon
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/impl/lookup/use_impl_from_definition.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/impl/lookup/use_impl_from_definition.carbon
// --- construct_facet_value_inside_definition.carbon
library "[[@TEST_NAME]]";
interface I {
let U:! type;
fn F() -> U;
}
class C { adapt {}; }
impl forall [T:! type] T as I where .U = C {
// `T as I` does an impl lookup to form a FacetValue, which must find the impl
// being defined and use that. The witness must be a final witness in order to
// know that `U` is `C`.
fn F() -> (T as I).U { return {} as C; }
}
// --- construct_facet_value_from_self_inside_definition.carbon
library "[[@TEST_NAME]]";
interface I {
let U:! type;
fn F() -> U;
}
class C { adapt {}; }
impl forall [T:! type] T as I where .U = C {
// `Self as I` is a symbolic facet value specified in the interface-with-self
// specific, and then monomorphized with the self type of the impl.
fn F() -> (Self as I).U { return {} as C; }
}