Skip to content

Commit df8b3f8

Browse files
Rollup merge of rust-lang#154049 - petrochenkov:deleglobspan, r=jackh726
delegation: Track more precise spans for glob delegations The last commit also fixes a macro hygiene issue with `self` in delegations found in rust-lang#154002.
2 parents b2226e9 + a9c2819 commit df8b3f8

17 files changed

Lines changed: 194 additions & 109 deletions

File tree

compiler/rustc_ast/src/ast.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3901,12 +3901,17 @@ pub struct Delegation {
39013901
pub from_glob: bool,
39023902
}
39033903

3904+
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
3905+
pub enum DelegationSuffixes {
3906+
List(ThinVec<(Ident, Option<Ident>)>),
3907+
Glob(Span),
3908+
}
3909+
39043910
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
39053911
pub struct DelegationMac {
39063912
pub qself: Option<Box<QSelf>>,
39073913
pub prefix: Path,
3908-
// Some for list delegation, and None for glob delegation.
3909-
pub suffixes: Option<ThinVec<(Ident, Option<Ident>)>>,
3914+
pub suffixes: DelegationSuffixes,
39103915
pub body: Option<Box<Block>>,
39113916
}
39123917

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ macro_rules! common_visitor_and_walkers {
430430
Defaultness,
431431
Delegation,
432432
DelegationMac,
433+
DelegationSuffixes,
433434
DelimArgs,
434435
DelimSpan,
435436
EnumDef,

compiler/rustc_ast_pretty/src/pprust/state/item.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,10 @@ impl<'a> State<'a> {
435435
&item.vis,
436436
&deleg.qself,
437437
&deleg.prefix,
438-
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
438+
match &deleg.suffixes {
439+
ast::DelegationSuffixes::List(s) => DelegationKind::List(s),
440+
ast::DelegationSuffixes::Glob(_) => DelegationKind::Glob,
441+
},
439442
&deleg.body,
440443
),
441444
}
@@ -641,7 +644,10 @@ impl<'a> State<'a> {
641644
vis,
642645
&deleg.qself,
643646
&deleg.prefix,
644-
deleg.suffixes.as_ref().map_or(DelegationKind::Glob, |s| DelegationKind::List(s)),
647+
match &deleg.suffixes {
648+
ast::DelegationSuffixes::List(s) => DelegationKind::List(s),
649+
ast::DelegationSuffixes::Glob(_) => DelegationKind::Glob,
650+
},
645651
&deleg.body,
646652
),
647653
}

compiler/rustc_expand/src/base.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,26 +1019,32 @@ impl SyntaxExtension {
10191019
pub fn glob_delegation(
10201020
trait_def_id: DefId,
10211021
impl_def_id: LocalDefId,
1022+
star_span: Span,
10221023
edition: Edition,
10231024
) -> SyntaxExtension {
10241025
struct GlobDelegationExpanderImpl {
10251026
trait_def_id: DefId,
10261027
impl_def_id: LocalDefId,
1028+
star_span: Span,
10271029
}
10281030
impl GlobDelegationExpander for GlobDelegationExpanderImpl {
10291031
fn expand(
10301032
&self,
10311033
ecx: &mut ExtCtxt<'_>,
10321034
) -> ExpandResult<Vec<(Ident, Option<Ident>)>, ()> {
1033-
match ecx.resolver.glob_delegation_suffixes(self.trait_def_id, self.impl_def_id) {
1035+
match ecx.resolver.glob_delegation_suffixes(
1036+
self.trait_def_id,
1037+
self.impl_def_id,
1038+
self.star_span,
1039+
) {
10341040
Ok(suffixes) => ExpandResult::Ready(suffixes),
10351041
Err(Indeterminate) if ecx.force_mode => ExpandResult::Ready(Vec::new()),
10361042
Err(Indeterminate) => ExpandResult::Retry(()),
10371043
}
10381044
}
10391045
}
10401046

1041-
let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id };
1047+
let expander = GlobDelegationExpanderImpl { trait_def_id, impl_def_id, star_span };
10421048
SyntaxExtension::default(SyntaxExtensionKind::GlobDelegation(Arc::new(expander)), edition)
10431049
}
10441050

@@ -1170,6 +1176,7 @@ pub trait ResolverExpand {
11701176
&self,
11711177
trait_def_id: DefId,
11721178
impl_def_id: LocalDefId,
1179+
star_span: Span,
11731180
) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate>;
11741181

11751182
/// Record the name of an opaque `Ty::ImplTrait` pre-expansion so that it can be used

compiler/rustc_expand/src/expand.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ use rustc_ast::tokenstream::TokenStream;
88
use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list};
99
use rustc_ast::{
1010
self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrItemKind, AttrStyle, AttrVec,
11-
DUMMY_NODE_ID, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline,
12-
ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId, PatKind, StmtKind,
13-
TyKind, token,
11+
DUMMY_NODE_ID, DelegationSuffixes, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs,
12+
HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId,
13+
PatKind, StmtKind, TyKind, token,
1414
};
1515
use rustc_ast_pretty::pprust;
1616
use rustc_attr_parsing::parser::AllowExprMetavar;
@@ -2401,7 +2401,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
24012401
res
24022402
}
24032403
None if let Some((deleg, item)) = node.delegation() => {
2404-
let Some(suffixes) = &deleg.suffixes else {
2404+
let DelegationSuffixes::List(suffixes) = &deleg.suffixes else {
24052405
let traitless_qself =
24062406
matches!(&deleg.qself, Some(qself) if qself.position == 0);
24072407
let (item, of_trait) = match node.to_annotatable() {

compiler/rustc_parse/src/parser/item.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,7 @@ impl<'a> Parser<'a> {
857857
kind: AssocItemKind::DelegationMac(Box::new(DelegationMac {
858858
qself: None,
859859
prefix: of_trait.trait_ref.path.clone(),
860-
suffixes: None,
860+
suffixes: DelegationSuffixes::Glob(whole_reuse_span),
861861
body,
862862
})),
863863
}));
@@ -879,10 +879,12 @@ impl<'a> Parser<'a> {
879879

880880
Ok(if self.eat_path_sep() {
881881
let suffixes = if self.eat(exp!(Star)) {
882-
None
882+
DelegationSuffixes::Glob(self.prev_token.span)
883883
} else {
884884
let parse_suffix = |p: &mut Self| Ok((p.parse_path_segment_ident()?, rename(p)?));
885-
Some(self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0)
885+
DelegationSuffixes::List(
886+
self.parse_delim_comma_seq(exp!(OpenBrace), exp!(CloseBrace), parse_suffix)?.0,
887+
)
886888
};
887889

888890
ItemKind::DelegationMac(Box::new(DelegationMac {
@@ -1517,7 +1519,10 @@ impl<'a> Parser<'a> {
15171519
let span = self.psess.source_map().guess_head_span(span);
15181520
let descr = kind.descr();
15191521
let help = match kind {
1520-
ItemKind::DelegationMac(deleg) if deleg.suffixes.is_none() => false,
1522+
ItemKind::DelegationMac(box DelegationMac {
1523+
suffixes: DelegationSuffixes::Glob(_),
1524+
..
1525+
}) => false,
15211526
_ => true,
15221527
};
15231528
self.dcx().emit_err(errors::BadItemKind { span, descr, ctx, help });

compiler/rustc_resolve/src/late.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3873,8 +3873,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
38733873

38743874
let Some(body) = &delegation.body else { return };
38753875
self.with_rib(ValueNS, RibKind::FnOrCoroutine, |this| {
3876-
let span = delegation.path.segments.last().unwrap().ident.span;
3877-
let ident = Ident::new(kw::SelfLower, span.normalize_to_macro_rules());
3876+
let ident = Ident::new(kw::SelfLower, body.span.normalize_to_macro_rules());
38783877
let res = Res::Local(delegation.id);
38793878
this.innermost_rib_bindings(ValueNS).insert(ident, res);
38803879

compiler/rustc_resolve/src/macros.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use std::mem;
55
use std::sync::Arc;
66

7-
use rustc_ast::{self as ast, Crate, DUMMY_NODE_ID, NodeId};
7+
use rustc_ast::{self as ast, Crate, DUMMY_NODE_ID, DelegationSuffixes, NodeId};
88
use rustc_ast_pretty::pprust;
99
use rustc_attr_parsing::AttributeParser;
1010
use rustc_errors::{Applicability, DiagCtxtHandle, StashKey};
@@ -286,7 +286,8 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
286286
InvocationKind::Derive { ref path, .. } => (path, MacroKind::Derive),
287287
InvocationKind::GlobDelegation { ref item, .. } => {
288288
let ast::AssocItemKind::DelegationMac(deleg) = &item.kind else { unreachable!() };
289-
deleg_impl = Some(self.invocation_parent(invoc_id));
289+
let DelegationSuffixes::Glob(star_span) = deleg.suffixes else { unreachable!() };
290+
deleg_impl = Some((self.invocation_parent(invoc_id), star_span));
290291
// It is sufficient to consider glob delegation a bang macro for now.
291292
(&deleg.prefix, MacroKind::Bang)
292293
}
@@ -530,6 +531,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
530531
&self,
531532
trait_def_id: DefId,
532533
impl_def_id: LocalDefId,
534+
star_span: Span,
533535
) -> Result<Vec<(Ident, Option<Ident>)>, Indeterminate> {
534536
let target_trait = self.expect_module(trait_def_id);
535537
if !target_trait.unexpanded_invocations.borrow().is_empty() {
@@ -549,13 +551,13 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
549551

550552
let mut idents = Vec::new();
551553
target_trait.for_each_child(self, |this, ident, orig_ident_span, ns, _binding| {
552-
// FIXME: Adjust hygiene for idents from globs, like for glob imports.
553554
if let Some(overriding_keys) = this.impl_binding_keys.get(&impl_def_id)
554555
&& overriding_keys.contains(&BindingKey::new(ident, ns))
555556
{
556557
// The name is overridden, do not produce it from the glob delegation.
557558
} else {
558-
idents.push((ident.orig(orig_ident_span), None));
559+
// FIXME: Adjust hygiene for idents from globs, like for glob imports.
560+
idents.push((ident.orig(star_span.with_ctxt(orig_ident_span.ctxt())), None));
559561
}
560562
});
561563
Ok(idents)
@@ -579,7 +581,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
579581
parent_scope: &ParentScope<'ra>,
580582
node_id: NodeId,
581583
force: bool,
582-
deleg_impl: Option<LocalDefId>,
584+
deleg_impl: Option<(LocalDefId, Span)>,
583585
invoc_in_mod_inert_attr: Option<LocalDefId>,
584586
suggestion_span: Option<Span>,
585587
) -> Result<(Arc<SyntaxExtension>, Res), Indeterminate> {
@@ -771,7 +773,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
771773
kind: MacroKind,
772774
parent_scope: &ParentScope<'ra>,
773775
force: bool,
774-
deleg_impl: Option<LocalDefId>,
776+
deleg_impl: Option<(LocalDefId, Span)>,
775777
invoc_in_mod_inert_attr: Option<(LocalDefId, NodeId)>,
776778
ignore_import: Option<Import<'ra>>,
777779
suggestion_span: Option<Span>,
@@ -856,10 +858,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
856858

857859
let res = res?;
858860
let ext = match deleg_impl {
859-
Some(impl_def_id) => match res {
861+
Some((impl_def_id, star_span)) => match res {
860862
def::Res::Def(DefKind::Trait, def_id) => {
861863
let edition = self.tcx.sess.edition();
862-
Some(Arc::new(SyntaxExtension::glob_delegation(def_id, impl_def_id, edition)))
864+
Some(Arc::new(SyntaxExtension::glob_delegation(
865+
def_id,
866+
impl_def_id,
867+
star_span,
868+
edition,
869+
)))
863870
}
864871
_ => None,
865872
},

tests/ui/delegation/generics/query-cycle-oom-154169.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ mod test_2 {
2020
trait Trait {
2121
fn foo() -> Self::Assoc;
2222
//~^ ERROR: associated type `Assoc` not found for `Self`
23-
//~| ERROR: this function takes 0 arguments but 1 argument was supplied
2423
fn bar(&self) -> u8;
2524
}
2625

@@ -33,20 +32,21 @@ mod test_2 {
3332

3433
impl Trait for S {
3534
reuse Trait::* { &self.0 }
35+
//~^ ERROR this function takes 0 arguments but 1 argument was supplied
3636
fn bar(&self) -> u8 { 2 }
3737
}
3838
}
3939

4040
mod test_3 {
4141
trait Trait {
4242
fn foo(&self) -> Self::Assoc<3> { //~ ERROR: associated type `Assoc` not found for `Self`
43-
//~^ ERROR: no method named `foo` found for reference `&()` in the current scope
4443
[(); 3]
4544
}
4645
}
4746

4847
impl () { //~ ERROR: cannot define inherent `impl` for primitive types
4948
reuse Trait::*;
49+
//~^ ERROR no method named `foo` found for reference `&()` in the current scope
5050
}
5151
}
5252

tests/ui/delegation/generics/query-cycle-oom-154169.stderr

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ LL | fn foo(&self) -> Self::Assoc<3> {
2727
| ^^^^^ associated type `Assoc` not found
2828

2929
error[E0046]: not all trait items implemented, missing: `foo`
30-
--> $DIR/query-cycle-oom-154169.rs:27:5
30+
--> $DIR/query-cycle-oom-154169.rs:26:5
3131
|
3232
LL | fn foo() -> Self::Assoc;
3333
| ------------------------ `foo` from trait
@@ -36,7 +36,7 @@ LL | impl Trait for u8 {
3636
| ^^^^^^^^^^^^^^^^^ missing `foo` in implementation
3737

3838
error[E0390]: cannot define inherent `impl` for primitive types
39-
--> $DIR/query-cycle-oom-154169.rs:48:5
39+
--> $DIR/query-cycle-oom-154169.rs:47:5
4040
|
4141
LL | impl () {
4242
| ^^^^^^^
@@ -52,13 +52,10 @@ LL | reuse to_reuse::foo { &self.0 }
5252
= help: you might be missing a crate named `to_reuse`
5353

5454
error[E0061]: this function takes 0 arguments but 1 argument was supplied
55-
--> $DIR/query-cycle-oom-154169.rs:21:12
55+
--> $DIR/query-cycle-oom-154169.rs:34:22
5656
|
57-
LL | fn foo() -> Self::Assoc;
58-
| ^^^
59-
...
6057
LL | reuse Trait::* { &self.0 }
61-
| ------- unexpected argument
58+
| ^ ------- unexpected argument
6259
|
6360
note: associated function defined here
6461
--> $DIR/query-cycle-oom-154169.rs:21:12
@@ -67,29 +64,15 @@ LL | fn foo() -> Self::Assoc;
6764
| ^^^
6865
help: remove the extra argument
6966
|
70-
LL - fn foo() -> Self::Assoc;
71-
LL -
72-
LL -
73-
LL - fn bar(&self) -> u8;
74-
LL - }
75-
LL -
76-
LL - impl Trait for u8 {
77-
LL -
78-
LL - fn bar(&self) -> u8 { 1 }
79-
LL - }
80-
LL -
81-
LL - struct S(u8);
82-
LL -
83-
LL - impl Trait for S {
8467
LL - reuse Trait::* { &self.0 }
85-
LL + fn fo&self.0 }
68+
LL + reuse Trait::&self.0 }
8669
|
8770

8871
error[E0599]: no method named `foo` found for reference `&()` in the current scope
89-
--> $DIR/query-cycle-oom-154169.rs:42:12
72+
--> $DIR/query-cycle-oom-154169.rs:48:22
9073
|
91-
LL | fn foo(&self) -> Self::Assoc<3> {
92-
| ^^^ method not found in `&()`
74+
LL | reuse Trait::*;
75+
| ^ method not found in `&()`
9376
|
9477
= help: items from traits can only be used if the trait is implemented and in scope
9578
= note: the following traits define an item `foo`, perhaps you need to implement one of them:

0 commit comments

Comments
 (0)