mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 09:51:04 +01:00
Deduce arguments against the canonical facet value (#6158)
When deducing an argument against a type that is `<facet value> as type` we don't care about the `as type` part of that expression. We want to find an argument that can convert to the `FacetType` of the facet value for the generic binding that is the `<facet value>`. This was done after-the-fact in the Deduce switch, but we move this canonicalization step to be more explicit and done up front at the start of the Deduce loop. This: - Avoids a trip through the Deduce loop for a `FacetAccessType` parameter, just to deduce through it in the switch, which avoids convert and creation of extraneous constant values. - Uses the `GetCanonicalFacetOrTypeValue()` function so that when we add `SymbolicBindingType` handling to that function it will apply to Deduce as well correctly, instead of needing to handle both in the switch.
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
#include "toolchain/check/convert.h"
|
||||
#include "toolchain/check/generic.h"
|
||||
#include "toolchain/check/subst.h"
|
||||
#include "toolchain/check/type.h"
|
||||
#include "toolchain/diagnostics/diagnostic.h"
|
||||
#include "toolchain/sem_ir/ids.h"
|
||||
#include "toolchain/sem_ir/impl.h"
|
||||
@@ -289,7 +290,14 @@ auto DeductionContext::Deduce() -> bool {
|
||||
if (context().types().Is<SemIR::PatternType>(param_type_id)) {
|
||||
param_type_id =
|
||||
SemIR::ExtractScrutineeType(context().sem_ir(), param_type_id);
|
||||
} else if (context().types().IsFacetType(param_type_id)) {
|
||||
// Given `fn F[G:! Interface](g: G)`, the type of `g` is `G as type`. For
|
||||
// deduction, we want to ignore the `as type`, and check that the argument
|
||||
// can convert to the FacetType of the canonical facet value.
|
||||
param_id = GetCanonicalFacetOrTypeValue(context(), param_id);
|
||||
param_type_id = context().insts().Get(param_id).type_id();
|
||||
}
|
||||
|
||||
// If the parameter has a symbolic type, deduce against that.
|
||||
if (param_type_id.is_symbolic()) {
|
||||
Add(context().types().GetInstId(param_type_id),
|
||||
@@ -411,20 +419,6 @@ auto DeductionContext::Deduce() -> bool {
|
||||
// TODO: Match field name order between param and arg.
|
||||
break;
|
||||
|
||||
case CARBON_KIND(SemIR::FacetAccessType access): {
|
||||
// Given `fn F[G:! Interface](g: G)`, the type of `g` is `G as type`.
|
||||
// `G` is a symbolic binding, whose type is a facet type, but `G as
|
||||
// type` converts into a `FacetAccessType`.
|
||||
//
|
||||
// When we see a `FacetAccessType` parameter here, we want to deduce the
|
||||
// facet type of `G`, not `G as type`, for the argument (so that the
|
||||
// argument would be a facet value, whose type is the same facet type of
|
||||
// `G`. So here we "undo" the `as type` operation that's built into the
|
||||
// `g` parameter's type.
|
||||
Add(access.facet_value_inst_id, arg_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: Handle more cases.
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user