From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7905) id BC45A385B532; Tue, 31 Jan 2023 13:15:22 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BC45A385B532 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1675170922; bh=MEJAm/XMOZYHfEn/olfWMhbut7BKlIb3d8e2WC9xc9U=; h=From:To:Subject:Date:From; b=tbyZZWdGax6aHiEMZL0gYK0SWbUZBmBK40tddtJHhbneCQ20LYjR2+2jHJ/4vK61S zHMZYA4rmLKLAtkatIFLSShOfl15TgEDkIKo3R2lOzJWYsJrqUY097xqdrgQSvDzNv 095Ak683Wc3/WsMIIEgvWNgx+puBEbYvSrriXymA= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Arthur Cohen To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-5547] gccrs: Add missing location info to coercions X-Act-Checkin: gcc X-Git-Author: Philip Herron X-Git-Refname: refs/heads/master X-Git-Oldrev: 245ce6f26a1688ad69a1802ec50fa865db409eec X-Git-Newrev: af22b54af53c0f2a46e56b157d832c516003b647 Message-Id: <20230131131522.BC45A385B532@sourceware.org> Date: Tue, 31 Jan 2023 13:15:22 +0000 (GMT) List-Id: https://gcc.gnu.org/g:af22b54af53c0f2a46e56b157d832c516003b647 commit r13-5547-gaf22b54af53c0f2a46e56b157d832c516003b647 Author: Philip Herron Date: Fri Aug 26 11:32:24 2022 +0100 gccrs: Add missing location info to coercions gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-base.cc (TypeCheckBase::TypeCheckBase): Remove constructor. (TypeCheckBase::coercion_site): Add `Location` argument to function. * typecheck/rust-hir-type-check-base.h: Use `TypeCheckBase::coercion_site` function with location argument. * typecheck/rust-hir-type-check-enumitem.cc (TypeCheckEnumItem::visit): Likewise. * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): Likewise. * typecheck/rust-hir-type-check-expr.h (class TypeCheckExpr): Likewise. * typecheck/rust-hir-type-check-stmt.cc (TypeCheckStmt::visit): Likewise. * typecheck/rust-hir-type-check-struct.cc (TypeCheckStructExpr::visit): Likewise. * typecheck/rust-hir-type-check-toplevel.cc (TypeCheckTopLevel::visit): Likewise. * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): Likewise. (TypeCheckMethodCallExpr::visit): Likewise. * typecheck/rust-tyty.h: Add missing locus field. * typecheck/rust-tyty.cc (StructFieldType::clone): Use locus field. (StructFieldType::monomorphized_clone): Likewise. Diff: --- gcc/rust/typecheck/rust-hir-type-check-base.cc | 12 +++++-- gcc/rust/typecheck/rust-hir-type-check-base.h | 10 ++---- gcc/rust/typecheck/rust-hir-type-check-enumitem.cc | 6 ++-- gcc/rust/typecheck/rust-hir-type-check-expr.cc | 4 ++- gcc/rust/typecheck/rust-hir-type-check-expr.h | 2 +- gcc/rust/typecheck/rust-hir-type-check-stmt.cc | 24 +++++++++---- gcc/rust/typecheck/rust-hir-type-check-struct.cc | 29 +++++++++++---- gcc/rust/typecheck/rust-hir-type-check-toplevel.cc | 9 +++-- gcc/rust/typecheck/rust-tyty-call.cc | 41 +++++++++++++++++----- gcc/rust/typecheck/rust-tyty.cc | 5 +-- gcc/rust/typecheck/rust-tyty.h | 11 +++--- 11 files changed, 109 insertions(+), 44 deletions(-) diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc index f75266b2160..b809ac33108 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc @@ -25,6 +25,11 @@ namespace Rust { namespace Resolver { +TypeCheckBase::TypeCheckBase () + : mappings (Analysis::Mappings::get ()), resolver (Resolver::get ()), + context (TypeCheckContext::get ()) +{} + bool TypeCheckBase::check_for_unconstrained ( const std::vector ¶ms_to_constrain, @@ -332,9 +337,12 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, Location locus) } TyTy::BaseType * -TypeCheckBase::coercion_site (HirId id, TyTy::BaseType *expected, - TyTy::BaseType *expr, Location locus) +TypeCheckBase::coercion_site (HirId id, TyTy::TyWithLocation lhs, + TyTy::TyWithLocation rhs, Location locus) { + TyTy::BaseType *expected = lhs.get_ty (); + TyTy::BaseType *expr = rhs.get_ty (); + rust_debug ("coercion_site id={%u} expected={%s} expr={%s}", id, expected->debug_str ().c_str (), expr->debug_str ().c_str ()); diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h index d5b12705f63..acdf55713d5 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.h +++ b/gcc/rust/typecheck/rust-hir-type-check-base.h @@ -24,7 +24,6 @@ #include "rust-name-resolver.h" #include "rust-hir-visitor.h" #include "rust-hir-map.h" -#include "rust-backend.h" namespace Rust { namespace Resolver { @@ -35,8 +34,8 @@ class TypeCheckBase public: virtual ~TypeCheckBase () {} - static TyTy::BaseType *coercion_site (HirId id, TyTy::BaseType *lhs, - TyTy::BaseType *rhs, + static TyTy::BaseType *coercion_site (HirId id, TyTy::TyWithLocation lhs, + TyTy::TyWithLocation rhs, Location coercion_locus); static TyTy::BaseType *cast_site (HirId id, TyTy::TyWithLocation from, @@ -44,10 +43,7 @@ public: Location cast_locus); protected: - TypeCheckBase () - : mappings (Analysis::Mappings::get ()), resolver (Resolver::get ()), - context (TypeCheckContext::get ()) - {} + TypeCheckBase (); TraitReference *resolve_trait_path (HIR::TypePath &); diff --git a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc index e7a7f08853b..0a99d444060 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-enumitem.cc @@ -129,7 +129,8 @@ TypeCheckEnumItem::visit (HIR::EnumItemTuple &item) = TypeCheckType::Resolve (field.get_field_type ().get ()); TyTy::StructFieldType *ty_field = new TyTy::StructFieldType (field.get_mappings ().get_hirid (), - std::to_string (idx), field_type); + std::to_string (idx), field_type, + field.get_locus ()); fields.push_back (ty_field); context->insert_type (field.get_mappings (), ty_field->get_field_type ()); idx++; @@ -176,7 +177,8 @@ TypeCheckEnumItem::visit (HIR::EnumItemStruct &item) = TypeCheckType::Resolve (field.get_field_type ().get ()); TyTy::StructFieldType *ty_field = new TyTy::StructFieldType (field.get_mappings ().get_hirid (), - field.get_field_name (), field_type); + field.get_field_name (), field_type, + field.get_locus ()); fields.push_back (ty_field); context->insert_type (field.get_mappings (), ty_field->get_field_type ()); } diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index c415ae98a7a..8079c3c5cb5 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -224,7 +224,9 @@ TypeCheckExpr::visit (HIR::AssignmentExpr &expr) auto lhs = TypeCheckExpr::Resolve (expr.get_lhs ()); auto rhs = TypeCheckExpr::Resolve (expr.get_rhs ()); - coercion_site (expr.get_mappings ().get_hirid (), lhs, rhs, + coercion_site (expr.get_mappings ().get_hirid (), + TyTy::TyWithLocation (lhs, expr.get_lhs ()->get_locus ()), + TyTy::TyWithLocation (rhs, expr.get_rhs ()->get_locus ()), expr.get_locus ()); } diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index 931f7fce5a8..8a37512ec6e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -25,7 +25,7 @@ namespace Rust { namespace Resolver { -class TypeCheckExpr : public TypeCheckBase, private HIR::HIRExpressionVisitor +class TypeCheckExpr : private TypeCheckBase, private HIR::HIRExpressionVisitor { public: static TyTy::BaseType *Resolve (HIR::Expr *expr); diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc index 707d024e9ca..2b4925383e5 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-stmt.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.cc @@ -79,8 +79,10 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt) const HIR::Pattern &stmt_pattern = *stmt.get_pattern (); TyTy::BaseType *init_expr_ty = nullptr; + Location init_expr_locus; if (stmt.has_init_expr ()) { + init_expr_locus = stmt.get_init_expr ()->get_locus (); init_expr_ty = TypeCheckExpr::Resolve (stmt.get_init_expr ()); if (init_expr_ty->get_kind () == TyTy::TypeKind::ERROR) return; @@ -90,15 +92,20 @@ TypeCheckStmt::visit (HIR::LetStmt &stmt) } TyTy::BaseType *specified_ty = nullptr; + Location specified_ty_locus; if (stmt.has_type ()) - specified_ty = TypeCheckType::Resolve (stmt.get_type ()); + { + specified_ty = TypeCheckType::Resolve (stmt.get_type ()); + specified_ty_locus = stmt.get_type ()->get_locus (); + } // let x:i32 = 123; if (specified_ty != nullptr && init_expr_ty != nullptr) { - // FIXME use this result and look at the regressions - coercion_site (stmt.get_mappings ().get_hirid (), specified_ty, - init_expr_ty, stmt.get_locus ()); + coercion_site (stmt.get_mappings ().get_hirid (), + TyTy::TyWithLocation (specified_ty, specified_ty_locus), + TyTy::TyWithLocation (init_expr_ty, init_expr_locus), + stmt.get_locus ()); context->insert_type (stmt_pattern.get_pattern_mappings (), specified_ty); } else @@ -165,7 +172,8 @@ TypeCheckStmt::visit (HIR::TupleStruct &struct_decl) = TypeCheckType::Resolve (field.get_field_type ().get ()); TyTy::StructFieldType *ty_field = new TyTy::StructFieldType (field.get_mappings ().get_hirid (), - std::to_string (idx), field_type); + std::to_string (idx), field_type, + field.get_locus ()); fields.push_back (ty_field); context->insert_type (field.get_mappings (), ty_field->get_field_type ()); idx++; @@ -297,7 +305,8 @@ TypeCheckStmt::visit (HIR::StructStruct &struct_decl) = TypeCheckType::Resolve (field.get_field_type ().get ()); TyTy::StructFieldType *ty_field = new TyTy::StructFieldType (field.get_mappings ().get_hirid (), - field.get_field_name (), field_type); + field.get_field_name (), field_type, + field.get_locus ()); fields.push_back (ty_field); context->insert_type (field.get_mappings (), ty_field->get_field_type ()); } @@ -368,7 +377,8 @@ TypeCheckStmt::visit (HIR::Union &union_decl) = TypeCheckType::Resolve (variant.get_field_type ().get ()); TyTy::StructFieldType *ty_variant = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (), - variant.get_field_name (), variant_type); + variant.get_field_name (), variant_type, + variant.get_locus ()); fields.push_back (ty_variant); context->insert_type (variant.get_mappings (), ty_variant->get_field_type ()); diff --git a/gcc/rust/typecheck/rust-hir-type-check-struct.cc b/gcc/rust/typecheck/rust-hir-type-check-struct.cc index af3308e3d61..38fd5e28c0d 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-struct.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-struct.cc @@ -252,9 +252,15 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifierValue &field) } TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ()); + Location value_locus = field.get_value ()->get_locus (); + + HirId coercion_site_id = field.get_mappings ().get_hirid (); resolved_field_value_expr - = coercion_site (field.get_mappings ().get_hirid (), - field_type->get_field_type (), value, field.get_locus ()); + = coercion_site (coercion_site_id, + TyTy::TyWithLocation (field_type->get_field_type (), + field_type->get_locus ()), + TyTy::TyWithLocation (value, value_locus), + field.get_locus ()); if (resolved_field_value_expr != nullptr) { fields_assigned.insert (field.field_name); @@ -283,9 +289,15 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIndexValue &field) } TyTy::BaseType *value = TypeCheckExpr::Resolve (field.get_value ()); + Location value_locus = field.get_value ()->get_locus (); + + HirId coercion_site_id = field.get_mappings ().get_hirid (); resolved_field_value_expr - = coercion_site (field.get_mappings ().get_hirid (), - field_type->get_field_type (), value, field.get_locus ()); + = coercion_site (coercion_site_id, + TyTy::TyWithLocation (field_type->get_field_type (), + field_type->get_locus ()), + TyTy::TyWithLocation (value, value_locus), + field.get_locus ()); if (resolved_field_value_expr != nullptr) { fields_assigned.insert (field_name); @@ -324,10 +336,15 @@ TypeCheckStructExpr::visit (HIR::StructExprFieldIdentifier &field) HIR::PathInExpression expr (mappings_copy2, {seg}, field.get_locus (), false, {}); TyTy::BaseType *value = TypeCheckExpr::Resolve (&expr); + Location value_locus = expr.get_locus (); + HirId coercion_site_id = field.get_mappings ().get_hirid (); resolved_field_value_expr - = coercion_site (field.get_mappings ().get_hirid (), - field_type->get_field_type (), value, field.get_locus ()); + = coercion_site (coercion_site_id, + TyTy::TyWithLocation (field_type->get_field_type (), + field_type->get_locus ()), + TyTy::TyWithLocation (value, value_locus), + field.get_locus ()); if (resolved_field_value_expr != nullptr) { diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc b/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc index 455aef0d7e3..dd9abdd7d0d 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.cc @@ -72,7 +72,8 @@ TypeCheckTopLevel::visit (HIR::TupleStruct &struct_decl) = TypeCheckType::Resolve (field.get_field_type ().get ()); TyTy::StructFieldType *ty_field = new TyTy::StructFieldType (field.get_mappings ().get_hirid (), - std::to_string (idx), field_type); + std::to_string (idx), field_type, + field.get_locus ()); fields.push_back (ty_field); context->insert_type (field.get_mappings (), ty_field->get_field_type ()); idx++; @@ -132,7 +133,8 @@ TypeCheckTopLevel::visit (HIR::StructStruct &struct_decl) = TypeCheckType::Resolve (field.get_field_type ().get ()); TyTy::StructFieldType *ty_field = new TyTy::StructFieldType (field.get_mappings ().get_hirid (), - field.get_field_name (), field_type); + field.get_field_name (), field_type, + field.get_locus ()); fields.push_back (ty_field); context->insert_type (field.get_mappings (), ty_field->get_field_type ()); } @@ -221,7 +223,8 @@ TypeCheckTopLevel::visit (HIR::Union &union_decl) = TypeCheckType::Resolve (variant.get_field_type ().get ()); TyTy::StructFieldType *ty_variant = new TyTy::StructFieldType (variant.get_mappings ().get_hirid (), - variant.get_field_name (), variant_type); + variant.get_field_name (), variant_type, + variant.get_locus ()); fields.push_back (ty_variant); context->insert_type (variant.get_mappings (), ty_variant->get_field_type ()); diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc index 1c80de5ec56..70bc3d3c2a0 100644 --- a/gcc/rust/typecheck/rust-tyty-call.cc +++ b/gcc/rust/typecheck/rust-tyty-call.cc @@ -49,6 +49,7 @@ TypeCheckCallExpr::visit (ADTType &type) { StructFieldType *field = variant.get_field_at_index (i); BaseType *field_tyty = field->get_field_type (); + Location arg_locus = argument->get_locus (); BaseType *arg = Resolver::TypeCheckExpr::Resolve (argument.get ()); if (arg->get_kind () == TyTy::TypeKind::ERROR) @@ -58,9 +59,10 @@ TypeCheckCallExpr::visit (ADTType &type) return; } + HirId coercion_side_id = argument->get_mappings ().get_hirid (); auto res = Resolver::TypeCheckBase::coercion_site ( - argument->get_mappings ().get_hirid (), field_tyty, arg, - argument->get_locus ()); + coercion_side_id, TyWithLocation (field_tyty), + TyWithLocation (arg, arg_locus), argument->get_locus ()); if (res->get_kind () == TyTy::TypeKind::ERROR) { return; @@ -111,6 +113,7 @@ TypeCheckCallExpr::visit (FnType &type) size_t i = 0; for (auto &argument : call.get_arguments ()) { + Location arg_locus = argument->get_locus (); auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (argument.get ()); if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR) @@ -125,9 +128,18 @@ TypeCheckCallExpr::visit (FnType &type) if (i < type.num_params ()) { auto fnparam = type.param_at (i); + HIR::Pattern *fn_param_pattern = fnparam.first; + BaseType *param_ty = fnparam.second; + Location param_locus + = fn_param_pattern == nullptr + ? mappings->lookup_location (param_ty->get_ref ()) + : fn_param_pattern->get_locus (); + + HirId coercion_side_id = argument->get_mappings ().get_hirid (); auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site ( - argument->get_mappings ().get_hirid (), fnparam.second, - argument_expr_tyty, argument->get_locus ()); + coercion_side_id, TyWithLocation (param_ty, param_locus), + TyWithLocation (argument_expr_tyty, arg_locus), + argument->get_locus ()); if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR) { rust_error_at (argument->get_locus (), @@ -166,7 +178,8 @@ TypeCheckCallExpr::visit (FnPtr &type) size_t i = 0; for (auto &argument : call.get_arguments ()) { - auto fnparam = type.param_at (i); + Location arg_locus = argument->get_locus (); + BaseType *fnparam = type.param_at (i); auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (argument.get ()); if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR) @@ -178,8 +191,8 @@ TypeCheckCallExpr::visit (FnPtr &type) } auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site ( - argument->get_mappings ().get_hirid (), fnparam, argument_expr_tyty, - argument->get_locus ()); + argument->get_mappings ().get_hirid (), TyWithLocation (fnparam), + TyWithLocation (argument_expr_tyty, arg_locus), argument->get_locus ()); if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR) { rust_error_at (argument->get_locus (), @@ -222,7 +235,16 @@ TypeCheckMethodCallExpr::visit (FnType &type) size_t i = 1; for (auto &argument : call.get_arguments ()) { + Location arg_locus = argument->get_locus (); + auto fnparam = type.param_at (i); + HIR::Pattern *fn_param_pattern = fnparam.first; + BaseType *param_ty = fnparam.second; + Location param_locus + = fn_param_pattern == nullptr + ? mappings->lookup_location (param_ty->get_ref ()) + : fn_param_pattern->get_locus (); + auto argument_expr_tyty = Resolver::TypeCheckExpr::Resolve (argument.get ()); if (argument_expr_tyty->get_kind () == TyTy::TypeKind::ERROR) @@ -233,9 +255,10 @@ TypeCheckMethodCallExpr::visit (FnType &type) return; } + HirId coercion_side_id = argument->get_mappings ().get_hirid (); auto resolved_argument_type = Resolver::TypeCheckBase::coercion_site ( - argument->get_mappings ().get_hirid (), fnparam.second, - argument_expr_tyty, argument->get_locus ()); + coercion_side_id, TyWithLocation (param_ty, param_locus), + TyWithLocation (argument_expr_tyty, arg_locus), argument->get_locus ()); if (resolved_argument_type->get_kind () == TyTy::TypeKind::ERROR) { rust_error_at (argument->get_locus (), diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 25993678cbf..42c021e3aa1 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -27,6 +27,7 @@ #include "rust-substitution-mapper.h" #include "rust-hir-trait-ref.h" #include "rust-hir-type-bounds.h" +#include "options.h" namespace Rust { namespace TyTy { @@ -559,14 +560,14 @@ StructFieldType * StructFieldType::clone () const { return new StructFieldType (get_ref (), get_name (), - get_field_type ()->clone ()); + get_field_type ()->clone (), locus); } StructFieldType * StructFieldType::monomorphized_clone () const { return new StructFieldType (get_ref (), get_name (), - get_field_type ()->monomorphized_clone ()); + get_field_type ()->monomorphized_clone (), locus); } bool diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h index 7707bf7f569..9252d2affc9 100644 --- a/gcc/rust/typecheck/rust-tyty.h +++ b/gcc/rust/typecheck/rust-tyty.h @@ -314,8 +314,8 @@ private: class TyWithLocation { public: - TyWithLocation (BaseType *ty, Location locus); - TyWithLocation (BaseType *ty); + explicit TyWithLocation (BaseType *ty, Location locus); + explicit TyWithLocation (BaseType *ty); BaseType *get_ty () const { return ty; } Location get_locus () const { return locus; } @@ -472,8 +472,8 @@ private: class StructFieldType { public: - StructFieldType (HirId ref, std::string name, BaseType *ty) - : ref (ref), name (name), ty (ty) + StructFieldType (HirId ref, std::string name, BaseType *ty, Location locus) + : ref (ref), name (name), ty (ty), locus (locus) {} HirId get_ref () const { return ref; } @@ -496,10 +496,13 @@ public: void debug () const { rust_debug ("%s", as_string ().c_str ()); } + Location get_locus () const { return locus; } + private: HirId ref; std::string name; BaseType *ty; + Location locus; }; class TupleType : public BaseType