Skip to content

Commit dde892c

Browse files
Rollup merge of rust-lang#140370 - WaffleLapkin:unqualified, r=jdonszelmann
Improve diagnostics for usage of qualified paths within tuple struct exprs/pats For patterns the old diagnostic was just incorrect, but I also added machine applicable suggestions. For context, this special cases errors for `<T as Trait>::Assoc(..)` patterns and expressions (latter is just a call). Tuple struct patterns and expressions both live in the value namespace, so they are not forwarded through associated *types*. r? `@jdonszelmann` cc `@petrochenkov` in rust-lang#80080 (comment) you were wondering why it doesn't work for types, that's why — tuple patterns are resolved in the value namespace.
2 parents 9b0268a + 8f765fc commit dde892c

File tree

13 files changed

+327
-97
lines changed

13 files changed

+327
-97
lines changed

compiler/rustc_resolve/src/late.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ pub(crate) enum AliasPossibility {
415415
}
416416

417417
#[derive(Copy, Clone, Debug)]
418-
pub(crate) enum PathSource<'a> {
418+
pub(crate) enum PathSource<'a, 'c> {
419419
/// Type paths `Path`.
420420
Type,
421421
/// Trait paths in bounds or impls.
@@ -429,7 +429,10 @@ pub(crate) enum PathSource<'a> {
429429
/// Paths in tuple struct patterns `Path(..)`.
430430
TupleStruct(Span, &'a [Span]),
431431
/// `m::A::B` in `<T as m::A>::B::C`.
432-
TraitItem(Namespace),
432+
///
433+
/// Second field holds the "cause" of this one, i.e. the context within
434+
/// which the trait item is resolved. Used for diagnostics.
435+
TraitItem(Namespace, &'c PathSource<'a, 'c>),
433436
/// Paths in delegation item
434437
Delegation,
435438
/// An arg in a `use<'a, N>` precise-capturing bound.
@@ -440,7 +443,7 @@ pub(crate) enum PathSource<'a> {
440443
DefineOpaques,
441444
}
442445

443-
impl<'a> PathSource<'a> {
446+
impl<'a> PathSource<'a, '_> {
444447
fn namespace(self) -> Namespace {
445448
match self {
446449
PathSource::Type
@@ -452,7 +455,7 @@ impl<'a> PathSource<'a> {
452455
| PathSource::TupleStruct(..)
453456
| PathSource::Delegation
454457
| PathSource::ReturnTypeNotation => ValueNS,
455-
PathSource::TraitItem(ns) => ns,
458+
PathSource::TraitItem(ns, _) => ns,
456459
PathSource::PreciseCapturingArg(ns) => ns,
457460
}
458461
}
@@ -480,8 +483,9 @@ impl<'a> PathSource<'a> {
480483
PathSource::Trait(_) => "trait",
481484
PathSource::Pat => "unit struct, unit variant or constant",
482485
PathSource::Struct => "struct, variant or union type",
483-
PathSource::TupleStruct(..) => "tuple struct or tuple variant",
484-
PathSource::TraitItem(ns) => match ns {
486+
PathSource::TraitItem(ValueNS, PathSource::TupleStruct(..))
487+
| PathSource::TupleStruct(..) => "tuple struct or tuple variant",
488+
PathSource::TraitItem(ns, _) => match ns {
485489
TypeNS => "associated type",
486490
ValueNS => "method or associated constant",
487491
MacroNS => bug!("associated macro"),
@@ -585,7 +589,7 @@ impl<'a> PathSource<'a> {
585589
) | Res::SelfTyParam { .. }
586590
| Res::SelfTyAlias { .. }
587591
),
588-
PathSource::TraitItem(ns) => match res {
592+
PathSource::TraitItem(ns, _) => match res {
589593
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true,
590594
Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
591595
_ => false,
@@ -2007,7 +2011,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
20072011
&mut self,
20082012
partial_res: PartialRes,
20092013
path: &[Segment],
2010-
source: PathSource<'_>,
2014+
source: PathSource<'_, '_>,
20112015
path_span: Span,
20122016
) {
20132017
let proj_start = path.len() - partial_res.unresolved_segments();
@@ -4206,7 +4210,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
42064210
id: NodeId,
42074211
qself: &Option<P<QSelf>>,
42084212
path: &Path,
4209-
source: PathSource<'ast>,
4213+
source: PathSource<'ast, '_>,
42104214
) {
42114215
self.smart_resolve_path_fragment(
42124216
qself,
@@ -4223,7 +4227,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
42234227
&mut self,
42244228
qself: &Option<P<QSelf>>,
42254229
path: &[Segment],
4226-
source: PathSource<'ast>,
4230+
source: PathSource<'ast, '_>,
42274231
finalize: Finalize,
42284232
record_partial_res: RecordPartialRes,
42294233
parent_qself: Option<&QSelf>,
@@ -4404,6 +4408,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
44044408
path_span,
44054409
source.defer_to_typeck(),
44064410
finalize,
4411+
source,
44074412
) {
44084413
Ok(Some(partial_res)) if let Some(res) = partial_res.full_res() => {
44094414
// if we also have an associated type that matches the ident, stash a suggestion
@@ -4526,12 +4531,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
45264531
span: Span,
45274532
defer_to_typeck: bool,
45284533
finalize: Finalize,
4534+
source: PathSource<'ast, '_>,
45294535
) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
45304536
let mut fin_res = None;
45314537

45324538
for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() {
45334539
if i == 0 || ns != primary_ns {
4534-
match self.resolve_qpath(qself, path, ns, finalize)? {
4540+
match self.resolve_qpath(qself, path, ns, finalize, source)? {
45354541
Some(partial_res)
45364542
if partial_res.unresolved_segments() == 0 || defer_to_typeck =>
45374543
{
@@ -4568,6 +4574,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
45684574
path: &[Segment],
45694575
ns: Namespace,
45704576
finalize: Finalize,
4577+
source: PathSource<'ast, '_>,
45714578
) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
45724579
debug!(
45734580
"resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})",
@@ -4615,7 +4622,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
46154622
let partial_res = self.smart_resolve_path_fragment(
46164623
&None,
46174624
&path[..=qself.position],
4618-
PathSource::TraitItem(ns),
4625+
PathSource::TraitItem(ns, &source),
46194626
Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span),
46204627
RecordPartialRes::No,
46214628
Some(&qself),

0 commit comments

Comments
 (0)