Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 8 additions & 2 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3336,13 +3336,12 @@ pub enum UseTreeKind {
/// use foo::{bar, baz};
/// ^^^^^^^^^^
/// ```
Nested { items: ThinVec<(UseTree, NodeId)>, span: Span },
Nested { items: ThinVec<UseTreeAndId>, span: Span },
/// `use prefix::*`
Glob(Span),
}

/// A tree of paths sharing common prefixes.
/// Used in `use` items both at top-level and inside of braces in import groups.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct UseTree {
pub prefix: Path,
Expand Down Expand Up @@ -3384,6 +3383,13 @@ impl UseTree {
}
}

/// Used in nested `use` trees.
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct UseTreeAndId {
pub inner: UseTree,
pub id: NodeId,
}

/// Distinguishes between `Attribute`s that decorate items and Attributes that
/// are contained as statements within items. These two cases need to be
/// distinguished for pretty-printing.
Expand Down
18 changes: 2 additions & 16 deletions compiler/rustc_ast/src/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,6 @@ macro_rules! for_each_ast_visit_hook {
visit_mac_call(MacCall) => walk_mac;
visit_macro_def(MacroDef) => walk_macro_def;
visit_mut_restriction(MutRestriction) => walk_mut_restriction;
//visit_nested_use_tree((UseTree, NodeId)) => walk_nested_use_tree;
visit_param(Param) => walk_param;
visit_param_bound(GenericBound, _ctxt: BoundKind) => walk_param_bound;
visit_pat(Pat) => walk_pat;
Expand All @@ -368,6 +367,7 @@ macro_rules! for_each_ast_visit_hook {
visit_ty(Ty) => walk_ty;
visit_ty_pat(TyPat) => walk_ty_pat;
visit_use_tree(UseTree) => walk_use_tree;
visit_use_tree_and_id(UseTreeAndId) => walk_use_tree_and_id;
visit_variant(Variant) => walk_variant;
visit_variant_data(VariantData) => walk_variant_data;
visit_vis(Visibility) => walk_vis;
Expand Down Expand Up @@ -477,6 +477,7 @@ macro_rules! common_visitor_and_walkers {
ThinVec<TestBinderExists>,
ThinVec<TestBinderForall>,
ThinVec<TyPat>,
ThinVec<UseTreeAndId>,
// tidy-alphabetical-end
}

Expand Down Expand Up @@ -681,13 +682,6 @@ macro_rules! common_visitor_and_walkers {
fn visit_stmt(&mut self, s: &$lt Stmt) -> Self::Result {
walk_stmt(self, s)
}

fn visit_nested_use_tree(&mut self, use_tree: &$lt UseTree, id: NodeId)
-> Self::Result
{
try_visit!(self.visit_id(id));
self.visit_use_tree(use_tree)
}
)?

// `MutVisitor`-only methods
Expand Down Expand Up @@ -812,14 +806,6 @@ macro_rules! common_visitor_and_walkers {
) -> V::Result;
}

$(impl_visitable!(|&$lt self: ThinVec<(UseTree, NodeId)>, vis: &mut V| {
for (nested_tree, nested_id) in self {
try_visit!(vis.visit_nested_use_tree(nested_tree, *nested_id));
}
V::Result::output()
});)?
$(${ignore($mut)} impl_visitable_list!(ThinVec<(UseTree, NodeId)>,);)?

fn walk_item_inner<$($lt,)? K: WalkItemKind, V: $Visitor$(<$lt>)?>(
visitor: &mut V,
item: &$($lt)? $($mut)? Item<K>,
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
let prefix = Path { segments, span };

// Add all the nested `PathListItem`s to the HIR.
for &(ref use_tree, id) in trees {
for use_tree in trees {
let id = use_tree.id;
let owner_id = self.owner_id(id);

// Each `use` import is an item and thus are owners of the
Expand All @@ -692,7 +693,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `prefix` is lowered multiple times, but in different HIR owners.
// So each segment gets renewed `HirId` with the same
// `ItemLocalId` and the new owner. (See `lower_node_id`)
let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs);
let kind =
this.lower_use_tree(&use_tree.inner, &prefix, id, vis_span, attrs);
if !attrs.is_empty() {
this.curr_owner.attrs.insert(hir::ItemLocalId::ZERO, attrs);
}
Expand All @@ -701,7 +703,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
owner_id,
kind,
vis_span,
span: this.lower_span(use_tree.span()),
span: this.lower_span(use_tree.inner.span()),
eii: find_attr!(attrs, EiiImpl(..) | EiiDeclaration(..)),
};
hir::OwnerNode::Item(this.arena.alloc(item))
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -674,12 +674,13 @@ fn index_ast<'tcx>(
match tree.kind {
UseTreeKind::Glob(_) | UseTreeKind::Simple(_) => {}
UseTreeKind::Nested { items: ref nested_vec, span } => {
for &(ref nested, id) in nested_vec {
for nested in nested_vec {
let id = nested.id;
self.insert(id, AstOwner::NestedUseTree(parent));
items.push(self.make_dummy(id, span, ItemKind::MacCall));

let def_id = self.owners[&id].def_id;
self.visit_item_id_use_tree(nested, def_id, items);
self.visit_item_id_use_tree(&nested.inner, def_id, items);
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_ast_pretty/src/pprust/state/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -911,25 +911,26 @@ impl<'a> State<'a> {
}
if items.is_empty() {
self.word("{}");
} else if let [(item, _)] = items.as_slice()
} else if let [item] = items.as_slice()
&& !item
.inner
.prefix
.segments
.first()
.is_some_and(|seg| seg.ident.name == rustc_span::symbol::kw::SelfLower)
{
self.print_use_tree(item);
self.print_use_tree(&item.inner);
} else {
let cb = self.cbox(INDENT_UNIT);
self.word("{");
self.zerobreak();
let ib = self.ibox(0);
for (idx, use_tree) in items.iter().enumerate() {
let is_last = idx == items.len() - 1;
self.print_use_tree(&use_tree.0);
self.print_use_tree(&use_tree.inner);
if !is_last {
self.word(",");
if let ast::UseTreeKind::Nested { .. } = use_tree.0.kind {
if let ast::UseTreeKind::Nested { .. } = use_tree.inner.kind {
self.hardbreak();
} else {
self.space();
Expand Down
16 changes: 7 additions & 9 deletions compiler/rustc_builtin_macros/src/assert/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use rustc_ast::token::{self, Delimiter, IdentIsRaw};
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree};
use rustc_ast::{
BinOpKind, BorrowKind, DUMMY_NODE_ID, DelimArgs, Expr, ExprKind, ItemKind, MacCall, MethodCall,
Mutability, Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind,
Mutability, Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeAndId, UseTreeKind,
};
use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet;
Expand Down Expand Up @@ -97,14 +97,12 @@ impl<'cx, 'a> Context<'cx, 'a> {
///
/// use ::core::asserting::{ ... };
fn build_initial_imports(&self) -> Stmt {
let nested_tree = |this: &Self, sym| {
(
UseTree {
prefix: this.cx.path(this.span, vec![Ident::with_dummy_span(sym)]),
kind: UseTreeKind::Simple(None),
},
DUMMY_NODE_ID,
)
let nested_tree = |this: &Self, sym| UseTreeAndId {
inner: UseTree {
prefix: this.cx.path(this.span, vec![Ident::with_dummy_span(sym)]),
kind: UseTreeKind::Simple(None),
},
id: DUMMY_NODE_ID,
};
self.cx.stmt_item(
self.span,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1463,8 +1463,8 @@ impl DeclaredIdents for Box<ast::Item> {
ast::UseTreeKind::Glob(_) => {}
ast::UseTreeKind::Simple(_) => idents.push(ut.ident()),
ast::UseTreeKind::Nested { items, .. } => {
for (ut, _) in items {
collect_use_tree_leaves(ut, idents);
for tree in items {
collect_use_tree_leaves(&tree.inner, idents);
}
}
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_lint/src/unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1318,17 +1318,17 @@ impl UnusedImportBraces {
fn check_use_tree(&self, cx: &EarlyContext<'_>, use_tree: &ast::UseTree, item: &ast::Item) {
if let ast::UseTreeKind::Nested { ref items, .. } = use_tree.kind {
// Recursively check nested UseTrees
for (tree, _) in items {
self.check_use_tree(cx, tree, item);
for tree in items {
self.check_use_tree(cx, &tree.inner, item);
}

// Trigger the lint only if there is one nested item
let [(tree, _)] = items.as_slice() else { return };
let [tree] = items.as_slice() else { return };

// Trigger the lint if the nested item is a non-self single item
let node_name = match tree.kind {
let node_name = match tree.inner.kind {
ast::UseTreeKind::Simple(rename) => {
let orig_ident = tree.prefix.segments.last().unwrap().ident;
let orig_ident = tree.inner.prefix.segments.last().unwrap().ident;
if orig_ident.name == kw::SelfLower {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1368,7 +1368,7 @@ impl<'a> Parser<'a> {
&mut self,
use_token_span: Span,
prefix: Option<&'b UsePathList<'b>>,
) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> {
) -> PResult<'a, ThinVec<UseTreeAndId>> {
self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), |p| {
p.recover_vcs_conflict_marker();

Expand All @@ -1386,7 +1386,7 @@ impl<'a> Parser<'a> {
p.emit_error_attr_in_use_tree(use_token_span, prefix, use_tree.span(), attr_span);
}

Ok((use_tree, DUMMY_NODE_ID))
Ok(UseTreeAndId { inner: use_tree, id: DUMMY_NODE_ID })
})
.map(|(r, _)| r)
}
Expand Down
43 changes: 20 additions & 23 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,16 +583,17 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
}
}

/// Note:
/// - `item` is the top-level `use` item.
/// - `use_tree` is the particular use tree within the top-level `use` item.
fn build_reduced_graph_for_use_tree(
&mut self,
// This particular use tree
item: &Item,
use_tree: &ast::UseTree,
id: NodeId,
parent_prefix: &[Segment],
nested: bool,
list_stem: bool,
// The whole `use` item
item: &Item,
vis: Visibility,
root_span: Span,
feed: TyCtxtFeed<'tcx, LocalDefId>,
Expand Down Expand Up @@ -753,12 +754,19 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
}
}
ast::UseTreeKind::Nested { ref items, .. } => {
for &(ref tree, id) in items {
for tree in items {
let id = tree.id;
self.with_owner(id, None, DefKind::Use, use_tree.span(), |this, feed| {
this.build_reduced_graph_for_use_tree(
// This particular use tree
tree, id, &prefix, true, false, // The whole `use` item
item, vis, root_span, feed,
item,
&tree.inner,
id,
&prefix,
true,
false,
vis,
root_span,
feed,
)
});
}
Expand All @@ -775,20 +783,11 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
prefix: ast::Path::from_ident(Ident::new(kw::SelfLower, new_span)),
kind: ast::UseTreeKind::Simple(Some(Ident::new(kw::Underscore, new_span))),
};
let vis = Visibility::Restricted(
self.parent_scope.module.nearest_parent_mod().expect_local(),
);
self.build_reduced_graph_for_use_tree(
// This particular use tree
&tree,
id,
&prefix,
true,
true,
// The whole `use` item
item,
Visibility::Restricted(
self.parent_scope.module.nearest_parent_mod().expect_local(),
),
root_span,
feed,
item, &tree, id, &prefix, true, true, vis, root_span, feed,
);
}
}
Expand Down Expand Up @@ -835,14 +834,12 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> {
match item.kind {
ItemKind::Use(ref use_tree) => {
self.build_reduced_graph_for_use_tree(
// This particular use tree
item,
use_tree,
item.id,
&[],
false,
false,
// The whole `use` item
item,
vis,
use_tree.span(),
feed,
Expand Down
Loading
Loading