diff options
23 files changed, 280 insertions, 29 deletions
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index dac76f5..b996e17 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -972,6 +972,8 @@ public: UNLOADED, }; + Identifier get_name () const { return module_name; } + private: Identifier module_name; Location locus; diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index 719d51c..8b36289 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -301,6 +301,12 @@ public: } } + void visit (HIR::ModuleBodied &module) override + { + for (auto &item : module.get_items ()) + CompileItem::compile (item.get (), ctx, compile_fns); + } + private: CompileItem (Context *ctx, bool compile_fns, TyTy::BaseType *concrete) : HIRCompileBase (ctx), compile_fns (compile_fns), concrete (concrete) diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 3c6a188..b9b5084 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -88,6 +88,7 @@ CompileExpr::visit (HIR::CallExpr &expr) { // must be a call to a function Bexpression *fn = CompileExpr::Compile (expr.get_fnexpr (), ctx); + rust_assert (fn != nullptr); std::vector<Bexpression *> args; expr.iterate_params ([&] (HIR::Expr *p) mutable -> bool { diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h index 3083554..bcf83ee 100644 --- a/gcc/rust/hir/rust-ast-lower-item.h +++ b/gcc/rust/hir/rust-ast-lower-item.h @@ -29,6 +29,7 @@ #include "rust-ast-lower-pattern.h" #include "rust-ast-lower-block.h" #include "rust-ast-lower-extern.h" +#include "rust-hir-full-decls.h" namespace Rust { namespace HIR { @@ -54,6 +55,43 @@ public: return resolver.translated; } + void visit (AST::Module &module) override + { + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, module.get_node_id (), + mappings->get_next_hir_id (crate_num), + mappings->get_next_localdef_id (crate_num)); + + // should be lowered from module.get_vis() + HIR::Visibility vis = HIR::Visibility::create_public (); + + auto items = std::vector<std::unique_ptr<Item> > (); + + for (auto &item : module.get_items ()) + { + auto transitem = translate (item.get ()); + items.push_back (std::unique_ptr<Item> (transitem)); + } + + // should be lowered/copied from module.get_in/outer_attrs() + AST::AttrVec inner_attrs; + AST::AttrVec outer_attrs; + + translated + = new HIR::ModuleBodied (mapping, module.get_name (), module.get_locus (), + std::move (items), std::move (vis), + std::move (inner_attrs), + std::move (outer_attrs)); + + mappings->insert_defid_mapping (mapping.get_defid (), translated); + mappings->insert_hir_item (mapping.get_crate_num (), mapping.get_hirid (), + translated); + mappings->insert_module (mapping.get_crate_num (), mapping.get_hirid (), + static_cast<Module *> (translated)); + mappings->insert_location (crate_num, mapping.get_hirid (), + module.get_locus ()); + } + void visit (AST::TypeAlias &alias) override { std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items; diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index ba04339..32ee317 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -718,6 +718,8 @@ public: void accept_vis (HIRVisitor &vis) override; + std::vector<std::unique_ptr<Item> > &get_items () { return items; }; + /* Override that runs the function recursively on all items contained within * the module. */ void add_crate_name (std::vector<std::string> &names) const override; diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index c67121d..bc05e93 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -19,8 +19,10 @@ #ifndef RUST_AST_RESOLVE_ITEM_H #define RUST_AST_RESOLVE_ITEM_H +#include "rust-ast-full-decls.h" #include "rust-ast-resolve-base.h" #include "rust-ast-full.h" +#include "rust-ast-resolve-toplevel.h" #include "rust-ast-resolve-type.h" #include "rust-ast-resolve-pattern.h" #include "rust-ast-resolve-stmt.h" @@ -214,6 +216,27 @@ public: resolver->get_type_scope ().pop (); } + void visit (AST::Module &module) override + { + NodeId scope_node_id = module.get_node_id (); + resolver->get_name_scope ().push (scope_node_id); + resolver->get_type_scope ().push (scope_node_id); + resolver->get_label_scope ().push (scope_node_id); + resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); + resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); + resolver->push_new_label_rib (resolver->get_type_scope ().peek ()); + + for (auto &item : module.get_items ()) + ResolveTopLevel::go (item.get ()); + + for (auto &item : module.get_items ()) + ResolveItem::go (item.get ()); + + resolver->get_name_scope ().pop (); + resolver->get_type_scope ().pop (); + resolver->get_label_scope ().pop (); + } + void visit (AST::TupleStruct &struct_decl) override { NodeId scope_node_id = struct_decl.get_node_id (); diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h index 57a0534..2c1de66 100644 --- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h +++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h @@ -23,6 +23,7 @@ #include "rust-ast-resolve-type.h" #include "rust-ast-resolve-implitem.h" #include "rust-ast-full.h" +#include "rust-name-resolver.h" namespace Rust { namespace Resolver { @@ -39,6 +40,26 @@ public: item->accept_vis (resolver); }; + void visit (AST::Module &module) override + { + auto path = prefix.append ( + CanonicalPath::new_seg (module.get_node_id (), module.get_name ())); + resolver->get_name_scope ().insert ( + path, module.get_node_id (), module.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + RichLocation r (module.get_locus ()); + r.add_range (locus); + rust_error_at (r, "redefined multiple times"); + }); + + resolver->insert_new_definition (module.get_node_id (), + Definition{module.get_node_id (), + module.get_node_id ()}); + + for (auto &item : module.get_items ()) + ResolveTopLevel::go (item.get (), path); + } + void visit (AST::TypeAlias &alias) override { auto path diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 49f1332..b8affe6 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -206,6 +206,9 @@ public: auto resolver = Resolver::get (); NodeId resolved_node = UNKNOWN_NODEID; + + // We may need to change how names are resolved, like described in : + // https://github.com/rust-lang/rust/blob/1f94abcda6884893d4723304102089198caa0839/compiler/rustc_resolve/src/lib.rs#L1722 if (!resolver->get_type_scope ().lookup (canonical_path, &resolved_node)) { rust_error_at (path.get_locus_slow (), "failed to resolve TypePath: %s", diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index 1b77ae2..5b24816 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -552,6 +552,10 @@ ResolvePath::resolve_path (AST::PathInExpression *expr) auto s = ResolvePathSegmentToCanonicalPath::resolve (seg); path = path.append (s); + // reset state + segment_is_type = false; + resolved_node = UNKNOWN_NODEID; + if (resolver->get_name_scope ().lookup (path, &resolved_node)) { resolver->insert_resolved_name (seg.get_node_id (), resolved_node); @@ -562,6 +566,7 @@ ResolvePath::resolve_path (AST::PathInExpression *expr) // check the type scope else if (resolver->get_type_scope ().lookup (path, &resolved_node)) { + segment_is_type = true; resolver->insert_resolved_type (seg.get_node_id (), resolved_node); resolver->insert_new_definition (seg.get_node_id (), Definition{expr->get_node_id (), @@ -611,6 +616,19 @@ ResolvePath::resolve_path (AST::PathInExpression *expr) return; } } + + // its fully resolved lets mark it as such + if (resolved_node != UNKNOWN_NODEID) + { + if (segment_is_type) + resolver->insert_resolved_type (expr->get_node_id (), resolved_node); + else + resolver->insert_resolved_name (expr->get_node_id (), resolved_node); + + resolver->insert_new_definition (expr->get_node_id (), + Definition{expr->get_node_id (), + parent}); + } } // rust-ast-resolve-type.h diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h index 6fac3d3..69da4a69 100644 --- a/gcc/rust/resolve/rust-name-resolver.h +++ b/gcc/rust/resolve/rust-name-resolver.h @@ -30,7 +30,7 @@ namespace Resolver { class Rib { public: - // Rusts uses local_def_ids assigned by def_collector on the AST + // Rust uses local_def_ids assigned by def_collector on the AST // lets use NodeId instead Rib (CrateNum crateNum, NodeId node_id) : crate_num (crateNum), node_id (node_id) diff --git a/gcc/rust/typecheck/rust-hir-path-probe.h b/gcc/rust/typecheck/rust-hir-path-probe.h index 87c9662..22b1074 100644 --- a/gcc/rust/typecheck/rust-hir-path-probe.h +++ b/gcc/rust/typecheck/rust-hir-path-probe.h @@ -260,6 +260,7 @@ private: break; case TraitItemReference::TraitItemType::ERROR: + default: gcc_unreachable (); break; } diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h index a833822..d39b2ee 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.h +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h @@ -936,6 +936,10 @@ public: if (tyseg->get_kind () == TyTy::TypeKind::ERROR) return; + // this is the case where the name resolver has already fully resolved the + // name, which means all the work is already done. + bool name_resolved_fully = offset >= expr.get_num_segments (); + if (expr.get_num_segments () == 1) { Location locus = expr.get_segments ().back ().get_locus (); @@ -1052,7 +1056,7 @@ public: { rust_assert (path_resolved_id == resolved_node_id); } - else + else if (!name_resolved_fully) { resolver->insert_resolved_name (expr.get_mappings ().get_nodeid (), resolved_node_id); @@ -1214,6 +1218,8 @@ private: for (size_t i = 0; i < expr.get_num_segments (); i++) { HIR::PathExprSegment &seg = expr.get_segments ().at (i); + + bool have_more_segments = (expr.get_num_segments () - 1 != i); bool is_root = *offset == 0; NodeId ast_node_id = seg.get_mappings ().get_nodeid (); @@ -1238,6 +1244,7 @@ private: resolver->lookup_resolved_type (ast_node_id, &ref_node_id); } + // ref_node_id is the NodeId that the segments refers to. if (ref_node_id == UNKNOWN_NODEID) { if (is_root) @@ -1265,27 +1272,33 @@ private: return new TyTy::ErrorType (expr.get_mappings ().get_hirid ()); } + return root_tyty; } - // FIXME - // modules are not going to have an explicit TyTy.In this case we - // can probably do some kind of check. By looking up if the HirId ref - // node is a module and continue. If the path expression is single - // segment of module we can error with expected value but found module - // or something. - // - // Something like this - // - // bool seg_is_module = mappings->lookup_module (ref); - // if (seg_is_module) - // { - // if (have_more_segments) - // continue; - // - // rust_error_at (seg.get_locus (), "expected value"); - // return new TyTy::ErrorType (expr.get_mappings ().get_hirid ()); - // } + auto seg_is_module + = (nullptr + != mappings->lookup_module (expr.get_mappings ().get_crate_num (), + ref)); + + if (seg_is_module) + { + // A::B::C::this_is_a_module::D::E::F + // ^^^^^^^^^^^^^^^^ + // Currently handling this. + if (have_more_segments) + { + (*offset)++; + continue; + } + + // In the case of : + // A::B::C::this_is_a_module + // ^^^^^^^^^^^^^^^^ + // This is an error, we are not expecting a module. + rust_error_at (seg.get_locus (), "expected value"); + return new TyTy::ErrorType (expr.get_mappings ().get_hirid ()); + } TyTy::BaseType *lookup = nullptr; if (!context->lookup_type (ref, &lookup)) diff --git a/gcc/rust/typecheck/rust-hir-type-check-item.h b/gcc/rust/typecheck/rust-hir-type-check-item.h index 8775502..372171f 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-item.h +++ b/gcc/rust/typecheck/rust-hir-type-check-item.h @@ -156,6 +156,12 @@ public: expected_ret_tyty->unify (block_expr_ty); } + void visit (HIR::ModuleBodied &module) override + { + for (auto &item : module.get_items ()) + TypeCheckItem::Resolve (item.get ()); + } + private: TypeCheckItem () : TypeCheckBase () {} }; diff --git a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h index 5b9757f..aad5cb9 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-toplevel.h +++ b/gcc/rust/typecheck/rust-hir-type-check-toplevel.h @@ -101,6 +101,12 @@ public: context->insert_type (struct_decl.get_mappings (), type); } + void visit (HIR::ModuleBodied &module) override + { + for (auto &item : module.get_items ()) + TypeCheckTopLevel::Resolve (item.get ()); + } + void visit (HIR::StructStruct &struct_decl) override { std::vector<TyTy::SubstitutionParamMapping> substitutions; diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc index 0f8f902..d544042 100644 --- a/gcc/rust/util/rust-hir-map.cc +++ b/gcc/rust/util/rust-hir-map.cc @@ -325,6 +325,28 @@ Mappings::lookup_hir_impl_block (CrateNum crateNum, HirId id) } void +Mappings::insert_module (CrateNum crateNum, HirId id, HIR::Module *module) +{ + rust_assert (lookup_module (crateNum, id) == nullptr); + + hirModuleMappings[crateNum][id] = module; +} + +HIR::Module * +Mappings::lookup_module (CrateNum crateNum, HirId id) +{ + auto it = hirModuleMappings.find (crateNum); + if (it == hirModuleMappings.end ()) + return nullptr; + + auto iy = it->second.find (id); + if (iy == it->second.end ()) + return nullptr; + + return iy->second; +} + +void Mappings::insert_hir_implitem (CrateNum crateNum, HirId id, HirId parent_impl_id, HIR::ImplItem *item) { diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h index 5c839b0..2366724 100644 --- a/gcc/rust/util/rust-hir-map.h +++ b/gcc/rust/util/rust-hir-map.h @@ -131,6 +131,9 @@ public: HIR::ImplBlock *item); HIR::ImplBlock *lookup_hir_impl_block (CrateNum crateNum, HirId id); + void insert_module (CrateNum crateNum, HirId id, HIR::Module *module); + HIR::Module *lookup_module (CrateNum crateNum, HirId id); + void insert_hir_implitem (CrateNum crateNum, HirId id, HirId parent_impl_id, HIR::ImplItem *item); HIR::ImplItem *lookup_hir_implitem (CrateNum crateNum, HirId id, @@ -279,6 +282,7 @@ private: std::map<DefId, HIR::Item *> defIdMappings; std::map<CrateNum, std::map<LocalDefId, HIR::Item *> > localDefIdMappings; + std::map<CrateNum, std::map<HirId, HIR::Module *> > hirModuleMappings; std::map<CrateNum, std::map<HirId, HIR::Item *> > hirItemMappings; std::map<CrateNum, std::map<HirId, HIR::Type *> > hirTypeMappings; std::map<CrateNum, std::map<HirId, HIR::Expr *> > hirExprMappings; diff --git a/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs index ab38ac6..41c3b51 100644 --- a/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs +++ b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks.rs @@ -9,7 +9,7 @@ /// outer doc line for module /** outer doc block for module */ -pub mod module +pub mod module // { dg-warning "unused name" } { //! inner line doc //!! inner line doc! @@ -24,21 +24,23 @@ pub mod module /** outer block doc */ /*** block comment */ - mod block_doc_comments + mod block_doc_comments // { dg-warning "unused name" } { /* /* */ /** */ /*! */ */ /*! /* */ /** */ /*! */ */ /** /* */ /** */ /*! */ */ - mod item { } + mod item { } // { dg-warning "unused name" } } - pub mod empty + pub mod empty // { dg-warning "unused name" } { //! /*!*/ // /// + // the following warning is issued one line earlier + // { dg-warning "unused name" } mod doc { } /**/ /***/ diff --git a/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs index 3ea2cd0..e5ed911 100644 --- a/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs +++ b/gcc/testsuite/rust/compile/torture/all_doc_comment_line_blocks_crlf.rs @@ -9,7 +9,7 @@ /// outer doc line for module
/** outer doc block for module */
-pub mod module
+pub mod module // { dg-warning "unused name" }
{
//! inner line doc
//!! inner line doc!
@@ -24,22 +24,23 @@ pub mod module /** outer block doc */
/*** block comment */
- mod block_doc_comments
+ mod block_doc_comments // { dg-warning "unused name" }
{
/* /* */ /** */ /*! */ */
/*! /* */ /** */ /*! */ */
/** /* */ /** */ /*! */ */
- mod item { }
+ mod item { } // { dg-warning "unused name" }
}
- pub mod empty
+ pub mod empty // { dg-warning "unused name" }
{
//!
/*!*/
//
///
- mod doc { }
+ mod doc { } // { dg-warning "unused name" }
+
/**/
/***/
}
diff --git a/gcc/testsuite/rust/compile/torture/mod-nameresolve.rs b/gcc/testsuite/rust/compile/torture/mod-nameresolve.rs new file mode 100644 index 0000000..218095c --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/mod-nameresolve.rs @@ -0,0 +1,5 @@ +mod foo { // { dg-warning "unused name" } + struct A; // { dg-warning "unused name" } +} + +fn main() {} diff --git a/gcc/testsuite/rust/compile/torture/mod1.rs b/gcc/testsuite/rust/compile/torture/mod1.rs new file mode 100644 index 0000000..ca272f7 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/mod1.rs @@ -0,0 +1,12 @@ +// This is testing name resolution + +mod _foo { + struct _A; +} + +mod _bar { + mod _barbis { + struct _B; + } +} + diff --git a/gcc/testsuite/rust/compile/torture/mod2.rs b/gcc/testsuite/rust/compile/torture/mod2.rs new file mode 100644 index 0000000..6a2d1ed --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/mod2.rs @@ -0,0 +1,15 @@ +mod foomod { + pub struct Foo { // { dg-warning "unused name" } + } +} + +impl foomod::Foo { + pub fn new() -> Self { + foomod::Foo { + } + } +} + +fn main() { + let _a = foomod::Foo::new(); +} diff --git a/gcc/testsuite/rust/compile/torture/mod3.rs b/gcc/testsuite/rust/compile/torture/mod3.rs new file mode 100644 index 0000000..e241839 --- /dev/null +++ b/gcc/testsuite/rust/compile/torture/mod3.rs @@ -0,0 +1,25 @@ +mod A { + pub mod B { // { dg-warning "unused name" } + pub mod C { // { dg-warning "unused name" } + pub struct Foo { + pub f: i32, + } + impl Foo { + pub fn new() -> Self { // { dg-warning "unused name" } + Foo { + f: 23i32, + } + } + } + } + } +} + +fn main() ->i32 { + let a = A::B::C::Foo::new(); + let b = A::B::C::Foo { + f: -23i32, + }; + + a.f - b.f +} diff --git a/gcc/testsuite/rust/execute/torture/mod1.rs b/gcc/testsuite/rust/execute/torture/mod1.rs new file mode 100644 index 0000000..37e7ce3 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/mod1.rs @@ -0,0 +1,25 @@ +mod A { + pub mod B { // { dg-warning "unused name" } + pub mod C { // { dg-warning "unused name" } + pub struct Foo { + pub f: i32, + } + impl Foo { + pub fn new() -> Self { // { dg-warning "unused name" } + Foo { + f: 23i32, + } + } + } + } + } +} + +fn main() ->i32 { + let a = A::B::C::Foo::new(); + let b = A::B::C::Foo { + f: -23i32, + }; + + a.f + b.f +} |