Skip to content

Commit 26bdfef

Browse files
Do precise capturing arg validation in resolve
1 parent 13b5a4e commit 26bdfef

File tree

6 files changed

+72
-33
lines changed

6 files changed

+72
-33
lines changed

Diff for: 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
}

Diff for: compiler/rustc_resolve/src/late.rs

+39-7
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,15 +541,25 @@ 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

540556
fn error_code(self, has_unexpected_resolution: bool) -> ErrCode {
541557
match (self, has_unexpected_resolution) {
542558
(PathSource::Trait(_), true) => E0404,
543559
(PathSource::Trait(_), false) => E0405,
544-
(PathSource::Type, true) => E0573,
545-
(PathSource::Type, false) => E0412,
560+
// TODO:
561+
(PathSource::Type | PathSource::PreciseCapturingArg(..), true) => E0573,
562+
(PathSource::Type | PathSource::PreciseCapturingArg(..), false) => E0412,
546563
(PathSource::Struct, true) => E0574,
547564
(PathSource::Struct, false) => E0422,
548565
(PathSource::Expr(..), true) | (PathSource::Delegation, true) => E0423,
@@ -1077,9 +1094,19 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
10771094
};
10781095
// Like `Ty::Param`, we try resolving this as both a const and a type.
10791096
if !check_ns(TypeNS) && check_ns(ValueNS) {
1080-
self.smart_resolve_path(*id, &None, path, PathSource::Expr(None));
1097+
self.smart_resolve_path(
1098+
*id,
1099+
&None,
1100+
path,
1101+
PathSource::PreciseCapturingArg(ValueNS),
1102+
);
10811103
} else {
1082-
self.smart_resolve_path(*id, &None, path, PathSource::Type);
1104+
self.smart_resolve_path(
1105+
*id,
1106+
&None,
1107+
path,
1108+
PathSource::PreciseCapturingArg(TypeNS),
1109+
);
10831110
}
10841111
}
10851112
}
@@ -1889,7 +1916,10 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
18891916
);
18901917

18911918
let inferred = match source {
1892-
PathSource::Trait(..) | PathSource::TraitItem(..) | PathSource::Type => false,
1919+
PathSource::Trait(..)
1920+
| PathSource::TraitItem(..)
1921+
| PathSource::Type
1922+
| PathSource::PreciseCapturingArg(..) => false,
18931923
PathSource::Expr(..)
18941924
| PathSource::Pat
18951925
| PathSource::Struct
@@ -3982,7 +4012,9 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
39824012
Applicability::MaybeIncorrect,
39834013
))
39844014
} else if res.is_none()
3985-
&& let PathSource::Type | PathSource::Expr(_) = source
4015+
&& let PathSource::Type
4016+
| PathSource::Expr(_)
4017+
| PathSource::PreciseCapturingArg(..) = source
39864018
{
39874019
this.suggest_adding_generic_parameter(path, source)
39884020
} else {

Diff for: 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[..] {

Diff for: tests/crashes/130399.rs

-5
This file was deleted.

Diff for: tests/ui/impl-trait/precise-capturing/bad-params.rs

+6-3
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() {}
+16-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0412]: cannot find type `T` in this scope
1+
error[E0412]: 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,14 +9,26 @@ 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[E0573]: 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[E0573]: 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+
2032
error: `Self` can't be captured in `use<...>` precise captures list, since it is an alias
2133
--> $DIR/bad-params.rs:9:48
2234
|
@@ -25,13 +37,7 @@ LL | impl MyType {
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, E0412, E0573.
3743
For more information about an error, try `rustc --explain E0411`.

0 commit comments

Comments
 (0)