diff --git a/common/fuzzing/carbon.proto b/common/fuzzing/carbon.proto index 65bf5f5b88c1..49c903a6a192 100644 --- a/common/fuzzing/carbon.proto +++ b/common/fuzzing/carbon.proto @@ -134,7 +134,7 @@ message ArrayTypeLiteral { optional Expression size = 2; } -message IsWhereClause { +message ImplsWhereClause { optional Expression type = 1; optional Expression constraint = 2; } @@ -151,7 +151,7 @@ message RewriteWhereClause { message WhereClause { oneof kind { - IsWhereClause is = 1; + ImplsWhereClause impls = 1; EqualsWhereClause equals = 2; RewriteWhereClause rewrite = 3; } @@ -442,7 +442,7 @@ message ImplDeclaration { } message MatchFirstDeclaration { - repeated Declaration impls = 1; + repeated Declaration impl_declarations = 1; } message AliasDeclaration { diff --git a/common/fuzzing/proto_to_carbon.cpp b/common/fuzzing/proto_to_carbon.cpp index 27b476ae1bd5..1a8297445b22 100644 --- a/common/fuzzing/proto_to_carbon.cpp +++ b/common/fuzzing/proto_to_carbon.cpp @@ -399,10 +399,10 @@ static auto ExpressionToCarbon(const Fuzzing::Expression& expression, for (const auto& clause : where.clauses()) { out << sep; switch (clause.kind_case()) { - case Fuzzing::WhereClause::kIs: - ExpressionToCarbon(clause.is().type(), out); - out << " is "; - ExpressionToCarbon(clause.is().constraint(), out); + case Fuzzing::WhereClause::kImpls: + ExpressionToCarbon(clause.impls().type(), out); + out << " impls "; + ExpressionToCarbon(clause.impls().constraint(), out); break; case Fuzzing::WhereClause::kEquals: ExpressionToCarbon(clause.equals().lhs(), out); @@ -970,7 +970,7 @@ static auto DeclarationToCarbon(const Fuzzing::Declaration& declaration, case Fuzzing::Declaration::kMatchFirst: { const auto& match_first = declaration.match_first(); out << "__match_first {\n"; - for (const auto& impl : match_first.impls()) { + for (const auto& impl : match_first.impl_declarations()) { DeclarationToCarbon(impl, out); out << "\n"; } diff --git a/explorer/ast/ast_rtti.txt b/explorer/ast/ast_rtti.txt index 7e97604536fa..a8d94f6e7eac 100644 --- a/explorer/ast/ast_rtti.txt +++ b/explorer/ast/ast_rtti.txt @@ -83,7 +83,7 @@ abstract class Expression : AstNode; class BuiltinConvertExpression : Expression; class UnimplementedExpression : Expression; abstract class WhereClause : AstNode; - class IsWhereClause : WhereClause; + class ImplsWhereClause : WhereClause; class EqualsWhereClause : WhereClause; class RewriteWhereClause : WhereClause; root class Element; diff --git a/explorer/ast/declaration.cpp b/explorer/ast/declaration.cpp index cdc6458893b4..2ce8caaa137a 100644 --- a/explorer/ast/declaration.cpp +++ b/explorer/ast/declaration.cpp @@ -45,7 +45,8 @@ void Declaration::Print(llvm::raw_ostream& out) const { const auto& match_first_decl = cast(*this); PrintID(out); out << " {\n"; - for (Nonnull m : match_first_decl.impls()) { + for (Nonnull m : + match_first_decl.impl_declarations()) { out << *m; } out << "}\n"; diff --git a/explorer/ast/declaration.h b/explorer/ast/declaration.h index 81641bda12af..8ca32512b66f 100644 --- a/explorer/ast/declaration.h +++ b/explorer/ast/declaration.h @@ -943,26 +943,31 @@ class ImplDeclaration : public Declaration { class MatchFirstDeclaration : public Declaration { public: - MatchFirstDeclaration(SourceLocation source_loc, - std::vector> impls) + MatchFirstDeclaration( + SourceLocation source_loc, + std::vector> impl_declarations) : Declaration(AstNodeKind::MatchFirstDeclaration, source_loc), - impls_(std::move(impls)) {} + impl_declarations_(std::move(impl_declarations)) {} explicit MatchFirstDeclaration(CloneContext& context, const MatchFirstDeclaration& other) - : Declaration(context, other), impls_(context.Clone(other.impls_)) {} + : Declaration(context, other), + impl_declarations_(context.Clone(other.impl_declarations_)) {} static auto classof(const AstNode* node) -> bool { return InheritsFromMatchFirstDeclaration(node->kind()); } - auto impls() const -> llvm::ArrayRef> { - return impls_; + auto impl_declarations() const + -> llvm::ArrayRef> { + return impl_declarations_; + } + auto impl_declarations() -> llvm::ArrayRef> { + return impl_declarations_; } - auto impls() -> llvm::ArrayRef> { return impls_; } private: - std::vector> impls_; + std::vector> impl_declarations_; }; class AliasDeclaration : public Declaration { diff --git a/explorer/ast/expression.cpp b/explorer/ast/expression.cpp index 52d297775d46..730102d4ad10 100644 --- a/explorer/ast/expression.cpp +++ b/explorer/ast/expression.cpp @@ -398,9 +398,9 @@ WhereClause::~WhereClause() = default; void WhereClause::Print(llvm::raw_ostream& out) const { switch (kind()) { - case WhereClauseKind::IsWhereClause: { - const auto& clause = cast(*this); - out << clause.type() << " is " << clause.constraint(); + case WhereClauseKind::ImplsWhereClause: { + const auto& clause = cast(*this); + out << clause.type() << " impls " << clause.constraint(); break; } case WhereClauseKind::EqualsWhereClause: { diff --git a/explorer/ast/expression.h b/explorer/ast/expression.h index e0983a2ba9a2..97e04228c97e 100644 --- a/explorer/ast/expression.h +++ b/explorer/ast/expression.h @@ -224,8 +224,8 @@ class IdentifierExpression : public Expression { // `A`, but with type `type`. // // In a `where` binding, the type of `.Self` is the constraint preceding the -// `where` keyword. For example, in `Foo where .Result is Bar(.Self)`, the type -// of `.Self` is `Foo`. +// `where` keyword. For example, in `Foo where .Result impls Bar(.Self)`, the +// type of `.Self` is `Foo`. class DotSelfExpression : public Expression { public: explicit DotSelfExpression(SourceLocation source_loc) @@ -747,7 +747,9 @@ class CallExpression : public Expression { // Maps each of `function`'s impl bindings to a witness. // Should not be called before typechecking, or if `function` is not // a generic function. - auto impls() const -> const ImplWitnessMap& { return bindings_.witnesses(); } + auto witnesses() const -> const ImplWitnessMap& { + return bindings_.witnesses(); + } // Can only be called by type-checking, if a conversion was required. void set_argument(Nonnull argument) { argument_ = argument; } @@ -982,25 +984,27 @@ class WhereClause : public AstNode { : AstNode(context, other) {} }; -// An `is` where clause. +// An `impls` where clause. // -// For example, `ConstraintA where .Type is ConstraintB` requires that the +// For example, `ConstraintA where .Type impls ConstraintB` requires that the // associated type `.Type` implements the constraint `ConstraintB`. -class IsWhereClause : public WhereClause { +class ImplsWhereClause : public WhereClause { public: - explicit IsWhereClause(SourceLocation source_loc, Nonnull type, - Nonnull constraint) - : WhereClause(WhereClauseKind::IsWhereClause, source_loc), + explicit ImplsWhereClause(SourceLocation source_loc, + Nonnull type, + Nonnull constraint) + : WhereClause(WhereClauseKind::ImplsWhereClause, source_loc), type_(type), constraint_(constraint) {} - explicit IsWhereClause(CloneContext& context, const IsWhereClause& other) + explicit ImplsWhereClause(CloneContext& context, + const ImplsWhereClause& other) : WhereClause(context, other), type_(context.Clone(other.type_)), constraint_(context.Clone(other.constraint_)) {} static auto classof(const AstNode* node) { - return InheritsFromIsWhereClause(node->kind()); + return InheritsFromImplsWhereClause(node->kind()); } auto type() const -> const Expression& { return *type_; } diff --git a/explorer/ast/impl_binding.h b/explorer/ast/impl_binding.h index 1ff9b0a6aee1..203378f322c1 100644 --- a/explorer/ast/impl_binding.h +++ b/explorer/ast/impl_binding.h @@ -23,7 +23,7 @@ class GenericBinding; // (`BindingPattern`) there is no explicit syntax that corresponds to // an `ImplBinding`, so they are not created during parsing. Instances // of `ImplBinding` are created during type checking, when processing -// a type parameter (a `GenericBinding`), or an `is` requirement in +// a type parameter (a `GenericBinding`), or an `impls` requirement in // a `where` clause. class ImplBinding : public AstNode { public: diff --git a/explorer/ast/value.cpp b/explorer/ast/value.cpp index ac0e67938a46..580cf1eb91ca 100644 --- a/explorer/ast/value.cpp +++ b/explorer/ast/value.cpp @@ -597,10 +597,10 @@ void Value::Print(llvm::raw_ostream& out) const { out << "." << *GetName(rewrite.constant->constant()) << ") = " << *rewrite.unconverted_replacement; } - for (const ImplConstraint& impl : constraint.impl_constraints()) { + for (const ImplsConstraint& impl : constraint.impls_constraints()) { // TODO: Skip cases where `impl.type` is `.Self` and the interface is // in `lookup_contexts()`. - out << sep << *impl.type << " is " << *impl.interface; + out << sep << *impl.type << " impls " << *impl.interface; } for (const EqualityConstraint& equality : constraint.equality_constraints()) { @@ -809,17 +809,17 @@ auto TypeEqual(Nonnull t1, Nonnull t2, case Value::Kind::ConstraintType: { const auto& constraint1 = cast(*t1); const auto& constraint2 = cast(*t2); - if (constraint1.impl_constraints().size() != - constraint2.impl_constraints().size() || + if (constraint1.impls_constraints().size() != + constraint2.impls_constraints().size() || constraint1.equality_constraints().size() != constraint2.equality_constraints().size() || constraint1.lookup_contexts().size() != constraint2.lookup_contexts().size()) { return false; } - for (size_t i = 0; i < constraint1.impl_constraints().size(); ++i) { - const auto& impl1 = constraint1.impl_constraints()[i]; - const auto& impl2 = constraint2.impl_constraints()[i]; + for (size_t i = 0; i < constraint1.impls_constraints().size(); ++i) { + const auto& impl1 = constraint1.impls_constraints()[i]; + const auto& impl2 = constraint2.impls_constraints()[i]; if (!TypeEqual(impl1.type, impl2.type, equality_ctx) || !TypeEqual(impl1.interface, impl2.interface, equality_ctx)) { return false; diff --git a/explorer/ast/value.h b/explorer/ast/value.h index 9b1a31e6d448..7b37c2770dc2 100644 --- a/explorer/ast/value.h +++ b/explorer/ast/value.h @@ -663,7 +663,7 @@ class FunctionType : public Value { -> llvm::ArrayRef> { return deduced_bindings_; } - // The bindings for the witness tables (impls) required by the + // The bindings for the impl witness tables required by the // bounds on the type parameters of the generic function. auto impl_bindings() const -> llvm::ArrayRef> { return impl_bindings_; @@ -927,7 +927,7 @@ class NamedConstraintType : public Value { }; // A constraint that requires implementation of an interface. -struct ImplConstraint { +struct ImplsConstraint { template auto Decompose(F f) const { return f(type, interface); @@ -1037,14 +1037,14 @@ class ConstraintType : public Value { public: explicit ConstraintType( Nonnull self_binding, - std::vector impl_constraints, + std::vector impls_constraints, std::vector intrinsic_constraints, std::vector equality_constraints, std::vector rewrite_constraints, std::vector lookup_contexts) : Value(Kind::ConstraintType), self_binding_(self_binding), - impl_constraints_(std::move(impl_constraints)), + impls_constraints_(std::move(impls_constraints)), intrinsic_constraints_(std::move(intrinsic_constraints)), equality_constraints_(std::move(equality_constraints)), rewrite_constraints_(std::move(rewrite_constraints)), @@ -1056,7 +1056,7 @@ class ConstraintType : public Value { template auto Decompose(F f) const { - return f(self_binding_, impl_constraints_, intrinsic_constraints_, + return f(self_binding_, impls_constraints_, intrinsic_constraints_, equality_constraints_, rewrite_constraints_, lookup_contexts_); } @@ -1064,8 +1064,8 @@ class ConstraintType : public Value { return self_binding_; } - auto impl_constraints() const -> llvm::ArrayRef { - return impl_constraints_; + auto impls_constraints() const -> llvm::ArrayRef { + return impls_constraints_; } auto intrinsic_constraints() const -> llvm::ArrayRef { @@ -1097,7 +1097,7 @@ class ConstraintType : public Value { private: Nonnull self_binding_; - std::vector impl_constraints_; + std::vector impls_constraints_; std::vector intrinsic_constraints_; std::vector equality_constraints_; std::vector rewrite_constraints_; @@ -1175,7 +1175,7 @@ class BindingWitness : public Witness { }; // A witness for a constraint type, expressed as a tuple of witnesses for the -// individual impl constraints in the constraint type. +// individual impls constraints in the constraint type. class ConstraintWitness : public Witness { public: explicit ConstraintWitness(std::vector> witnesses) @@ -1198,11 +1198,11 @@ class ConstraintWitness : public Witness { std::vector> witnesses_; }; -// A witness for an impl constraint in a constraint type, expressed in terms of +// A witness for an impls constraint in a constraint type, expressed in terms of // a symbolic witness for the constraint type. class ConstraintImplWitness : public Witness { public: - // Make a witness for the given impl_constraint of the given `ConstraintType` + // Make a witness for the given impls_constraint of the given `ConstraintType` // witness. If we're indexing into a known tuple of witnesses, pull out the // element. static auto Make(Nonnull arena, Nonnull witness, @@ -1239,7 +1239,7 @@ class ConstraintImplWitness : public Witness { return constraint_witness_; } - // Get the index of the impl constraint within the constraint type. + // Get the index of the impls constraint within the constraint type. auto index() const -> int { return index_; } private: diff --git a/explorer/data/prelude.carbon b/explorer/data/prelude.carbon index 62a9941ed736..d957ae6df9d9 100644 --- a/explorer/data/prelude.carbon +++ b/explorer/data/prelude.carbon @@ -70,8 +70,8 @@ __match_first { } // A tuple explicitly converts to another tuple if all its elements do. Note - // that this fully overlaps with the previous set of impls for the case where - // an implicit conversion is possible. + // that this fully overlaps with the previous set of impl declarations for + // the case where an implicit conversion is possible. impl forall [U1:! type, T1:! As(U1)] (T1,) as As((U1,)) { fn Convert[self: Self]() -> (U1,) { @@ -389,7 +389,7 @@ constraint Mod { extends ModWith(Self) where .Result = Self; } -// Note, these impls use the builtin addition for i32. +// Note, these impl declarations use the builtin addition for i32. external impl i32 as Negate where .Result = i32 { fn Op[self: i32]() -> i32 { return -self; } } @@ -571,70 +571,70 @@ impl forall [T:! type, U:! ImplicitAs(T)] } // TODO: Should `AddWith(U) & AssignWith(.Self.(AddWith(U).Result))` work? -impl forall [U:! type, T:! AddWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! AddWith(U) where .Self impls AssignWith(.Self.Result)] T as AddAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self + other; } } -impl forall [U:! type, T:! SubWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! SubWith(U) where .Self impls AssignWith(.Self.Result)] T as SubAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self - other; } } -impl forall [U:! type, T:! MulWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! MulWith(U) where .Self impls AssignWith(.Self.Result)] T as MulAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self * other; } } -impl forall [U:! type, T:! DivWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! DivWith(U) where .Self impls AssignWith(.Self.Result)] T as DivAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self / other; } } -impl forall [U:! type, T:! ModWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! ModWith(U) where .Self impls AssignWith(.Self.Result)] T as ModAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self % other; } } -impl forall [U:! type, T:! BitAndWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! BitAndWith(U) where .Self impls AssignWith(.Self.Result)] T as BitAndAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self & other; } } -impl forall [U:! type, T:! BitOrWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! BitOrWith(U) where .Self impls AssignWith(.Self.Result)] T as BitOrAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self | other; } } -impl forall [U:! type, T:! BitXorWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! BitXorWith(U) where .Self impls AssignWith(.Self.Result)] T as BitXorAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self ^ other; } } -impl forall [U:! type, T:! LeftShiftWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! LeftShiftWith(U) where .Self impls AssignWith(.Self.Result)] T as LeftShiftAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self << other; } } -impl forall [U:! type, T:! RightShiftWith(U) where .Self is AssignWith(.Self.Result)] +impl forall [U:! type, T:! RightShiftWith(U) where .Self impls AssignWith(.Self.Result)] T as RightShiftAssignWith(U) { fn Op[addr self: Self*](other: U) { *self = *self >> other; diff --git a/explorer/fuzzing/ast_to_proto.cpp b/explorer/fuzzing/ast_to_proto.cpp index b62c46e4ee7c..9c6b2c2a4a45 100644 --- a/explorer/fuzzing/ast_to_proto.cpp +++ b/explorer/fuzzing/ast_to_proto.cpp @@ -256,12 +256,12 @@ static auto ExpressionToProto(const Expression& expression) for (const WhereClause* where : where.clauses()) { Fuzzing::WhereClause clause_proto; switch (where->kind()) { - case WhereClauseKind::IsWhereClause: { - auto* is_proto = clause_proto.mutable_is(); - *is_proto->mutable_type() = - ExpressionToProto(cast(where)->type()); - *is_proto->mutable_constraint() = - ExpressionToProto(cast(where)->constraint()); + case WhereClauseKind::ImplsWhereClause: { + auto* impls_proto = clause_proto.mutable_impls(); + *impls_proto->mutable_type() = + ExpressionToProto(cast(where)->type()); + *impls_proto->mutable_constraint() = + ExpressionToProto(cast(where)->constraint()); break; } case WhereClauseKind::EqualsWhereClause: { @@ -845,8 +845,8 @@ static auto DeclarationToProto(const Declaration& declaration) case DeclarationKind::MatchFirstDeclaration: { const auto& match_first = cast(declaration); auto* match_first_proto = declaration_proto.mutable_match_first(); - for (const auto* impl : match_first.impls()) { - *match_first_proto->add_impls() = DeclarationToProto(*impl); + for (const auto* impl : match_first.impl_declarations()) { + *match_first_proto->add_impl_declarations() = DeclarationToProto(*impl); } break; } diff --git a/explorer/fuzzing/fuzzer_corpus/a39216150512f65b529af0981e77f61b3301ff22 b/explorer/fuzzing/fuzzer_corpus/26c2d5cf1d3f39a1f0fc16691f770713002312a0 similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/a39216150512f65b529af0981e77f61b3301ff22 rename to explorer/fuzzing/fuzzer_corpus/26c2d5cf1d3f39a1f0fc16691f770713002312a0 index ddd531e94e46..7033a4912f00 100644 --- a/explorer/fuzzing/fuzzer_corpus/a39216150512f65b529af0981e77f61b3301ff22 +++ b/explorer/fuzzing/fuzzer_corpus/26c2d5cf1d3f39a1f0fc16691f770713002312a0 @@ -32,7 +32,7 @@ compilation_unit { } } clauses { - is { + impls { type { int_type_literal { } @@ -76,3 +76,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/1d5c57e26f96532fca3fab7cf9474049a8cd71b7 b/explorer/fuzzing/fuzzer_corpus/2d454cacd53c4ed55138382f919c3547d81059fd similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/1d5c57e26f96532fca3fab7cf9474049a8cd71b7 rename to explorer/fuzzing/fuzzer_corpus/2d454cacd53c4ed55138382f919c3547d81059fd index 2a289aece683..7bd719a4eec1 100644 --- a/explorer/fuzzing/fuzzer_corpus/1d5c57e26f96532fca3fab7cf9474049a8cd71b7 +++ b/explorer/fuzzing/fuzzer_corpus/2d454cacd53c4ed55138382f919c3547d81059fd @@ -30,7 +30,7 @@ compilation_unit { } declarations { match_first { - impls { + impl_declarations { impl { kind: ExternalImpl impl_type { @@ -69,7 +69,7 @@ compilation_unit { } } } - impls { + impl_declarations { impl { kind: ExternalImpl impl_type { diff --git a/explorer/fuzzing/fuzzer_corpus/e581bd5064e962288e5e78d9938def1e40feb12b b/explorer/fuzzing/fuzzer_corpus/4e0c2238235281a56e0b58c3ec927a3466c8b1e4 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/e581bd5064e962288e5e78d9938def1e40feb12b rename to explorer/fuzzing/fuzzer_corpus/4e0c2238235281a56e0b58c3ec927a3466c8b1e4 index bf9b9a4b47c7..e41d1e09b3ac 100644 --- a/explorer/fuzzing/fuzzer_corpus/e581bd5064e962288e5e78d9938def1e40feb12b +++ b/explorer/fuzzing/fuzzer_corpus/4e0c2238235281a56e0b58c3ec927a3466c8b1e4 @@ -82,7 +82,7 @@ compilation_unit { } } clauses { - is { + impls { type { int_type_literal { } @@ -239,3 +239,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/1cffd9bfbbba52a53c5f886563683d230d02ad80 b/explorer/fuzzing/fuzzer_corpus/4ee954ee8c71e3023e3855608bd6c60185453505 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/1cffd9bfbbba52a53c5f886563683d230d02ad80 rename to explorer/fuzzing/fuzzer_corpus/4ee954ee8c71e3023e3855608bd6c60185453505 index 1dfd12d50266..c37b301b0a42 100644 --- a/explorer/fuzzing/fuzzer_corpus/1cffd9bfbbba52a53c5f886563683d230d02ad80 +++ b/explorer/fuzzing/fuzzer_corpus/4ee954ee8c71e3023e3855608bd6c60185453505 @@ -66,7 +66,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -393,3 +393,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/03527ef9005c1d05b8bf667521a324a622e81ba9 b/explorer/fuzzing/fuzzer_corpus/59f5bff3c89e6ae504001fd40e25570fa68f4816 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/03527ef9005c1d05b8bf667521a324a622e81ba9 rename to explorer/fuzzing/fuzzer_corpus/59f5bff3c89e6ae504001fd40e25570fa68f4816 index d4135047dcfc..c95694c6c7a8 100644 --- a/explorer/fuzzing/fuzzer_corpus/03527ef9005c1d05b8bf667521a324a622e81ba9 +++ b/explorer/fuzzing/fuzzer_corpus/59f5bff3c89e6ae504001fd40e25570fa68f4816 @@ -148,7 +148,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -323,3 +323,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/2ded3a52f879950b9f7c70626708f433c4e1af2a b/explorer/fuzzing/fuzzer_corpus/604e3189c3c6fdcd4ba5375a88614370264f92e1 similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/2ded3a52f879950b9f7c70626708f433c4e1af2a rename to explorer/fuzzing/fuzzer_corpus/604e3189c3c6fdcd4ba5375a88614370264f92e1 index d85c3ed85be8..19626d687a52 100644 --- a/explorer/fuzzing/fuzzer_corpus/2ded3a52f879950b9f7c70626708f433c4e1af2a +++ b/explorer/fuzzing/fuzzer_corpus/604e3189c3c6fdcd4ba5375a88614370264f92e1 @@ -23,7 +23,7 @@ compilation_unit { } } clauses { - is { + impls { type { int_literal { value: 4 @@ -68,3 +68,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/990a34d604db8cb646b94ed74212a06796bf6639 b/explorer/fuzzing/fuzzer_corpus/6d8efa516d912ed4fb3a51abe81181ac5a3ce7de similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/990a34d604db8cb646b94ed74212a06796bf6639 rename to explorer/fuzzing/fuzzer_corpus/6d8efa516d912ed4fb3a51abe81181ac5a3ce7de index fc11ce557e9a..08d772a8e930 100644 --- a/explorer/fuzzing/fuzzer_corpus/990a34d604db8cb646b94ed74212a06796bf6639 +++ b/explorer/fuzzing/fuzzer_corpus/6d8efa516d912ed4fb3a51abe81181ac5a3ce7de @@ -75,7 +75,7 @@ compilation_unit { } } clauses { - is { + impls { type { int_type_literal { } @@ -300,3 +300,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/db160c03d69c93b692d6f4e2ef1c15f0bcdb7f8f b/explorer/fuzzing/fuzzer_corpus/8c82de66ed8c2c2e00ff9d0da8d299a7bc2e0a52 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/db160c03d69c93b692d6f4e2ef1c15f0bcdb7f8f rename to explorer/fuzzing/fuzzer_corpus/8c82de66ed8c2c2e00ff9d0da8d299a7bc2e0a52 index 3e73b33a485c..114c3e6c9a5a 100644 --- a/explorer/fuzzing/fuzzer_corpus/db160c03d69c93b692d6f4e2ef1c15f0bcdb7f8f +++ b/explorer/fuzzing/fuzzer_corpus/8c82de66ed8c2c2e00ff9d0da8d299a7bc2e0a52 @@ -49,7 +49,7 @@ compilation_unit { } declarations { match_first { - impls { + impl_declarations { impl { kind: ExternalImpl impl_type { @@ -91,7 +91,7 @@ compilation_unit { } } } - impls { + impl_declarations { impl { kind: ExternalImpl impl_type { @@ -133,7 +133,7 @@ compilation_unit { } } } - impls { + impl_declarations { impl { kind: ExternalImpl impl_type { @@ -175,7 +175,7 @@ compilation_unit { } } } - impls { + impl_declarations { impl { kind: ExternalImpl impl_type { diff --git a/explorer/fuzzing/fuzzer_corpus/31f34f507f6d8c70cc7934fc807d90e32031ecfb b/explorer/fuzzing/fuzzer_corpus/91ac9c25f698c4efb6886c33ba330739e7087851 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/31f34f507f6d8c70cc7934fc807d90e32031ecfb rename to explorer/fuzzing/fuzzer_corpus/91ac9c25f698c4efb6886c33ba330739e7087851 index c24d20c42d87..4dde53c968d5 100644 --- a/explorer/fuzzing/fuzzer_corpus/31f34f507f6d8c70cc7934fc807d90e32031ecfb +++ b/explorer/fuzzing/fuzzer_corpus/91ac9c25f698c4efb6886c33ba330739e7087851 @@ -162,7 +162,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -204,7 +204,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -246,7 +246,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -288,7 +288,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -330,7 +330,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -890,3 +890,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/84467b7cbaaa2931dc227bb0e46c3adac0ede663 b/explorer/fuzzing/fuzzer_corpus/abe990a35bad5c0ed6f66289dac8b310bccf732a similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/84467b7cbaaa2931dc227bb0e46c3adac0ede663 rename to explorer/fuzzing/fuzzer_corpus/abe990a35bad5c0ed6f66289dac8b310bccf732a index ef269bf82807..1d3a0ffabe3c 100644 --- a/explorer/fuzzing/fuzzer_corpus/84467b7cbaaa2931dc227bb0e46c3adac0ede663 +++ b/explorer/fuzzing/fuzzer_corpus/abe990a35bad5c0ed6f66289dac8b310bccf732a @@ -23,7 +23,7 @@ compilation_unit { } } clauses { - is { + impls { type { int_type_literal { } @@ -66,3 +66,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/d47bc23011a4973b678586a56ebae479f4dd39ec b/explorer/fuzzing/fuzzer_corpus/b0104f7d6a22c98bb612f42cec045f64f0599507 similarity index 98% rename from explorer/fuzzing/fuzzer_corpus/d47bc23011a4973b678586a56ebae479f4dd39ec rename to explorer/fuzzing/fuzzer_corpus/b0104f7d6a22c98bb612f42cec045f64f0599507 index 00a3922714ac..016ed345ed9e 100644 --- a/explorer/fuzzing/fuzzer_corpus/d47bc23011a4973b678586a56ebae479f4dd39ec +++ b/explorer/fuzzing/fuzzer_corpus/b0104f7d6a22c98bb612f42cec045f64f0599507 @@ -23,7 +23,7 @@ compilation_unit { } } clauses { - is { + impls { type { int_type_literal { } @@ -67,3 +67,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/169f839edd28aed284d4b38125e1833f73edac02 b/explorer/fuzzing/fuzzer_corpus/b6faa454160b04a71aebd4eefba1074e82f6b991 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/169f839edd28aed284d4b38125e1833f73edac02 rename to explorer/fuzzing/fuzzer_corpus/b6faa454160b04a71aebd4eefba1074e82f6b991 index 994c274d3ebe..9b11dd791b72 100644 --- a/explorer/fuzzing/fuzzer_corpus/169f839edd28aed284d4b38125e1833f73edac02 +++ b/explorer/fuzzing/fuzzer_corpus/b6faa454160b04a71aebd4eefba1074e82f6b991 @@ -208,7 +208,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -370,3 +370,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/79f09fae3aeb20dfc1e988e2fcbd1bff13db295f b/explorer/fuzzing/fuzzer_corpus/c1dda40eae19225720932d324f3f0610f31ab471 similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/79f09fae3aeb20dfc1e988e2fcbd1bff13db295f rename to explorer/fuzzing/fuzzer_corpus/c1dda40eae19225720932d324f3f0610f31ab471 index 0f004e2fae66..25c73cdcb178 100644 --- a/explorer/fuzzing/fuzzer_corpus/79f09fae3aeb20dfc1e988e2fcbd1bff13db295f +++ b/explorer/fuzzing/fuzzer_corpus/c1dda40eae19225720932d324f3f0610f31ab471 @@ -52,7 +52,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -245,3 +245,4 @@ compilation_unit { } } } + diff --git a/explorer/fuzzing/fuzzer_corpus/9e19f13bb23a93ba4f740a11563c2246fee796be b/explorer/fuzzing/fuzzer_corpus/f69e3144cbc99fb1dc4d1c8f7a1547679ffeb93a similarity index 99% rename from explorer/fuzzing/fuzzer_corpus/9e19f13bb23a93ba4f740a11563c2246fee796be rename to explorer/fuzzing/fuzzer_corpus/f69e3144cbc99fb1dc4d1c8f7a1547679ffeb93a index aea9304cdfd9..358f64583ed6 100644 --- a/explorer/fuzzing/fuzzer_corpus/9e19f13bb23a93ba4f740a11563c2246fee796be +++ b/explorer/fuzzing/fuzzer_corpus/f69e3144cbc99fb1dc4d1c8f7a1547679ffeb93a @@ -167,7 +167,7 @@ compilation_unit { } } clauses { - is { + impls { type { designator { name: "Self" @@ -476,3 +476,4 @@ compilation_unit { } } } + diff --git a/explorer/interpreter/impl_scope.cpp b/explorer/interpreter/impl_scope.cpp index bdf676f826e0..02df59ed0cd0 100644 --- a/explorer/interpreter/impl_scope.cpp +++ b/explorer/interpreter/impl_scope.cpp @@ -32,7 +32,7 @@ void ImplScope::Add(Nonnull iface, CARBON_CHECK(!sort_key) << "should only be given a sort key for an impl of an interface"; // The caller should have substituted `.Self` for `type` already. - Add(constraint->impl_constraints(), deduced, impl_bindings, witness, + Add(constraint->impls_constraints(), deduced, impl_bindings, witness, type_checker); // A parameterized impl declaration doesn't contribute any equality // constraints to the scope. Instead, we'll resolve the equality @@ -46,30 +46,32 @@ void ImplScope::Add(Nonnull iface, return; } - Impl new_impl = {.interface = cast(iface), - .deduced = deduced, - .type = type, - .impl_bindings = impl_bindings, - .witness = witness, - .sort_key = std::move(sort_key)}; + ImplFact new_impl = {.interface = cast(iface), + .deduced = deduced, + .type = type, + .impl_bindings = impl_bindings, + .witness = witness, + .sort_key = std::move(sort_key)}; // Find the first impl that's more specific than this one, and place this // impl right before it. This keeps the impls with the same type structure // sorted in lexical order, which is important for `match_first` semantics. - auto insert_pos = std::upper_bound( - impls_.begin(), impls_.end(), new_impl, - [](const Impl& a, const Impl& b) { return a.sort_key < b.sort_key; }); + auto insert_pos = + std::upper_bound(impl_facts_.begin(), impl_facts_.end(), new_impl, + [](const ImplFact& a, const ImplFact& b) { + return a.sort_key < b.sort_key; + }); - impls_.insert(insert_pos, std::move(new_impl)); + impl_facts_.insert(insert_pos, std::move(new_impl)); } -void ImplScope::Add(llvm::ArrayRef impls, +void ImplScope::Add(llvm::ArrayRef impls_constraints, llvm::ArrayRef> deduced, llvm::ArrayRef> impl_bindings, Nonnull witness, const TypeChecker& type_checker) { - for (size_t i = 0; i != impls.size(); ++i) { - ImplConstraint impl = impls[i]; + for (size_t i = 0; i != impls_constraints.size(); ++i) { + ImplsConstraint impl = impls_constraints[i]; Add(impl.interface, deduced, impl.type, impl_bindings, type_checker.MakeConstraintWitnessAccess(witness, i), type_checker); } @@ -129,18 +131,18 @@ auto ImplScope::TryResolve(Nonnull constraint_type, } if (const auto* constraint = dyn_cast(constraint_type)) { std::vector> witnesses; - for (auto impl : constraint->impl_constraints()) { - // Note that later impl constraints can refer to earlier impl constraints - // via impl bindings. For example, in - // `C where .Self.AssocType is D`, - // ... the `.Self.AssocType is D` constraint refers to the `.Self is C` - // constraint when naming `AssocType`. So incrementally build up a - // partial constraint witness as we go. + for (auto impl : constraint->impls_constraints()) { + // Note that later impls constraints can refer to earlier impls + // constraints via impl bindings. For example, in + // `C where .Self.AssocType impls D`, + // ... the `.Self.AssocType impls D` constraint refers to the + // `.Self impls C` constraint when naming `AssocType`. So incrementally + // build up a partial constraint witness as we go. std::optional> witness; if (constraint->self_binding()->impl_binding()) { // Note, this is a partial impl binding covering only the impl - // constraints that we've already seen. Earlier impl constraints should - // not be able to refer to impl bindings for later impl constraints. + // constraints that we've already seen. Earlier impls constraints should + // not be able to refer to impl bindings for later impls constraints. witness = type_checker.MakeConstraintWitness(witnesses); } Bindings local_bindings = bindings; @@ -382,9 +384,9 @@ auto ImplScope::TryResolveInterfaceHere( const TypeChecker& type_checker) const -> ErrorOr> { std::optional result = std::nullopt; - for (const Impl& impl : impls_) { + for (const ImplFact& impl : impl_facts_) { // If we've passed the final impl with a sort key matching our best impl, - // all further impls are worse and don't need to be checked. + // all further are worse and don't need to be checked. if (result && result->impl->sort_key < impl.sort_key) { break; } @@ -417,9 +419,9 @@ auto ImplScope::TryResolveInterfaceHere( // TODO: Add indentation when printing the parents. void ImplScope::Print(llvm::raw_ostream& out) const { - out << "impls: "; + out << "impl declarations: "; llvm::ListSeparator sep; - for (const Impl& impl : impls_) { + for (const ImplFact& impl : impl_facts_) { out << sep << *(impl.type) << " as " << *(impl.interface); if (impl.sort_key) { out << " " << *impl.sort_key; diff --git a/explorer/interpreter/impl_scope.h b/explorer/interpreter/impl_scope.h index 19c13533f900..1f9ed8650f1a 100644 --- a/explorer/interpreter/impl_scope.h +++ b/explorer/interpreter/impl_scope.h @@ -16,15 +16,15 @@ class TypeChecker; // The `ImplScope` class is responsible for mapping a type and // interface to the location of the witness table for the `impl` for // that type and interface. A scope may have parent scopes, whose -// impls will also be visible in the child scope. +// implementations will also be visible in the child scope. // // There is typically one instance of `ImplScope` class per scope -// because the impls that are visible for a given type and interface -// can vary from scope to scope. For example, consider the `bar` and -// `baz` methods in the following class C and nested class D. +// because the implementationss that are visible for a given type and +// interface can vary from scope to scope. For example, consider the +// `bar` and `baz` methods in the following class C and nested class D. // // class C(U:! type, T:! type) { -// class D(V:! type where U is Fooable(T)) { +// class D(V:! type where U impls Fooable(T)) { // fn bar[self: Self](x: U, y : T) -> T{ // return x.foo(y) // } @@ -43,7 +43,7 @@ class TypeChecker; // scope. class ImplScope { public: - // The `Impl` struct is a key-value pair where the key is the + // The `ImplFact` struct is a key-value pair where the key is the // combination of a type and an interface, e.g., `List` and `Container`, // and the value is the result of statically resolving to the `impl` // for `List` as `Container`, which is an `Expression` that produces @@ -54,7 +54,7 @@ class ImplScope { // later are impl bindings, that is, parameters for witnesses. In this case, // `sort_key` indicates the order in which this impl should be considered // relative to other matching impls. - struct Impl { + struct ImplFact { Nonnull interface; std::vector> deduced; Nonnull type; @@ -66,7 +66,7 @@ class ImplScope { // Internal type used to represent the result of resolving a lookup in a // particular impl scope. struct ResolveResult { - Nonnull impl; + Nonnull impl; Nonnull witness; }; @@ -89,10 +89,10 @@ class ImplScope { llvm::ArrayRef> impl_bindings, Nonnull witness, const TypeChecker& type_checker, std::optional sort_key = std::nullopt); - // Adds a list of impl constraints from a constraint type into scope. Any + // Adds a list of impls 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_constraints, llvm::ArrayRef> deduced, llvm::ArrayRef> impl_bindings, Nonnull witness, const TypeChecker& type_checker); @@ -176,7 +176,7 @@ class ImplScope { const TypeChecker& type_checker) const -> ErrorOr>; - std::vector impls_; + std::vector impl_facts_; std::vector> equalities_; std::optional> parent_scope_; }; diff --git a/explorer/interpreter/interpreter.cpp b/explorer/interpreter/interpreter.cpp index e697ef8204f2..45575c799626 100644 --- a/explorer/interpreter/interpreter.cpp +++ b/explorer/interpreter/interpreter.cpp @@ -1355,7 +1355,7 @@ auto Interpreter::StepExp() -> ErrorOr { } case ExpressionKind::CallExpression: { const auto& call = cast(exp); - unsigned int num_impls = call.impls().size(); + unsigned int num_witnesses = call.witnesses().size(); if (act.pos() == 0) { // { {e1(e2) :: C, E, F} :: S, H} // -> { {e1 :: [](e2) :: C, E, F} :: S, H} @@ -1366,31 +1366,32 @@ auto Interpreter::StepExp() -> ErrorOr { // -> { { e :: v([]) :: C, E, F} :: S, H} return todo_.Spawn( std::make_unique(&call.argument())); - } else if (num_impls > 0 && act.pos() < 2 + static_cast(num_impls)) { - auto iter = call.impls().begin(); + } else if (num_witnesses > 0 && + act.pos() < 2 + static_cast(num_witnesses)) { + auto iter = call.witnesses().begin(); std::advance(iter, act.pos() - 2); return todo_.Spawn( std::make_unique(cast(iter->second))); - } else if (act.pos() == 2 + static_cast(num_impls)) { + } else if (act.pos() == 2 + static_cast(num_witnesses)) { // { { v2 :: v1([]) :: C, E, F} :: S, H} // -> { {C',E',F'} :: {C, E, F} :: S, H} ImplWitnessMap witnesses; - if (num_impls > 0) { + if (num_witnesses > 0) { int i = 2; - for (const auto& [impl_bind, impl_exp] : call.impls()) { + for (const auto& [impl_bind, impl_exp] : call.witnesses()) { witnesses[impl_bind] = act.results()[i]; ++i; } } return CallFunction(call, act.results()[0], act.results()[1], std::move(witnesses)); - } else if (act.pos() == 3 + static_cast(num_impls)) { - if (act.results().size() < 3 + num_impls) { + } else if (act.pos() == 3 + static_cast(num_witnesses)) { + if (act.results().size() < 3 + num_witnesses) { // Control fell through without explicit return. return todo_.FinishAction(TupleValue::Empty()); } else { return todo_.FinishAction( - act.results()[2 + static_cast(num_impls)]); + act.results()[2 + static_cast(num_witnesses)]); } } else { CARBON_FATAL() << "in StepExp with Call pos " << act.pos(); @@ -1521,7 +1522,7 @@ auto Interpreter::StepExp() -> ErrorOr { .kind = IntrinsicConstraint::ImplicitAs, .arguments = args}; auto* result = arena_->New( - self_binding, std::vector{}, + self_binding, std::vector{}, std::vector{std::move(constraint)}, std::vector{}, std::vector{}, std::vector{}); diff --git a/explorer/interpreter/matching_impl_set.cpp b/explorer/interpreter/matching_impl_set.cpp index a84209600e8b..dbf00983b27f 100644 --- a/explorer/interpreter/matching_impl_set.cpp +++ b/explorer/interpreter/matching_impl_set.cpp @@ -105,7 +105,7 @@ auto MatchingImplSet::GetLabelForDeclaration(const Declaration& declaration) } MatchingImplSet::Match::Match(Nonnull parent, - Nonnull impl, + Nonnull impl, Nonnull type, Nonnull interface) : parent_(parent), impl_(impl), type_(type), interface_(interface) { diff --git a/explorer/interpreter/matching_impl_set.h b/explorer/interpreter/matching_impl_set.h index 9bb4ac970d3b..18e0399a9376 100644 --- a/explorer/interpreter/matching_impl_set.h +++ b/explorer/interpreter/matching_impl_set.h @@ -44,7 +44,7 @@ class MatchingImplSet { class Match { public: explicit Match(Nonnull parent, - Nonnull impl, + Nonnull impl, Nonnull type, Nonnull interface); ~Match(); @@ -63,7 +63,7 @@ class MatchingImplSet { // The set that this match is part of. Nonnull parent_; // The `impl` that is being matched against. - Nonnull impl_; + Nonnull impl_; // The type that is being matched against the impl. Nonnull type_; // The interface that is being matched against the impl. diff --git a/explorer/interpreter/resolve_control_flow.cpp b/explorer/interpreter/resolve_control_flow.cpp index 049aa6a08050..416b05e0320b 100644 --- a/explorer/interpreter/resolve_control_flow.cpp +++ b/explorer/interpreter/resolve_control_flow.cpp @@ -181,7 +181,7 @@ auto ResolveControlFlow(Nonnull declaration) -> ErrorOr { } case DeclarationKind::MatchFirstDeclaration: { auto& match_first_decl = cast(*declaration); - for (Nonnull impl : match_first_decl.impls()) { + for (Nonnull impl : match_first_decl.impl_declarations()) { CARBON_RETURN_IF_ERROR(ResolveControlFlow(impl)); } break; diff --git a/explorer/interpreter/resolve_names.cpp b/explorer/interpreter/resolve_names.cpp index 657f0ad56292..8b12c012192a 100644 --- a/explorer/interpreter/resolve_names.cpp +++ b/explorer/interpreter/resolve_names.cpp @@ -413,11 +413,12 @@ auto NameResolver::ResolveNames(WhereClause& clause, const StaticScope& enclosing_scope) -> ErrorOr { switch (clause.kind()) { - case WhereClauseKind::IsWhereClause: { - auto& is_clause = cast(clause); - CARBON_RETURN_IF_ERROR(ResolveNames(is_clause.type(), enclosing_scope)); + case WhereClauseKind::ImplsWhereClause: { + auto& impls_clause = cast(clause); CARBON_RETURN_IF_ERROR( - ResolveNames(is_clause.constraint(), enclosing_scope)); + ResolveNames(impls_clause.type(), enclosing_scope)); + CARBON_RETURN_IF_ERROR( + ResolveNames(impls_clause.constraint(), enclosing_scope)); break; } case WhereClauseKind::EqualsWhereClause: { @@ -697,7 +698,8 @@ auto NameResolver::ResolveNames(Declaration& declaration, } case DeclarationKind::MatchFirstDeclaration: { // A `match_first` declaration does not introduce a scope. - for (auto* impl : cast(declaration).impls()) { + for (auto* impl : + cast(declaration).impl_declarations()) { CARBON_RETURN_IF_ERROR(ResolveNames(*impl, enclosing_scope, bodies)); } break; diff --git a/explorer/interpreter/type_checker.cpp b/explorer/interpreter/type_checker.cpp index 09cd24e6545c..4b1da5a54487 100644 --- a/explorer/interpreter/type_checker.cpp +++ b/explorer/interpreter/type_checker.cpp @@ -526,7 +526,7 @@ auto TypeChecker::IsImplicitlyConvertible( const ImplScope& impl_scope, bool allow_user_defined_conversions) const -> ErrorOr { // Check for an exact match or for an implicit conversion. - // TODO: `impl`s of `ImplicitAs` should be provided to cover these + // TODO: `impl` definitions of `ImplicitAs` should be provided to cover these // conversions. CARBON_CHECK(IsConcreteType(source)); CARBON_CHECK(IsConcreteType(destination)); @@ -1515,18 +1515,18 @@ class TypeChecker::ConstraintTypeBuilder { return cast(*impl_binding_->symbolic_identity()); } - // Adds an `impl` constraint -- `T is C` if not already present. - // Returns the index of the impl constraint within the self witness. - auto AddImplConstraint(ImplConstraint impl) -> int { - for (int i = 0; i != static_cast(impl_constraints_.size()); ++i) { - ImplConstraint& existing = impl_constraints_[i]; - if (TypeEqual(existing.type, impl.type, std::nullopt) && - TypeEqual(existing.interface, impl.interface, std::nullopt)) { + // Adds an `impls` constraint -- `T impls C` if not already present. + // Returns the index of the impls constraint within the self witness. + auto AddImplsConstraint(ImplsConstraint impls) -> int { + for (int i = 0; i != static_cast(impls_constraints_.size()); ++i) { + ImplsConstraint& existing = impls_constraints_[i]; + if (TypeEqual(existing.type, impls.type, std::nullopt) && + TypeEqual(existing.interface, impls.interface, std::nullopt)) { return i; } } - impl_constraints_.push_back(impl); - return impl_constraints_.size() - 1; + impls_constraints_.push_back(impls); + return impls_constraints_.size() - 1; } // Adds an intrinsic constraint, if not already present. @@ -1585,17 +1585,17 @@ class TypeChecker::ConstraintTypeBuilder { // First substitute into the impl bindings to form the full witness for // the constraint type. std::vector> witnesses; - for (const auto& impl_constraint : constraint->impl_constraints()) { + for (const auto& impls_constraint : constraint->impls_constraints()) { Bindings local_bindings = bindings; local_bindings.Add(constraint->self_binding(), self, type_checker.MakeConstraintWitness(witnesses)); CARBON_ASSIGN_OR_RETURN( Nonnull type, - type_checker.Substitute(local_bindings, impl_constraint.type)); + type_checker.Substitute(local_bindings, impls_constraint.type)); CARBON_ASSIGN_OR_RETURN(const auto* interface, type_checker.SubstituteCast( - local_bindings, impl_constraint.interface)); - int index = AddImplConstraint({.type = type, .interface = interface}); + local_bindings, impls_constraint.interface)); + int index = AddImplsConstraint({.type = type, .interface = interface}); witnesses.push_back( type_checker.MakeConstraintWitnessAccess(self_witness, index)); } @@ -1622,8 +1622,8 @@ class TypeChecker::ConstraintTypeBuilder { rewrite_constraint.converted_replacement)); // Form a symbolic value naming the non-rewritten associated constant. - // The impl constraint will always already exist. - int index = AddImplConstraint({.type = self, .interface = interface}); + // The impls constraint will always already exist. + int index = AddImplsConstraint({.type = self, .interface = interface}); const auto* witness = type_checker.MakeConstraintWitnessAccess(self_witness, index); const auto* constant_value = arena_->New( @@ -1700,31 +1700,31 @@ class TypeChecker::ConstraintTypeBuilder { friend class ConstraintTypeBuilder; private: - int num_impls_added = 0; - int num_equals_added = 0; + int num_impls_constraints_added = 0; + int num_equality_constraints_added = 0; }; - // Brings all the constraints accumulated so far into the given impl scope, - // as if we built the constraint type and then added it into the scope. If - // this will be called more than once, an ImplsInScopeTracker can be provided - // to avoid adding the same impls more than once. + // Brings all the constraints accumulated so far into the given impl scope, as + // if we built the constraint type and then added it into the scope. If this + // will be called more than once, an ConstraintssInScopeTracker can be + // provided to avoid adding the same implementations more than once. void BringConstraintsIntoScope(const TypeChecker& type_checker, Nonnull impl_scope, Nonnull tracker) { // Figure out which constraints we're going to add. - int first_impl_to_add = - std::exchange(tracker->num_impls_added, impl_constraints_.size()); - int first_equal_to_add = - std::exchange(tracker->num_equals_added, equality_constraints_.size()); - auto new_impl_constraints = - llvm::ArrayRef(impl_constraints_) - .drop_front(first_impl_to_add); + int first_impls_constraint_to_add = std::exchange( + tracker->num_impls_constraints_added, impls_constraints_.size()); + int first_equality_constraint_to_add = std::exchange( + tracker->num_equality_constraints_added, equality_constraints_.size()); + auto new_impls_constraints = + llvm::ArrayRef(impls_constraints_) + .drop_front(first_impls_constraint_to_add); auto new_equality_constraints = llvm::ArrayRef(equality_constraints_) - .drop_front(first_equal_to_add); + .drop_front(first_equality_constraint_to_add); // Add all of the new constraints. - impl_scope->Add(new_impl_constraints, std::nullopt, std::nullopt, + impl_scope->Add(new_impls_constraints, std::nullopt, std::nullopt, GetSelfWitness(), type_checker); for (const auto& equal : new_equality_constraints) { impl_scope->AddEqualityConstraint(arena_->New(equal)); @@ -1751,7 +1751,7 @@ class TypeChecker::ConstraintTypeBuilder { auto Build() && -> Nonnull { // Create the new type. auto* result = arena_->New( - self_binding_, std::move(impl_constraints_), + self_binding_, std::move(impls_constraints_), std::move(intrinsic_constraints_), std::move(equality_constraints_), std::move(rewrite_constraints_), std::move(lookup_contexts_)); // Update the impl binding to denote the constraint type itself. @@ -1912,14 +1912,14 @@ class TypeChecker::ConstraintTypeBuilder { type_checker.RebuildValue(rewrite.unconverted_replacement_type)); } - // Apply rewrites throughout impl constraints. - for (auto& impl_constraint : impl_constraints_) { - CARBON_ASSIGN_OR_RETURN(impl_constraint.type, - type_checker.RebuildValue(impl_constraint.type)); + // Apply rewrites throughout impls constraints. + for (auto& impls_constraint : impls_constraints_) { + CARBON_ASSIGN_OR_RETURN(impls_constraint.type, + type_checker.RebuildValue(impls_constraint.type)); CARBON_ASSIGN_OR_RETURN( const auto* subst_interface, - type_checker.RebuildValue(impl_constraint.interface)); - impl_constraint.interface = cast(subst_interface); + type_checker.RebuildValue(impls_constraint.interface)); + impls_constraint.interface = cast(subst_interface); } // Apply rewrites throughout intrinsic constraints. @@ -1952,7 +1952,7 @@ class TypeChecker::ConstraintTypeBuilder { Nonnull arena_; Nonnull self_binding_; Nonnull impl_binding_; - std::vector impl_constraints_; + std::vector impls_constraints_; std::vector intrinsic_constraints_; std::vector equality_constraints_; std::vector rewrite_constraints_; @@ -2274,7 +2274,7 @@ auto TypeChecker::RefineWitness(Nonnull witness, auto TypeChecker::MatchImpl(const InterfaceType& iface, Nonnull impl_type, - const ImplScope::Impl& impl, + const ImplScope::ImplFact& impl, const ImplScope& impl_scope, SourceLocation source_loc) const -> ErrorOr>> { @@ -2343,9 +2343,9 @@ auto TypeChecker::MatchImpl(const InterfaceType& iface, } auto TypeChecker::MakeConstraintWitness( - std::vector> impl_constraint_witnesses) const + std::vector> impls_constraint_witnesses) const -> Nonnull { - return arena_->New(std::move(impl_constraint_witnesses)); + return arena_->New(std::move(impls_constraint_witnesses)); } auto TypeChecker::MakeConstraintWitnessAccess(Nonnull witness, @@ -3866,20 +3866,22 @@ auto TypeChecker::TypeCheckExp(Nonnull e, CARBON_RETURN_IF_ERROR(TypeCheckWhereClause(clause, inner_impl_scope)); switch (clause->kind()) { - case WhereClauseKind::IsWhereClause: { - auto& is_clause = cast(*clause); + case WhereClauseKind::ImplsWhereClause: { + auto& impls_clause = cast(*clause); CARBON_ASSIGN_OR_RETURN( Nonnull type, - TypeCheckTypeExp(&is_clause.type(), inner_impl_scope)); + TypeCheckTypeExp(&impls_clause.type(), inner_impl_scope)); CARBON_ASSIGN_OR_RETURN( Nonnull constraint, - InterpExp(&is_clause.constraint(), arena_, trace_stream_)); + InterpExp(&impls_clause.constraint(), arena_, trace_stream_)); CARBON_ASSIGN_OR_RETURN( Nonnull constraint_type, - ConvertToConstraintType(is_clause.source_loc(), - "expression after `is`", constraint)); - // Transform `where .B is (C where .D is E)` into `where .B is C - // and .B.D is E` then add all the resulting constraints. + ConvertToConstraintType(impls_clause.source_loc(), + "expression after `impls`", + constraint)); + // Transform `where .B impls (C where .D impls E)` into + // `where .B impls C and .B.D impls E` then add all the resulting + // constraints. CARBON_RETURN_IF_ERROR( builder.AddAndSubstitute(*this, constraint_type, type, builder.GetSelfWitness(), Bindings(), @@ -3915,10 +3917,10 @@ auto TypeChecker::TypeCheckExp(Nonnull e, << "` does not name an associated constant"; } - // Find (or add) `.Self is I`, and form a symbolic value naming the - // associated constant. - // TODO: Reject if the impl constraint didn't already exist. - int index = builder.AddImplConstraint( + // Find (or add) `.Self impls I`, and form a symbolic value naming + // the associated constant. + // TODO: Reject if the impls constraint didn't already exist. + int index = builder.AddImplsConstraint( {.type = builder.GetSelfType(), .interface = result.interface}); const auto* witness = MakeConstraintWitnessAccess(builder.GetSelfWitness(), index); @@ -4023,23 +4025,23 @@ void TypeChecker::CollectImplBindingsInPattern( }); } -void TypeChecker::BringPatternImplsIntoScope(Nonnull p, - ImplScope& impl_scope) { +void TypeChecker::BringPatternImplBindingsIntoScope(Nonnull p, + ImplScope& impl_scope) { std::vector> impl_bindings; CollectImplBindingsInPattern(p, impl_bindings); - BringImplsIntoScope(impl_bindings, impl_scope); + BringImplBindingsIntoScope(impl_bindings, impl_scope); } -void TypeChecker::BringImplsIntoScope( +void TypeChecker::BringImplBindingsIntoScope( llvm::ArrayRef> impl_bindings, ImplScope& impl_scope) { for (Nonnull impl_binding : impl_bindings) { - BringImplIntoScope(impl_binding, impl_scope); + BringImplBindingIntoScope(impl_binding, impl_scope); } } -void TypeChecker::BringImplIntoScope(Nonnull impl_binding, - ImplScope& impl_scope) { +void TypeChecker::BringImplBindingIntoScope( + Nonnull impl_binding, ImplScope& impl_scope) { CARBON_CHECK(impl_binding->type_var()->symbolic_identity().has_value() && impl_binding->symbolic_identity().has_value()); impl_scope.Add(impl_binding->interface(), @@ -4076,15 +4078,16 @@ auto TypeChecker::TypeCheckWhereClause(Nonnull clause, const ImplScope& impl_scope) -> ErrorOr { switch (clause->kind()) { - case WhereClauseKind::IsWhereClause: { - auto& is_clause = cast(*clause); + case WhereClauseKind::ImplsWhereClause: { + auto& impls_clause = cast(*clause); // TODO: `type` is checked in the caller, because its converted value is // needed. Find a way to move that checking back here. - CARBON_RETURN_IF_ERROR(TypeCheckExp(&is_clause.constraint(), impl_scope)); - if (!isa(is_clause.constraint().static_type())) { - return ProgramError(is_clause.constraint().source_loc()) - << "expression after `is` does not resolve to a constraint, " - << "found " << is_clause.constraint().static_type(); + CARBON_RETURN_IF_ERROR( + TypeCheckExp(&impls_clause.constraint(), impl_scope)); + if (!isa(impls_clause.constraint().static_type())) { + return ProgramError(impls_clause.constraint().source_loc()) + << "expression after `impls` does not resolve to a constraint, " + << "found " << impls_clause.constraint().static_type(); } return Success(); } @@ -4355,8 +4358,8 @@ auto TypeChecker::TypeCheckGenericBinding(GenericBinding& binding, binding.set_impl_binding(impl_binding); // Substitute the VariableType as `.Self` of the constraint to form the - // resolved type of the binding. Eg, `T:! X where .Self is Y` resolves - // to `T:! `. + // resolved type of the binding. Eg, `T:! X where .Self impls Y` resolves + // to `T:! `. ConstraintTypeBuilder builder(arena_, &binding, impl_binding); CARBON_RETURN_IF_ERROR( builder.AddAndSubstitute(*this, constraint, symbolic_value, witness, @@ -4372,7 +4375,7 @@ auto TypeChecker::TypeCheckGenericBinding(GenericBinding& binding, *trace_stream_ << "resolved constraint type is " << *type << "\n"; } - BringImplIntoScope(impl_binding, impl_scope); + BringImplBindingIntoScope(impl_binding, impl_scope); } binding.set_static_type(type); @@ -4873,10 +4876,10 @@ auto TypeChecker::TypeCheckCallableDeclaration(Nonnull f, // If f->return_term().is_auto(), the function body was already // type checked in DeclareFunctionDeclaration. if (f->body().has_value() && !f->return_term().is_auto()) { - // Bring the impls into scope. + // Bring the impl bindings into scope. ImplScope function_scope(&impl_scope); - BringImplsIntoScope(cast(f->static_type()).impl_bindings(), - function_scope); + BringImplBindingsIntoScope( + cast(f->static_type()).impl_bindings(), function_scope); if (trace_stream_->is_enabled()) { *trace_stream_ << function_scope; } @@ -5069,7 +5072,7 @@ auto TypeChecker::TypeCheckClassDeclaration( } ImplScope class_scope(&impl_scope); if (class_decl->type_params().has_value()) { - BringPatternImplsIntoScope(*class_decl->type_params(), class_scope); + BringPatternImplBindingsIntoScope(*class_decl->type_params(), class_scope); } if (trace_stream_->is_enabled()) { *trace_stream_ << class_scope; @@ -5157,7 +5160,7 @@ auto TypeChecker::TypeCheckMixinDeclaration( } ImplScope mixin_scope(&impl_scope); if (mixin_decl->params().has_value()) { - BringPatternImplsIntoScope(*mixin_decl->params(), mixin_scope); + BringPatternImplBindingsIntoScope(*mixin_decl->params(), mixin_scope); } if (trace_stream_->is_enabled()) { *trace_stream_ << mixin_scope; @@ -5282,12 +5285,12 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( // this interface. std::optional> iface_impl_witness; if (is_interface) { - // The impl constraint says only that the direct members of the interface + // The impls constraint says only that the direct members of the interface // are available. For any indirect constraints, we need to add separate // entries to the constraint type. This ensures that all indirect // constraints are lifted to the top level so they can be accessed directly // and resolved independently if necessary. - int index = builder.AddImplConstraint( + int index = builder.AddImplsConstraint( {.type = builder.GetSelfType(), .interface = cast(constraint_type)}); iface_impl_witness = @@ -5303,7 +5306,8 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( // to update state that's not available from there. switch (m->kind()) { case DeclarationKind::InterfaceExtendsDeclaration: { - // For an `extends C;` declaration, add `Self is C` to our constraint. + // For an `extends C;` declaration, add `Self impls C` to our + // constraint. auto* extends = cast(m); CARBON_ASSIGN_OR_RETURN( Nonnull base, @@ -5320,7 +5324,7 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( } case DeclarationKind::InterfaceImplDeclaration: { - // For an `impl X as Y;` declaration, add `X is Y` to our constraint. + // For an `impl X as Y;` declaration, add `X impls Y` to our constraint. auto* impl = cast(m); CARBON_ASSIGN_OR_RETURN( Nonnull impl_type, @@ -5364,8 +5368,8 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( // The type specified for the associated constant becomes a // constraint for the constraint type: `let X:! Interface` adds a - // `Self.X is Interface` constraint that `impl`s must satisfy and users - // of the constraint type can rely on. + // `Self.X impls Interface` constraint that `impl` declarations must + // satisfy and users of the constraint type can rely on. if (const auto* constraint_type = dyn_cast(constraint)) { CARBON_RETURN_IF_ERROR( @@ -5393,7 +5397,7 @@ auto TypeChecker::DeclareConstraintTypeDeclaration( } } - // Add any new impl constraints to the scope. + // Add any new impls constraints to the scope. builder.BringConstraintsIntoScope(*this, &constraint_scope, &constraint_tracker); } @@ -5418,7 +5422,8 @@ auto TypeChecker::TypeCheckConstraintTypeDeclaration( } ImplScope constraint_scope(&impl_scope); if (constraint_decl->params().has_value()) { - BringPatternImplsIntoScope(*constraint_decl->params(), constraint_scope); + BringPatternImplBindingsIntoScope(*constraint_decl->params(), + constraint_scope); } if (trace_stream_->is_enabled()) { *trace_stream_ << constraint_scope; @@ -5506,7 +5511,7 @@ auto TypeChecker::CheckAndAddImplBindings( const ScopeInfo& scope_info) -> ErrorOr { // Each interface that is a lookup context is required to be implemented by // the impl members. Other constraints are required to be satisfied by - // either those impls or impls available elsewhere. + // either those implementations or implementations available elsewhere. Nonnull constraint = impl_decl->constraint_type(); for (auto lookup : constraint->lookup_contexts()) { if (const auto* iface_type = dyn_cast(lookup.context)) { @@ -5648,15 +5653,15 @@ auto TypeChecker::DeclareImplDeclaration(Nonnull impl_decl, builder.GetSelfWitness(), Bindings(), /*add_lookup_contexts=*/true)); if (trace_stream_->is_enabled()) { - *trace_stream_ << "resolving impl constraint type for " << *impl_decl + *trace_stream_ << "resolving impls constraint type for " << *impl_decl << " from " << *implemented_constraint << "\n"; } CARBON_RETURN_IF_ERROR(builder.Resolve( *this, impl_decl->interface().source_loc(), impl_scope)); constraint_type = std::move(builder).Build(); if (trace_stream_->is_enabled()) { - *trace_stream_ << "resolving impl constraint type as " << *constraint_type - << "\n"; + *trace_stream_ << "resolving impls constraint type as " + << *constraint_type << "\n"; } impl_decl->set_constraint_type(constraint_type); } @@ -5764,9 +5769,9 @@ auto TypeChecker::TypeCheckImplDeclaration(Nonnull impl_decl, Nonnull self = *impl_decl->self()->constant_value(); Nonnull constraint = impl_decl->constraint_type(); - // Bring the impls from the parameters into scope. + // Bring the impl bindings from the parameters into scope. ImplScope impl_scope(&enclosing_scope); - BringImplsIntoScope(impl_decl->impl_bindings(), impl_scope); + BringImplBindingsIntoScope(impl_decl->impl_bindings(), impl_scope); for (Nonnull m : impl_decl->members()) { CARBON_ASSIGN_OR_RETURN( ConstraintLookupResult result, @@ -5966,7 +5971,7 @@ auto TypeChecker::TypeCheckDeclaration( } case DeclarationKind::MatchFirstDeclaration: { auto* match_first = cast(d); - for (auto* impl : match_first->impls()) { + for (auto* impl : match_first->impl_declarations()) { impl->set_match_first(match_first); CARBON_RETURN_IF_ERROR(TypeCheckImplDeclaration(impl, impl_scope)); } @@ -6057,7 +6062,7 @@ auto TypeChecker::DeclareDeclaration(Nonnull d, break; } case DeclarationKind::MatchFirstDeclaration: { - for (auto* impl : cast(d)->impls()) { + for (auto* impl : cast(d)->impl_declarations()) { CARBON_RETURN_IF_ERROR(DeclareImplDeclaration( impl, scope_info, /*is_template_instantiation=*/false)); } diff --git a/explorer/interpreter/type_checker.h b/explorer/interpreter/type_checker.h index 25dc41bfc714..88ac6a418931 100644 --- a/explorer/interpreter/type_checker.h +++ b/explorer/interpreter/type_checker.h @@ -78,7 +78,7 @@ class TypeChecker { // `type`, then return the witness for this `impl`. Otherwise return // std::nullopt. auto MatchImpl(const InterfaceType& iface, Nonnull type, - const ImplScope::Impl& impl, const ImplScope& impl_scope, + const ImplScope::ImplFact& impl, const ImplScope& impl_scope, SourceLocation source_loc) const -> ErrorOr>>; @@ -105,7 +105,7 @@ class TypeChecker { // Given the witnesses for the components of a constraint, form a witness for // the constraint. auto MakeConstraintWitness( - std::vector> impl_constraint_witnesses) const + std::vector> impls_constraint_witnesses) const -> Nonnull; // Given the witnesses for the components of a constraint, form a witness for @@ -143,11 +143,11 @@ class TypeChecker { .bindings = std::move(class_bindings)}; } - // The innermost enclosing impl scope, within which impls should be looked - // up. + // The innermost enclosing impl scope, within which impl declarations should + // be looked up. Nonnull innermost_scope; // The innermost enclosing non-class impl scope, where impl declarations - // should introduce new impls. + // should introduce new implementations. Nonnull innermost_non_class_scope; // The enclosing generic bindings, if any. std::vector> bindings; @@ -192,7 +192,7 @@ class TypeChecker { // surrounding context gives us that information. Otherwise, it is nullopt. // Implicit conversions from `expected` to the pattern's type are permitted. // - // `impl_scope` is extended with all impls implied by the pattern. + // `impl_scope` is extended with all implementations implied by the pattern. auto TypeCheckPattern(Nonnull p, std::optional> expected, ImplScope& impl_scope, @@ -214,7 +214,7 @@ class TypeChecker { -> ErrorOr; // Perform deduction for the deduced bindings in a function call, and set its - // lists of generic bindings and impls. + // lists of generic bindings and implementations. // // - `params` is the list of parameters. // - `generic_params` indicates which parameters are generic parameters, @@ -302,20 +302,20 @@ class TypeChecker { Nonnull p, std::vector>& impl_bindings); - // Add the impls from the pattern into the given `impl_scope`. - void BringPatternImplsIntoScope(Nonnull p, - ImplScope& impl_scope); + // Add the impl bindings from the pattern into the given `impl_scope`. + void BringPatternImplBindingsIntoScope(Nonnull p, + ImplScope& impl_scope); // Create a witness for the given `impl` binding. auto CreateImplBindingWitness(Nonnull impl_binding) -> Nonnull; // Add the given ImplBinding to the given `impl_scope`. - void BringImplIntoScope(Nonnull impl_binding, - ImplScope& impl_scope); + void BringImplBindingIntoScope(Nonnull impl_binding, + ImplScope& impl_scope); // Add all of the `impl_bindings` into the `scope`. - void BringImplsIntoScope( + void BringImplBindingsIntoScope( llvm::ArrayRef> impl_bindings, ImplScope& scope); @@ -436,8 +436,8 @@ class TypeChecker { const ImplScope& impl_scope) const -> ErrorOr; // Rebuild a value in the current type-checking context. Applies any rewrites - // that are in scope and attempts to resolve associated constants using impls - // that have been declared since the value was formed. + // that are in scope and attempts to resolve associated constants using + // implementations that have been declared since the value was formed. auto RebuildValue(Nonnull value) const -> ErrorOr>; @@ -544,7 +544,7 @@ class TypeChecker { // rewrites that are not yet visible in any type. std::vector partial_constraint_types_; - // A set of impls we're currently matching. + // A set of implementations we're currently matching. // TODO: This is `mutable` because `MatchImpl` is `const`. We need to remove // the `const`s from everywhere that transitively does `impl` matching to get // rid of this `mutable`. diff --git a/explorer/interpreter/type_structure.cpp b/explorer/interpreter/type_structure.cpp index 84e7046d0436..a36ac3ef93fe 100644 --- a/explorer/interpreter/type_structure.cpp +++ b/explorer/interpreter/type_structure.cpp @@ -86,7 +86,7 @@ struct TypeStructureBuilder { // Constraint types can contain mentions of VariableTypes, but they aren't // deducible so it's not important to look for them. - void Visit(const ImplConstraint&) {} + void Visit(const ImplsConstraint&) {} void Visit(const IntrinsicConstraint&) {} void Visit(const EqualityConstraint&) {} void Visit(const RewriteConstraint&) {} diff --git a/explorer/syntax/lexer.lpp b/explorer/syntax/lexer.lpp index c5e8fb1cbbb4..9847722b9e7b 100644 --- a/explorer/syntax/lexer.lpp +++ b/explorer/syntax/lexer.lpp @@ -76,10 +76,10 @@ GREATER_GREATER ">>" GREATER_GREATER_EQUAL ">>=" IF "if" IMPL "impl" +IMPLS "impls" IMPORT "import" IN "in" INTERFACE "interface" -IS "is" LEFT_CURLY_BRACE "{" LEFT_PARENTHESIS "(" LEFT_SQUARE_BRACKET "[" @@ -198,11 +198,11 @@ operand_start [(A-Za-z0-9_\"] {GREATER_GREATER} { return CARBON_SIMPLE_TOKEN(GREATER_GREATER); } {GREATER} { return CARBON_SIMPLE_TOKEN(GREATER); } {IF} { return CARBON_SIMPLE_TOKEN(IF); } +{IMPLS} { return CARBON_SIMPLE_TOKEN(IMPLS); } {IMPL} { return CARBON_SIMPLE_TOKEN(IMPL); } {IMPORT} { return CARBON_SIMPLE_TOKEN(IMPORT); } {INTERFACE} { return CARBON_SIMPLE_TOKEN(INTERFACE); } {IN} { return CARBON_SIMPLE_TOKEN(IN); } -{IS} { return CARBON_SIMPLE_TOKEN(IS); } {LEFT_CURLY_BRACE} { return CARBON_SIMPLE_TOKEN(LEFT_CURLY_BRACE); } {LEFT_PARENTHESIS} { return CARBON_SIMPLE_TOKEN(LEFT_PARENTHESIS); } {LEFT_SQUARE_BRACKET} { return CARBON_SIMPLE_TOKEN(LEFT_SQUARE_BRACKET); } diff --git a/explorer/syntax/parser.ypp b/explorer/syntax/parser.ypp index 3c5963719b4d..61e803db7536 100644 --- a/explorer/syntax/parser.ypp +++ b/explorer/syntax/parser.ypp @@ -252,10 +252,10 @@ GREATER_GREATER_EQUAL IF IMPL + IMPLS IMPORT IN INTERFACE - IS LEFT_CURLY_BRACE LEFT_PARENTHESIS LEFT_SQUARE_BRACKET @@ -721,8 +721,8 @@ or_expression: } ; where_clause: - comparison_operand IS comparison_operand - { $$ = arena->New(context.source_loc(), $1, $3); } + comparison_operand IMPLS comparison_operand + { $$ = arena->New(context.source_loc(), $1, $3); } | comparison_operand EQUAL_EQUAL comparison_operand { $$ = arena->New(context.source_loc(), $1, $3); } // TODO: .(expression) = expression diff --git a/explorer/testdata/assoc_const/impl_used_by_later_rewrite.carbon b/explorer/testdata/assoc_const/impl_used_by_later_rewrite.carbon index 78ea7829b21a..2940e461ef48 100644 --- a/explorer/testdata/assoc_const/impl_used_by_later_rewrite.carbon +++ b/explorer/testdata/assoc_const/impl_used_by_later_rewrite.carbon @@ -16,9 +16,9 @@ interface Y(T:! type) { } interface Z { - // The `i32 is X(.Self)` constraint is indirectly required by + // The `i32 impls X(.Self)` constraint is indirectly required by // specifying that `.M = i32`. - let N:! Y(.Self) where i32 is X(.Self) and .M = i32; + let N:! Y(.Self) where i32 impls X(.Self) and .M = i32; } impl i32 as X(i32) {} diff --git a/explorer/testdata/assoc_const/rewrite_interface_params.carbon b/explorer/testdata/assoc_const/rewrite_interface_params.carbon index 9c8421dcf96f..93ed6d579809 100644 --- a/explorer/testdata/assoc_const/rewrite_interface_params.carbon +++ b/explorer/testdata/assoc_const/rewrite_interface_params.carbon @@ -25,11 +25,11 @@ interface HasParams(A:! type, B:! type, C:! type, D:! type) { // Here we discover that there is a rewrite for `HasParams(...).V` only after // substitution converts each one to `HasParam(X, X, X, X).V`. fn F[X:! (HasTypes & HasParams(.Self, .Self, .Self, .Self)) where - .Self is HasParams(.A, .A, .A, .A) and - .Self is HasParams(.B, .B, .B, .B) and - .Self is HasParams(.C, .C, .C, .C) and - .Self is HasParams(.D, .D, .D, .D) and - .Self is HasParams(.E, .E, .E, .E) and + .Self impls HasParams(.A, .A, .A, .A) and + .Self impls HasParams(.B, .B, .B, .B) and + .Self impls HasParams(.C, .C, .C, .C) and + .Self impls HasParams(.D, .D, .D, .D) and + .Self impls HasParams(.E, .E, .E, .E) and .F = .Self.(HasParams(.E, .E, .E, .E).V).A and .E = .Self.(HasParams(.D, .D, .D, .D).V).A and .D = .Self.(HasParams(.C, .C, .C, .C).V).A and diff --git a/explorer/testdata/constraint/dot_self_is_other.carbon b/explorer/testdata/constraint/dot_self_is_other.carbon index 0ec8729a9ca2..dfd2f63dca49 100644 --- a/explorer/testdata/constraint/dot_self_is_other.carbon +++ b/explorer/testdata/constraint/dot_self_is_other.carbon @@ -16,7 +16,7 @@ impl i32 as A { fn F() -> i32 { return 1; } } impl i32 as B { fn F() -> i32 { return 2; } } fn GetA[T:! A](x: T) -> i32 { return x.F(); } -fn GetAB[T:! B where .Self is A](x: T) -> i32 { +fn GetAB[T:! B where .Self impls A](x: T) -> i32 { // Note that there's no ambiguity in the use of the name F here. // `x.F` is `x.(B.F)` because the constraint only treats `B`, not // `A`, as a lookup context. diff --git a/explorer/testdata/constraint/fail_combine_equality.carbon b/explorer/testdata/constraint/fail_combine_equality.carbon index 20bfc09b9018..54ebac0007d3 100644 --- a/explorer/testdata/constraint/fail_combine_equality.carbon +++ b/explorer/testdata/constraint/fail_combine_equality.carbon @@ -13,7 +13,7 @@ impl i32 as I {} fn F(A:! i32, B:! i32, C:! i32, D:! i32, E:! i32, T:! I where A == B and C == D and C == E and B == D) { - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_combine_equality.carbon:[[@LINE+1]]: member access, F not in interface I where T is interface I and A == B and C == D and C == E and B == D + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_combine_equality.carbon:[[@LINE+1]]: member access, F not in interface I where T impls interface I and A == B and C == D and C == E and B == D T.F(); } diff --git a/explorer/testdata/constraint/fail_missing_member.carbon b/explorer/testdata/constraint/fail_missing_member.carbon index a641a9671d19..f6d52fac05ed 100644 --- a/explorer/testdata/constraint/fail_missing_member.carbon +++ b/explorer/testdata/constraint/fail_missing_member.carbon @@ -11,7 +11,7 @@ package ExplorerTest api; interface A { fn F() -> i32; } interface B { fn G() -> i32; } -// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_missing_member.carbon:[[@LINE+1]]: member access, H not in interface A & interface B where T is interface A and T is interface B +// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_missing_member.carbon:[[@LINE+1]]: member access, H not in interface A & interface B where T impls interface A and T impls interface B fn Get[T:! A & B](n: T) -> i32 { return n.H(); } impl i32 as A { diff --git a/explorer/testdata/constraint/fail_where_is_non_constraint.carbon b/explorer/testdata/constraint/fail_where_impls_non_constraint.carbon similarity index 73% rename from explorer/testdata/constraint/fail_where_is_non_constraint.carbon rename to explorer/testdata/constraint/fail_where_impls_non_constraint.carbon index e6953b575480..230de8280789 100644 --- a/explorer/testdata/constraint/fail_where_is_non_constraint.carbon +++ b/explorer/testdata/constraint/fail_where_impls_non_constraint.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; interface A {} -// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_where_is_non_constraint.carbon:[[@LINE+1]]: expected a constraint in expression after `is`, found i32 -alias B = A where i32 is i32; +// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_where_impls_non_constraint.carbon:[[@LINE+1]]: expected a constraint in expression after `impls`, found i32 +alias B = A where i32 impls i32; fn Main() -> i32 { return 0; } diff --git a/explorer/testdata/constraint/fail_where_is_non_type.carbon b/explorer/testdata/constraint/fail_where_impls_non_type.carbon similarity index 73% rename from explorer/testdata/constraint/fail_where_is_non_type.carbon rename to explorer/testdata/constraint/fail_where_impls_non_type.carbon index 95587d50b8e9..cfed8113b00b 100644 --- a/explorer/testdata/constraint/fail_where_is_non_type.carbon +++ b/explorer/testdata/constraint/fail_where_impls_non_type.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; interface A {} -// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_where_is_non_type.carbon:[[@LINE+1]]: expression after `is` does not resolve to a constraint, found i32 -alias B = A where i32 is 5; +// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_where_impls_non_type.carbon:[[@LINE+1]]: expression after `impls` does not resolve to a constraint, found i32 +alias B = A where i32 impls 5; fn Main() -> i32 { return 0; } diff --git a/explorer/testdata/constraint/fail_where_non_type_is.carbon b/explorer/testdata/constraint/fail_where_non_type_impls.carbon similarity index 72% rename from explorer/testdata/constraint/fail_where_non_type_is.carbon rename to explorer/testdata/constraint/fail_where_non_type_impls.carbon index 6628d0368642..9edcef50960c 100644 --- a/explorer/testdata/constraint/fail_where_non_type_is.carbon +++ b/explorer/testdata/constraint/fail_where_non_type_impls.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; interface A {} -// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_where_non_type_is.carbon:[[@LINE+1]]: type error in type expression: 'i32' is not implicitly convertible to 'type' -alias B = A where 4 is A; +// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/constraint/fail_where_non_type_impls.carbon:[[@LINE+1]]: type error in type expression: 'i32' is not implicitly convertible to 'type' +alias B = A where 4 impls A; fn Main() -> i32 { return 0; } diff --git a/explorer/testdata/constraint/nondependent_where.carbon b/explorer/testdata/constraint/nondependent_where.carbon index 70ee4e7f2dd1..6d418581c80f 100644 --- a/explorer/testdata/constraint/nondependent_where.carbon +++ b/explorer/testdata/constraint/nondependent_where.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; interface A { fn Get() -> Self; } impl i32 as A { fn Get() -> Self { return 1; } } -alias AlsoA = A where i32 is A and 4 == 4; +alias AlsoA = A where i32 impls A and 4 == 4; fn F[T:! AlsoA](x: T) -> T { return T.Get(); } diff --git a/explorer/testdata/constraint/qualified_lookup_in_where.carbon b/explorer/testdata/constraint/qualified_lookup_in_where.carbon index dd3e20dbee17..0f00e468154c 100644 --- a/explorer/testdata/constraint/qualified_lookup_in_where.carbon +++ b/explorer/testdata/constraint/qualified_lookup_in_where.carbon @@ -15,7 +15,7 @@ interface B { fn F() -> i32; } impl i32 as A { fn F() -> i32 { return 1; } } impl i32 as B { fn F() -> i32 { return 2; } } -fn GetAB(T:! B where .Self is A) -> i32 { +fn GetAB(T:! B where .Self impls A) -> i32 { return 100 * T.(A.F)() + 10 * T.(B.F)() + T.F(); } diff --git a/explorer/testdata/constraint/where_is.carbon b/explorer/testdata/constraint/where_impls.carbon similarity index 91% rename from explorer/testdata/constraint/where_is.carbon rename to explorer/testdata/constraint/where_impls.carbon index b1010b7ed628..0d0f8f4f33c9 100644 --- a/explorer/testdata/constraint/where_is.carbon +++ b/explorer/testdata/constraint/where_impls.carbon @@ -18,7 +18,7 @@ interface Extension { extends Base; } -fn F[T:! type where .Self is Extension](x: T) { +fn F[T:! type where .Self impls Extension](x: T) { x.(Extension.F)(); } diff --git a/explorer/testdata/constraint/where_self.carbon b/explorer/testdata/constraint/where_self.carbon index 4a44e973dfc4..27d2a2361252 100644 --- a/explorer/testdata/constraint/where_self.carbon +++ b/explorer/testdata/constraint/where_self.carbon @@ -15,7 +15,7 @@ interface SwizzleWith(T:! type) { // TODO: There should be some way to write this that includes // `SwizzleWith(.Self)` in the list of lookup contexts. -alias Swizzle = type where .Self is SwizzleWith(.Self); +alias Swizzle = type where .Self impls SwizzleWith(.Self); impl i32 as SwizzleWith(i32) { fn Op[self: Self](x: Self) -> Self { return self * 10 + x; } diff --git a/explorer/testdata/impl/fail_unmet_impl_constraint.carbon b/explorer/testdata/impl/fail_unmet_impls_constraint.carbon similarity index 74% rename from explorer/testdata/impl/fail_unmet_impl_constraint.carbon rename to explorer/testdata/impl/fail_unmet_impls_constraint.carbon index 8c746bbebdfa..75b7947b2539 100644 --- a/explorer/testdata/impl/fail_unmet_impl_constraint.carbon +++ b/explorer/testdata/impl/fail_unmet_impls_constraint.carbon @@ -11,8 +11,8 @@ package ExplorerTest api; interface A {} interface B {} -// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/impl/fail_unmet_impl_constraint.carbon:[[@LINE+1]]: could not find implementation of interface B for i32 -external impl i32 as A where i32 is B {} +// CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/impl/fail_unmet_impls_constraint.carbon:[[@LINE+1]]: could not find implementation of interface B for i32 +external impl i32 as A where i32 impls B {} fn Main() -> i32 { return 0; diff --git a/explorer/testdata/impl/impl_constraint.carbon b/explorer/testdata/impl/impls_constraint.carbon similarity index 92% rename from explorer/testdata/impl/impl_constraint.carbon rename to explorer/testdata/impl/impls_constraint.carbon index de5e509ba8ff..0fbedf6bba22 100644 --- a/explorer/testdata/impl/impl_constraint.carbon +++ b/explorer/testdata/impl/impls_constraint.carbon @@ -24,7 +24,7 @@ external impl i32 as A { fn F() -> i32 { return 1; } } -external impl i32 as B & C(i32) where .Self is A { +external impl i32 as B & C(i32) where .Self impls A { fn F() -> i32 { return 2; } fn G() -> i32 { return 3; } fn H() -> i32 { return 4; } diff --git a/explorer/testdata/impl_match/fail_self_recurse.carbon b/explorer/testdata/impl_match/fail_self_recurse.carbon index 2360f73bdf99..dc0d69f7ffaf 100644 --- a/explorer/testdata/impl_match/fail_self_recurse.carbon +++ b/explorer/testdata/impl_match/fail_self_recurse.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; interface Foo {} -impl forall [T:! type where .Self* is Foo] T as Foo {} +impl forall [T:! type where .Self* impls Foo] T as Foo {} fn F[T:! Foo](x: T) {} diff --git a/explorer/testdata/impl_match/fail_self_recurse_without_match_first.carbon b/explorer/testdata/impl_match/fail_self_recurse_without_match_first.carbon index 9831e75ee719..2b6bbe384ab7 100644 --- a/explorer/testdata/impl_match/fail_self_recurse_without_match_first.carbon +++ b/explorer/testdata/impl_match/fail_self_recurse_without_match_first.carbon @@ -11,7 +11,7 @@ package ExplorerTest api; interface Foo {} impl forall [T:! type where .Self == i32*] T as Foo {} -impl forall [T:! type where .Self* is Foo] T as Foo {} +impl forall [T:! type where .Self* impls Foo] T as Foo {} fn F[T:! Foo](x: T) {} diff --git a/explorer/testdata/impl_match/fail_struct_recurse.carbon b/explorer/testdata/impl_match/fail_struct_recurse.carbon index 4d9df9b1fc0d..052b1f20c571 100644 --- a/explorer/testdata/impl_match/fail_struct_recurse.carbon +++ b/explorer/testdata/impl_match/fail_struct_recurse.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; interface Foo {} -impl forall [T:! type where {.a: .Self} is Foo] T as Foo {} +impl forall [T:! type where {.a: .Self} impls Foo] T as Foo {} fn F[T:! Foo](x: T) {} diff --git a/explorer/testdata/impl_match/fail_three_step_recurse.carbon b/explorer/testdata/impl_match/fail_three_step_recurse.carbon index 3b1e587110d7..392e3056d0c0 100644 --- a/explorer/testdata/impl_match/fail_three_step_recurse.carbon +++ b/explorer/testdata/impl_match/fail_three_step_recurse.carbon @@ -12,9 +12,9 @@ interface A {} interface B {} interface C {} -impl forall [T:! type where .Self* is A] T as B {} -impl forall [T:! type where .Self* is B] T as C {} -impl forall [T:! type where .Self* is C] T as A {} +impl forall [T:! type where .Self* impls A] T as B {} +impl forall [T:! type where .Self* impls B] T as C {} +impl forall [T:! type where .Self* impls C] T as A {} fn F[T:! A](x: T) {} diff --git a/explorer/testdata/impl_match/fail_tuple_recurse.carbon b/explorer/testdata/impl_match/fail_tuple_recurse.carbon index e5475bda8c7a..380edcfdc84d 100644 --- a/explorer/testdata/impl_match/fail_tuple_recurse.carbon +++ b/explorer/testdata/impl_match/fail_tuple_recurse.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; interface Foo {} -impl forall [T:! type where (.Self,) is Foo] T as Foo {} +impl forall [T:! type where (.Self,) impls Foo] T as Foo {} fn F[T:! Foo](x: T) {} diff --git a/explorer/testdata/impl_match/self_recurse_with_match.carbon b/explorer/testdata/impl_match/self_recurse_with_match.carbon index 64357aecbb5f..a56e45319ec6 100644 --- a/explorer/testdata/impl_match/self_recurse_with_match.carbon +++ b/explorer/testdata/impl_match/self_recurse_with_match.carbon @@ -12,7 +12,7 @@ package ExplorerTest api; interface Foo {} impl i32* as Foo {} -impl forall [T:! type where .Self* is Foo] T as Foo {} +impl forall [T:! type where .Self* impls Foo] T as Foo {} fn F[T:! Foo](x: T) {} diff --git a/explorer/testdata/impl_match/self_recurse_with_match_first.carbon b/explorer/testdata/impl_match/self_recurse_with_match_first.carbon index 81a1e1f4134e..8b1b4773e61c 100644 --- a/explorer/testdata/impl_match/self_recurse_with_match_first.carbon +++ b/explorer/testdata/impl_match/self_recurse_with_match_first.carbon @@ -13,7 +13,7 @@ interface Foo {} __match_first { impl forall [T:! type where .Self == i32*] T as Foo {} - impl forall [T:! type where .Self* is Foo] T as Foo {} + impl forall [T:! type where .Self* impls Foo] T as Foo {} } fn F[T:! Foo](x: T) {} diff --git a/explorer/testdata/interface/fail_interface_missing_member.carbon b/explorer/testdata/interface/fail_interface_missing_member.carbon index e9830c6ab092..4b20dec653d9 100644 --- a/explorer/testdata/interface/fail_interface_missing_member.carbon +++ b/explorer/testdata/interface/fail_interface_missing_member.carbon @@ -13,7 +13,7 @@ interface Vector { } fn ScaleGeneric[T:! Vector](a: T, s: i32) -> T { - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/interface/fail_interface_missing_member.carbon:[[@LINE+1]]: member access, Scale not in interface Vector where T is interface Vector + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/interface/fail_interface_missing_member.carbon:[[@LINE+1]]: member access, Scale not in interface Vector where T impls interface Vector return a.Scale(s); } diff --git a/explorer/testdata/name_lookup/class_fn_body_reorder.carbon b/explorer/testdata/name_lookup/class_fn_body_reorder.carbon index c374c052aafc..0d18f7892414 100644 --- a/explorer/testdata/name_lookup/class_fn_body_reorder.carbon +++ b/explorer/testdata/name_lookup/class_fn_body_reorder.carbon @@ -10,7 +10,7 @@ package ExplorerTest api; // The bodies of member functions are processed after all immediately enclosing -// classes, impls, and interfaces. +// classes, impl declarations, and interfaces. class A { fn F[self: Self]() -> i32 { return G() + self.H(); diff --git a/explorer/testdata/name_lookup/fail_class_fn_use_before_declaration.carbon b/explorer/testdata/name_lookup/fail_class_fn_use_before_declaration.carbon index 162b312cca47..0cfb07ab6534 100644 --- a/explorer/testdata/name_lookup/fail_class_fn_use_before_declaration.carbon +++ b/explorer/testdata/name_lookup/fail_class_fn_use_before_declaration.carbon @@ -9,7 +9,7 @@ package ExplorerTest api; // The bodies of member functions are processed after all immediately enclosing -// classes, impls, and interfaces. +// classes, impl declarations, and interfaces. class A { fn F() -> type { return i32; diff --git a/explorer/testdata/named_constraint/fail_impl_as_member_access.carbon b/explorer/testdata/named_constraint/fail_impl_as_member_access.carbon index ebb612dfe4a0..40299666d4ef 100644 --- a/explorer/testdata/named_constraint/fail_impl_as_member_access.carbon +++ b/explorer/testdata/named_constraint/fail_impl_as_member_access.carbon @@ -19,7 +19,7 @@ constraint ImplAsHasFoo { fn CallFoo[T:! ImplAsHasFoo](x: T) { // OK, T is HasFoo. x.(HasFoo.Foo)(); - // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/named_constraint/fail_impl_as_member_access.carbon:[[@LINE+1]]: member access, Foo not in constraint ImplAsHasFoo where T is interface HasFoo + // CHECK:STDERR: COMPILATION ERROR: {{.*}}/explorer/testdata/named_constraint/fail_impl_as_member_access.carbon:[[@LINE+1]]: member access, Foo not in constraint ImplAsHasFoo where T impls interface HasFoo x.Foo(); } diff --git a/toolchain/lexer/token_kind.def b/toolchain/lexer/token_kind.def index 465000552359..9ce9970625d1 100644 --- a/toolchain/lexer/token_kind.def +++ b/toolchain/lexer/token_kind.def @@ -136,6 +136,7 @@ CARBON_KEYWORD_TOKEN(For, "for") CARBON_KEYWORD_TOKEN(Friend, "friend") CARBON_KEYWORD_TOKEN(If, "if") CARBON_KEYWORD_TOKEN(Impl, "impl") +CARBON_KEYWORD_TOKEN(Impls, "impls") CARBON_KEYWORD_TOKEN(Import, "import") CARBON_KEYWORD_TOKEN(In, "in") CARBON_KEYWORD_TOKEN(Interface, "interface")