mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Make built-in conversions visible to ImplicitAs. (#2525)
Add a blanket `ImplicitAs` implementation to perform the conversions that explorer can perform as built-in conversions. This allows those conversions to be detected by constraints and to be used as part of other user-defined conversions. For now, a single monolithic conversion is exposed. I intend to split this up into multiple smaller conversion kinds for each kind of conversion in a follow-up change. Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This commit is contained in:
co-authored by
Jon Ross-Perkins
parent
94872ef6da
commit
0d279b388a
@@ -128,13 +128,15 @@ auto ImplScope::Resolve(Nonnull<const Value*> constraint_type,
|
||||
witnesses.push_back(result);
|
||||
}
|
||||
|
||||
// Check that all equality and rewrite constraints are satisfied in this
|
||||
// scope.
|
||||
// Check that all intrinsic, equality, and rewrite constraints
|
||||
// are satisfied in this scope.
|
||||
llvm::ArrayRef<IntrinsicConstraint> intrinsics =
|
||||
constraint->intrinsic_constraints();
|
||||
llvm::ArrayRef<EqualityConstraint> equals =
|
||||
constraint->equality_constraints();
|
||||
llvm::ArrayRef<RewriteConstraint> rewrites =
|
||||
constraint->rewrite_constraints();
|
||||
if (!equals.empty() || !rewrites.empty()) {
|
||||
if (!intrinsics.empty() || !equals.empty() || !rewrites.empty()) {
|
||||
std::optional<Nonnull<const Witness*>> witness;
|
||||
if (constraint->self_binding()->impl_binding()) {
|
||||
witness = type_checker.MakeConstraintWitness(witnesses);
|
||||
@@ -142,6 +144,21 @@ auto ImplScope::Resolve(Nonnull<const Value*> constraint_type,
|
||||
Bindings local_bindings = bindings;
|
||||
local_bindings.Add(constraint->self_binding(), impl_type, witness);
|
||||
SingleStepEqualityContext equality_ctx(this);
|
||||
for (const auto& intrinsic : intrinsics) {
|
||||
IntrinsicConstraint converted = {
|
||||
.type = type_checker.Substitute(local_bindings, intrinsic.type),
|
||||
.kind = intrinsic.kind,
|
||||
.arguments = {}};
|
||||
converted.arguments.reserve(intrinsic.arguments.size());
|
||||
for (Nonnull<const Value*> argument : intrinsic.arguments) {
|
||||
converted.arguments.push_back(
|
||||
type_checker.Substitute(local_bindings, argument));
|
||||
}
|
||||
if (!type_checker.IsIntrinsicConstraintSatisfied(converted, *this)) {
|
||||
return ProgramError(source_loc)
|
||||
<< "constraint requires that " << converted;
|
||||
}
|
||||
}
|
||||
for (const auto& equal : equals) {
|
||||
auto it = equal.values.begin();
|
||||
Nonnull<const Value*> first =
|
||||
|
||||
Reference in New Issue
Block a user