diff --git a/compiler/rustc_error_codes/src/error_codes/E0799.md b/compiler/rustc_error_codes/src/error_codes/E0799.md
new file mode 100644
index 0000000000000..38ebc84060497
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0799.md
@@ -0,0 +1,19 @@
+Something other than a type or const parameter has been used when one was
+expected.
+
+Erroneous code example:
+
+```compile_fail,E0799
+fn bad1() -> impl Sized + use {}
+
+fn bad2(x: ()) -> impl Sized + use {}
+
+fn main() {}
+```
+
+In the given examples, for `bad1`, the name `main` corresponds to a function
+rather than a type or const parameter. In `bad2`, the name `x` corresponds to
+a function argument rather than a type or const parameter.
+
+Only type and const parameters, including `Self`, may be captured by
+`use<...>` precise capturing bounds.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0800.md b/compiler/rustc_error_codes/src/error_codes/E0800.md
new file mode 100644
index 0000000000000..3e08cd499b7e6
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0800.md
@@ -0,0 +1,11 @@
+A type or const parameter of the given name is not in scope.
+
+Erroneous code examples:
+
+```compile_fail,E0800
+fn missing() -> impl Sized + use {}
+```
+
+To fix this error, please verify you didn't misspell the type or const
+parameter, or double-check if you forgot to declare the parameter in
+the list of generics.
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index 150f99a3ee743..d6f0206b0de0a 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -538,6 +538,8 @@ E0795: 0795,
E0796: 0796,
E0797: 0797,
E0798: 0798,
+E0799: 0799,
+E0800: 0800,
);
)
}
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index b4cbd1f309c97..53dcede91c36a 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -584,7 +584,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
| Res::SelfTyParam { trait_: def_id } => {
self.resolve_type_ref(def_id.expect_local(), param.hir_id);
}
- Res::Err => {}
Res::SelfTyAlias { alias_to, .. } => {
self.tcx.dcx().emit_err(errors::PreciseCaptureSelfAlias {
span: param.ident.span,
@@ -593,11 +592,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
});
}
res => {
- self.tcx.dcx().emit_err(errors::BadPreciseCapture {
- span: param.ident.span,
- kind: "type or const",
- found: res.descr().to_string(),
- });
+ self.tcx.dcx().span_delayed_bug(
+ param.ident.span,
+ format!("expected type or const param, found {res:?}"),
+ );
}
},
}
diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
index af2bb053c0ab4..b6cffb90805b3 100644
--- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
+++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs
@@ -1,3 +1,4 @@
+use rustc_errors::E0799;
use rustc_macros::Diagnostic;
use rustc_span::{Span, Symbol};
@@ -43,7 +44,7 @@ pub(crate) struct BadPreciseCapture {
}
#[derive(Diagnostic)]
-#[diag(hir_analysis_precise_capture_self_alias)]
+#[diag(hir_analysis_precise_capture_self_alias, code = E0799)]
pub(crate) struct PreciseCaptureSelfAlias {
#[primary_span]
pub span: Span,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 0aa351cad4043..4bf2cc287daae 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -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,
}
}
@@ -551,6 +567,8 @@ impl<'a> PathSource<'a> {
(PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,
(PathSource::TraitItem(..), true) => E0575,
(PathSource::TraitItem(..), false) => E0576,
+ (PathSource::PreciseCapturingArg(..), true) => E0799,
+ (PathSource::PreciseCapturingArg(..), false) => E0800,
}
}
}
@@ -1077,9 +1095,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 +1917,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 +4013,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 {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 1c584bf833862..676b242fda15b 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2538,8 +2538,13 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
}
let (msg, sugg) = match source {
- PathSource::Type => ("you might be missing a type parameter", ident),
- PathSource::Expr(_) => ("you might be missing a const parameter", format!("const {ident}: /* Type */")),
+ PathSource::Type | PathSource::PreciseCapturingArg(TypeNS) => {
+ ("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,
};
let (span, sugg) = if let [.., param] = &generics.params[..] {
diff --git a/tests/crashes/130399.rs b/tests/crashes/130399.rs
deleted file mode 100644
index 2248c8c0124a9..0000000000000
--- a/tests/crashes/130399.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ known-bug: rust-lang/rust#130399
-
-fn elided(main: &()) -> impl Sized + use {}
-
-fn main() {}
diff --git a/tests/ui/error-codes/E0799.rs b/tests/ui/error-codes/E0799.rs
new file mode 100644
index 0000000000000..a1e5b5326691f
--- /dev/null
+++ b/tests/ui/error-codes/E0799.rs
@@ -0,0 +1,4 @@
+fn test() -> impl Sized + use {}
+//~^ ERROR E0799
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0799.stderr b/tests/ui/error-codes/E0799.stderr
new file mode 100644
index 0000000000000..3639424e466f0
--- /dev/null
+++ b/tests/ui/error-codes/E0799.stderr
@@ -0,0 +1,9 @@
+error[E0799]: expected type or const parameter, found function `main`
+ --> $DIR/E0799.rs:1:31
+ |
+LL | fn test() -> impl Sized + use {}
+ | ^^^^ not a type or const parameter
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0799`.
diff --git a/tests/ui/error-codes/E0800.rs b/tests/ui/error-codes/E0800.rs
new file mode 100644
index 0000000000000..6112157feca5d
--- /dev/null
+++ b/tests/ui/error-codes/E0800.rs
@@ -0,0 +1,4 @@
+fn test() -> impl Sized + use {}
+//~^ ERROR E0800
+
+fn main() {}
diff --git a/tests/ui/error-codes/E0800.stderr b/tests/ui/error-codes/E0800.stderr
new file mode 100644
index 0000000000000..282981a91732e
--- /dev/null
+++ b/tests/ui/error-codes/E0800.stderr
@@ -0,0 +1,9 @@
+error[E0800]: cannot find type or const parameter `Missing` in this scope
+ --> $DIR/E0800.rs:1:31
+ |
+LL | fn test() -> impl Sized + use {}
+ | ^^^^^^^ not found in this scope
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0800`.
diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.rs b/tests/ui/impl-trait/precise-capturing/bad-params.rs
index 17b517abd74e4..d1ec48df48c7b 100644
--- a/tests/ui/impl-trait/precise-capturing/bad-params.rs
+++ b/tests/ui/impl-trait/precise-capturing/bad-params.rs
@@ -1,8 +1,8 @@
fn missing() -> impl Sized + use {}
-//~^ 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 {}
-//~^ ERROR cannot find type `Self` in this scope
+//~^ ERROR cannot find type or const parameter `Self` in this scope
struct MyType;
impl MyType {
@@ -11,6 +11,9 @@ impl MyType {
}
fn hello() -> impl Sized + use {}
-//~^ 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 {}
+//~^ ERROR expected type or const parameter, found local variable `x`
fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.stderr b/tests/ui/impl-trait/precise-capturing/bad-params.stderr
index 06ccf35694811..07ada8da30019 100644
--- a/tests/ui/impl-trait/precise-capturing/bad-params.stderr
+++ b/tests/ui/impl-trait/precise-capturing/bad-params.stderr
@@ -1,4 +1,4 @@
-error[E0412]: cannot find type `T` in this scope
+error[E0800]: cannot find type or const parameter `T` in this scope
--> $DIR/bad-params.rs:1:34
|
LL | fn missing() -> impl Sized + use {}
@@ -9,7 +9,7 @@ help: you might be missing a type parameter
LL | fn missing() -> impl Sized + use {}
| +++
-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
|
LL | fn missing_self() -> impl Sized + use {}
@@ -17,7 +17,19 @@ LL | fn missing_self() -> impl Sized + use {}
| |
| `Self` not allowed in a function
-error: `Self` can't be captured in `use<...>` precise captures list, since it is an alias
+error[E0799]: expected type or const parameter, found function `hello`
+ --> $DIR/bad-params.rs:13:32
+ |
+LL | fn hello() -> impl Sized + use {}
+ | ^^^^^ not a type or const parameter
+
+error[E0799]: expected type or const parameter, found local variable `x`
+ --> $DIR/bad-params.rs:16:35
+ |
+LL | fn arg(x: ()) -> impl Sized + use {}
+ | ^ not a type or const parameter
+
+error[E0799]: `Self` can't be captured in `use<...>` precise captures list, since it is an alias
--> $DIR/bad-params.rs:9:48
|
LL | impl MyType {
@@ -25,13 +37,7 @@ LL | impl MyType {
LL | fn self_is_not_param() -> impl Sized + use {}
| ^^^^
-error: expected type or const parameter in `use<...>` precise captures list, found function
- --> $DIR/bad-params.rs:13:32
- |
-LL | fn hello() -> impl Sized + use {}
- | ^^^^^
-
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
-Some errors have detailed explanations: E0411, E0412.
+Some errors have detailed explanations: E0411, E0799, E0800.
For more information about an error, try `rustc --explain E0411`.