Skip to content

Commit 82f1d10

Browse files
committed
Make error for tuple struct pat/expr w/ FQS clearer
1. Fix "expected" and the note for the pattern case 2. Add suggestions
1 parent 5f294f0 commit 82f1d10

File tree

6 files changed

+270
-57
lines changed

6 files changed

+270
-57
lines changed

compiler/rustc_resolve/src/late.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ pub(crate) enum AliasPossibility {
402402
}
403403

404404
#[derive(Copy, Clone, Debug)]
405-
pub(crate) enum PathSource<'a> {
405+
pub(crate) enum PathSource<'a, 'c> {
406406
/// Type paths `Path`.
407407
Type,
408408
/// Trait paths in bounds or impls.
@@ -416,7 +416,10 @@ pub(crate) enum PathSource<'a> {
416416
/// Paths in tuple struct patterns `Path(..)`.
417417
TupleStruct(Span, &'a [Span]),
418418
/// `m::A::B` in `<T as m::A>::B::C`.
419-
TraitItem(Namespace),
419+
///
420+
/// Second field holds the "cause" of this one, i.e. the context within
421+
/// which the trait item is resolved. Used for diagnostics.
422+
TraitItem(Namespace, &'c PathSource<'a, 'c>),
420423
/// Paths in delegation item
421424
Delegation,
422425
/// An arg in a `use<'a, N>` precise-capturing bound.
@@ -427,7 +430,7 @@ pub(crate) enum PathSource<'a> {
427430
DefineOpaques,
428431
}
429432

430-
impl<'a> PathSource<'a> {
433+
impl<'a> PathSource<'a, '_> {
431434
fn namespace(self) -> Namespace {
432435
match self {
433436
PathSource::Type
@@ -439,7 +442,7 @@ impl<'a> PathSource<'a> {
439442
| PathSource::TupleStruct(..)
440443
| PathSource::Delegation
441444
| PathSource::ReturnTypeNotation => ValueNS,
442-
PathSource::TraitItem(ns) => ns,
445+
PathSource::TraitItem(ns, _) => ns,
443446
PathSource::PreciseCapturingArg(ns) => ns,
444447
}
445448
}
@@ -467,8 +470,9 @@ impl<'a> PathSource<'a> {
467470
PathSource::Trait(_) => "trait",
468471
PathSource::Pat => "unit struct, unit variant or constant",
469472
PathSource::Struct => "struct, variant or union type",
470-
PathSource::TupleStruct(..) => "tuple struct or tuple variant",
471-
PathSource::TraitItem(ns) => match ns {
473+
PathSource::TraitItem(ValueNS, PathSource::TupleStruct(..))
474+
| PathSource::TupleStruct(..) => "tuple struct or tuple variant",
475+
PathSource::TraitItem(ns, _) => match ns {
472476
TypeNS => "associated type",
473477
ValueNS => "method or associated constant",
474478
MacroNS => bug!("associated macro"),
@@ -572,7 +576,7 @@ impl<'a> PathSource<'a> {
572576
) | Res::SelfTyParam { .. }
573577
| Res::SelfTyAlias { .. }
574578
),
575-
PathSource::TraitItem(ns) => match res {
579+
PathSource::TraitItem(ns, _) => match res {
576580
Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true,
577581
Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true,
578582
_ => false,
@@ -1983,7 +1987,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
19831987
&mut self,
19841988
partial_res: PartialRes,
19851989
path: &[Segment],
1986-
source: PathSource<'_>,
1990+
source: PathSource<'_, '_>,
19871991
path_span: Span,
19881992
) {
19891993
let proj_start = path.len() - partial_res.unresolved_segments();
@@ -4135,7 +4139,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
41354139
id: NodeId,
41364140
qself: &Option<P<QSelf>>,
41374141
path: &Path,
4138-
source: PathSource<'ast>,
4142+
source: PathSource<'ast, '_>,
41394143
) {
41404144
self.smart_resolve_path_fragment(
41414145
qself,
@@ -4152,7 +4156,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
41524156
&mut self,
41534157
qself: &Option<P<QSelf>>,
41544158
path: &[Segment],
4155-
source: PathSource<'ast>,
4159+
source: PathSource<'ast, '_>,
41564160
finalize: Finalize,
41574161
record_partial_res: RecordPartialRes,
41584162
parent_qself: Option<&QSelf>,
@@ -4333,6 +4337,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
43334337
path_span,
43344338
source.defer_to_typeck(),
43354339
finalize,
4340+
source,
43364341
) {
43374342
Ok(Some(partial_res)) if let Some(res) = partial_res.full_res() => {
43384343
// if we also have an associated type that matches the ident, stash a suggestion
@@ -4455,12 +4460,13 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
44554460
span: Span,
44564461
defer_to_typeck: bool,
44574462
finalize: Finalize,
4463+
source: PathSource<'ast, '_>,
44584464
) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
44594465
let mut fin_res = None;
44604466

44614467
for (i, &ns) in [primary_ns, TypeNS, ValueNS].iter().enumerate() {
44624468
if i == 0 || ns != primary_ns {
4463-
match self.resolve_qpath(qself, path, ns, finalize)? {
4469+
match self.resolve_qpath(qself, path, ns, finalize, source)? {
44644470
Some(partial_res)
44654471
if partial_res.unresolved_segments() == 0 || defer_to_typeck =>
44664472
{
@@ -4497,6 +4503,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
44974503
path: &[Segment],
44984504
ns: Namespace,
44994505
finalize: Finalize,
4506+
source: PathSource<'ast, '_>,
45004507
) -> Result<Option<PartialRes>, Spanned<ResolutionError<'ra>>> {
45014508
debug!(
45024509
"resolve_qpath(qself={:?}, path={:?}, ns={:?}, finalize={:?})",
@@ -4544,7 +4551,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
45444551
let partial_res = self.smart_resolve_path_fragment(
45454552
&None,
45464553
&path[..=qself.position],
4547-
PathSource::TraitItem(ns),
4554+
PathSource::TraitItem(ns, &source),
45484555
Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span),
45494556
RecordPartialRes::No,
45504557
Some(&qself),

0 commit comments

Comments
 (0)