Do precise capturing arg validation in resolve

This commit is contained in:
Michael Goulet
2024-09-15 17:14:49 -04:00
parent 13b5a4e43b
commit 26bdfefae1
6 changed files with 72 additions and 33 deletions

View File

@@ -402,6 +402,8 @@ pub(crate) enum PathSource<'a> {
TraitItem(Namespace),
// Paths in delegation item
Delegation,
/// An arg in a `use<'a, N>` precise-capturing bound.
PreciseCapturingArg(Namespace),
}
impl<'a> PathSource<'a> {
@@ -413,6 +415,7 @@ impl<'a> PathSource<'a> {
| PathSource::TupleStruct(..)
| PathSource::Delegation => ValueNS,
PathSource::TraitItem(ns) => ns,
PathSource::PreciseCapturingArg(ns) => ns,
}
}
@@ -423,7 +426,10 @@ impl<'a> PathSource<'a> {
| PathSource::Pat
| PathSource::Struct
| PathSource::TupleStruct(..) => true,
PathSource::Trait(_) | PathSource::TraitItem(..) | PathSource::Delegation => false,
PathSource::Trait(_)
| PathSource::TraitItem(..)
| PathSource::Delegation
| PathSource::PreciseCapturingArg(..) => false,
}
}
@@ -466,6 +472,7 @@ impl<'a> PathSource<'a> {
_ => "value",
},
PathSource::Delegation => "function",
PathSource::PreciseCapturingArg(..) => "type or const parameter",
}
}
@@ -534,6 +541,15 @@ impl<'a> PathSource<'a> {
_ => false,
},
PathSource::Delegation => matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn, _)),
PathSource::PreciseCapturingArg(ValueNS) => {
matches!(res, Res::Def(DefKind::ConstParam, _))
}
// We allow `SelfTyAlias` here so we can give a more descriptive error later.
PathSource::PreciseCapturingArg(TypeNS) => matches!(
res,
Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }
),
PathSource::PreciseCapturingArg(MacroNS) => false,
}
}
@@ -541,8 +557,9 @@ impl<'a> PathSource<'a> {
match (self, has_unexpected_resolution) {
(PathSource::Trait(_), true) => E0404,
(PathSource::Trait(_), false) => E0405,
(PathSource::Type, true) => E0573,
(PathSource::Type, false) => E0412,
// TODO:
(PathSource::Type | PathSource::PreciseCapturingArg(..), true) => E0573,
(PathSource::Type | PathSource::PreciseCapturingArg(..), false) => E0412,
(PathSource::Struct, true) => E0574,
(PathSource::Struct, false) => E0422,
(PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
@@ -1077,9 +1094,19 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
};
// Like `Ty::Param`, we try resolving this as both a const and a type.
if !check_ns(TypeNS) && check_ns(ValueNS) {
self.smart_resolve_path(*id, &None, path, PathSource::Expr(None));
self.smart_resolve_path(
*id,
&None,
path,
PathSource::PreciseCapturingArg(ValueNS),
);
} else {
self.smart_resolve_path(*id, &None, path, PathSource::Type);
self.smart_resolve_path(
*id,
&None,
path,
PathSource::PreciseCapturingArg(TypeNS),
);
}
}
}
@@ -1889,7 +1916,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
);
let inferred = match source {
PathSource::Trait(..) | PathSource::TraitItem(..) | PathSource::Type => false,
PathSource::Trait(..)
| PathSource::TraitItem(..)
| PathSource::Type
| PathSource::PreciseCapturingArg(..) => false,
PathSource::Expr(..)
| PathSource::Pat
| PathSource::Struct
@@ -3982,7 +4012,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
Applicability::MaybeIncorrect,
))
} else if res.is_none()
&& let PathSource::Type | PathSource::Expr(_) = source
&& let PathSource::Type
| PathSource::Expr(_)
| PathSource::PreciseCapturingArg(..) = source
{
this.suggest_adding_generic_parameter(path, source)
} else {