Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow use before items being used continued #3150

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
7347cb0
nr2.0: default-visitor: Conditionally visit type in self parameters.
CohenArthur Mar 27, 2024
fbe034d
toplevel: Add note for resolving use declarations
CohenArthur Apr 3, 2024
d226286
toplevel: Build list of imports for Early to resolve
CohenArthur Apr 4, 2024
b655a51
early: Resolve imports and create import mappings
CohenArthur Apr 4, 2024
7abd0c4
imports: Add FinalizeImports class
CohenArthur Apr 4, 2024
a5a4a1d
imports: Create ImportData class and use it in import_mappings
CohenArthur Apr 5, 2024
51e89e5
imports: Start storing Ribs in ImportKind
CohenArthur Apr 5, 2024
3ee7238
imports: Make FinalizeImports a resolver visitor as well
CohenArthur Apr 6, 2024
d08788f
early: Do not emit errors for unresolved imports, store them instead
CohenArthur Apr 6, 2024
4d8fda3
Insert imports in all namespaces they were resolved in
CohenArthur Apr 8, 2024
c636cdf
nr2.0: Cleanup import mappings and factor into a class.
CohenArthur Apr 10, 2024
26df0d8
Fix missing error on duplicated nodes
P-E-P Aug 21, 2024
05e097d
Loop on expansion if a new export has been defined
P-E-P Aug 21, 2024
3e1992c
Mark virtual function override in default resolver
P-E-P Sep 5, 2024
cc4ba51
Remove empty visit functions
P-E-P Sep 5, 2024
91ea827
Remove regular visit code
P-E-P Sep 5, 2024
25f219b
Change lambda content with default visitor call
P-E-P Sep 5, 2024
03a9a24
Add default resolver parent functions by default
P-E-P Sep 5, 2024
858e308
Make AST default visitor visit functions public
P-E-P Sep 5, 2024
9ee6537
Move failing test to xfail
P-E-P Sep 4, 2024
1c3cf3f
Move bir builder function implementation
P-E-P Sep 6, 2024
d357b2a
Do not assert insertion result
P-E-P Sep 17, 2024
838e2c8
Update exclude list with working tests
P-E-P Sep 17, 2024
a795621
Change resolved type segment
P-E-P Sep 26, 2024
df3b02a
Make node id getter const.
P-E-P Sep 26, 2024
fab6c61
This test requires the standard library
P-E-P Sep 26, 2024
f1518be
Add box definition to avoid error
P-E-P Sep 26, 2024
25d4ed7
Resolve TypeParam with name resolution 2.0
P-E-P Sep 26, 2024
4c3f7d5
Postpone break on error after name resolution
P-E-P Sep 26, 2024
2843ceb
Remove some passing test from nr2 passing list
P-E-P Sep 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions gcc/rust/Make-lang.in
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ GRS_OBJS = \
rust/rust-default-resolver.o \
rust/rust-toplevel-name-resolver-2.0.o \
rust/rust-early-name-resolver-2.0.o \
rust/rust-finalize-imports-2.0.o \
rust/rust-late-name-resolver-2.0.o \
rust/rust-immutable-name-resolution-context.o \
rust/rust-early-name-resolver.o \
Expand Down Expand Up @@ -171,6 +172,7 @@ GRS_OBJS = \
rust/rust-borrow-checker.o \
rust/rust-borrow-checker-diagnostics.o\
rust/rust-bir-builder-expr-stmt.o \
rust/rust-bir-builder-pattern.o \
rust/rust-bir-dump.o \
rust/rust-polonius.o\
rust/rust-hir-dot-operator.o \
Expand Down
1 change: 0 additions & 1 deletion gcc/rust/ast/rust-ast-visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ class DefaultASTVisitor : public ASTVisitor
public:
virtual void visit (AST::Crate &crate);

protected:
virtual void visit (AST::Token &tok) override;
virtual void visit (AST::DelimTokenTree &delim_tok_tree) override;
virtual void visit (AST::AttrInputMetaItemContainer &input) override;
Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/ast/rust-ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -1587,7 +1587,7 @@ class GenericParam : public Visitable

virtual Kind get_kind () const = 0;

NodeId get_node_id () { return node_id; }
NodeId get_node_id () const { return node_id; }

protected:
GenericParam () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {}
Expand Down
2 changes: 1 addition & 1 deletion gcc/rust/ast/rust-item.h
Original file line number Diff line number Diff line change
Expand Up @@ -1213,7 +1213,7 @@ class UseTreeRebind : public UseTree

std::string as_string () const override;

NewBindType get_new_bind_type () { return bind_type; }
NewBindType get_new_bind_type () const { return bind_type; }

void accept_vis (ASTVisitor &vis) override;

Expand Down
273 changes: 273 additions & 0 deletions gcc/rust/checks/errors/borrowck/rust-bir-builder-pattern.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
#include "rust-bir-builder-pattern.h"

namespace Rust {
namespace BIR {

void
PatternBindingBuilder::visit_identifier (const Analysis::NodeMapping &node,
bool is_ref, location_t location,
bool is_mut)
{
if (is_ref)
{
translated = declare_variable (
node,
new TyTy::ReferenceType (node.get_hirid (),
TyTy::TyVar (node.get_hirid ()),
(is_mut) ? Mutability::Mut : Mutability::Imm));
}
else
{
translated = declare_variable (node);
}

if (init.has_value ())
{
push_assignment (translated, init.value (), location);
}
}

void
PatternBindingBuilder::visit (HIR::IdentifierPattern &pattern)
{
// Top-level identifiers are resolved directly to avoid useless temporary
// (for cleaner BIR).
visit_identifier (pattern.get_mappings (), pattern.get_is_ref (),
pattern.get_locus (), pattern.is_mut ());
}

void
PatternBindingBuilder::visit (HIR::ReferencePattern &pattern)
{
SavedState saved (this);

init = init.map ([&] (PlaceId id) {
return ctx.place_db.lookup_or_add_path (Place::DEREF, lookup_type (pattern),
id);
});

type_annotation = type_annotation.map ([&] (TyTy::BaseType *ty) {
return ty->as<TyTy::ReferenceType> ()->get_base ();
});

pattern.get_referenced_pattern ()->accept_vis (*this);
}

void
PatternBindingBuilder::visit (HIR::SlicePattern &pattern)
{
SavedState saved (this);

// All indexes are supposed to point to the same place for borrow-checking.
// init = ctx.place_db.lookup_or_add_path (Place::INDEX, lookup_type
// (pattern), saved.init);
init = init.map ([&] (PlaceId id) {
return ctx.place_db.lookup_or_add_path (Place::INDEX, lookup_type (pattern),
id);
});

type_annotation = type_annotation.map ([&] (TyTy::BaseType *ty) {
return ty->as<TyTy::SliceType> ()->get_element_type ();
});

// Regions are unchnaged.

for (auto &item : pattern.get_items ())
{
item->accept_vis (*this);
}
}

void
PatternBindingBuilder::visit (HIR::AltPattern &pattern)
{
rust_sorry_at (pattern.get_locus (),
"borrow-checking of alt patterns is not yet implemented");
}

void
PatternBindingBuilder::visit (HIR::StructPattern &pattern)
{
SavedState saved (this);

auto tyty = ctx.place_db[init.value ()].tyty;
rust_assert (tyty->get_kind () == TyTy::ADT);
auto adt_ty = static_cast<TyTy::ADTType *> (tyty);
rust_assert (adt_ty->is_struct_struct ());
auto struct_ty = adt_ty->get_variants ().at (0);

for (auto &field :
pattern.get_struct_pattern_elems ().get_struct_pattern_fields ())
{
switch (field->get_item_type ())
{
case HIR::StructPatternField::TUPLE_PAT: {
auto tuple
= static_cast<HIR::StructPatternFieldTuplePat *> (field.get ());

init = init.map ([&] (PlaceId id) {
return ctx.place_db.lookup_or_add_path (
Place::FIELD, lookup_type (*tuple->get_tuple_pattern ()), id,
tuple->get_index ());
});

type_annotation = type_annotation.map ([&] (TyTy::BaseType *ty) {
return ty->as<TyTy::ADTType> ()
->get_variants ()
.at (0)
->get_fields ()
.at (tuple->get_index ())
->get_field_type ();
});

tuple->get_tuple_pattern ()->accept_vis (*this);
break;
}
case HIR::StructPatternField::IDENT_PAT: {
auto ident_field
= static_cast<HIR::StructPatternFieldIdentPat *> (field.get ());
TyTy::StructFieldType *field_ty = nullptr;
size_t field_index = 0;
auto ok = struct_ty->lookup_field (
ident_field->get_identifier ().as_string (), &field_ty,
&field_index);
rust_assert (ok);
init = ctx.place_db.lookup_or_add_path (Place::FIELD,
field_ty->get_field_type (),
saved.init.value (),
field_index);
ident_field->get_pattern ()->accept_vis (*this);
break;
}
case HIR::StructPatternField::IDENT: {
auto ident_field
= static_cast<HIR::StructPatternFieldIdent *> (field.get ());
TyTy::StructFieldType *field_ty = nullptr;
size_t field_index = 0;
auto ok = struct_ty->lookup_field (
ident_field->get_identifier ().as_string (), &field_ty,
&field_index);
rust_assert (ok);
init = ctx.place_db.lookup_or_add_path (Place::FIELD,
field_ty->get_field_type (),
saved.init.value (),
field_index);
visit_identifier (ident_field->get_mappings (),
ident_field->get_has_ref (),
ident_field->get_locus (),
ident_field->is_mut ());
break;
}
}
}
}

void
PatternBindingBuilder::visit_tuple_fields (
std::vector<std::unique_ptr<HIR::Pattern>> &fields, SavedState &saved,
size_t &index)
{
for (auto &item : fields)
{
auto type = lookup_type (*item);

init = init.map ([&] (PlaceId id) {
return ctx.place_db.lookup_or_add_path (Place::FIELD, type, id, index);
});

type_annotation = type_annotation.map ([&] (TyTy::BaseType *ty) {
return ty->as<TyTy::TupleType> ()->get_fields ().at (index).get_tyty ();
});

regions = regions.map ([&] (FreeRegions regs) {
return bind_regions (Resolver::TypeCheckContext::get ()
->get_variance_analysis_ctx ()
.query_type_regions (type),
regs);
});

item->accept_vis (*this);
index++;
}
}

void
PatternBindingBuilder::visit (HIR::TuplePattern &pattern)
{
SavedState saved (this);

size_t index = 0;
switch (pattern.get_items ()->get_item_type ())
{
case HIR::TuplePatternItems::MULTIPLE: {
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
*pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
break;
}
case HIR::TuplePatternItems::RANGED: {
auto &items
= static_cast<HIR::TuplePatternItemsRanged &> (*pattern.get_items ());

auto tyty = ctx.place_db[init.value ()].tyty;
rust_assert (tyty->get_kind () == TyTy::TUPLE);

auto skipped = (static_cast<TyTy::TupleType *> (tyty))->num_fields ()
- items.get_lower_patterns ().size ()
- items.get_upper_patterns ().size ();

visit_tuple_fields (items.get_lower_patterns (), saved, index);
index += skipped;
visit_tuple_fields (items.get_upper_patterns (), saved, index);
break;
}
}
init = saved.init;
}

void
PatternBindingBuilder::visit (HIR::TupleStructPattern &pattern)
{
SavedState saved (this);

type_annotation = tl::nullopt;

auto type = lookup_type (pattern);

regions = regions.map ([&] (FreeRegions regs) {
return bind_regions (Resolver::TypeCheckContext::get ()
->get_variance_analysis_ctx ()
.query_type_regions (type),
regs);
});

size_t index = 0;
switch (pattern.get_items ()->get_item_type ())
{
case HIR::TupleStructItems::RANGED: {
auto &items
= static_cast<HIR::TupleStructItemsRange &> (*pattern.get_items ());

rust_assert (type->get_kind () == TyTy::ADT);
auto adt_ty = static_cast<TyTy::ADTType *> (type);
rust_assert (adt_ty->is_tuple_struct ());

auto skipped = adt_ty->get_variants ().at (0)->get_fields ().size ()
- items.get_lower_patterns ().size ()
- items.get_upper_patterns ().size ();

visit_tuple_fields (items.get_lower_patterns (), saved, index);
index += skipped;
visit_tuple_fields (items.get_upper_patterns (), saved, index);
break;
}
case HIR::TupleStructItems::MULTIPLE: {
auto &items
= static_cast<HIR::TupleStructItemsNoRange &> (*pattern.get_items ());
visit_tuple_fields (items.get_patterns (), saved, index);
break;
}
}
}
} // namespace BIR
} // namespace Rust
Loading
Loading