about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs17
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs8
-rw-r--r--compiler/rustc_hir/src/hir.rs11
-rw-r--r--compiler/rustc_hir/src/intravisit.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs4
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs2
-rw-r--r--tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs7
-rw-r--r--tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr28
-rw-r--r--tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs10
-rw-r--r--tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr33
-rw-r--r--tests/ui/impl-trait/precise-capturing/self-capture.rs10
-rw-r--r--tests/ui/impl-trait/precise-capturing/self-capture.stderr11
14 files changed, 110 insertions, 38 deletions
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 4c552289a81..93be9b9b8cf 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -385,4 +385,21 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) {
         self.visit_pat(p)
     }
+
+    fn visit_precise_capturing_arg(
+        &mut self,
+        arg: &'hir PreciseCapturingArg<'hir>,
+    ) -> Self::Result {
+        match arg {
+            PreciseCapturingArg::Lifetime(_) => {
+                // This is represented as a `Node::Lifetime`, intravisit will get to it below.
+            }
+            PreciseCapturingArg::Param(param) => self.insert(
+                param.ident.span,
+                param.hir_id,
+                Node::PreciseCapturingNonLifetimeArg(param),
+            ),
+        }
+        intravisit::walk_precise_capturing_arg(self, arg);
+    }
 }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index b586d2a1bf5..84776f920c4 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1790,11 +1790,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             PreciseCapturingArg::Lifetime(lt) => {
                 hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt))
             }
-            PreciseCapturingArg::Arg(_, node_id) => {
+            PreciseCapturingArg::Arg(ident, node_id) => {
                 let res = self.resolver.get_partial_res(*node_id).map_or(Res::Err, |partial_res| {
                     partial_res.full_res().expect("no partial res expected for precise capture arg")
                 });
-                hir::PreciseCapturingArg::Param(self.lower_res(res), self.lower_node_id(*node_id))
+                hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
+                    hir_id: self.lower_node_id(*node_id),
+                    ident: self.lower_ident(*ident),
+                    res: self.lower_res(res),
+                })
             }
         }))
     }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index dc76deb1815..00b1ea061cc 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -2565,7 +2565,14 @@ pub struct OpaqueTy<'hir> {
 pub enum PreciseCapturingArg<'hir> {
     Lifetime(&'hir Lifetime),
     /// Non-lifetime argument (type or const)
-    Param(Res, HirId),
+    Param(PreciseCapturingNonLifetimeArg),
+}
+
+#[derive(Debug, Clone, Copy, HashStable_Generic)]
+pub struct PreciseCapturingNonLifetimeArg {
+    pub hir_id: HirId,
+    pub ident: Ident,
+    pub res: Res,
 }
 
 /// From whence the opaque type came.
@@ -3544,6 +3551,7 @@ pub enum Node<'hir> {
     WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
     // FIXME: Merge into `Node::Infer`.
     ArrayLenInfer(&'hir InferArg),
+    PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg),
     // Created by query feeding
     Synthetic,
     // Span by reference to minimize `Node`'s size
@@ -3580,6 +3588,7 @@ impl<'hir> Node<'hir> {
             Node::TypeBinding(b) => Some(b.ident),
             Node::PatField(f) => Some(f.ident),
             Node::ExprField(f) => Some(f.ident),
+            Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident),
             Node::Param(..)
             | Node::AnonConst(..)
             | Node::ConstBlock(..)
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index d3ede3a904f..cd9f9ff9109 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -1151,7 +1151,7 @@ pub fn walk_precise_capturing_arg<'v, V: Visitor<'v>>(
 ) -> V::Result {
     match *arg {
         PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt),
-        PreciseCapturingArg::Param(_, hir_id) => visitor.visit_id(hir_id),
+        PreciseCapturingArg::Param(param) => visitor.visit_id(param.hir_id),
     }
 }
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index f4d443c324a..592a8648f14 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -487,7 +487,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe
     for arg in precise_capturing_args {
         match *arg {
             hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, .. })
-            | hir::PreciseCapturingArg::Param(_, hir_id) => match tcx.named_bound_var(hir_id) {
+            | hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
+                hir_id, ..
+            }) => match tcx.named_bound_var(hir_id) {
                 Some(ResolvedArg::EarlyBound(def_id)) => {
                     expected_captures.insert(def_id);
                 }
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 8d5f4c13721..fb3713140ff 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -577,10 +577,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                     });
                 }
             },
-            hir::PreciseCapturingArg::Param(res, hir_id) => match res {
+            hir::PreciseCapturingArg::Param(param) => match param.res {
                 Res::Def(DefKind::TyParam | DefKind::ConstParam, def_id)
                 | Res::SelfTyParam { trait_: def_id } => {
-                    self.resolve_type_ref(def_id.expect_local(), hir_id);
+                    self.resolve_type_ref(def_id.expect_local(), param.hir_id);
                 }
                 Res::Err => {}
                 _ => {
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 39312614c1b..3d3b16baf69 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -99,6 +99,7 @@ impl<'a> State<'a> {
             Node::PatField(a) => self.print_patfield(a),
             Node::Arm(a) => self.print_arm(a),
             Node::Infer(_) => self.word("_"),
+            Node::PreciseCapturingNonLifetimeArg(param) => self.print_ident(param.ident),
             Node::Block(a) => {
                 // Containing cbox, will be closed by print-block at `}`.
                 self.cbox(INDENT_UNIT);
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 72f849b534a..88de834c436 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -909,6 +909,7 @@ impl<'hir> Map<'hir> {
             Node::Crate(item) => item.spans.inner_span,
             Node::WhereBoundPredicate(pred) => pred.span,
             Node::ArrayLenInfer(inf) => inf.span,
+            Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span,
             Node::Synthetic => unreachable!(),
             Node::Err(span) => *span,
         }
@@ -1176,6 +1177,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
         Node::ArrayLenInfer(_) => node_str("array len infer"),
         Node::Synthetic => unreachable!(),
         Node::Err(_) => node_str("error"),
+        Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"),
     }
 }
 
diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs
index 7e856ba9517..cc86bf83107 100644
--- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs
+++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs
@@ -1,7 +1,10 @@
 #![feature(precise_capturing)]
 //~^ WARN the feature `precise_capturing` is incomplete
 
-fn type_param<T>() -> impl use<> Sized {}
-//~^ ERROR `impl Trait` must mention all type parameters in scope
+fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
+//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
+
+fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
+//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr
index 1ef46a36e46..e472c898050 100644
--- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr
+++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr
@@ -7,13 +7,29 @@ LL | #![feature(precise_capturing)]
    = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: `impl Trait` must mention all type parameters in scope
-  --> $DIR/forgot-to-capture-lifetime.rs:4:15
+error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
+  --> $DIR/forgot-to-capture-lifetime.rs:4:58
    |
-LL | fn type_param<T>() -> impl use<> Sized {}
-   |               ^       ---------------- type parameter is implicitly captured by this `impl Trait`
+LL | fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
+   |                       --                -----------------^^----
+   |                       |                 |
+   |                       |                 lifetime captured due to being mentioned in the bounds of the `impl Trait`
+   |                       this lifetime parameter is captured
+
+error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
+  --> $DIR/forgot-to-capture-lifetime.rs:7:60
+   |
+LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
+   |                       --                ----------------   ^
+   |                       |                 |
+   |                       |                 opaque type defined here
+   |                       hidden type `&'a ()` captures the lifetime `'a` as defined here
+   |
+help: to declare that `impl Sized` captures `'a`, you can add an explicit `'a` lifetime bound
    |
-   = note: currently, all type parameters are required to be mentioned in the precise captures list
+LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized + 'a { x }
+   |                                                          ++++
 
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 2 previous errors; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs
index cc86bf83107..6eaff01183d 100644
--- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs
+++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs
@@ -1,10 +1,12 @@
 #![feature(precise_capturing)]
 //~^ WARN the feature `precise_capturing` is incomplete
 
-fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
-//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
+fn type_param<T>() -> impl use<> Sized {}
+//~^ ERROR `impl Trait` must mention all type parameters in scope
 
-fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
-//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds
+trait Foo {
+//~^ ERROR `impl Trait` must mention all type parameters in scope
+    fn bar() -> impl use<> Sized;
+}
 
 fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr
index 58f284ec6bc..a8eb4547dcd 100644
--- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr
+++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr
@@ -7,29 +7,24 @@ LL | #![feature(precise_capturing)]
    = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
-  --> $DIR/forgot-to-capture-type.rs:4:58
+error: `impl Trait` must mention all type parameters in scope
+  --> $DIR/forgot-to-capture-type.rs:4:15
    |
-LL | fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x }
-   |                       --                -----------------^^----
-   |                       |                 |
-   |                       |                 lifetime captured due to being mentioned in the bounds of the `impl Trait`
-   |                       this lifetime parameter is captured
-
-error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
-  --> $DIR/forgot-to-capture-type.rs:7:60
+LL | fn type_param<T>() -> impl use<> Sized {}
+   |               ^       ---------------- type parameter is implicitly captured by this `impl Trait`
    |
-LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x }
-   |                       --                ----------------   ^
-   |                       |                 |
-   |                       |                 opaque type defined here
-   |                       hidden type `&'a ()` captures the lifetime `'a` as defined here
+   = note: currently, all type parameters are required to be mentioned in the precise captures list
+
+error: `impl Trait` must mention all type parameters in scope
+  --> $DIR/forgot-to-capture-type.rs:7:1
    |
-help: to declare that `impl Sized` captures `'a`, you can add an explicit `'a` lifetime bound
+LL | trait Foo {
+   | ^^^^^^^^^
+LL |
+LL |     fn bar() -> impl use<> Sized;
+   |                 ---------------- type parameter is implicitly captured by this `impl Trait`
    |
-LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized + 'a { x }
-   |                                                          ++++
+   = note: currently, all type parameters are required to be mentioned in the precise captures list
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.rs b/tests/ui/impl-trait/precise-capturing/self-capture.rs
new file mode 100644
index 00000000000..ecbc388e27b
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/self-capture.rs
@@ -0,0 +1,10 @@
+//@ check-pass
+
+#![feature(precise_capturing)]
+//~^ WARN the feature `precise_capturing` is incomplete
+
+trait Foo {
+    fn bar<'a>() -> impl use<Self> Sized;
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.stderr b/tests/ui/impl-trait/precise-capturing/self-capture.stderr
new file mode 100644
index 00000000000..5a058c6826d
--- /dev/null
+++ b/tests/ui/impl-trait/precise-capturing/self-capture.stderr
@@ -0,0 +1,11 @@
+warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/self-capture.rs:3:12
+   |
+LL | #![feature(precise_capturing)]
+   |            ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+warning: 1 warning emitted
+