Skip to content

Commit 02d7317

Browse files
Add hir::Node::PreciseCapturingNonLifetimeArg
1 parent 42ba57c commit 02d7317

File tree

14 files changed

+110
-38
lines changed

14 files changed

+110
-38
lines changed

compiler/rustc_ast_lowering/src/index.rs

+17
Original file line numberDiff line numberDiff line change
@@ -385,4 +385,21 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
385385
fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
386386
self.visit_pat(p)
387387
}
388+
389+
fn visit_precise_capturing_arg(
390+
&mut self,
391+
arg: &'hir PreciseCapturingArg<'hir>,
392+
) -> Self::Result {
393+
match arg {
394+
PreciseCapturingArg::Lifetime(_) => {
395+
// This is represented as a `Node::Lifetime`, intravisit will get to it below.
396+
}
397+
PreciseCapturingArg::Param(param) => self.insert(
398+
param.ident.span,
399+
param.hir_id,
400+
Node::PreciseCapturingNonLifetimeArg(param),
401+
),
402+
}
403+
intravisit::walk_precise_capturing_arg(self, arg);
404+
}
388405
}

compiler/rustc_ast_lowering/src/lib.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1790,11 +1790,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17901790
PreciseCapturingArg::Lifetime(lt) => {
17911791
hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt))
17921792
}
1793-
PreciseCapturingArg::Arg(_, node_id) => {
1793+
PreciseCapturingArg::Arg(ident, node_id) => {
17941794
let res = self.resolver.get_partial_res(*node_id).map_or(Res::Err, |partial_res| {
17951795
partial_res.full_res().expect("no partial res expected for precise capture arg")
17961796
});
1797-
hir::PreciseCapturingArg::Param(self.lower_res(res), self.lower_node_id(*node_id))
1797+
hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1798+
hir_id: self.lower_node_id(*node_id),
1799+
ident: self.lower_ident(*ident),
1800+
res: self.lower_res(res),
1801+
})
17981802
}
17991803
}))
18001804
}

compiler/rustc_hir/src/hir.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -2565,7 +2565,14 @@ pub struct OpaqueTy<'hir> {
25652565
pub enum PreciseCapturingArg<'hir> {
25662566
Lifetime(&'hir Lifetime),
25672567
/// Non-lifetime argument (type or const)
2568-
Param(Res, HirId),
2568+
Param(PreciseCapturingNonLifetimeArg),
2569+
}
2570+
2571+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
2572+
pub struct PreciseCapturingNonLifetimeArg {
2573+
pub hir_id: HirId,
2574+
pub ident: Ident,
2575+
pub res: Res,
25692576
}
25702577

25712578
/// From whence the opaque type came.
@@ -3544,6 +3551,7 @@ pub enum Node<'hir> {
35443551
WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
35453552
// FIXME: Merge into `Node::Infer`.
35463553
ArrayLenInfer(&'hir InferArg),
3554+
PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
35473555
// Created by query feeding
35483556
Synthetic,
35493557
// Span by reference to minimize `Node`'s size
@@ -3580,6 +3588,7 @@ impl<'hir> Node<'hir> {
35803588
Node::TypeBinding(b) => Some(b.ident),
35813589
Node::PatField(f) => Some(f.ident),
35823590
Node::ExprField(f) => Some(f.ident),
3591+
Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
35833592
Node::Param(..)
35843593
| Node::AnonConst(..)
35853594
| Node::ConstBlock(..)

compiler/rustc_hir/src/intravisit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1151,7 +1151,7 @@ pub fn walk_precise_capturing_arg<'v, V: Visitor<'v>>(
11511151
) -> V::Result {
11521152
match *arg {
11531153
PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt),
1154-
PreciseCapturingArg::Param(_, hir_id) => visitor.visit_id(hir_id),
1154+
PreciseCapturingArg::Param(param) => visitor.visit_id(param.hir_id),
11551155
}
11561156
}
11571157

compiler/rustc_hir_analysis/src/check/check.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
487487
for arg in precise_capturing_args {
488488
match *arg {
489489
hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, .. })
490-
| hir::PreciseCapturingArg::Param(_, hir_id) => match tcx.named_bound_var(hir_id) {
490+
| hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
491+
hir_id, ..
492+
}) => match tcx.named_bound_var(hir_id) {
491493
Some(ResolvedArg::EarlyBound(def_id)) => {
492494
expected_captures.insert(def_id);
493495
}

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -577,10 +577,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
577577
});
578578
}
579579
},
580-
hir::PreciseCapturingArg::Param(res, hir_id) => match res {
580+
hir::PreciseCapturingArg::Param(param) => match param.res {
581581
Res::Def(DefKind::TyParam | DefKind::ConstParam, def_id)
582582
| Res::SelfTyParam { trait_: def_id } => {
583-
self.resolve_type_ref(def_id.expect_local(), hir_id);
583+
self.resolve_type_ref(def_id.expect_local(), param.hir_id);
584584
}
585585
Res::Err => {}
586586
_ => {

compiler/rustc_hir_pretty/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ impl<'a> State<'a> {
9999
Node::PatField(a) => self.print_patfield(a),
100100
Node::Arm(a) => self.print_arm(a),
101101
Node::Infer(_) => self.word("_"),
102+
Node::PreciseCapturingNonLifetimeArg(param) => self.print_ident(param.ident),
102103
Node::Block(a) => {
103104
// Containing cbox, will be closed by print-block at `}`.
104105
self.cbox(INDENT_UNIT);

compiler/rustc_middle/src/hir/map/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ impl<'hir> Map<'hir> {
909909
Node::Crate(item) => item.spans.inner_span,
910910
Node::WhereBoundPredicate(pred) => pred.span,
911911
Node::ArrayLenInfer(inf) => inf.span,
912+
Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span,
912913
Node::Synthetic => unreachable!(),
913914
Node::Err(span) => *span,
914915
}
@@ -1176,6 +1177,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
11761177
Node::ArrayLenInfer(_) => node_str("array len infer"),
11771178
Node::Synthetic => unreachable!(),
11781179
Node::Err(_) => node_str("error"),
1180+
Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"),
11791181
}
11801182
}
11811183

Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
#![feature(precise_capturing)]
22
//~^ WARN the feature `precise_capturing` is incomplete
33

4-
fn type_param<T>() -> impl use<> Sized {}
5-
//~^ ERROR `impl Trait` must mention all type parameters in scope
4+
fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
5+
//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
6+
7+
fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
8+
//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
69

710
fn main() {}

tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr

+22-6
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,29 @@ LL | #![feature(precise_capturing)]
77
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
error: `impl Trait` must mention all type parameters in scope
11-
--> $DIR/forgot-to-capture-lifetime.rs:4:15
10+
error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
11+
--> $DIR/forgot-to-capture-lifetime.rs:4:58
1212
|
13-
LL | fn type_param<T>() -> impl use<> Sized {}
14-
| ^ ---------------- type parameter is implicitly captured by this `impl Trait`
13+
LL | fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
14+
| -- -----------------^^----
15+
| | |
16+
| | lifetime captured due to being mentioned in the bounds of the `impl Trait`
17+
| this lifetime parameter is captured
18+
19+
error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
20+
--> $DIR/forgot-to-capture-lifetime.rs:7:60
21+
|
22+
LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
23+
| -- ---------------- ^
24+
| | |
25+
| | opaque type defined here
26+
| hidden type `&'a ()` captures the lifetime `'a` as defined here
27+
|
28+
help: to declare that `impl Sized` captures `'a`, you can add an explicit `'a` lifetime bound
1529
|
16-
= note: currently, all type parameters are required to be mentioned in the precise captures list
30+
LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized + 'a { x }
31+
| ++++
1732

18-
error: aborting due to 1 previous error; 1 warning emitted
33+
error: aborting due to 2 previous errors; 1 warning emitted
1934

35+
For more information about this error, try `rustc --explain E0700`.
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#![feature(precise_capturing)]
22
//~^ WARN the feature `precise_capturing` is incomplete
33

4-
fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
5-
//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
4+
fn type_param<T>() -> impl use<> Sized {}
5+
//~^ ERROR `impl Trait` must mention all type parameters in scope
66

7-
fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
8-
//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
7+
trait Foo {
8+
//~^ ERROR `impl Trait` must mention all type parameters in scope
9+
fn bar() -> impl use<> Sized;
10+
}
911

1012
fn main() {}

tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr

+14-19
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,24 @@ LL | #![feature(precise_capturing)]
77
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
11-
--> $DIR/forgot-to-capture-type.rs:4:58
10+
error: `impl Trait` must mention all type parameters in scope
11+
--> $DIR/forgot-to-capture-type.rs:4:15
1212
|
13-
LL | fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
14-
| -- -----------------^^----
15-
| | |
16-
| | lifetime captured due to being mentioned in the bounds of the `impl Trait`
17-
| this lifetime parameter is captured
18-
19-
error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
20-
--> $DIR/forgot-to-capture-type.rs:7:60
13+
LL | fn type_param<T>() -> impl use<> Sized {}
14+
| ^ ---------------- type parameter is implicitly captured by this `impl Trait`
2115
|
22-
LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
23-
| -- ---------------- ^
24-
| | |
25-
| | opaque type defined here
26-
| hidden type `&'a ()` captures the lifetime `'a` as defined here
16+
= note: currently, all type parameters are required to be mentioned in the precise captures list
17+
18+
error: `impl Trait` must mention all type parameters in scope
19+
--> $DIR/forgot-to-capture-type.rs:7:1
2720
|
28-
help: to declare that `impl Sized` captures `'a`, you can add an explicit `'a` lifetime bound
21+
LL | trait Foo {
22+
| ^^^^^^^^^
23+
LL |
24+
LL | fn bar() -> impl use<> Sized;
25+
| ---------------- type parameter is implicitly captured by this `impl Trait`
2926
|
30-
LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized + 'a { x }
31-
| ++++
27+
= note: currently, all type parameters are required to be mentioned in the precise captures list
3228

3329
error: aborting due to 2 previous errors; 1 warning emitted
3430

35-
For more information about this error, try `rustc --explain E0700`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ check-pass
2+
3+
#![feature(precise_capturing)]
4+
//~^ WARN the feature `precise_capturing` is incomplete
5+
6+
trait Foo {
7+
fn bar<'a>() -> impl use<Self> Sized;
8+
}
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/self-capture.rs:3:12
3+
|
4+
LL | #![feature(precise_capturing)]
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
warning: 1 warning emitted
11+

0 commit comments

Comments
 (0)