mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Build value representations for all kinds of witness (#2250)
Instead of forming a `SymbolicWitness` that contains an `Expression` when we can't directly resolve a witness to an `impl`, form different kinds of `Witness` values for the various situations: - A `BindingWitness` witnesses that a type implements a constraint by reference to an `ImplBinding`. - A `ConstraintWitness` witnesses that a type implements a constraint by reference to witnesses for each of the impl constraints within the constraint. - A `ConstraintImplWitness` witnesses that a type implements a constraint by reference to a larger constraint which contains that constraint as an impl constraint. Remove `SymbolicWitness` values and `InstantiateImpl` expressions, which are now unused. In order to remove the final usage of `SymbolicWitness`, I fixed a TODO to give `Self` the proper type within an interface declaration. I don't think this is an observable change. No functional change intended.
This commit is contained in:
@@ -50,34 +50,27 @@ static auto GetMember(Nonnull<Arena*> arena, Nonnull<const Value*> v,
|
||||
}
|
||||
|
||||
// Associated functions.
|
||||
switch (witness->kind()) {
|
||||
case Value::Kind::ImplWitness: {
|
||||
auto* impl_witness = cast<ImplWitness>(witness);
|
||||
if (std::optional<Nonnull<const Declaration*>> mem_decl =
|
||||
FindMember(f, impl_witness->declaration().members());
|
||||
mem_decl.has_value()) {
|
||||
const auto& fun_decl = cast<FunctionDeclaration>(**mem_decl);
|
||||
if (fun_decl.is_method()) {
|
||||
return arena->New<BoundMethodValue>(&fun_decl, v,
|
||||
&impl_witness->bindings());
|
||||
} else {
|
||||
// Class function.
|
||||
auto* fun = cast<FunctionValue>(*fun_decl.constant_value());
|
||||
return arena->New<FunctionValue>(&fun->declaration(),
|
||||
&impl_witness->bindings());
|
||||
}
|
||||
if (auto* impl_witness = dyn_cast<ImplWitness>(witness)) {
|
||||
if (std::optional<Nonnull<const Declaration*>> mem_decl =
|
||||
FindMember(f, impl_witness->declaration().members());
|
||||
mem_decl.has_value()) {
|
||||
const auto& fun_decl = cast<FunctionDeclaration>(**mem_decl);
|
||||
if (fun_decl.is_method()) {
|
||||
return arena->New<BoundMethodValue>(&fun_decl, v,
|
||||
&impl_witness->bindings());
|
||||
} else {
|
||||
return CompilationError(source_loc)
|
||||
<< "member " << f << " not in " << *witness;
|
||||
// Class function.
|
||||
auto* fun = cast<FunctionValue>(*fun_decl.constant_value());
|
||||
return arena->New<FunctionValue>(&fun->declaration(),
|
||||
&impl_witness->bindings());
|
||||
}
|
||||
} else {
|
||||
return CompilationError(source_loc)
|
||||
<< "member " << f << " not in " << *witness;
|
||||
}
|
||||
case Value::Kind::SymbolicWitness: {
|
||||
return RuntimeError(source_loc)
|
||||
<< "member lookup for " << f << " in symbolic " << *witness
|
||||
<< " not implemented yet";
|
||||
}
|
||||
default:
|
||||
CARBON_FATAL() << "expected Witness, not " << *witness;
|
||||
} else {
|
||||
return RuntimeError(source_loc)
|
||||
<< "member lookup for " << f << " in symbolic " << *witness;
|
||||
}
|
||||
}
|
||||
switch (v->kind()) {
|
||||
@@ -455,13 +448,29 @@ void Value::Print(llvm::raw_ostream& out) const {
|
||||
}
|
||||
case Value::Kind::ImplWitness: {
|
||||
const auto& witness = cast<ImplWitness>(*this);
|
||||
out << "witness " << *witness.declaration().impl_type() << " as "
|
||||
out << "witness for impl " << *witness.declaration().impl_type() << " as "
|
||||
<< witness.declaration().interface();
|
||||
break;
|
||||
}
|
||||
case Value::Kind::SymbolicWitness: {
|
||||
const auto& witness = cast<SymbolicWitness>(*this);
|
||||
out << "witness " << witness.impl_expression();
|
||||
case Value::Kind::BindingWitness: {
|
||||
const auto& witness = cast<BindingWitness>(*this);
|
||||
out << "witness for " << *witness.binding()->type_var();
|
||||
break;
|
||||
}
|
||||
case Value::Kind::ConstraintWitness: {
|
||||
const auto& witness = cast<ConstraintWitness>(*this);
|
||||
out << "(";
|
||||
llvm::ListSeparator sep;
|
||||
for (auto* elem : witness.witnesses()) {
|
||||
out << sep << *elem;
|
||||
}
|
||||
out << ")";
|
||||
break;
|
||||
}
|
||||
case Value::Kind::ConstraintImplWitness: {
|
||||
const auto& witness = cast<ConstraintImplWitness>(*this);
|
||||
out << "witness " << witness.index() << " of "
|
||||
<< *witness.constraint_witness();
|
||||
break;
|
||||
}
|
||||
case Value::Kind::ParameterizedEntityName:
|
||||
@@ -767,7 +776,9 @@ auto TypeEqual(Nonnull<const Value*> t1, Nonnull<const Value*> t2,
|
||||
<< *t1 << "\n"
|
||||
<< *t2;
|
||||
case Value::Kind::ImplWitness:
|
||||
case Value::Kind::SymbolicWitness:
|
||||
case Value::Kind::BindingWitness:
|
||||
case Value::Kind::ConstraintWitness:
|
||||
case Value::Kind::ConstraintImplWitness:
|
||||
CARBON_FATAL() << "TypeEqual: unexpected Witness";
|
||||
break;
|
||||
case Value::Kind::AutoType:
|
||||
@@ -868,7 +879,9 @@ auto ValueStructurallyEqual(
|
||||
case Value::Kind::InterfaceType:
|
||||
case Value::Kind::ConstraintType:
|
||||
case Value::Kind::ImplWitness:
|
||||
case Value::Kind::SymbolicWitness:
|
||||
case Value::Kind::BindingWitness:
|
||||
case Value::Kind::ConstraintWitness:
|
||||
case Value::Kind::ConstraintImplWitness:
|
||||
case Value::Kind::ChoiceType:
|
||||
case Value::Kind::ContinuationType:
|
||||
case Value::Kind::VariableType:
|
||||
|
||||
Reference in New Issue
Block a user