Skip to content

Commit

Permalink
Merge #1292 #1293
Browse files Browse the repository at this point in the history
1292: Add name resolution to for loops r=philberty a=philberty

This just adds basic name resolution and hir lowering for
the loop. Eventually we will make all Loops into a single
HIR::LoopExpr but for now its really useful having a separate
visitor to implement this to avoid regressions in the short
term.

Addresses #869 

1293: Fixup name canonicalization for impl blocks r=philberty a=philberty

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.


Co-authored-by: Philip Herron <[email protected]>
  • Loading branch information
bors[bot] and philberty authored Jun 3, 2022
3 parents a71fa22 + 92f9eb4 + 91b16af commit 664bd46
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 23 deletions.
2 changes: 2 additions & 0 deletions gcc/rust/hir/rust-ast-lower-block.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
5 changes: 5 additions & 0 deletions gcc/rust/hir/rust-ast-lower-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 ());
Expand Down
26 changes: 26 additions & 0 deletions gcc/rust/hir/rust-ast-lower.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<HIR::Pattern> (loop_pattern),
std::unique_ptr<HIR::Expr> (iterator_expr),
std::unique_ptr<HIR::BlockExpr> (loop_block),
expr.get_locus (), std::move (loop_label),
expr.get_outer_attrs ());
}

void
ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
{
Expand Down
47 changes: 47 additions & 0 deletions gcc/rust/resolve/rust-ast-resolve-expr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/resolve/rust-ast-resolve-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions gcc/rust/resolve/rust-ast-resolve-item.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 ();
Expand All @@ -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
Expand Down
49 changes: 32 additions & 17 deletions gcc/rust/resolve/rust-ast-resolve-type.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 1 addition & 6 deletions gcc/rust/resolve/rust-ast-resolve-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 &param : fntype.get_function_params ())
ResolveType::go (param.get_type ().get (), fntype.get_node_id ());

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 664bd46

Please sign in to comment.