Skip to content

Commit 3a22be3

Browse files
committed
Auto merge of #130414 - compiler-errors:precise-capturing-arg-valid, r=jieyouxu
Do precise capturing arg validation in resolve Moves the validation of precise capturing args (`use<T, N>`) out of `resolve_bound_vars` and into `rustc_resolve`. This both simplifies the impl and fixes a bug when we have `use<arg>` where `arg` is one of the function args. This also introduces new error codes specifically for precise capturing, to avoid reusing the other error codes which are not as accurate. Fixes #130399
2 parents 13b5a4e + ae8b460 commit 3a22be3

File tree

14 files changed

+132
-33
lines changed

14 files changed

+132
-33
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Something other than a type or const parameter has been used when one was
2+
expected.
3+
4+
Erroneous code example:
5+
6+
```compile_fail,E0799
7+
fn bad1() -> impl Sized + use<main> {}
8+
9+
fn bad2(x: ()) -> impl Sized + use<x> {}
10+
11+
fn main() {}
12+
```
13+
14+
In the given examples, for `bad1`, the name `main` corresponds to a function
15+
rather than a type or const parameter. In `bad2`, the name `x` corresponds to
16+
a function argument rather than a type or const parameter.
17+
18+
Only type and const parameters, including `Self`, may be captured by
19+
`use<...>` precise capturing bounds.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
A type or const parameter of the given name is not in scope.
2+
3+
Erroneous code examples:
4+
5+
```compile_fail,E0800
6+
fn missing() -> impl Sized + use<T> {}
7+
```
8+
9+
To fix this error, please verify you didn't misspell the type or const
10+
parameter, or double-check if you forgot to declare the parameter in
11+
the list of generics.

compiler/rustc_error_codes/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,8 @@ E0795: 0795,
538538
E0796: 0796,
539539
E0797: 0797,
540540
E0798: 0798,
541+
E0799: 0799,
542+
E0800: 0800,
541543
);
542544
)
543545
}

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
584584
| Res::SelfTyParam { trait_: def_id } => {
585585
self.resolve_type_ref(def_id.expect_local(), param.hir_id);
586586
}
587-
Res::Err => {}
588587
Res::SelfTyAlias { alias_to, .. } => {
589588
self.tcx.dcx().emit_err(errors::PreciseCaptureSelfAlias {
590589
span: param.ident.span,
@@ -593,11 +592,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
593592
});
594593
}
595594
res => {
596-
self.tcx.dcx().emit_err(errors::BadPreciseCapture {
597-
span: param.ident.span,
598-
kind: "type or const",
599-
found: res.descr().to_string(),
600-
});
595+
self.tcx.dcx().span_delayed_bug(
596+
param.ident.span,
597+
format!("expected type or const param, found {res:?}"),
598+
);
601599
}
602600
},
603601
}

compiler/rustc_hir_analysis/src/errors/precise_captures.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_errors::E0799;
12
use rustc_macros::Diagnostic;
23
use rustc_span::{Span, Symbol};
34

@@ -43,7 +44,7 @@ pub(crate) struct BadPreciseCapture {
4344
}
4445

4546
#[derive(Diagnostic)]
46-
#[diag(hir_analysis_precise_capture_self_alias)]
47+
#[diag(hir_analysis_precise_capture_self_alias, code = E0799)]
4748
pub(crate) struct PreciseCaptureSelfAlias {
4849
#[primary_span]
4950
pub span: Span,

compiler/rustc_resolve/src/late.rs

+38-5
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ pub(crate) enum PathSource<'a> {
402402
TraitItem(Namespace),
403403
// Paths in delegation item
404404
Delegation,
405+
/// An arg in a `use<'a, N>` precise-capturing bound.
406+
PreciseCapturingArg(Namespace),
405407
}
406408

407409
impl<'a> PathSource<'a> {
@@ -413,6 +415,7 @@ impl<'a> PathSource<'a> {
413415
| PathSource::TupleStruct(..)
414416
| PathSource::Delegation => ValueNS,
415417
PathSource::TraitItem(ns) => ns,
418+
PathSource::PreciseCapturingArg(ns) => ns,
416419
}
417420
}
418421

@@ -423,7 +426,10 @@ impl<'a> PathSource<'a> {
423426
| PathSource::Pat
424427
| PathSource::Struct
425428
| PathSource::TupleStruct(..) => true,
426-
PathSource::Trait(_) | PathSource::TraitItem(..) | PathSource::Delegation => false,
429+
PathSource::Trait(_)
430+
| PathSource::TraitItem(..)
431+
| PathSource::Delegation
432+
| PathSource::PreciseCapturingArg(..) => false,
427433
}
428434
}
429435

@@ -466,6 +472,7 @@ impl<'a> PathSource<'a> {
466472
_ => "value",
467473
},
468474
PathSource::Delegation => "function",
475+
PathSource::PreciseCapturingArg(..) => "type or const parameter",
469476
}
470477
}
471478

@@ -534,6 +541,15 @@ impl<'a> PathSource<'a> {
534541
_ => false,
535542
},
536543
PathSource::Delegation => matches!(res, Res::Def(DefKind::Fn | DefKind::AssocFn, _)),
544+
PathSource::PreciseCapturingArg(ValueNS) => {
545+
matches!(res, Res::Def(DefKind::ConstParam, _))
546+
}
547+
// We allow `SelfTyAlias` here so we can give a more descriptive error later.
548+
PathSource::PreciseCapturingArg(TypeNS) => matches!(
549+
res,
550+
Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }
551+
),
552+
PathSource::PreciseCapturingArg(MacroNS) => false,
537553
}
538554
}
539555

@@ -551,6 +567,8 @@ impl<'a> PathSource<'a> {
551567
(PathSource::Pat | PathSource::TupleStruct(..), false) => E0531,
552568
(PathSource::TraitItem(..), true) => E0575,
553569
(PathSource::TraitItem(..), false) => E0576,
570+
(PathSource::PreciseCapturingArg(..), true) => E0799,
571+
(PathSource::PreciseCapturingArg(..), false) => E0800,
554572
}
555573
}
556574
}
@@ -1077,9 +1095,19 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
10771095
};
10781096
// Like `Ty::Param`, we try resolving this as both a const and a type.
10791097
if !check_ns(TypeNS) && check_ns(ValueNS) {
1080-
self.smart_resolve_path(*id, &None, path, PathSource::Expr(None));
1098+
self.smart_resolve_path(
1099+
*id,
1100+
&None,
1101+
path,
1102+
PathSource::PreciseCapturingArg(ValueNS),
1103+
);
10811104
} else {
1082-
self.smart_resolve_path(*id, &None, path, PathSource::Type);
1105+
self.smart_resolve_path(
1106+
*id,
1107+
&None,
1108+
path,
1109+
PathSource::PreciseCapturingArg(TypeNS),
1110+
);
10831111
}
10841112
}
10851113
}
@@ -1889,7 +1917,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18891917
);
18901918

18911919
let inferred = match source {
1892-
PathSource::Trait(..) | PathSource::TraitItem(..) | PathSource::Type => false,
1920+
PathSource::Trait(..)
1921+
| PathSource::TraitItem(..)
1922+
| PathSource::Type
1923+
| PathSource::PreciseCapturingArg(..) => false,
18931924
PathSource::Expr(..)
18941925
| PathSource::Pat
18951926
| PathSource::Struct
@@ -3982,7 +4013,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
39824013
Applicability::MaybeIncorrect,
39834014
))
39844015
} else if res.is_none()
3985-
&& let PathSource::Type | PathSource::Expr(_) = source
4016+
&& let PathSource::Type
4017+
| PathSource::Expr(_)
4018+
| PathSource::PreciseCapturingArg(..) = source
39864019
{
39874020
this.suggest_adding_generic_parameter(path, source)
39884021
} else {

compiler/rustc_resolve/src/late/diagnostics.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -2538,8 +2538,13 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
25382538
}
25392539

25402540
let (msg, sugg) = match source {
2541-
PathSource::Type => ("you might be missing a type parameter", ident),
2542-
PathSource::Expr(_) => ("you might be missing a const parameter", format!("const {ident}: /* Type */")),
2541+
PathSource::Type | PathSource::PreciseCapturingArg(TypeNS) => {
2542+
("you might be missing a type parameter", ident)
2543+
}
2544+
PathSource::Expr(_) | PathSource::PreciseCapturingArg(ValueNS) => (
2545+
"you might be missing a const parameter",
2546+
format!("const {ident}: /* Type */"),
2547+
),
25432548
_ => return None,
25442549
};
25452550
let (span, sugg) = if let [.., param] = &generics.params[..] {

tests/crashes/130399.rs

-5
This file was deleted.

tests/ui/error-codes/E0799.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn test() -> impl Sized + use<main> {}
2+
//~^ ERROR E0799
3+
4+
fn main() {}

tests/ui/error-codes/E0799.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0799]: expected type or const parameter, found function `main`
2+
--> $DIR/E0799.rs:1:31
3+
|
4+
LL | fn test() -> impl Sized + use<main> {}
5+
| ^^^^ not a type or const parameter
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0799`.

tests/ui/error-codes/E0800.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn test() -> impl Sized + use<Missing> {}
2+
//~^ ERROR E0800
3+
4+
fn main() {}

tests/ui/error-codes/E0800.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0800]: cannot find type or const parameter `Missing` in this scope
2+
--> $DIR/E0800.rs:1:31
3+
|
4+
LL | fn test() -> impl Sized + use<Missing> {}
5+
| ^^^^^^^ not found in this scope
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0800`.
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
fn missing() -> impl Sized + use<T> {}
2-
//~^ ERROR cannot find type `T` in this scope
2+
//~^ ERROR cannot find type or const parameter `T` in this scope
33

44
fn missing_self() -> impl Sized + use<Self> {}
5-
//~^ ERROR cannot find type `Self` in this scope
5+
//~^ ERROR cannot find type or const parameter `Self` in this scope
66

77
struct MyType;
88
impl MyType {
@@ -11,6 +11,9 @@ impl MyType {
1111
}
1212

1313
fn hello() -> impl Sized + use<hello> {}
14-
//~^ ERROR expected type or const parameter in `use<...>` precise captures list, found function
14+
//~^ ERROR expected type or const parameter, found function `hello`
15+
16+
fn arg(x: ()) -> impl Sized + use<x> {}
17+
//~^ ERROR expected type or const parameter, found local variable `x`
1518

1619
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0412]: cannot find type `T` in this scope
1+
error[E0800]: cannot find type or const parameter `T` in this scope
22
--> $DIR/bad-params.rs:1:34
33
|
44
LL | fn missing() -> impl Sized + use<T> {}
@@ -9,29 +9,35 @@ help: you might be missing a type parameter
99
LL | fn missing<T>() -> impl Sized + use<T> {}
1010
| +++
1111

12-
error[E0411]: cannot find type `Self` in this scope
12+
error[E0411]: cannot find type or const parameter `Self` in this scope
1313
--> $DIR/bad-params.rs:4:39
1414
|
1515
LL | fn missing_self() -> impl Sized + use<Self> {}
1616
| ------------ ^^^^ `Self` is only available in impls, traits, and type definitions
1717
| |
1818
| `Self` not allowed in a function
1919

20-
error: `Self` can't be captured in `use<...>` precise captures list, since it is an alias
20+
error[E0799]: expected type or const parameter, found function `hello`
21+
--> $DIR/bad-params.rs:13:32
22+
|
23+
LL | fn hello() -> impl Sized + use<hello> {}
24+
| ^^^^^ not a type or const parameter
25+
26+
error[E0799]: expected type or const parameter, found local variable `x`
27+
--> $DIR/bad-params.rs:16:35
28+
|
29+
LL | fn arg(x: ()) -> impl Sized + use<x> {}
30+
| ^ not a type or const parameter
31+
32+
error[E0799]: `Self` can't be captured in `use<...>` precise captures list, since it is an alias
2133
--> $DIR/bad-params.rs:9:48
2234
|
2335
LL | impl MyType {
2436
| ----------- `Self` is not a generic argument, but an alias to the type of the implementation
2537
LL | fn self_is_not_param() -> impl Sized + use<Self> {}
2638
| ^^^^
2739

28-
error: expected type or const parameter in `use<...>` precise captures list, found function
29-
--> $DIR/bad-params.rs:13:32
30-
|
31-
LL | fn hello() -> impl Sized + use<hello> {}
32-
| ^^^^^
33-
34-
error: aborting due to 4 previous errors
40+
error: aborting due to 5 previous errors
3541

36-
Some errors have detailed explanations: E0411, E0412.
42+
Some errors have detailed explanations: E0411, E0799, E0800.
3743
For more information about an error, try `rustc --explain E0411`.

0 commit comments

Comments
 (0)