diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 2 | ||||
-rw-r--r-- | gcc/rust/backend/rust-mangle.cc | 79 | ||||
-rw-r--r-- | gcc/rust/backend/rust-mangle.h | 3 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-base.h | 5 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.h | 119 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-implitem.h | 86 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 287 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-pattern.cc | 6 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-stmt.h | 110 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h | 15 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-toplevel.h | 167 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 82 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 57 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolver.h | 2 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 2 | ||||
-rw-r--r-- | gcc/rust/util/rust-canonical-path.h | 36 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/canonical_paths1.rs | 25 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/torture/mod3.rs | 17 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/traits9.rs | 2 |
19 files changed, 833 insertions, 269 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h index b6f76ab..46f88b3 100644 --- a/gcc/rust/backend/rust-compile-context.h +++ b/gcc/rust/backend/rust-compile-context.h @@ -304,7 +304,7 @@ public: std::string mangle_item (const TyTy::BaseType *ty, const Resolver::CanonicalPath &path) const { - return mangler.mangle_item (ty, path, mappings->get_current_crate_name ()); + return mangler.mangle_item (ty, path); } private: diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc index 26c760e..eaf7814 100644 --- a/gcc/rust/backend/rust-mangle.cc +++ b/gcc/rust/backend/rust-mangle.cc @@ -9,6 +9,9 @@ static const std::string kMangledSymbolDelim = "E"; static const std::string kMangledGenericDelim = "$C$"; static const std::string kMangledSubstBegin = "$LT$"; static const std::string kMangledSubstEnd = "$GT$"; +static const std::string kMangledSpace = "$u20$"; +static const std::string kMangledRef = "$RF$"; +static const std::string kQualPathBegin = "_" + kMangledSubstBegin; namespace Rust { namespace Compile { @@ -22,17 +25,35 @@ legacy_mangle_name (const std::string &name) // <&T as core::fmt::Debug>::fmt: // _ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h6dac924c0051eef7E // replace all white space with $ and & with RF - + // + // <example::Bar as example::A>::fooA: + // _ZN43_$LT$example..Bar$u20$as$u20$example..A$GT$4fooA17hfc615fa76c7db7a0E: + // + // example::Foo<T>::new: + // _ZN7example12Foo$LT$T$GT$3new17h9a2aacb7fd783515E: std::string buffer; - for (const auto &c : name) + for (size_t i = 0; i < name.size (); i++) { std::string m; + char c = name.at (i); + if (c == ' ') - m = "$"; + m = kMangledSpace; else if (c == '&') - m = "RF"; - else if (c == '<' || c == '>') - m = ".."; + m = kMangledRef; + else if (i == 0 && c == '<') + m = kQualPathBegin; + else if (c == '<') + m = kMangledSubstBegin; + else if (c == '>') + m = kMangledSubstEnd; + else if (c == ':') + { + rust_assert (i + 1 < name.size ()); + rust_assert (name.at (i + 1) == ':'); + i++; + m = ".."; + } else m.push_back (c); @@ -46,10 +67,11 @@ static std::string legacy_mangle_canonical_path (const Resolver::CanonicalPath &path) { std::string buffer; - path.iterate_segs ([&] (const Resolver::CanonicalPath &p) -> bool { - buffer += legacy_mangle_name (p.get ()); - return true; - }); + for (size_t i = 0; i < path.size (); i++) + { + auto &seg = path.get_seg_at (i); + buffer += legacy_mangle_name (seg.second); + } return buffer; } @@ -150,7 +172,8 @@ v0_simple_type_prefix (const TyTy::BaseType *ty) // Add an underscore-terminated base62 integer to the mangling string. // This corresponds to the `<base-62-number>` grammar in the v0 mangling RFC: // - 0 is encoded as "_" -// - any other value is encoded as itself minus one in base 62, followed by "_" +// - any other value is encoded as itself minus one in base 62, followed by +// "_" static void v0_add_integer_62 (std::string &mangled, uint64_t x) { @@ -188,11 +211,11 @@ v0_add_identifier (std::string &mangled, const std::string &identifier) { // FIXME: gccrs cannot handle unicode identifiers yet, so we never have to // create mangling for unicode values for now. However, this is handled - // by the v0 mangling scheme. The grammar for unicode identifier is contained - // in <undisambiguated-identifier>, right under the <identifier> one. If the - // identifier contains unicode values, then an extra "u" needs to be added - // to the mangling string and `punycode` must be used to encode the - // characters. + // by the v0 mangling scheme. The grammar for unicode identifier is + // contained in <undisambiguated-identifier>, right under the <identifier> + // one. If the identifier contains unicode values, then an extra "u" needs + // to be added to the mangling string and `punycode` must be used to encode + // the characters. mangled += std::to_string (identifier.size ()); @@ -217,22 +240,25 @@ v0_type_prefix (const TyTy::BaseType *ty) static std::string legacy_mangle_item (const TyTy::BaseType *ty, - const Resolver::CanonicalPath &path, - const std::string &crate_name) + const Resolver::CanonicalPath &path) { const std::string hash = legacy_hash (ty->as_string ()); const std::string hash_sig = legacy_mangle_name (hash); - return kMangledSymbolPrefix + legacy_mangle_name (crate_name) - + legacy_mangle_canonical_path (path) + hash_sig + kMangledSymbolDelim; + return kMangledSymbolPrefix + legacy_mangle_canonical_path (path) + hash_sig + + kMangledSymbolDelim; } static std::string -v0_mangle_item (const TyTy::BaseType *ty, const Resolver::CanonicalPath &path, - const std::string &crate_name) +v0_mangle_item (const TyTy::BaseType *ty, const Resolver::CanonicalPath &path) { - std::string mangled; + // we can get this from the canonical_path + auto mappings = Analysis::Mappings::get (); + std::string crate_name; + bool ok = mappings->get_crate_name (path.get_crate_num (), crate_name); + rust_assert (ok); + std::string mangled; // FIXME: Add real algorithm once all pieces are implemented auto ty_prefix = v0_type_prefix (ty); v0_add_identifier (mangled, crate_name); @@ -243,15 +269,14 @@ v0_mangle_item (const TyTy::BaseType *ty, const Resolver::CanonicalPath &path, std::string Mangler::mangle_item (const TyTy::BaseType *ty, - const Resolver::CanonicalPath &path, - const std::string &crate_name) const + const Resolver::CanonicalPath &path) const { switch (version) { case Mangler::MangleVersion::LEGACY: - return legacy_mangle_item (ty, path, crate_name); + return legacy_mangle_item (ty, path); case Mangler::MangleVersion::V0: - return v0_mangle_item (ty, path, crate_name); + return v0_mangle_item (ty, path); default: gcc_unreachable (); } diff --git a/gcc/rust/backend/rust-mangle.h b/gcc/rust/backend/rust-mangle.h index 0cc7f76..03e1dc6 100644 --- a/gcc/rust/backend/rust-mangle.h +++ b/gcc/rust/backend/rust-mangle.h @@ -34,8 +34,7 @@ public: // this needs to support Legacy and V0 see github #429 or #305 std::string mangle_item (const TyTy::BaseType *ty, - const Resolver::CanonicalPath &path, - const std::string &crate_name) const; + const Resolver::CanonicalPath &path) const; static void set_mangling (int frust_mangling_value) { diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h index 237a971..6ee5f3d 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.h +++ b/gcc/rust/resolve/rust-ast-resolve-base.h @@ -201,13 +201,14 @@ public: protected: ResolverBase (NodeId parent) - : resolver (Resolver::get ()), resolved_node (UNKNOWN_NODEID), - parent (parent), locus (Location ()) + : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ()), + resolved_node (UNKNOWN_NODEID), parent (parent), locus (Location ()) {} bool resolved () const { return resolved_node != UNKNOWN_NODEID; } Resolver *resolver; + Analysis::Mappings *mappings; NodeId resolved_node; NodeId parent; Location locus; diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index 392f4f4..b7b8646 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -63,15 +63,16 @@ class ResolveExpr : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::Expr *expr, NodeId parent) + static void go (AST::Expr *expr, NodeId parent, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveExpr resolver (parent); + ResolveExpr resolver (parent, prefix, canonical_prefix); expr->accept_vis (resolver); }; void visit (AST::TupleIndexExpr &expr) override { - ResolveExpr::go (expr.get_tuple_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_tuple_expr ().get (), expr.get_node_id ()); } void visit (AST::TupleExpr &expr) override @@ -80,7 +81,7 @@ public: return; for (auto &elem : expr.get_tuple_elems ()) - ResolveExpr::go (elem.get (), expr.get_node_id ()); + resolve_expr (elem.get (), expr.get_node_id ()); } void visit (AST::PathInExpression &expr) override @@ -96,20 +97,20 @@ public: void visit (AST::ReturnExpr &expr) override { if (expr.has_returned_expr ()) - ResolveExpr::go (expr.get_returned_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_returned_expr ().get (), expr.get_node_id ()); } void visit (AST::CallExpr &expr) override { - ResolveExpr::go (expr.get_function_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_function_expr ().get (), expr.get_node_id ()); auto const &in_params = expr.get_params (); for (auto ¶m : in_params) - ResolveExpr::go (param.get (), expr.get_node_id ()); + resolve_expr (param.get (), expr.get_node_id ()); } void visit (AST::MethodCallExpr &expr) override { - ResolveExpr::go (expr.get_receiver_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_receiver_expr ().get (), expr.get_node_id ()); if (expr.get_method_name ().has_generic_args ()) { @@ -119,13 +120,13 @@ public: auto const &in_params = expr.get_params (); for (auto ¶m : in_params) - ResolveExpr::go (param.get (), expr.get_node_id ()); + resolve_expr (param.get (), expr.get_node_id ()); } void visit (AST::AssignmentExpr &expr) override { - ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ()); // need to verify the assignee VerifyAsignee::go (expr.get_left_expr ().get (), expr.get_node_id ()); @@ -160,14 +161,14 @@ public: void visit (AST::ArithmeticOrLogicalExpr &expr) override { - ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ()); } void visit (AST::CompoundAssignmentExpr &expr) override { - ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ()); // need to verify the assignee VerifyAsignee::go (expr.get_left_expr ().get (), expr.get_node_id ()); @@ -175,45 +176,45 @@ public: void visit (AST::ComparisonExpr &expr) override { - ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ()); } void visit (AST::LazyBooleanExpr &expr) override { - ResolveExpr::go (expr.get_left_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_right_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_left_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_right_expr ().get (), expr.get_node_id ()); } void visit (AST::NegationExpr &expr) override { - ResolveExpr::go (expr.get_negated_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_negated_expr ().get (), expr.get_node_id ()); } void visit (AST::TypeCastExpr &expr) override { ResolveType::go (expr.get_type_to_cast_to ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_casted_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_casted_expr ().get (), expr.get_node_id ()); } void visit (AST::IfExpr &expr) override { - ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_if_block ().get (), expr.get_node_id ()); + resolve_expr (expr.get_condition_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_if_block ().get (), expr.get_node_id ()); } void visit (AST::IfExprConseqElse &expr) override { - ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_if_block ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_else_block ().get (), expr.get_node_id ()); + resolve_expr (expr.get_condition_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_if_block ().get (), expr.get_node_id ()); + resolve_expr (expr.get_else_block ().get (), expr.get_node_id ()); } void visit (AST::IfExprConseqIf &expr) override { - ResolveExpr::go (expr.get_condition_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_if_block ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_conseq_if_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_condition_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_if_block ().get (), expr.get_node_id ()); + resolve_expr (expr.get_conseq_if_expr ().get (), expr.get_node_id ()); } void visit (AST::BlockExpr &expr) override; @@ -226,7 +227,7 @@ public: void visit (AST::ArrayElemsValues &elems) override { for (auto &elem : elems.get_values ()) - ResolveExpr::go (elem.get (), elems.get_node_id ()); + resolve_expr (elem.get (), elems.get_node_id ()); } void visit (AST::ArrayExpr &expr) override @@ -236,52 +237,51 @@ public: void visit (AST::ArrayIndexExpr &expr) override { - ResolveExpr::go (expr.get_array_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_index_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_array_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_index_expr ().get (), expr.get_node_id ()); } void visit (AST::ArrayElemsCopied &elems) override { - ResolveExpr::go (elems.get_num_copies ().get (), elems.get_node_id ()); - ResolveExpr::go (elems.get_elem_to_copy ().get (), elems.get_node_id ()); + resolve_expr (elems.get_num_copies ().get (), elems.get_node_id ()); + resolve_expr (elems.get_elem_to_copy ().get (), elems.get_node_id ()); } // this this an empty struct constructor like 'S {}' void visit (AST::StructExprStruct &struct_expr) override { - ResolveExpr::go (&struct_expr.get_struct_name (), - struct_expr.get_node_id ()); + resolve_expr (&struct_expr.get_struct_name (), struct_expr.get_node_id ()); } // this this a struct constructor with fields void visit (AST::StructExprStructFields &struct_expr) override { - ResolveExpr::go (&struct_expr.get_struct_name (), - struct_expr.get_node_id ()); + resolve_expr (&struct_expr.get_struct_name (), struct_expr.get_node_id ()); if (struct_expr.has_struct_base ()) { AST::StructBase &base = struct_expr.get_struct_base (); - ResolveExpr::go (base.get_base_struct ().get (), - struct_expr.get_node_id ()); + resolve_expr (base.get_base_struct ().get (), + struct_expr.get_node_id ()); } auto const &struct_fields = struct_expr.get_fields (); for (auto &struct_field : struct_fields) { ResolveStructExprField::go (struct_field.get (), - struct_expr.get_node_id ()); + struct_expr.get_node_id (), prefix, + canonical_prefix); } } void visit (AST::GroupedExpr &expr) override { - ResolveExpr::go (expr.get_expr_in_parens ().get (), expr.get_node_id ()); + resolve_expr (expr.get_expr_in_parens ().get (), expr.get_node_id ()); } void visit (AST::FieldAccessExpr &expr) override { - ResolveExpr::go (expr.get_receiver_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_receiver_expr ().get (), expr.get_node_id ()); } void visit (AST::LoopExpr &expr) override @@ -311,7 +311,7 @@ public: Definition{label_lifetime_node_id, label.get_node_id ()}); } - ResolveExpr::go (expr.get_loop_block ().get (), expr.get_node_id ()); + resolve_expr (expr.get_loop_block ().get (), expr.get_node_id ()); } void visit (AST::BreakExpr &expr) override @@ -340,7 +340,7 @@ public: } if (expr.has_break_expr ()) - ResolveExpr::go (expr.get_break_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_break_expr ().get (), expr.get_node_id ()); } void visit (AST::WhileLoopExpr &expr) override @@ -370,8 +370,8 @@ public: Definition{label_lifetime_node_id, label.get_node_id ()}); } - ResolveExpr::go (expr.get_predicate_expr ().get (), expr.get_node_id ()); - ResolveExpr::go (expr.get_loop_block ().get (), expr.get_node_id ()); + resolve_expr (expr.get_predicate_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_loop_block ().get (), expr.get_node_id ()); } void visit (AST::ContinueExpr &expr) override @@ -402,17 +402,17 @@ public: void visit (AST::BorrowExpr &expr) override { - ResolveExpr::go (expr.get_borrowed_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_borrowed_expr ().get (), expr.get_node_id ()); } void visit (AST::DereferenceExpr &expr) override { - ResolveExpr::go (expr.get_dereferenced_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_dereferenced_expr ().get (), expr.get_node_id ()); } void visit (AST::MatchExpr &expr) override { - ResolveExpr::go (expr.get_scrutinee_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_scrutinee_expr ().get (), expr.get_node_id ()); for (auto &match_case : expr.get_match_cases ()) { // each arm is in its own scope @@ -427,7 +427,7 @@ public: // resolve AST::MatchArm &arm = match_case.get_arm (); if (arm.has_match_arm_guard ()) - ResolveExpr::go (arm.get_guard_expr ().get (), expr.get_node_id ()); + resolve_expr (arm.get_guard_expr ().get (), expr.get_node_id ()); // insert any possible new patterns for (auto &pattern : arm.get_patterns ()) @@ -436,7 +436,7 @@ public: } // resolve the body - ResolveExpr::go (match_case.get_expr ().get (), expr.get_node_id ()); + resolve_expr (match_case.get_expr ().get (), expr.get_node_id ()); // done resolver->get_name_scope ().pop (); @@ -445,8 +445,21 @@ public: } } +protected: + void resolve_expr (AST::Expr *e, NodeId parent) + { + ResolveExpr::go (e, parent, prefix, canonical_prefix); + } + private: - ResolveExpr (NodeId parent) : ResolverBase (parent) {} + ResolveExpr (NodeId parent, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) + : ResolverBase (parent), prefix (prefix), + canonical_prefix (canonical_prefix) + {} + + const CanonicalPath &prefix; + const CanonicalPath &canonical_prefix; }; } // namespace Resolver diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h index 4bc14b9..074855e 100644 --- a/gcc/rust/resolve/rust-ast-resolve-implitem.h +++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h @@ -45,8 +45,10 @@ public: void visit (AST::TypeAlias &type) override { - auto path = prefix.append ( - CanonicalPath::new_seg (type.get_node_id (), type.get_new_type_name ())); + auto decl + = CanonicalPath::new_seg (type.get_node_id (), type.get_new_type_name ()); + auto path = prefix.append (decl); + resolver->get_type_scope ().insert ( path, type.get_node_id (), type.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -58,8 +60,9 @@ public: void visit (AST::ConstantItem &constant) override { - auto path - = prefix.append (ResolveConstantItemToCanonicalPath::resolve (constant)); + auto decl = ResolveConstantItemToCanonicalPath::resolve (constant); + auto path = prefix.append (decl); + resolver->get_name_scope ().insert ( path, constant.get_node_id (), constant.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -74,8 +77,9 @@ public: void visit (AST::Function &function) override { - auto path - = prefix.append (ResolveFunctionItemToCanonicalPath::resolve (function)); + auto decl = ResolveFunctionItemToCanonicalPath::resolve (function); + auto path = prefix.append (decl); + resolver->get_name_scope ().insert ( path, function.get_node_id (), function.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -90,8 +94,9 @@ public: void visit (AST::Method &method) override { - auto path - = prefix.append (ResolveMethodItemToCanonicalPath::resolve (method)); + auto decl = ResolveMethodItemToCanonicalPath::resolve (method); + auto path = prefix.append (decl); + resolver->get_name_scope ().insert ( path, method.get_node_id (), method.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -119,17 +124,19 @@ class ResolveTopLevelTraitItems : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::TraitItem *item, - const CanonicalPath &prefix = CanonicalPath::create_empty ()) + static void go (AST::TraitItem *item, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveTopLevelTraitItems resolver (prefix); + ResolveTopLevelTraitItems resolver (prefix, canonical_prefix); item->accept_vis (resolver); }; void visit (AST::TraitItemFunc &function) override { - auto path = prefix.append ( - ResolveTraitItemFunctionToCanonicalPath::resolve (function)); + auto decl = ResolveTraitItemFunctionToCanonicalPath::resolve (function); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_name_scope ().insert ( path, function.get_node_id (), function.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -140,12 +147,17 @@ public: resolver->insert_new_definition (function.get_node_id (), Definition{function.get_node_id (), function.get_node_id ()}); + + mappings->insert_canonical_path (mappings->get_current_crate (), + function.get_node_id (), cpath); } void visit (AST::TraitItemMethod &method) override { - auto path - = prefix.append (ResolveTraitItemMethodToCanonicalPath::resolve (method)); + auto decl = ResolveTraitItemMethodToCanonicalPath::resolve (method); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_name_scope ().insert ( path, method.get_node_id (), method.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -156,12 +168,17 @@ public: resolver->insert_new_definition (method.get_node_id (), Definition{method.get_node_id (), method.get_node_id ()}); + + mappings->insert_canonical_path (mappings->get_current_crate (), + method.get_node_id (), cpath); } void visit (AST::TraitItemConst &constant) override { - auto path = prefix.append ( - ResolveTraitItemConstToCanonicalPath::resolve (constant)); + auto decl = ResolveTraitItemConstToCanonicalPath::resolve (constant); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_name_scope ().insert ( path, constant.get_node_id (), constant.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -172,12 +189,17 @@ public: resolver->insert_new_definition (constant.get_node_id (), Definition{constant.get_node_id (), constant.get_node_id ()}); + + mappings->insert_canonical_path (mappings->get_current_crate (), + constant.get_node_id (), cpath); } void visit (AST::TraitItemType &type) override { - auto path - = prefix.append (ResolveTraitItemTypeToCanonicalPath::resolve (type)); + auto decl = ResolveTraitItemTypeToCanonicalPath::resolve (type); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, type.get_node_id (), type.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -185,14 +207,20 @@ public: r.add_range (locus); rust_error_at (r, "redefined multiple times"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + type.get_node_id (), cpath); } private: - ResolveTopLevelTraitItems (const CanonicalPath &prefix) - : ResolverBase (UNKNOWN_NODEID), prefix (prefix) + ResolveTopLevelTraitItems (const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) + : ResolverBase (UNKNOWN_NODEID), prefix (prefix), + canonical_prefix (canonical_prefix) {} const CanonicalPath &prefix; + const CanonicalPath &canonical_prefix; }; class ResolveToplevelExternItem : public ResolverBase @@ -200,8 +228,7 @@ class ResolveToplevelExternItem : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::ExternalItem *item, - const CanonicalPath &prefix = CanonicalPath::create_empty ()) + static void go (AST::ExternalItem *item, const CanonicalPath &prefix) { ResolveToplevelExternItem resolver (prefix); item->accept_vis (resolver); @@ -209,9 +236,10 @@ public: void visit (AST::ExternalFunctionItem &function) override { - auto path - = prefix.append (CanonicalPath::new_seg (function.get_node_id (), - function.get_identifier ())); + auto decl = CanonicalPath::new_seg (function.get_node_id (), + function.get_identifier ()); + auto path = prefix.append (decl); + resolver->get_name_scope ().insert ( path, function.get_node_id (), function.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -226,8 +254,10 @@ public: void visit (AST::ExternalStaticItem &item) override { - auto path = prefix.append ( - CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + auto decl + = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); + auto path = prefix.append (decl); + resolver->get_name_scope ().insert ( path, item.get_node_id (), item.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index 200c5ff..e428880 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -35,20 +35,33 @@ class ResolveTraitItems : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::TraitItem *item) + static void go (AST::TraitItem *item, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveTraitItems resolver; + ResolveTraitItems resolver (prefix, canonical_prefix); item->accept_vis (resolver); }; void visit (AST::TraitItemType &type) override { + auto decl = ResolveTraitItemTypeToCanonicalPath::resolve (type); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + type.get_node_id (), cpath); + for (auto &bound : type.get_type_param_bounds ()) ResolveTypeBound::go (bound.get (), type.get_node_id ()); } void visit (AST::TraitItemFunc &func) override { + auto decl = ResolveTraitItemFunctionToCanonicalPath::resolve (func); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + func.get_node_id (), cpath); + NodeId scope_node_id = func.get_node_id (); resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); @@ -86,7 +99,8 @@ public: // trait items have an optional body if (func.has_definition ()) - ResolveExpr::go (func.get_definition ().get (), func.get_node_id ()); + ResolveExpr::go (func.get_definition ().get (), func.get_node_id (), path, + cpath); resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); @@ -95,6 +109,12 @@ public: void visit (AST::TraitItemMethod &func) override { + auto decl = ResolveTraitItemMethodToCanonicalPath::resolve (func); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + func.get_node_id (), cpath); + NodeId scope_node_id = func.get_node_id (); resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); @@ -152,7 +172,8 @@ public: // trait items have an optional body if (func.has_definition ()) - ResolveExpr::go (func.get_definition ().get (), func.get_node_id ()); + ResolveExpr::go (func.get_definition ().get (), func.get_node_id (), path, + cpath); resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); @@ -161,10 +182,17 @@ public: void visit (AST::TraitItemConst &constant) override { + auto decl = ResolveTraitItemConstToCanonicalPath::resolve (constant); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + constant.get_node_id (), cpath); + ResolveType::go (constant.get_type ().get (), constant.get_node_id ()); if (constant.has_expr ()) - ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ()); + ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id (), + path, cpath); // the mutability checker needs to verify for immutable decls the number // of assignments are <1. This marks an implicit assignment @@ -174,7 +202,14 @@ public: } private: - ResolveTraitItems () : ResolverBase (UNKNOWN_NODEID) {} + ResolveTraitItems (const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) + : ResolverBase (UNKNOWN_NODEID), prefix (prefix), + canonical_prefix (canonical_prefix) + {} + + const CanonicalPath &prefix; + const CanonicalPath &canonical_prefix; }; class ResolveItem : public ResolverBase @@ -182,14 +217,22 @@ class ResolveItem : public ResolverBase public: using Rust::Resolver::ResolverBase::visit; - static void go (AST::Item *item) + static void go (AST::Item *item, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveItem resolver; + ResolveItem resolver (prefix, canonical_prefix); item->accept_vis (resolver); }; void visit (AST::TypeAlias &alias) override { + auto talias = CanonicalPath::new_seg (alias.get_node_id (), + alias.get_new_type_name ()); + auto path = prefix.append (talias); + auto cpath = canonical_prefix.append (talias); + mappings->insert_canonical_path (mappings->get_current_crate (), + alias.get_node_id (), cpath); + NodeId scope_node_id = alias.get_node_id (); resolver->get_type_scope ().push (scope_node_id); @@ -209,6 +252,13 @@ public: void visit (AST::Module &module) override { + auto mod + = CanonicalPath::new_seg (module.get_node_id (), module.get_name ()); + auto path = prefix.append (mod); + auto cpath = canonical_prefix.append (mod); + mappings->insert_canonical_path (mappings->get_current_crate (), + module.get_node_id (), cpath); + NodeId scope_node_id = module.get_node_id (); resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); @@ -218,10 +268,10 @@ public: resolver->push_new_label_rib (resolver->get_type_scope ().peek ()); for (auto &item : module.get_items ()) - ResolveTopLevel::go (item.get ()); + ResolveTopLevel::go (item.get (), CanonicalPath::create_empty (), cpath); for (auto &item : module.get_items ()) - ResolveItem::go (item.get ()); + ResolveItem::go (item.get (), path, cpath); resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); @@ -230,6 +280,13 @@ public: void visit (AST::TupleStruct &struct_decl) override { + auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (), + struct_decl.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + struct_decl.get_node_id (), cpath); + NodeId scope_node_id = struct_decl.get_node_id (); resolver->get_type_scope ().push (scope_node_id); @@ -254,6 +311,13 @@ public: void visit (AST::Enum &enum_decl) override { + auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (), + enum_decl.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + enum_decl.get_node_id (), cpath); + NodeId scope_node_id = enum_decl.get_node_id (); resolver->get_type_scope ().push (scope_node_id); @@ -270,7 +334,7 @@ public: /* The actual fields are inside the variants. */ for (auto &variant : enum_decl.get_variants ()) - ResolveItem::go (variant.get ()); + ResolveItem::go (variant.get (), path, cpath); resolver->get_type_scope ().pop (); } @@ -279,20 +343,50 @@ public: void visit (AST::EnumItemTuple &item) override { + auto decl + = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); + for (auto &field : item.get_tuple_fields ()) ResolveType::go (field.get_field_type ().get (), item.get_node_id ()); } void visit (AST::EnumItemStruct &item) override { + auto decl + = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); + for (auto &field : item.get_struct_fields ()) ResolveType::go (field.get_field_type ().get (), item.get_node_id ()); } - /* EnumItemDiscriminant doesn't need to be handled, no fields. */ + void visit (AST::EnumItemDiscriminant &item) override + { + auto decl + = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); + } void visit (AST::StructStruct &struct_decl) override { + auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (), + struct_decl.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + struct_decl.get_node_id (), cpath); + NodeId scope_node_id = struct_decl.get_node_id (); resolver->get_type_scope ().push (scope_node_id); @@ -317,6 +411,13 @@ public: void visit (AST::Union &union_decl) override { + auto decl = CanonicalPath::new_seg (union_decl.get_node_id (), + union_decl.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + union_decl.get_node_id (), cpath); + NodeId scope_node_id = union_decl.get_node_id (); resolver->get_type_scope ().push (scope_node_id); @@ -340,8 +441,15 @@ public: void visit (AST::StaticItem &var) override { + auto decl + = CanonicalPath::new_seg (var.get_node_id (), var.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + var.get_node_id (), cpath); + ResolveType::go (var.get_type ().get (), var.get_node_id ()); - ResolveExpr::go (var.get_expr ().get (), var.get_node_id ()); + ResolveExpr::go (var.get_expr ().get (), var.get_node_id (), path, cpath); // the mutability checker needs to verify for immutable decls the number // of assignments are <1. This marks an implicit assignment @@ -350,8 +458,15 @@ public: void visit (AST::ConstantItem &constant) override { + auto decl = ResolveConstantItemToCanonicalPath::resolve (constant); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + constant.get_node_id (), cpath); + ResolveType::go (constant.get_type ().get (), constant.get_node_id ()); - ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ()); + ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id (), path, + cpath); // the mutability checker needs to verify for immutable decls the number // of assignments are <1. This marks an implicit assignment @@ -365,6 +480,12 @@ public: if (function.is_marked_for_strip ()) return; + auto decl = ResolveFunctionItemToCanonicalPath::resolve (function); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + function.get_node_id (), cpath); + NodeId scope_node_id = function.get_node_id (); resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); @@ -402,8 +523,8 @@ public: } // resolve the function body - ResolveExpr::go (function.get_definition ().get (), - function.get_node_id ()); + ResolveExpr::go (function.get_definition ().get (), function.get_node_id (), + path, cpath); resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); @@ -430,10 +551,15 @@ public: if (impl_block.has_where_clause ()) ResolveWhereClause::Resolve (impl_block.get_where_clause ()); + // FIXME this needs to be protected behind nominal type-checks see: + // rustc --explain E0118 + + CanonicalPath self_cpath = CanonicalPath::create_empty (); bool canonicalize_type_with_generics = false; - NodeId resolved_node = ResolveType::go (impl_block.get_type ().get (), - impl_block.get_node_id (), - canonicalize_type_with_generics); + NodeId resolved_node + = ResolveType::go (impl_block.get_type ().get (), + impl_block.get_node_id (), + canonicalize_type_with_generics, &self_cpath); if (resolved_node == UNKNOWN_NODEID) { resolver->get_type_scope ().pop (); @@ -441,6 +567,31 @@ public: return; } + // Setup paths + bool canonicalize_type_args = !impl_block.has_generics (); + bool type_resolve_generic_args = false; + + CanonicalPath impl_type + = ResolveTypeToCanonicalPath::resolve (*impl_block.get_type ().get (), + canonicalize_type_args, + type_resolve_generic_args); + CanonicalPath impl_prefix = prefix.append (impl_type); + + // see https://godbolt.org/z/a3vMbsT6W + CanonicalPath cpath = CanonicalPath::create_empty (); + if (canonical_prefix.size () > 1) + { + std::string seg_buf = "<impl " + self_cpath.get () + ">"; + CanonicalPath seg + = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf); + cpath = canonical_prefix.append (seg); + } + else + { + cpath = canonical_prefix.append (self_cpath); + } + // done setup paths + auto Self = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ()); @@ -450,7 +601,7 @@ public: for (auto &impl_item : impl_block.get_impl_items ()) { - resolve_impl_item (impl_item.get ()); + resolve_impl_item (impl_item.get (), impl_prefix, cpath); } resolver->get_type_scope ().peek ()->clear_name ( @@ -462,6 +613,12 @@ public: void visit (AST::Method &method) override { + auto decl = ResolveMethodItemToCanonicalPath::resolve (method); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + method.get_node_id (), cpath); + NodeId scope_node_id = method.get_node_id (); resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); @@ -522,7 +679,8 @@ public: ResolveWhereClause::Resolve (method.get_where_clause ()); // resolve the function body - ResolveExpr::go (method.get_definition ().get (), method.get_node_id ()); + ResolveExpr::go (method.get_definition ().get (), method.get_node_id (), + path, cpath); resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); @@ -549,11 +707,13 @@ public: if (impl_block.has_where_clause ()) ResolveWhereClause::Resolve (impl_block.get_where_clause ()); + CanonicalPath canonical_trait_type = CanonicalPath::create_empty (); bool canonicalize_type_with_generics = false; NodeId trait_resolved_node = ResolveType::go (&impl_block.get_trait_path (), impl_block.get_node_id (), - canonicalize_type_with_generics); + canonicalize_type_with_generics, + &canonical_trait_type); if (trait_resolved_node == UNKNOWN_NODEID) { resolver->get_type_scope ().pop (); @@ -561,10 +721,11 @@ public: return; } + CanonicalPath canonical_impl_type = CanonicalPath::create_empty (); NodeId type_resolved_node = ResolveType::go (impl_block.get_type ().get (), impl_block.get_node_id (), - canonicalize_type_with_generics); + canonicalize_type_with_generics, &canonical_impl_type); if (type_resolved_node == UNKNOWN_NODEID) { resolver->get_type_scope ().pop (); @@ -572,6 +733,46 @@ public: return; } + // setup paths + bool canonicalize_type_args = !impl_block.has_generics (); + bool type_resolve_generic_args = false; + + CanonicalPath impl_type_seg + = ResolveTypeToCanonicalPath::resolve (*impl_block.get_type ().get (), + canonicalize_type_args, + type_resolve_generic_args); + CanonicalPath trait_type_seg + = ResolveTypeToCanonicalPath::resolve (impl_block.get_trait_path (), + canonicalize_type_args, + type_resolve_generic_args); + + CanonicalPath projection + = TraitImplProjection::resolve (impl_block.get_node_id (), trait_type_seg, + impl_type_seg); + CanonicalPath impl_prefix = prefix.append (projection); + + // setup canonical-path + CanonicalPath canonical_projection + = TraitImplProjection::resolve (impl_block.get_node_id (), + canonical_trait_type, + canonical_impl_type); + CanonicalPath cpath = CanonicalPath::create_empty (); + if (canonical_prefix.size () > 1) + { + std::string projection_str = canonical_projection.get (); + std::string seg_buf + = "<impl " + projection_str.substr (1, projection_str.size () - 2) + + ">"; + CanonicalPath seg + = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf); + cpath = canonical_prefix.append (seg); + } + else + { + cpath = canonical_prefix.append (canonical_projection); + } + // DONE setup canonical-path + auto Self = CanonicalPath::get_big_self (impl_block.get_type ()->get_node_id ()); @@ -581,7 +782,7 @@ public: for (auto &impl_item : impl_block.get_impl_items ()) { - resolve_impl_item (impl_item.get ()); + resolve_impl_item (impl_item.get (), impl_prefix, cpath); } resolver->get_type_scope ().peek ()->clear_name ( @@ -625,9 +826,14 @@ public: if (trait.has_where_clause ()) ResolveWhereClause::Resolve (trait.get_where_clause ()); + // resolve the paths + CanonicalPath path = CanonicalPath::create_empty (); + CanonicalPath cpath = CanonicalPath::create_empty (); + // + for (auto &item : trait.get_trait_items ()) { - ResolveTraitItems::go (item.get ()); + ResolveTraitItems::go (item.get (), path, cpath); } resolver->get_type_scope ().pop (); @@ -643,11 +849,21 @@ public: } protected: - void resolve_impl_item (AST::TraitImplItem *item); - void resolve_impl_item (AST::InherentImplItem *item); + void resolve_impl_item (AST::TraitImplItem *item, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix); + void resolve_impl_item (AST::InherentImplItem *item, + const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix); void resolve_extern_item (AST::ExternalItem *item); - ResolveItem () : ResolverBase (UNKNOWN_NODEID) {} + ResolveItem (const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) + : ResolverBase (UNKNOWN_NODEID), prefix (prefix), + canonical_prefix (canonical_prefix) + {} + + const CanonicalPath &prefix; + const CanonicalPath &canonical_prefix; }; class ResolveImplItems : public ResolveItem @@ -655,15 +871,17 @@ class ResolveImplItems : public ResolveItem using Rust::Resolver::ResolveItem::visit; public: - static void go (AST::InherentImplItem *item) + static void go (AST::InherentImplItem *item, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveImplItems resolver; + ResolveImplItems resolver (prefix, canonical_prefix); item->accept_vis (resolver); }; - static void go (AST::TraitImplItem *item) + static void go (AST::TraitImplItem *item, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveImplItems resolver; + ResolveImplItems resolver (prefix, canonical_prefix); item->accept_vis (resolver); }; @@ -677,7 +895,10 @@ public: } private: - ResolveImplItems () : ResolveItem () {} + ResolveImplItems (const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) + : ResolveItem (prefix, canonical_prefix) + {} }; class ResolveExternItem : public ResolverBase diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc index 8a4a634..0c7c8f3 100644 --- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc +++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc @@ -25,13 +25,13 @@ namespace Resolver { void PatternDeclaration::visit (AST::PathInExpression &pattern) { - ResolveExpr::go (&pattern, parent); + ResolvePath::go (&pattern, parent); } void PatternDeclaration::visit (AST::TupleStructPattern &pattern) { - ResolveExpr::go (&pattern.get_path (), parent); + ResolvePath::go (&pattern.get_path (), parent); std::unique_ptr<AST::TupleStructItems> &items = pattern.get_items (); switch (items->get_item_type ()) @@ -59,7 +59,7 @@ PatternDeclaration::visit (AST::TupleStructPattern &pattern) void PatternDeclaration::visit (AST::StructPattern &pattern) { - ResolveExpr::go (&pattern.get_path (), parent); + ResolvePath::go (&pattern.get_path (), parent); auto &struct_pattern_elems = pattern.get_struct_pattern_elems (); for (auto &field : struct_pattern_elems.get_struct_pattern_fields ()) diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h index c84d842..308de14 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h @@ -33,27 +33,34 @@ class ResolveStmt : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::Stmt *stmt, NodeId parent, - const CanonicalPath &enum_prefix - = CanonicalPath::create_empty ()) + static void go (AST::Stmt *stmt, NodeId parent, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix, + const CanonicalPath &enum_prefix) { - ResolveStmt resolver (parent, enum_prefix); + ResolveStmt resolver (parent, prefix, canonical_prefix, enum_prefix); stmt->accept_vis (resolver); }; void visit (AST::ExprStmtWithBlock &stmt) override { - ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ()); + ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id (), prefix, + canonical_prefix); } void visit (AST::ExprStmtWithoutBlock &stmt) override { - ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id ()); + ResolveExpr::go (stmt.get_expr ().get (), stmt.get_node_id (), prefix, + canonical_prefix); } void visit (AST::ConstantItem &constant) override { - auto path = ResolveConstantItemToCanonicalPath::resolve (constant); + auto decl = ResolveConstantItemToCanonicalPath::resolve (constant); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + constant.get_node_id (), cpath); + resolver->get_name_scope ().insert ( path, constant.get_node_id (), constant.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -66,7 +73,8 @@ public: constant.get_node_id ()}); ResolveType::go (constant.get_type ().get (), constant.get_node_id ()); - ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id ()); + ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id (), + prefix, canonical_prefix); // the mutability checker needs to verify for immutable decls the number // of assignments are <1. This marks an implicit assignment @@ -79,7 +87,8 @@ public: { if (stmt.has_init_expr ()) { - ResolveExpr::go (stmt.get_init_expr ().get (), stmt.get_node_id ()); + ResolveExpr::go (stmt.get_init_expr ().get (), stmt.get_node_id (), + prefix, canonical_prefix); // mark the assignment resolver->mark_assignment_to_decl ( @@ -93,8 +102,13 @@ public: void visit (AST::TupleStruct &struct_decl) override { - auto path = CanonicalPath::new_seg (struct_decl.get_node_id (), + auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (), struct_decl.get_identifier ()); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + struct_decl.get_node_id (), cpath); + resolver->get_type_scope ().insert ( path, struct_decl.get_node_id (), struct_decl.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -124,10 +138,15 @@ public: void visit (AST::Enum &enum_decl) override { - auto enum_path = CanonicalPath::new_seg (enum_decl.get_node_id (), - enum_decl.get_identifier ()); + auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (), + enum_decl.get_identifier ()); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + enum_decl.get_node_id (), cpath); + resolver->get_type_scope ().insert ( - enum_path, enum_decl.get_node_id (), enum_decl.get_locus (), false, + path, enum_decl.get_node_id (), enum_decl.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { RichLocation r (enum_decl.get_locus ()); r.add_range (locus); @@ -146,15 +165,20 @@ public: } for (auto &variant : enum_decl.get_variants ()) - ResolveStmt::go (variant.get (), parent, enum_path); + ResolveStmt::go (variant.get (), parent, path, canonical_prefix, path); resolver->get_type_scope ().pop (); } void visit (AST::EnumItem &item) override { - auto path = enum_prefix.append ( + auto decl = enum_prefix.append ( CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); + resolver->get_type_scope ().insert ( path, item.get_node_id (), item.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -168,8 +192,13 @@ public: void visit (AST::EnumItemTuple &item) override { - auto path = enum_prefix.append ( + auto decl = enum_prefix.append ( CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); + resolver->get_type_scope ().insert ( path, item.get_node_id (), item.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -184,8 +213,13 @@ public: void visit (AST::EnumItemStruct &item) override { - auto path = enum_prefix.append ( + auto decl = enum_prefix.append ( CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); + resolver->get_type_scope ().insert ( path, item.get_node_id (), item.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -200,8 +234,13 @@ public: void visit (AST::EnumItemDiscriminant &item) override { - auto path = enum_prefix.append ( + auto decl = enum_prefix.append ( CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); + resolver->get_type_scope ().insert ( path, item.get_node_id (), item.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -215,8 +254,13 @@ public: void visit (AST::StructStruct &struct_decl) override { - auto path = CanonicalPath::new_seg (struct_decl.get_node_id (), + auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (), struct_decl.get_identifier ()); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + struct_decl.get_node_id (), cpath); + resolver->get_type_scope ().insert ( path, struct_decl.get_node_id (), struct_decl.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -246,8 +290,13 @@ public: void visit (AST::Union &union_decl) override { - auto path = CanonicalPath::new_seg (union_decl.get_node_id (), + auto decl = CanonicalPath::new_seg (union_decl.get_node_id (), union_decl.get_identifier ()); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + union_decl.get_node_id (), cpath); + resolver->get_type_scope ().insert ( path, union_decl.get_node_id (), union_decl.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -276,7 +325,12 @@ public: void visit (AST::Function &function) override { - auto path = ResolveFunctionItemToCanonicalPath::resolve (function); + auto decl = ResolveFunctionItemToCanonicalPath::resolve (function); + auto path = decl; // this ensures we have the correct relative resolution + auto cpath = canonical_prefix.append (decl); + mappings->insert_canonical_path (mappings->get_current_crate (), + function.get_node_id (), cpath); + resolver->get_name_scope ().insert ( path, function.get_node_id (), function.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -321,8 +375,8 @@ public: } // resolve the function body - ResolveExpr::go (function.get_definition ().get (), - function.get_node_id ()); + ResolveExpr::go (function.get_definition ().get (), function.get_node_id (), + path, cpath); resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); @@ -330,10 +384,16 @@ public: } private: - ResolveStmt (NodeId parent, const CanonicalPath &enum_prefix) - : ResolverBase (parent), enum_prefix (enum_prefix) + ResolveStmt (NodeId parent, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix, + const CanonicalPath &enum_prefix) + : ResolverBase (parent), prefix (prefix), + canonical_prefix (canonical_prefix), enum_prefix (enum_prefix) {} + const CanonicalPath &prefix; + const CanonicalPath &canonical_prefix; + /* item declaration statements are not given a canonical path, but enum items * (variants) do inherit the enum path/identifier name. */ const CanonicalPath &enum_prefix; diff --git a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h index 1923d9e..b2c30a9 100644 --- a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h +++ b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h @@ -32,9 +32,11 @@ class ResolveStructExprField : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::StructExprField *field, NodeId parent) + static void go (AST::StructExprField *field, NodeId parent, + const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveStructExprField resolver (parent); + ResolveStructExprField resolver (parent, prefix, canonical_prefix); field->accept_vis (resolver); } @@ -47,7 +49,14 @@ public: void visit (AST::StructExprFieldIdentifier &field) override; private: - ResolveStructExprField (NodeId parent) : ResolverBase (parent) {} + ResolveStructExprField (NodeId parent, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) + : ResolverBase (parent), prefix (prefix), + canonical_prefix (canonical_prefix) + {} + + const CanonicalPath &prefix; + const CanonicalPath &canonical_prefix; }; } // namespace Resolver diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h index 4993649..56962f6 100644 --- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h +++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h @@ -33,17 +33,20 @@ class ResolveTopLevel : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static void go (AST::Item *item, - const CanonicalPath &prefix = CanonicalPath::create_empty ()) + static void go (AST::Item *item, const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveTopLevel resolver (prefix); + ResolveTopLevel resolver (prefix, canonical_prefix); item->accept_vis (resolver); }; void visit (AST::Module &module) override { - auto path = prefix.append ( - CanonicalPath::new_seg (module.get_node_id (), module.get_name ())); + auto mod + = CanonicalPath::new_seg (module.get_node_id (), module.get_name ()); + auto path = prefix.append (mod); + auto cpath = canonical_prefix.append (mod); + resolver->get_name_scope ().insert ( path, module.get_node_id (), module.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -57,14 +60,19 @@ public: module.get_node_id ()}); for (auto &item : module.get_items ()) - ResolveTopLevel::go (item.get (), path); + ResolveTopLevel::go (item.get (), path, cpath); + + mappings->insert_canonical_path (mappings->get_current_crate (), + module.get_node_id (), cpath); } void visit (AST::TypeAlias &alias) override { - auto path - = prefix.append (CanonicalPath::new_seg (alias.get_node_id (), - alias.get_new_type_name ())); + auto talias = CanonicalPath::new_seg (alias.get_node_id (), + alias.get_new_type_name ()); + auto path = prefix.append (talias); + auto cpath = canonical_prefix.append (talias); + resolver->get_type_scope ().insert ( path, alias.get_node_id (), alias.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -72,13 +80,18 @@ public: r.add_range (locus); rust_error_at (r, "redefined multiple times"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + alias.get_node_id (), cpath); } void visit (AST::TupleStruct &struct_decl) override { - auto path - = prefix.append (CanonicalPath::new_seg (struct_decl.get_node_id (), - struct_decl.get_identifier ())); + auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (), + struct_decl.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, struct_decl.get_node_id (), struct_decl.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -86,13 +99,18 @@ public: r.add_range (locus); rust_error_at (r, "redefined multiple times"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + struct_decl.get_node_id (), cpath); } void visit (AST::Enum &enum_decl) override { - auto path - = prefix.append (CanonicalPath::new_seg (enum_decl.get_node_id (), - enum_decl.get_identifier ())); + auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (), + enum_decl.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, enum_decl.get_node_id (), enum_decl.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -102,13 +120,19 @@ public: }); for (auto &variant : enum_decl.get_variants ()) - ResolveTopLevel::go (variant.get (), path); + ResolveTopLevel::go (variant.get (), path, cpath); + + mappings->insert_canonical_path (mappings->get_current_crate (), + enum_decl.get_node_id (), cpath); } void visit (AST::EnumItem &item) override { - auto path = prefix.append ( - CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + auto decl + = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, item.get_node_id (), item.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -116,12 +140,18 @@ public: r.add_range (locus); rust_error_at (r, "redefined multiple times"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); } void visit (AST::EnumItemTuple &item) override { - auto path = prefix.append ( - CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + auto decl + = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, item.get_node_id (), item.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -129,12 +159,18 @@ public: r.add_range (locus); rust_error_at (r, "redefined multiple times"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); } void visit (AST::EnumItemStruct &item) override { - auto path = prefix.append ( - CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + auto decl + = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, item.get_node_id (), item.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -142,12 +178,18 @@ public: r.add_range (locus); rust_error_at (r, "redefined multiple times"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); } void visit (AST::EnumItemDiscriminant &item) override { - auto path = prefix.append ( - CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ())); + auto decl + = CanonicalPath::new_seg (item.get_node_id (), item.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, item.get_node_id (), item.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -155,13 +197,18 @@ public: r.add_range (locus); rust_error_at (r, "redefined multiple times"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + item.get_node_id (), cpath); } void visit (AST::StructStruct &struct_decl) override { - auto path - = prefix.append (CanonicalPath::new_seg (struct_decl.get_node_id (), - struct_decl.get_identifier ())); + auto decl = CanonicalPath::new_seg (struct_decl.get_node_id (), + struct_decl.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, struct_decl.get_node_id (), struct_decl.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -169,13 +216,18 @@ public: r.add_range (locus); rust_error_at (r, "redefined multiple times"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + struct_decl.get_node_id (), cpath); } void visit (AST::Union &union_decl) override { - auto path - = prefix.append (CanonicalPath::new_seg (union_decl.get_node_id (), - union_decl.get_identifier ())); + auto decl = CanonicalPath::new_seg (union_decl.get_node_id (), + union_decl.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, union_decl.get_node_id (), union_decl.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -183,12 +235,18 @@ public: r.add_range (locus); rust_error_at (r, "redefined multiple times"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + union_decl.get_node_id (), cpath); } void visit (AST::StaticItem &var) override { - auto path = prefix.append ( - CanonicalPath::new_seg (var.get_node_id (), var.get_identifier ())); + auto decl + = CanonicalPath::new_seg (var.get_node_id (), var.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_name_scope ().insert ( path, var.get_node_id (), var.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -200,12 +258,17 @@ public: Definition{var.get_node_id (), var.get_node_id ()}); resolver->mark_decl_mutability (var.get_node_id (), var.is_mutable ()); + + mappings->insert_canonical_path (mappings->get_current_crate (), + var.get_node_id (), cpath); } void visit (AST::ConstantItem &constant) override { - auto path - = prefix.append (ResolveConstantItemToCanonicalPath::resolve (constant)); + auto decl = ResolveConstantItemToCanonicalPath::resolve (constant); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_name_scope ().insert ( path, constant.get_node_id (), constant.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -216,6 +279,9 @@ public: resolver->insert_new_definition (constant.get_node_id (), Definition{constant.get_node_id (), constant.get_node_id ()}); + + mappings->insert_canonical_path (mappings->get_current_crate (), + constant.get_node_id (), cpath); } void visit (AST::Function &function) override @@ -223,8 +289,10 @@ public: if (function.is_marked_for_strip ()) return; - auto path - = prefix.append (ResolveFunctionItemToCanonicalPath::resolve (function)); + auto decl = ResolveFunctionItemToCanonicalPath::resolve (function); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_name_scope ().insert ( path, function.get_node_id (), function.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -243,12 +311,16 @@ public: resolver->insert_resolved_name (function.get_node_id (), function.get_node_id ()); } + + mappings->insert_canonical_path (mappings->get_current_crate (), + function.get_node_id (), cpath); } void visit (AST::InherentImpl &impl_block) override { bool canonicalize_type_args = !impl_block.has_generics (); bool type_resolve_generic_args = false; + CanonicalPath impl_type = ResolveTypeToCanonicalPath::resolve (*impl_block.get_type ().get (), canonicalize_type_args, @@ -257,6 +329,8 @@ public: for (auto &impl_item : impl_block.get_impl_items ()) ResolveToplevelImplItem::go (impl_item.get (), impl_prefix); + + // we cannot resolve canonical paths here until later on } void visit (AST::TraitImpl &impl_block) override @@ -293,12 +367,17 @@ public: for (auto &impl_item : impl_block.get_impl_items ()) ResolveToplevelImplItem::go (impl_item.get (), impl_prefix); + + // we cannot resolve canonical paths here until later on } void visit (AST::Trait &trait) override { - CanonicalPath path = prefix.append ( - CanonicalPath::new_seg (trait.get_node_id (), trait.get_identifier ())); + auto decl + = CanonicalPath::new_seg (trait.get_node_id (), trait.get_identifier ()); + auto path = prefix.append (decl); + auto cpath = canonical_prefix.append (decl); + resolver->get_type_scope ().insert ( path, trait.get_node_id (), trait.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { @@ -308,7 +387,10 @@ public: }); for (auto &item : trait.get_trait_items ()) - ResolveTopLevelTraitItems::go (item.get (), path); + ResolveTopLevelTraitItems::go (item.get (), path, cpath); + + mappings->insert_canonical_path (mappings->get_current_crate (), + trait.get_node_id (), cpath); } void visit (AST::ExternBlock &extern_block) override @@ -320,11 +402,14 @@ public: } private: - ResolveTopLevel (const CanonicalPath &prefix) - : ResolverBase (UNKNOWN_NODEID), prefix (prefix) + ResolveTopLevel (const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) + : ResolverBase (UNKNOWN_NODEID), prefix (prefix), + canonical_prefix (canonical_prefix) {} const CanonicalPath &prefix; + const CanonicalPath &canonical_prefix; }; } // namespace Resolver diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 97c4dd8..f7bdc9e 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -250,9 +250,11 @@ class ResolveType : public ResolverBase public: static NodeId go (AST::Type *type, NodeId parent, - bool canonicalize_type_with_generics = false) + bool canonicalize_type_with_generics = false, + CanonicalPath *canonical_path = nullptr) { - ResolveType resolver (parent, canonicalize_type_with_generics); + ResolveType resolver (parent, canonicalize_type_with_generics, + canonical_path); type->accept_vis (resolver); if (!resolver.ok) rust_error_at (type->get_locus (), "unresolved type"); @@ -285,35 +287,52 @@ public: void visit (AST::TypePath &path) override { - auto canonical_path + auto rel_canonical_path = ResolveTypeToCanonicalPath::resolve (path, canonicalize_type_with_generics, true); - if (canonical_path.is_empty ()) + if (rel_canonical_path.is_empty ()) { rust_error_at (path.get_locus (), "Failed to resolve canonical path for TypePath"); return; } - ok = !canonical_path.is_empty (); + ok = !rel_canonical_path.is_empty (); // lets try and resolve in one go else leave it up to the type resolver to // figure outer - if (resolver->get_type_scope ().lookup (canonical_path, &resolved_node)) + if (resolver->get_type_scope ().lookup (rel_canonical_path, &resolved_node)) { resolver->insert_resolved_type (path.get_node_id (), resolved_node); resolver->insert_new_definition (path.get_node_id (), Definition{path.get_node_id (), parent}); + + if (canonical_path != nullptr) + { + const CanonicalPath *cpath = nullptr; + bool ok + = mappings->lookup_canonical_path (mappings->get_current_crate (), + resolved_node, &cpath); + if (!ok) + { + *canonical_path = rel_canonical_path; + } + else + { + *canonical_path = *cpath; + } + } + return; } // lets resolve as many segments as we can and leave it up to the type // resolver otherwise size_t nprocessed = 0; - canonical_path.iterate ([&] (const CanonicalPath &seg) -> bool { + rel_canonical_path.iterate ([&] (const CanonicalPath &seg) -> bool { resolved_node = UNKNOWN_NODEID; if (!resolver->get_type_scope ().lookup (seg, &resolved_node)) @@ -336,12 +355,22 @@ public: // its ok if this fails since the type resolver sometimes will need to // investigate the bounds of a type for the associated type for example see: // https://github.com/Rust-GCC/gccrs/issues/746 - if (nprocessed == canonical_path.size ()) + if (nprocessed == rel_canonical_path.size ()) { resolver->insert_resolved_type (path.get_node_id (), resolved_node); resolver->insert_new_definition (path.get_node_id (), Definition{path.get_node_id (), parent}); + + if (canonical_path != nullptr) + { + const CanonicalPath *cpath = nullptr; + bool ok + = mappings->lookup_canonical_path (mappings->get_current_crate (), + resolved_node, &cpath); + rust_assert (ok); + *canonical_path = *cpath; + } } } @@ -356,6 +385,13 @@ public: void visit (AST::ReferenceType &type) override { type.get_type_referenced ()->accept_vis (*this); + + if (canonical_path != nullptr && canonical_path->size () > 0) + { + std::string seg = canonical_path->get (); + *canonical_path + = CanonicalPath::new_seg (type.get_node_id (), "&" + seg); + } } void visit (AST::InferredType &type) override { ok = true; } @@ -363,6 +399,13 @@ public: void visit (AST::RawPointerType &type) override { type.get_type_pointed_to ()->accept_vis (*this); + + if (canonical_path != nullptr && canonical_path->size () > 0) + { + std::string seg = canonical_path->get (); + *canonical_path + = CanonicalPath::new_seg (type.get_node_id (), "*" + seg); + } } void visit (AST::TraitObjectTypeOneBound &type) override; @@ -370,14 +413,16 @@ public: void visit (AST::TraitObjectType &type) override; private: - ResolveType (NodeId parent, bool canonicalize_type_with_generics) + ResolveType (NodeId parent, bool canonicalize_type_with_generics, + CanonicalPath *canonical_path) : ResolverBase (parent), canonicalize_type_with_generics (canonicalize_type_with_generics), - ok (false) + ok (false), canonical_path (canonical_path) {} bool canonicalize_type_with_generics; bool ok; + CanonicalPath *canonical_path; }; class ResolveTypeBound : public ResolverBase @@ -453,16 +498,18 @@ public: } } - // for now lets focus on handling the basics: like struct<T> { a:T, ....} + auto seg = CanonicalPath::new_seg (param.get_node_id (), + param.get_type_representation ()); resolver->get_type_scope ().insert ( - CanonicalPath::new_seg (param.get_node_id (), - param.get_type_representation ()), - param.get_node_id (), param.get_locus (), false, + seg, param.get_node_id (), param.get_locus (), false, [&] (const CanonicalPath &, NodeId, Location locus) -> void { rust_error_at (param.get_locus (), "generic param redefined multiple times"); rust_error_at (locus, "was defined here"); }); + + mappings->insert_canonical_path (mappings->get_current_crate (), + param.get_node_id (), seg); } private: @@ -483,7 +530,10 @@ public: clause->accept_vis (r); } - void visit (AST::LifetimeWhereClauseItem &) override {} + void visit (AST::LifetimeWhereClauseItem &) override + { + // nothing to do + } void visit (AST::TypeBoundWhereClauseItem &item) override { @@ -499,7 +549,7 @@ public: private: ResolveWhereClause (NodeId parent) : ResolverBase (parent) {} -}; // namespace Resolver +}; } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index a34e631..96524d2 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -313,6 +313,13 @@ NameResolution::Resolve (AST::Crate &crate) void NameResolution::go (AST::Crate &crate) { + // lookup current crate name + CrateNum cnum = mappings->get_current_crate (); + std::string crate_name; + bool ok = mappings->get_crate_name (cnum, crate_name); + rust_assert (ok); + + // setup the ribs NodeId scope_node_id = crate.get_node_id (); resolver->get_name_scope ().push (scope_node_id); resolver->get_type_scope ().push (scope_node_id); @@ -321,16 +328,25 @@ NameResolution::go (AST::Crate &crate) resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); resolver->push_new_label_rib (resolver->get_type_scope ().peek ()); - // first gather the top-level namespace names then we drill down + // get the root segment + CanonicalPath crate_prefix + = CanonicalPath::new_seg (scope_node_id, crate_name); + crate_prefix.set_crate_num (cnum); + + // first gather the top-level namespace names then we drill down so this + // allows for resolving forward declarations since an impl block might have + // a Self type Foo which is defined after the impl block for example. for (auto it = crate.items.begin (); it != crate.items.end (); it++) - ResolveTopLevel::go (it->get ()); + ResolveTopLevel::go (it->get (), CanonicalPath::create_empty (), + crate_prefix); + // FIXME remove this if (saw_errors ()) return; // next we can drill down into the items and their scopes for (auto it = crate.items.begin (); it != crate.items.end (); it++) - ResolveItem::go (it->get ()); + ResolveItem::go (it->get (), CanonicalPath::create_empty (), crate_prefix); } // rust-ast-resolve-expr.h @@ -349,17 +365,19 @@ ResolveExpr::visit (AST::BlockExpr &expr) for (auto &s : expr.get_statements ()) { if (s->is_item ()) - ResolveStmt::go (s.get (), s->get_node_id ()); + ResolveStmt::go (s.get (), s->get_node_id (), prefix, canonical_prefix, + CanonicalPath::create_empty ()); } for (auto &s : expr.get_statements ()) { if (!s->is_item ()) - ResolveStmt::go (s.get (), s->get_node_id ()); + ResolveStmt::go (s.get (), s->get_node_id (), prefix, canonical_prefix, + CanonicalPath::create_empty ()); } if (expr.has_tail_expr ()) - ResolveExpr::go (expr.get_tail_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_tail_expr ().get (), expr.get_node_id ()); resolver->get_name_scope ().pop (); resolver->get_type_scope ().pop (); @@ -371,13 +389,15 @@ ResolveExpr::visit (AST::BlockExpr &expr) void ResolveStructExprField::visit (AST::StructExprFieldIdentifierValue &field) { - ResolveExpr::go (field.get_value ().get (), field.get_node_id ()); + ResolveExpr::go (field.get_value ().get (), field.get_node_id (), prefix, + canonical_prefix); } void ResolveStructExprField::visit (AST::StructExprFieldIndexValue &field) { - ResolveExpr::go (field.get_value ().get (), field.get_node_id ()); + ResolveExpr::go (field.get_value ().get (), field.get_node_id (), prefix, + canonical_prefix); } void @@ -386,7 +406,7 @@ ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field) AST::IdentifierExpr expr (field.get_field_name (), {}, field.get_locus ()); expr.set_node_id (field.get_node_id ()); - ResolveExpr::go (&expr, field.get_node_id ()); + ResolveExpr::go (&expr, field.get_node_id (), prefix, canonical_prefix); } // rust-ast-resolve-type.h @@ -746,7 +766,12 @@ void ResolveType::visit (AST::ArrayType &type) { type.get_elem_type ()->accept_vis (*this); - ResolveExpr::go (type.get_size_expr ().get (), type.get_node_id ()); + // FIXME + // the capacity expr can contain block-expr with functions but these should be + // folded via constexpr code + ResolveExpr::go (type.get_size_expr ().get (), type.get_node_id (), + CanonicalPath::create_empty (), + CanonicalPath::create_empty ()); } void @@ -771,15 +796,19 @@ ResolveType::visit (AST::TraitObjectType &type) // rust-ast-resolve-item.h void -ResolveItem::resolve_impl_item (AST::TraitImplItem *item) +ResolveItem::resolve_impl_item (AST::TraitImplItem *item, + const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveImplItems::go (item); + ResolveImplItems::go (item, prefix, canonical_prefix); } void -ResolveItem::resolve_impl_item (AST::InherentImplItem *item) +ResolveItem::resolve_impl_item (AST::InherentImplItem *item, + const CanonicalPath &prefix, + const CanonicalPath &canonical_prefix) { - ResolveImplItems::go (item); + ResolveImplItems::go (item, prefix, canonical_prefix); } void diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h index ac00d58..199b0f9 100644 --- a/gcc/rust/resolve/rust-name-resolver.h +++ b/gcc/rust/resolve/rust-name-resolver.h @@ -39,6 +39,7 @@ public: ~Rib () {} + // this takes the relative paths of items within a compilation unit for lookup void insert_name ( const CanonicalPath &path, NodeId id, Location locus, bool shadow, std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb) @@ -60,7 +61,6 @@ public: reverse_path_mappings.insert (std::pair<NodeId, CanonicalPath> (id, path)); decls_within_rib.insert (std::pair<NodeId, Location> (id, locus)); references[id] = {}; - mappings->insert_canonical_path (mappings->get_current_crate (), id, path); } bool lookup_name (const CanonicalPath &ident, NodeId *id) diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index c930f55..83f35ff 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -69,7 +69,7 @@ const char *kHIRDumpFile = "gccrs.hir.dump"; const char *kHIRTypeResolutionDumpFile = "gccrs.type-resolution.dump"; const char *kTargetOptionsDumpFile = "gccrs.target-options.dump"; -const std::string kDefaultCrateName = "TestCrate"; +const std::string kDefaultCrateName = "example"; // Implicitly enable a target_feature (and recursively enable dependencies). void diff --git a/gcc/rust/util/rust-canonical-path.h b/gcc/rust/util/rust-canonical-path.h index 8473df6..9b34075 100644 --- a/gcc/rust/util/rust-canonical-path.h +++ b/gcc/rust/util/rust-canonical-path.h @@ -57,7 +57,8 @@ public: static CanonicalPath new_seg (NodeId id, const std::string &path) { rust_assert (!path.empty ()); - return CanonicalPath ({std::pair<NodeId, std::string> (id, path)}); + return CanonicalPath ({std::pair<NodeId, std::string> (id, path)}, + UNKNOWN_CREATENUM); } std::string get () const @@ -77,7 +78,10 @@ public: return CanonicalPath::new_seg (id, "Self"); } - static CanonicalPath create_empty () { return CanonicalPath ({}); } + static CanonicalPath create_empty () + { + return CanonicalPath ({}, UNKNOWN_CREATENUM); + } bool is_empty () const { return segs.size () == 0; } @@ -85,13 +89,13 @@ public: { rust_assert (!other.is_empty ()); if (is_empty ()) - return CanonicalPath (other.segs); + return CanonicalPath (other.segs, crate_num); std::vector<std::pair<NodeId, std::string>> copy (segs); for (auto &s : other.segs) copy.push_back (s); - return CanonicalPath (copy); + return CanonicalPath (copy, crate_num); } // if we have the path A::B::C this will give a callback for each segment @@ -110,7 +114,7 @@ public: for (auto &seg : segs) { buf.push_back (seg); - if (!cb (CanonicalPath (buf))) + if (!cb (CanonicalPath (buf, crate_num))) return; } } @@ -131,7 +135,7 @@ public: { std::vector<std::pair<NodeId, std::string>> buf; buf.push_back ({seg.first, seg.second}); - if (!cb (CanonicalPath (buf))) + if (!cb (CanonicalPath (buf, crate_num))) return; } } @@ -144,21 +148,37 @@ public: return segs.back ().first; } + const std::pair<NodeId, std::string> &get_seg_at (size_t index) const + { + rust_assert (index < size ()); + return segs.at (index); + } + bool is_equal (const CanonicalPath &b) const { return get ().compare (b.get ()) == 0; } + void set_crate_num (CrateNum n) { crate_num = n; } + + CrateNum get_crate_num () const + { + rust_assert (crate_num != UNKNOWN_CREATENUM); + return crate_num; + } + bool operator== (const CanonicalPath &b) const { return is_equal (b); } bool operator< (const CanonicalPath &b) const { return get () < b.get (); } private: - explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path) - : segs (path) + explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path, + CrateNum crate_num) + : segs (path), crate_num (crate_num) {} std::vector<std::pair<NodeId, std::string>> segs; + CrateNum crate_num; }; } // namespace Resolver diff --git a/gcc/testsuite/rust/compile/canonical_paths1.rs b/gcc/testsuite/rust/compile/canonical_paths1.rs new file mode 100644 index 0000000..af547ef --- /dev/null +++ b/gcc/testsuite/rust/compile/canonical_paths1.rs @@ -0,0 +1,25 @@ +// { dg-additional-options "-w -fdump-tree-gimple" } +struct Foo(i32); + +trait TR { + fn test(&self) -> i32; +} + +mod A { + impl ::Foo { + pub fn test(self) {} + // { dg-final { scan-tree-dump-times {example::A::<impl example::Foo>::test} 2 gimple } } + } + + impl ::TR for ::Foo { + fn test(&self) -> i32 { + // { dg-final { scan-tree-dump-times {example::A::<impl example::Foo as example::TR>::test} 1 gimple } } + self.0 + } + } +} + +pub fn test() { + let a = Foo(123); + a.test(); +} diff --git a/gcc/testsuite/rust/compile/torture/mod3.rs b/gcc/testsuite/rust/compile/torture/mod3.rs index e241839..2ace8c0 100644 --- a/gcc/testsuite/rust/compile/torture/mod3.rs +++ b/gcc/testsuite/rust/compile/torture/mod3.rs @@ -1,25 +1,22 @@ +// { dg-additional-options "-w" } mod A { - pub mod B { // { dg-warning "unused name" } - pub mod C { // { dg-warning "unused name" } + pub mod B { + pub mod C { pub struct Foo { pub f: i32, } impl Foo { - pub fn new() -> Self { // { dg-warning "unused name" } - Foo { - f: 23i32, - } + pub fn new() -> Self { + Foo { f: 23i32 } } } } } } -fn main() ->i32 { +fn main() -> i32 { let a = A::B::C::Foo::new(); - let b = A::B::C::Foo { - f: -23i32, - }; + let b = A::B::C::Foo { f: -23i32 }; a.f - b.f } diff --git a/gcc/testsuite/rust/compile/traits9.rs b/gcc/testsuite/rust/compile/traits9.rs index e1aef539..7ef577a 100644 --- a/gcc/testsuite/rust/compile/traits9.rs +++ b/gcc/testsuite/rust/compile/traits9.rs @@ -8,6 +8,6 @@ fn main() { a = Foo(123); let b: &dyn Bar = &a; - // { dg-error "bounds not satisfied for Foo .Bar. is not satisfied" "" { target *-*-* } .-1 } + // { dg-error "bounds not satisfied for Foo .example::Bar. is not satisfied" "" { target *-*-* } .-1 } // { dg-error "expected" "" { target *-*-* } .-2 } } |