diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-01-29 15:00:30 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-29 15:00:30 +0000 |
commit | 631f7ae7b9dbb55ed3adce942952f93b48983a53 (patch) | |
tree | f5fc89773ab1941593f3f2230908919063679c68 /gcc | |
parent | bc7f518ac6f5c05f1c6edd7a1601f32753bab47d (diff) | |
parent | 2fbf9cb25e930e2df86d05e0f7f707e69bae2b1f (diff) | |
download | gcc-631f7ae7b9dbb55ed3adce942952f93b48983a53.zip gcc-631f7ae7b9dbb55ed3adce942952f93b48983a53.tar.gz gcc-631f7ae7b9dbb55ed3adce942952f93b48983a53.tar.bz2 |
Merge #894
894: Update name-resolution to build up canonical-path with the crate-name r=philberty a=philberty
The name resolver there are two types of canonical-path object.
1. The relative canonical path to a type for name resolution
2. The full canonical-path including the crate-name (this-was-missing)
The lack of the crate-name being present in the canonical-path meant the
symbol mangling system was required to append it where appropriate but this
was going to be too messy to handle all cases. Such as module blocks
containing impl blocks requires a ```prefix::<impl crate::path>::item``` and
similarly for trait impl blocks.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
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 } } |