diff --git a/explorer/interpreter/impl_scope.cpp b/explorer/interpreter/impl_scope.cpp index a7a97c300310..ed0cccbf222b 100644 --- a/explorer/interpreter/impl_scope.cpp +++ b/explorer/interpreter/impl_scope.cpp @@ -49,13 +49,13 @@ void ImplScope::Add(Nonnull iface, .witness = witness}); } -void ImplScope::Add(llvm::ArrayRef impls, +void ImplScope::Add(llvm::ArrayRef impls, llvm::ArrayRef> deduced, llvm::ArrayRef> impl_bindings, Nonnull witness, const TypeChecker& type_checker) { for (size_t i = 0; i != impls.size(); ++i) { - ConstraintType::ImplConstraint impl = impls[i]; + ImplConstraint impl = impls[i]; Add(impl.interface, deduced, impl.type, impl_bindings, type_checker.MakeConstraintWitnessAccess(witness, i), type_checker); } @@ -172,7 +172,7 @@ auto ImplScope::Resolve(Nonnull constraint_type, auto ImplScope::VisitEqualValues( Nonnull value, llvm::function_ref)> visitor) const -> bool { - for (Nonnull eq : equalities_) { + for (Nonnull eq : equalities_) { if (!eq->VisitEqualValues(value, visitor)) { return false; } @@ -279,7 +279,7 @@ void ImplScope::Print(llvm::raw_ostream& out) const { for (const Impl& impl : impls_) { out << sep << *(impl.type) << " as " << *(impl.interface); } - for (Nonnull eq : equalities_) { + for (Nonnull eq : equalities_) { out << sep; llvm::ListSeparator equal(" == "); for (Nonnull value : eq->values) { diff --git a/explorer/interpreter/impl_scope.h b/explorer/interpreter/impl_scope.h index 5abadc3fcb03..fcaa16ee91f6 100644 --- a/explorer/interpreter/impl_scope.h +++ b/explorer/interpreter/impl_scope.h @@ -59,7 +59,7 @@ class ImplScope { // Adds a list of impl constraints from a constraint type into scope. Any // references to `.Self` are expected to have already been substituted for // the type implementing the constraint. - void Add(llvm::ArrayRef impls, + void Add(llvm::ArrayRef impls, llvm::ArrayRef> deduced, llvm::ArrayRef> impl_bindings, Nonnull witness, const TypeChecker& type_checker); diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index 7da79e414b57..258ee082bcae 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -1119,9 +1119,9 @@ class TypeChecker::ConstraintTypeBuilder { // Adds an `impl` constraint -- `T is C` if not already present. // Returns the index of the impl constraint within the self witness. - auto AddImplConstraint(ConstraintType::ImplConstraint impl) -> int { + auto AddImplConstraint(ImplConstraint impl) -> int { for (int i = 0; i != static_cast(impl_constraints_.size()); ++i) { - ConstraintType::ImplConstraint& existing = impl_constraints_[i]; + ImplConstraint& existing = impl_constraints_[i]; if (TypeEqual(existing.type, impl.type, std::nullopt) && TypeEqual(existing.interface, impl.interface, std::nullopt)) { return i; @@ -1132,7 +1132,7 @@ class TypeChecker::ConstraintTypeBuilder { } // Adds an equality constraint -- `A == B`. - void AddEqualityConstraint(ConstraintType::EqualityConstraint equal) { + void AddEqualityConstraint(EqualityConstraint equal) { if (equal.values.size() < 2) { // There's no need to track degenerate equality constraints. These can be // formed by rewrites. @@ -1148,9 +1148,8 @@ class TypeChecker::ConstraintTypeBuilder { } auto AddRewriteConstraint(SourceLocation source_loc, - ConstraintType::RewriteConstraint rewrite) - -> ErrorOr { - for (ConstraintType::RewriteConstraint existing : rewrite_constraints_) { + RewriteConstraint rewrite) -> ErrorOr { + for (RewriteConstraint existing : rewrite_constraints_) { if (ValueEqual(existing.constant, rewrite.constant, std::nullopt)) { if (ValueEqual(existing.unconverted_replacement, rewrite.unconverted_replacement, std::nullopt) && @@ -1170,8 +1169,8 @@ class TypeChecker::ConstraintTypeBuilder { } // Add a context for qualified name lookup, if not already present. - void AddLookupContext(ConstraintType::LookupContext context) { - for (ConstraintType::LookupContext existing : lookup_contexts_) { + void AddLookupContext(LookupContext context) { + for (LookupContext existing : lookup_contexts_) { if (ValueEqual(existing.context, context.context, std::nullopt)) { return; } @@ -1296,11 +1295,10 @@ class TypeChecker::ConstraintTypeBuilder { int first_equal_to_add = std::exchange(tracker->num_equals_added, equality_constraints_.size()); auto new_impl_constraints = - llvm::ArrayRef(impl_constraints_) + llvm::ArrayRef(impl_constraints_) .drop_front(first_impl_to_add); auto new_equality_constraints = - llvm::ArrayRef( - equality_constraints_) + llvm::ArrayRef(equality_constraints_) .drop_front(first_equal_to_add); // Add all of the new constraints. @@ -1382,10 +1380,10 @@ class TypeChecker::ConstraintTypeBuilder { Nonnull arena_; Nonnull self_binding_; Nonnull impl_binding_; - std::vector impl_constraints_; - std::vector equality_constraints_; - std::vector rewrite_constraints_; - std::vector lookup_contexts_; + std::vector impl_constraints_; + std::vector equality_constraints_; + std::vector rewrite_constraints_; + std::vector lookup_contexts_; }; // A collection of substituted `GenericBinding`s and `ImplBinding`s. @@ -1916,11 +1914,11 @@ auto TypeChecker::LookupInConstraint(SourceLocation source_loc, CARBON_ASSIGN_OR_RETURN( Nonnull constraint_type, ConvertToConstraintType(source_loc, lookup_kind, type)); - llvm::ArrayRef lookup_contexts = + llvm::ArrayRef lookup_contexts = constraint_type->lookup_contexts(); std::optional found; - for (ConstraintType::LookupContext lookup : lookup_contexts) { + for (LookupContext lookup : lookup_contexts) { if (!isa(lookup.context)) { // TODO: Support other kinds of lookup context, notably named // constraints. @@ -1961,7 +1959,7 @@ auto TypeChecker::LookupInConstraint(SourceLocation source_loc, static auto LookupRewrite(llvm::ArrayRef rewrites, Nonnull interface, Nonnull member) - -> std::optional { + -> std::optional { if (!isa(member)) { return std::nullopt; } @@ -1984,11 +1982,11 @@ static auto LookupRewrite(llvm::ArrayRef rewrites, static auto LookupRewrite(Nonnull type_of_type, Nonnull interface, Nonnull member) - -> std::optional { + -> std::optional { // Find the set of rewrites. Only ConstraintTypes have rewrites. // TODO: If we can ever see an InterfaceType here, we should convert it to a // constraint type. - llvm::ArrayRef rewrites; + llvm::ArrayRef rewrites; if (const auto* constraint_type = dyn_cast(type_of_type)) { rewrites = constraint_type->rewrite_constraints(); } @@ -2008,7 +2006,7 @@ auto TypeChecker::GetTypeForAssociatedConstant( auto TypeChecker::LookupRewriteInTypeOf( Nonnull type, Nonnull interface, Nonnull member) const - -> std::optional { + -> std::optional { // Given `(T:! C).Y`, look in `C` for rewrites. if (const auto* var_type = dyn_cast(type)) { if (!var_type->binding().has_static_type()) { @@ -2043,7 +2041,7 @@ auto TypeChecker::LookupRewriteInTypeOf( auto TypeChecker::LookupRewriteInWitness( Nonnull witness, Nonnull interface, Nonnull member) const - -> std::optional { + -> std::optional { if (const auto* impl_witness = dyn_cast(witness)) { Nonnull constraint = Substitute(impl_witness->bindings(), @@ -2054,9 +2052,8 @@ auto TypeChecker::LookupRewriteInWitness( } // Rewrites a member access expression to produce the given constant value. -static void RewriteMemberAccess( - Nonnull access, - Nonnull value) { +static void RewriteMemberAccess(Nonnull access, + Nonnull value) { access->set_value_category(ValueCategory::Let); access->set_static_type(value->unconverted_replacement_type); access->set_constant_value(value->unconverted_replacement); diff --git a/explorer/interpreter/value.cpp b/explorer/interpreter/value.cpp index 15004599e4bd..c4c512f07c2c 100644 --- a/explorer/interpreter/value.cpp +++ b/explorer/interpreter/value.cpp @@ -426,13 +426,12 @@ void Value::Print(llvm::raw_ostream& out) const { const auto& constraint = cast(*this); out << "constraint "; llvm::ListSeparator combine(" & "); - for (const ConstraintType::LookupContext& ctx : - constraint.lookup_contexts()) { + for (const LookupContext& ctx : constraint.lookup_contexts()) { out << combine << *ctx.context; } out << " where "; llvm::ListSeparator sep(" and "); - for (const ConstraintType::RewriteConstraint& rewrite : + for (const RewriteConstraint& rewrite : constraint.rewrite_constraints()) { out << sep << ".("; PrintNameWithBindings(out, &rewrite.constant->interface().declaration(), @@ -440,13 +439,12 @@ void Value::Print(llvm::raw_ostream& out) const { out << "." << *GetName(rewrite.constant->constant()) << ") = " << *rewrite.unconverted_replacement; } - for (const ConstraintType::ImplConstraint& impl : - constraint.impl_constraints()) { + for (const ImplConstraint& impl : constraint.impl_constraints()) { // TODO: Skip cases where `impl.type` is `.Self` and the interface is // in `lookup_contexts()`. out << sep << *impl.type << " is " << *impl.interface; } - for (const ConstraintType::EqualityConstraint& equality : + for (const EqualityConstraint& equality : constraint.equality_constraints()) { // TODO: Skip cases matching something in `rewrite_constraints()`. out << sep; diff --git a/explorer/interpreter/value.h b/explorer/interpreter/value.h index 05ab6771f53a..2ff2368e5cdc 100644 --- a/explorer/interpreter/value.h +++ b/explorer/interpreter/value.h @@ -732,7 +732,15 @@ class InterfaceType : public Value { Nonnull bindings_ = Bindings::None(); }; -// A collection of values that are known to be the same. +// A constraint that requires implementation of an interface. +struct ImplConstraint { + // The type that is required to implement the interface. + Nonnull type; + // The interface that is required to be implemented. + Nonnull interface; +}; + +// A constraint that a collection of values are known to be the same. struct EqualityConstraint { // Visit the values in this equality constraint that are a single step away // from the given value according to this equality constraint. That is: if @@ -762,6 +770,11 @@ struct RewriteConstraint { Nonnull converted_replacement; }; +// A context in which we might look up a name. +struct LookupContext { + Nonnull context; +}; + // A type-of-type for an unknown constrained type. // // These types are formed by the `&` operator that combines constraints and by @@ -780,21 +793,6 @@ struct RewriteConstraint { // `VariableType` naming the `self_binding`. class ConstraintType : public Value { public: - // A required implementation of an interface. - struct ImplConstraint { - Nonnull type; - Nonnull interface; - }; - - using RewriteConstraint = Carbon::RewriteConstraint; - - using EqualityConstraint = Carbon::EqualityConstraint; - - // A context in which we might look up a name. - struct LookupContext { - Nonnull context; - }; - explicit ConstraintType(Nonnull self_binding, std::vector impl_constraints, std::vector equality_constraints,