From f6589ca957b2a1d0bea6c43dd60e37b06cb04ab3 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Wed, 1 Jun 2022 10:53:04 +0100 Subject: [PATCH 1/3] Add name resolution to ForLoopExpr --- gcc/rust/resolve/rust-ast-resolve-expr.cc | 47 +++++++++++++++++++++++ gcc/rust/resolve/rust-ast-resolve-expr.h | 2 + 2 files changed, 49 insertions(+) diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc index 402c0488277d..4bf35efdbbe0 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.cc +++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc @@ -420,6 +420,53 @@ ResolveExpr::visit (AST::WhileLoopExpr &expr) resolve_expr (expr.get_loop_block ().get (), expr.get_node_id ()); } +void +ResolveExpr::visit (AST::ForLoopExpr &expr) +{ + if (expr.has_loop_label ()) + { + auto label = expr.get_loop_label (); + if (label.get_lifetime ().get_lifetime_type () + != AST::Lifetime::LifetimeType::NAMED) + { + rust_error_at (label.get_locus (), + "Labels must be a named lifetime value"); + return; + } + + auto label_name = label.get_lifetime ().get_lifetime_name (); + auto label_lifetime_node_id = label.get_lifetime ().get_node_id (); + resolver->get_label_scope ().insert ( + CanonicalPath::new_seg (label.get_node_id (), label_name), + label_lifetime_node_id, label.get_locus (), false, + [&] (const CanonicalPath &, NodeId, Location locus) -> void { + rust_error_at (label.get_locus (), "label redefined multiple times"); + rust_error_at (locus, "was defined here"); + }); + resolver->insert_new_definition (label_lifetime_node_id, + Definition{label_lifetime_node_id, + label.get_node_id ()}); + } + + // this needs a new rib to contain the pattern + NodeId scope_node_id = expr.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 ()); + + // resolve the expression + PatternDeclaration::go (expr.get_pattern ().get (), expr.get_node_id ()); + resolve_expr (expr.get_iterator_expr ().get (), expr.get_node_id ()); + resolve_expr (expr.get_loop_block ().get (), expr.get_node_id ()); + + resolver->get_name_scope ().pop (); + resolver->get_type_scope ().pop (); + resolver->get_label_scope ().pop (); +} + void ResolveExpr::visit (AST::ContinueExpr &expr) { diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h index 72e608532fda..4f189decc9d2 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ b/gcc/rust/resolve/rust-ast-resolve-expr.h @@ -99,6 +99,8 @@ class ResolveExpr : public ResolverBase void visit (AST::WhileLoopExpr &expr) override; + void visit (AST::ForLoopExpr &expr) override; + void visit (AST::ContinueExpr &expr) override; void visit (AST::BorrowExpr &expr) override; From 92f9eb46ec0ef70c808db613da4312af09f736df Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Wed, 1 Jun 2022 10:53:37 +0100 Subject: [PATCH 2/3] Add hir lowering to ForLoopExpr this will eventually all become a simple HIR::LoopExpr --- gcc/rust/hir/rust-ast-lower-block.h | 2 ++ gcc/rust/hir/rust-ast-lower-expr.h | 5 +++++ gcc/rust/hir/rust-ast-lower.cc | 26 ++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h index 5c328b534466..b8f717509505 100644 --- a/gcc/rust/hir/rust-ast-lower-block.h +++ b/gcc/rust/hir/rust-ast-lower-block.h @@ -225,6 +225,8 @@ class ASTLoweringExprWithBlock : public ASTLoweringBase void visit (AST::WhileLoopExpr &expr) override; + void visit (AST::ForLoopExpr &expr) override; + void visit (AST::MatchExpr &expr) override; private: diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h index 5ae538621aa1..a3f8d6e24a0b 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.h +++ b/gcc/rust/hir/rust-ast-lower-expr.h @@ -579,6 +579,11 @@ class ASTLoweringExpr : public ASTLoweringBase translated = ASTLoweringExprWithBlock::translate (&expr, &terminated); } + void visit (AST::ForLoopExpr &expr) override + { + translated = ASTLoweringExprWithBlock::translate (&expr, &terminated); + } + void visit (AST::BreakExpr &expr) override { HIR::Lifetime break_label = lower_lifetime (expr.get_label ()); diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index d8a048832327..b3b0ee8c4659 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -323,6 +323,32 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr) expr.get_outer_attrs ()); } +void +ASTLoweringExprWithBlock::visit (AST::ForLoopExpr &expr) +{ + HIR::BlockExpr *loop_block + = ASTLoweringBlock::translate (expr.get_loop_block ().get (), &terminated); + HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ()); + HIR::Expr *iterator_expr + = ASTLoweringExpr::translate (expr.get_iterator_expr ().get (), + &terminated); + HIR::Pattern *loop_pattern + = ASTLoweringPattern::translate (expr.get_pattern ().get ()); + + auto crate_num = mappings->get_current_crate (); + Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), + mappings->get_next_hir_id (crate_num), + UNKNOWN_LOCAL_DEFID); + + translated + = new HIR::ForLoopExpr (mapping, + std::unique_ptr (loop_pattern), + std::unique_ptr (iterator_expr), + std::unique_ptr (loop_block), + expr.get_locus (), std::move (loop_label), + expr.get_outer_attrs ()); +} + void ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr) { From 91b16af14cb4f7cdf6414b1314c35202d5883fd9 Mon Sep 17 00:00:00 2001 From: Philip Herron Date: Thu, 2 Jun 2022 12:13:43 +0100 Subject: [PATCH 3/3] Fixup name canonicalization for impl blocks When we generate the path for impl items we need to base this of the Self type but this was ignoring cases like pointers, references or slices. This meant generic slices had the same path has generic pointers etc. The only reason we didn't end up with a linker symbol clash is due to the symbol hash. --- gcc/rust/resolve/rust-ast-resolve-item.cc | 2 + gcc/rust/resolve/rust-ast-resolve-type.cc | 49 +++++++++++++++-------- gcc/rust/resolve/rust-ast-resolve-type.h | 7 +--- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc index 38e7713e45df..603037e8d8fd 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.cc +++ b/gcc/rust/resolve/rust-ast-resolve-item.cc @@ -613,6 +613,7 @@ ResolveItem::visit (AST::InherentImpl &impl_block) resolver->get_name_scope ().pop (); return; } + rust_assert (!self_cpath.is_empty ()); // Setup paths bool canonicalize_type_args = !impl_block.has_generics (); @@ -637,6 +638,7 @@ ResolveItem::visit (AST::InherentImpl &impl_block) = CanonicalPath::new_seg (impl_block.get_node_id (), seg_buf); cpath = canonical_prefix.append (seg); } + // done setup paths auto Self diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc index 141788019ee8..2b5c68447a08 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.cc +++ b/gcc/rust/resolve/rust-ast-resolve-type.cc @@ -209,43 +209,58 @@ ResolveTypeToCanonicalPath::visit (AST::SliceType &slice) void ResolveType::visit (AST::ReferenceType &type) { - type.get_type_referenced ()->accept_vis (*this); - - if (canonical_path != nullptr && canonical_path->size () > 0) + CanonicalPath path = CanonicalPath::create_empty (); + resolved_node + = ResolveType::go (type.get_type_referenced ().get (), type.get_node_id (), + canonicalize_type_with_generics, &path); + if (canonical_path != nullptr) { - std::string seg = canonical_path->get (); - *canonical_path = CanonicalPath::new_seg (type.get_node_id (), "&" + seg); + std::string ref_type_str = type.is_mut () ? "mut" : ""; + std::string ref_path = "&" + ref_type_str + " " + path.get (); + *canonical_path = canonical_path->append ( + CanonicalPath::new_seg (type.get_node_id (), ref_path)); } } void ResolveType::visit (AST::RawPointerType &type) { - type.get_type_pointed_to ()->accept_vis (*this); - - if (canonical_path != nullptr && canonical_path->size () > 0) + CanonicalPath path = CanonicalPath::create_empty (); + resolved_node + = ResolveType::go (type.get_type_pointed_to ().get (), type.get_node_id (), + canonicalize_type_with_generics, &path); + if (canonical_path != nullptr) { - std::string seg = canonical_path->get (); - *canonical_path = CanonicalPath::new_seg (type.get_node_id (), "*" + seg); + std::string ptr_type_str + = type.get_pointer_type () == AST::RawPointerType::CONST ? "const" + : "mut"; + std::string ptr_path = "*" + ptr_type_str + " " + path.get (); + *canonical_path = canonical_path->append ( + CanonicalPath::new_seg (type.get_node_id (), ptr_path)); } } void ResolveType::visit (AST::InferredType &type) -{ - ok = true; -} +{} void ResolveType::visit (AST::NeverType &type) -{ - ok = true; -} +{} void ResolveType::visit (AST::SliceType &type) { - type.get_elem_type ()->accept_vis (*this); + CanonicalPath path = CanonicalPath::create_empty (); + resolved_node + = ResolveType::go (type.get_elem_type ().get (), type.get_node_id (), + canonicalize_type_with_generics, &path); + if (canonical_path != nullptr) + { + std::string slice_path = "[" + path.get () + "]"; + *canonical_path = canonical_path->append ( + CanonicalPath::new_seg (type.get_node_id (), slice_path)); + } } ResolveRelativeTypePath::ResolveRelativeTypePath (CanonicalPath qualified_path) diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 933413537b6d..d10cec2835bd 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -211,15 +211,12 @@ class ResolveType : public ResolverBase ResolveType resolver (parent, canonicalize_type_with_generics, canonical_path); type->accept_vis (resolver); - if (!resolver.ok) - rust_error_at (type->get_locus (), "unresolved type"); return resolver.resolved_node; }; void visit (AST::BareFunctionType &fntype) override { - ok = true; for (auto ¶m : fntype.get_function_params ()) ResolveType::go (param.get_type ().get (), fntype.get_node_id ()); @@ -253,8 +250,6 @@ class ResolveType : public ResolverBase return; } - ok = !rel_canonical_path.is_empty (); - // lets try and resolve in one go else leave it up to the type resolver to // figure outer @@ -331,7 +326,7 @@ class ResolveType : public ResolverBase void visit (AST::QualifiedPathInType &path) override { - ok = ResolveRelativeTypePath::go (path); + ResolveRelativeTypePath::go (path); } void visit (AST::ArrayType &type) override;