Do precise capturing arg validation in resolve
This commit is contained in:
parent
13b5a4e43b
commit
26bdfefae1
@ -584,7 +584,6 @@ fn visit_precise_capturing_arg(
|
|||||||
| Res::SelfTyParam { trait_: def_id } => {
|
| Res::SelfTyParam { trait_: def_id } => {
|
||||||
self.resolve_type_ref(def_id.expect_local(), param.hir_id);
|
self.resolve_type_ref(def_id.expect_local(), param.hir_id);
|
||||||
}
|
}
|
||||||
Res::Err => {}
|
|
||||||
Res::SelfTyAlias { alias_to, .. } => {
|
Res::SelfTyAlias { alias_to, .. } => {
|
||||||
self.tcx.dcx().emit_err(errors::PreciseCaptureSelfAlias {
|
self.tcx.dcx().emit_err(errors::PreciseCaptureSelfAlias {
|
||||||
span: param.ident.span,
|
span: param.ident.span,
|
||||||
@ -593,11 +592,10 @@ fn visit_precise_capturing_arg(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
res => {
|
res => {
|
||||||
self.tcx.dcx().emit_err(errors::BadPreciseCapture {
|
self.tcx.dcx().span_delayed_bug(
|
||||||
span: param.ident.span,
|
param.ident.span,
|
||||||
kind: "type or const",
|
format!("expected type or const param, found {res:?}"),
|
||||||
found: res.descr().to_string(),
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -402,6 +402,8 @@ pub(crate) enum PathSource<'a> {
|
|||||||
TraitItem(Namespace),
|
TraitItem(Namespace),
|
||||||
// Paths in delegation item
|
// Paths in delegation item
|
||||||
Delegation,
|
Delegation,
|
||||||
|
/// An arg in a `use<'a, N>` precise-capturing bound.
|
||||||
|
PreciseCapturingArg(Namespace),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PathSource<'a> {
|
impl<'a> PathSource<'a> {
|
||||||
@ -413,6 +415,7 @@ fn namespace(self) -> Namespace {
|
|||||||
| PathSource::TupleStruct(..)
|
| PathSource::TupleStruct(..)
|
||||||
| PathSource::Delegation => ValueNS,
|
| PathSource::Delegation => ValueNS,
|
||||||
PathSource::TraitItem(ns) => ns,
|
PathSource::TraitItem(ns) => ns,
|
||||||
|
PathSource::PreciseCapturingArg(ns) => ns,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +426,10 @@ fn defer_to_typeck(self) -> bool {
|
|||||||
| PathSource::Pat
|
| PathSource::Pat
|
||||||
| PathSource::Struct
|
| PathSource::Struct
|
||||||
| PathSource::TupleStruct(..) => true,
|
| PathSource::TupleStruct(..) => true,
|
||||||
PathSource::Trait(_) | PathSource::TraitItem(..) | PathSource::Delegation => false,
|
PathSource::Trait(_)
|
||||||
|
| PathSource::TraitItem(..)
|
||||||
|
| PathSource::Delegation
|
||||||
|
| PathSource::PreciseCapturingArg(..) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,6 +472,7 @@ fn descr_expected(self) -> &'static str {
|
|||||||
_ => "value",
|
_ => "value",
|
||||||
},
|
},
|
||||||
PathSource::Delegation => "function",
|
PathSource::Delegation => "function",
|
||||||
|
PathSource::PreciseCapturingArg(..) => "type or const parameter",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,6 +541,15 @@ pub(crate) fn is_expected(self, res: Res) -> bool {
|
|||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
PathSource::Delegation => matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn, _)),
|
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 @@ fn error_code(self, has_unexpected_resolution: bool) -> ErrCode {
|
|||||||
match (self, has_unexpected_resolution) {
|
match (self, has_unexpected_resolution) {
|
||||||
(PathSource::Trait(_), true) => E0404,
|
(PathSource::Trait(_), true) => E0404,
|
||||||
(PathSource::Trait(_), false) => E0405,
|
(PathSource::Trait(_), false) => E0405,
|
||||||
(PathSource::Type, true) => E0573,
|
// TODO:
|
||||||
(PathSource::Type, false) => E0412,
|
(PathSource::Type | PathSource::PreciseCapturingArg(..), true) => E0573,
|
||||||
|
(PathSource::Type | PathSource::PreciseCapturingArg(..), false) => E0412,
|
||||||
(PathSource::Struct, true) => E0574,
|
(PathSource::Struct, true) => E0574,
|
||||||
(PathSource::Struct, false) => E0422,
|
(PathSource::Struct, false) => E0422,
|
||||||
(PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
|
(PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
|
||||||
@ -1077,9 +1094,19 @@ fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) {
|
|||||||
};
|
};
|
||||||
// Like `Ty::Param`, we try resolving this as both a const and a type.
|
// Like `Ty::Param`, we try resolving this as both a const and a type.
|
||||||
if !check_ns(TypeNS) && check_ns(ValueNS) {
|
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 {
|
} else {
|
||||||
self.smart_resolve_path(*id, &None, path, PathSource::Type);
|
self.smart_resolve_path(
|
||||||
|
*id,
|
||||||
|
&None,
|
||||||
|
path,
|
||||||
|
PathSource::PreciseCapturingArg(TypeNS),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1889,7 +1916,10 @@ fn resolve_elided_lifetimes_in_path(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let inferred = match source {
|
let inferred = match source {
|
||||||
PathSource::Trait(..) | PathSource::TraitItem(..) | PathSource::Type => false,
|
PathSource::Trait(..)
|
||||||
|
| PathSource::TraitItem(..)
|
||||||
|
| PathSource::Type
|
||||||
|
| PathSource::PreciseCapturingArg(..) => false,
|
||||||
PathSource::Expr(..)
|
PathSource::Expr(..)
|
||||||
| PathSource::Pat
|
| PathSource::Pat
|
||||||
| PathSource::Struct
|
| PathSource::Struct
|
||||||
@ -3982,7 +4012,9 @@ fn smart_resolve_path_fragment(
|
|||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
))
|
))
|
||||||
} else if res.is_none()
|
} 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)
|
this.suggest_adding_generic_parameter(path, source)
|
||||||
} else {
|
} else {
|
||||||
|
@ -2538,8 +2538,13 @@ pub(crate) fn suggest_adding_generic_parameter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (msg, sugg) = match source {
|
let (msg, sugg) = match source {
|
||||||
PathSource::Type => ("you might be missing a type parameter", ident),
|
PathSource::Type | PathSource::PreciseCapturingArg(TypeNS) => {
|
||||||
PathSource::Expr(_) => ("you might be missing a const parameter", format!("const {ident}: /* Type */")),
|
("you might be missing a type parameter", ident)
|
||||||
|
}
|
||||||
|
PathSource::Expr(_) | PathSource::PreciseCapturingArg(ValueNS) => (
|
||||||
|
"you might be missing a const parameter",
|
||||||
|
format!("const {ident}: /* Type */"),
|
||||||
|
),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
let (span, sugg) = if let [.., param] = &generics.params[..] {
|
let (span, sugg) = if let [.., param] = &generics.params[..] {
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
//@ known-bug: rust-lang/rust#130399
|
|
||||||
|
|
||||||
fn elided(main: &()) -> impl Sized + use<main> {}
|
|
||||||
|
|
||||||
fn main() {}
|
|
@ -1,8 +1,8 @@
|
|||||||
fn missing() -> impl Sized + use<T> {}
|
fn missing() -> impl Sized + use<T> {}
|
||||||
//~^ ERROR cannot find type `T` in this scope
|
//~^ ERROR cannot find type or const parameter `T` in this scope
|
||||||
|
|
||||||
fn missing_self() -> impl Sized + use<Self> {}
|
fn missing_self() -> impl Sized + use<Self> {}
|
||||||
//~^ ERROR cannot find type `Self` in this scope
|
//~^ ERROR cannot find type or const parameter `Self` in this scope
|
||||||
|
|
||||||
struct MyType;
|
struct MyType;
|
||||||
impl MyType {
|
impl MyType {
|
||||||
@ -11,6 +11,9 @@ fn self_is_not_param() -> impl Sized + use<Self> {}
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn hello() -> impl Sized + use<hello> {}
|
fn hello() -> impl Sized + use<hello> {}
|
||||||
//~^ ERROR expected type or const parameter in `use<...>` precise captures list, found function
|
//~^ ERROR expected type or const parameter, found function `hello`
|
||||||
|
|
||||||
|
fn arg(x: ()) -> impl Sized + use<x> {}
|
||||||
|
//~^ ERROR expected type or const parameter, found local variable `x`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
error[E0412]: cannot find type `T` in this scope
|
error[E0412]: cannot find type or const parameter `T` in this scope
|
||||||
--> $DIR/bad-params.rs:1:34
|
--> $DIR/bad-params.rs:1:34
|
||||||
|
|
|
|
||||||
LL | fn missing() -> impl Sized + use<T> {}
|
LL | fn missing() -> impl Sized + use<T> {}
|
||||||
@ -9,7 +9,7 @@ help: you might be missing a type parameter
|
|||||||
LL | fn missing<T>() -> impl Sized + use<T> {}
|
LL | fn missing<T>() -> impl Sized + use<T> {}
|
||||||
| +++
|
| +++
|
||||||
|
|
||||||
error[E0411]: cannot find type `Self` in this scope
|
error[E0411]: cannot find type or const parameter `Self` in this scope
|
||||||
--> $DIR/bad-params.rs:4:39
|
--> $DIR/bad-params.rs:4:39
|
||||||
|
|
|
|
||||||
LL | fn missing_self() -> impl Sized + use<Self> {}
|
LL | fn missing_self() -> impl Sized + use<Self> {}
|
||||||
@ -17,6 +17,18 @@ LL | fn missing_self() -> impl Sized + use<Self> {}
|
|||||||
| |
|
| |
|
||||||
| `Self` not allowed in a function
|
| `Self` not allowed in a function
|
||||||
|
|
||||||
|
error[E0573]: expected type or const parameter, found function `hello`
|
||||||
|
--> $DIR/bad-params.rs:13:32
|
||||||
|
|
|
||||||
|
LL | fn hello() -> impl Sized + use<hello> {}
|
||||||
|
| ^^^^^ not a type or const parameter
|
||||||
|
|
||||||
|
error[E0573]: expected type or const parameter, found local variable `x`
|
||||||
|
--> $DIR/bad-params.rs:16:35
|
||||||
|
|
|
||||||
|
LL | fn arg(x: ()) -> impl Sized + use<x> {}
|
||||||
|
| ^ not a type or const parameter
|
||||||
|
|
||||||
error: `Self` can't be captured in `use<...>` precise captures list, since it is an alias
|
error: `Self` can't be captured in `use<...>` precise captures list, since it is an alias
|
||||||
--> $DIR/bad-params.rs:9:48
|
--> $DIR/bad-params.rs:9:48
|
||||||
|
|
|
|
||||||
@ -25,13 +37,7 @@ LL | impl MyType {
|
|||||||
LL | fn self_is_not_param() -> impl Sized + use<Self> {}
|
LL | fn self_is_not_param() -> impl Sized + use<Self> {}
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: expected type or const parameter in `use<...>` precise captures list, found function
|
error: aborting due to 5 previous errors
|
||||||
--> $DIR/bad-params.rs:13:32
|
|
||||||
|
|
|
||||||
LL | fn hello() -> impl Sized + use<hello> {}
|
|
||||||
| ^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
Some errors have detailed explanations: E0411, E0412, E0573.
|
||||||
|
|
||||||
Some errors have detailed explanations: E0411, E0412.
|
|
||||||
For more information about an error, try `rustc --explain E0411`.
|
For more information about an error, try `rustc --explain E0411`.
|
||||||
|
Loading…
Reference in New Issue
Block a user