diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 18f7a18625edb..1160290cdff59 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -21,12 +21,16 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh .label = deref recursion limit reached .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) -hir_analysis_cannot_capture_late_bound_const_in_anon_const = - cannot capture late-bound const parameter in a constant +hir_analysis_cannot_capture_late_bound_const = + cannot capture late-bound const parameter in {$what} .label = parameter defined here -hir_analysis_cannot_capture_late_bound_ty_in_anon_const = - cannot capture late-bound type parameter in a constant +hir_analysis_cannot_capture_late_bound_lifetime = + cannot capture late-bound lifetime in {$what} + .label = lifetime defined here + +hir_analysis_cannot_capture_late_bound_ty = + cannot capture late-bound type parameter in {$what} .label = parameter defined here hir_analysis_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_ty}` to fat pointer `{$cast_ty}` diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index acfd8dcb11275..3a97a383ee19e 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -268,9 +268,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // (*) -- not late-bound, won't change } - Some(rbv::ResolvedArg::Error(_)) => { - bug!("only ty/ct should resolve as ResolvedArg::Error") - } + Some(rbv::ResolvedArg::Error(guar)) => ty::Region::new_error(tcx, guar), None => { self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| { 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 2bee272772538..6869c86960380 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -158,13 +158,14 @@ enum Scope<'a> { s: ScopeRef<'a>, }, - /// Disallows capturing non-lifetime binders from parent scopes. + /// Disallows capturing late-bound vars from parent scopes. /// /// This is necessary for something like `for [(); { /* references T */ }]:`, /// since we don't do something more correct like replacing any captured /// late-bound vars with early-bound params in the const's own generics. - AnonConstBoundary { + LateBoundary { s: ScopeRef<'a>, + what: &'static str, }, Root { @@ -216,7 +217,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> { .field("s", &"..") .finish(), Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(), - Scope::AnonConstBoundary { s: _ } => f.debug_struct("AnonConstBoundary").finish(), + Scope::LateBoundary { s: _, what } => { + f.debug_struct("LateBoundary").field("what", what).finish() + } Scope::Root { opt_parent_item } => { f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish() } @@ -318,7 +321,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { break (vec![], BinderScopeType::Normal); } - Scope::ObjectLifetimeDefault { s, .. } | Scope::AnonConstBoundary { s } => { + Scope::ObjectLifetimeDefault { s, .. } | Scope::LateBoundary { s, .. } => { scope = s; } @@ -697,9 +700,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { }) => { intravisit::walk_ty(self, ty); - // Elided lifetimes are not allowed in non-return - // position impl Trait - let scope = Scope::TraitRefBoundary { s: self.scope }; + // Elided lifetimes and late-bound lifetimes (from the parent) + // are not allowed in non-return position impl Trait + let scope = Scope::LateBoundary { + s: &Scope::TraitRefBoundary { s: self.scope }, + what: "type alias impl trait", + }; self.with(scope, |this| intravisit::walk_item(this, opaque_ty)); return; @@ -979,7 +985,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) { - self.with(Scope::AnonConstBoundary { s: self.scope }, |this| { + self.with(Scope::LateBoundary { s: self.scope, what: "constant" }, |this| { intravisit::walk_anon_const(this, c); }); } @@ -1174,6 +1180,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { let mut late_depth = 0; let mut scope = self.scope; let mut outermost_body = None; + let mut crossed_late_boundary = None; let result = loop { match *scope { Scope::Body { id, s } => { @@ -1258,8 +1265,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { Scope::ObjectLifetimeDefault { s, .. } | Scope::Supertrait { s, .. } - | Scope::TraitRefBoundary { s, .. } - | Scope::AnonConstBoundary { s } => { + | Scope::TraitRefBoundary { s, .. } => { + scope = s; + } + + Scope::LateBoundary { s, what } => { + crossed_late_boundary = Some(what); scope = s; } } @@ -1268,6 +1279,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { if let Some(mut def) = result { if let ResolvedArg::EarlyBound(..) = def { // Do not free early-bound regions, only late-bound ones. + } else if let ResolvedArg::LateBound(_, _, param_def_id) = def + && let Some(what) = crossed_late_boundary + { + let use_span = lifetime_ref.ident.span; + let def_span = self.tcx.def_span(param_def_id); + let guar = match self.tcx.def_kind(param_def_id) { + DefKind::LifetimeParam => { + self.tcx.sess.emit_err(errors::CannotCaptureLateBound::Lifetime { + use_span, + def_span, + what, + }) + } + _ => unreachable!(), + }; + def = ResolvedArg::Error(guar); } else if let Some(body_id) = outermost_body { let fn_id = self.tcx.hir().body_owner(body_id); match self.tcx.hir().get(fn_id) { @@ -1322,7 +1349,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { | Scope::ObjectLifetimeDefault { s, .. } | Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } - | Scope::AnonConstBoundary { s } => { + | Scope::LateBoundary { s, .. } => { scope = s; } } @@ -1341,7 +1368,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // search. let mut late_depth = 0; let mut scope = self.scope; - let mut crossed_anon_const = false; + let mut crossed_late_boundary = None; let result = loop { match *scope { @@ -1376,28 +1403,32 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { scope = s; } - Scope::AnonConstBoundary { s } => { - crossed_anon_const = true; + Scope::LateBoundary { s, what } => { + crossed_late_boundary = Some(what); scope = s; } } }; if let Some(def) = result { - if let ResolvedArg::LateBound(..) = def && crossed_anon_const { + if let ResolvedArg::LateBound(..) = def + && let Some(what) = crossed_late_boundary + { let use_span = self.tcx.hir().span(hir_id); let def_span = self.tcx.def_span(param_def_id); let guar = match self.tcx.def_kind(param_def_id) { DefKind::ConstParam => { - self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Const { + self.tcx.sess.emit_err(errors::CannotCaptureLateBound::Const { use_span, def_span, + what, }) } DefKind::TyParam => { - self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Type { + self.tcx.sess.emit_err(errors::CannotCaptureLateBound::Type { use_span, def_span, + what, }) } _ => unreachable!(), @@ -1446,7 +1477,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { | Scope::ObjectLifetimeDefault { s, .. } | Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } - | Scope::AnonConstBoundary { s } => { + | Scope::LateBoundary { s, .. } => { scope = s; } } @@ -1526,7 +1557,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { | Scope::ObjectLifetimeDefault { s, .. } | Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } - | Scope::AnonConstBoundary { s } => { + | Scope::LateBoundary { s, .. } => { scope = s; } } @@ -1831,7 +1862,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { Scope::Supertrait { s, .. } | Scope::TraitRefBoundary { s, .. } - | Scope::AnonConstBoundary { s } => { + | Scope::LateBoundary { s, .. } => { scope = s; } } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index b83ef8d07db4d..4705e40988b2f 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -430,20 +430,30 @@ pub(crate) struct VariadicFunctionCompatibleConvention<'a> { } #[derive(Diagnostic)] -pub(crate) enum CannotCaptureLateBoundInAnonConst { - #[diag(hir_analysis_cannot_capture_late_bound_ty_in_anon_const)] +pub(crate) enum CannotCaptureLateBound { + #[diag(hir_analysis_cannot_capture_late_bound_ty)] Type { #[primary_span] use_span: Span, #[label] def_span: Span, + what: &'static str, }, - #[diag(hir_analysis_cannot_capture_late_bound_const_in_anon_const)] + #[diag(hir_analysis_cannot_capture_late_bound_const)] Const { #[primary_span] use_span: Span, #[label] def_span: Span, + what: &'static str, + }, + #[diag(hir_analysis_cannot_capture_late_bound_lifetime)] + Lifetime { + #[primary_span] + use_span: Span, + #[label] + def_span: Span, + what: &'static str, }, } diff --git a/tests/ui/const-generics/late-bound-vars/in_closure.rs b/tests/ui/const-generics/late-bound-vars/in_closure.rs index 6549cad629b04..443c755c601cd 100644 --- a/tests/ui/const-generics/late-bound-vars/in_closure.rs +++ b/tests/ui/const-generics/late-bound-vars/in_closure.rs @@ -1,23 +1,5 @@ -// failure-status: 1 // known-bug: unknown -// error-pattern:internal compiler error -// normalize-stderr-test "internal compiler error.*" -> "" -// normalize-stderr-test "DefId\([^)]*\)" -> "..." -// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" -// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" -// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" -// normalize-stderr-test "note: compiler flags.*\n\n" -> "" -// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" -// normalize-stderr-test "thread.*panicked.*:\n.*\n" -> "" -// normalize-stderr-test "stack backtrace:\n" -> "" -// normalize-stderr-test "\s\d{1,}: .*\n" -> "" -// normalize-stderr-test "\s at .*\n" -> "" -// normalize-stderr-test ".*note: Some details.*\n" -> "" -// normalize-stderr-test "\n[ ]*\n" -> "" -// normalize-stderr-test "compiler/.*: projection" -> "projection" -// normalize-stderr-test ".*omitted \d{1,} frame.*\n" -> "" -// normalize-stderr-test "error: [\s\n]*query stack during panic:\n" -> "" -// this should run-pass +// see comment on `tests/ui/const-generics/late-bound-vars/simple.rs` #![feature(generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/late-bound-vars/in_closure.stderr b/tests/ui/const-generics/late-bound-vars/in_closure.stderr index ac406bf2bb13e..e15496454a025 100644 --- a/tests/ui/const-generics/late-bound-vars/in_closure.stderr +++ b/tests/ui/const-generics/late-bound-vars/in_closure.stderr @@ -1,10 +1,20 @@ -#0 [mir_borrowck] borrow-checking `test::{closure#0}::{constant#1}` -#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{closure#0}::{constant#1}` -#2 [mir_for_ctfe] caching mir of `test::{closure#0}::{constant#1}` for CTFE -#3 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}` -#4 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}` -#5 [eval_to_valtree] evaluating type-level constant -#6 [typeck] type-checking `test` -#7 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to previous error \ No newline at end of file +error: cannot capture late-bound lifetime in constant + --> $DIR/in_closure.rs:16:29 + | +LL | fn test<'a>() { + | -- lifetime defined here +LL | let _ = || { +LL | let _: [u8; inner::<'a>()]; + | ^^ + +error: cannot capture late-bound lifetime in constant + --> $DIR/in_closure.rs:17:29 + | +LL | fn test<'a>() { + | -- lifetime defined here +... +LL | let _ = [0; inner::<'a>()]; + | ^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.rs b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.rs new file mode 100644 index 0000000000000..b81aa50d9a908 --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.rs @@ -0,0 +1,13 @@ +// known-bug: unknown +// see comment on `tests/ui/const-generics/late-bound-vars/simple.rs` + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +trait MyTrait {} + +fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + todo!() +} + +fn main() {} diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr new file mode 100644 index 0000000000000..21c8fe6865cc1 --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr @@ -0,0 +1,8 @@ +error: cannot capture late-bound lifetime in constant + --> $DIR/late-bound-in-return-issue-77357.rs:9:53 + | +LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { + | -- lifetime defined here ^^ + +error: aborting due to previous error + diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.rs b/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.rs new file mode 100644 index 0000000000000..89f01748fc90a --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.rs @@ -0,0 +1,15 @@ +// known-bug: unknown +// see comment on `tests/ui/const-generics/late-bound-vars/simple.rs` + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +fn bug<'a>() +where + for<'b> [(); { + let x: &'b (); + 0 + }]: +{} + +fn main() {} diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.stderr b/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.stderr new file mode 100644 index 0000000000000..a66dc8db91442 --- /dev/null +++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-where-issue-83993.stderr @@ -0,0 +1,10 @@ +error: cannot capture late-bound lifetime in constant + --> $DIR/late-bound-in-where-issue-83993.rs:10:17 + | +LL | for<'b> [(); { + | -- lifetime defined here +LL | let x: &'b (); + | ^^ + +error: aborting due to previous error + diff --git a/tests/ui/const-generics/late-bound-vars/simple.rs b/tests/ui/const-generics/late-bound-vars/simple.rs index 544073b5a563c..a562bd8cb41ce 100644 --- a/tests/ui/const-generics/late-bound-vars/simple.rs +++ b/tests/ui/const-generics/late-bound-vars/simple.rs @@ -1,22 +1,13 @@ -// failure-status: 101 // known-bug: unknown -// error-pattern:internal compiler error -// normalize-stderr-test "internal compiler error.*" -> "" -// normalize-stderr-test "DefId\([^)]*\)" -> "..." -// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" -// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" -// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" -// normalize-stderr-test "note: compiler flags.*\n\n" -> "" -// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" -// normalize-stderr-test "thread.*panicked.*:\n.*\n" -> "" -// normalize-stderr-test "stack backtrace:\n" -> "" -// normalize-stderr-test "\s\d{1,}: .*\n" -> "" -// normalize-stderr-test "\s at .*\n" -> "" -// normalize-stderr-test ".*note: Some details.*\n" -> "" -// normalize-stderr-test "\n\n[ ]*\n" -> "" -// normalize-stderr-test "compiler/.*: projection" -> "projection" -// normalize-stderr-test ".*omitted \d{1,} frame.*\n" -> "" -// normalize-stderr-test "error: [\s\n]*query stack" -> "error: query stack" + +// If we want this to compile, then we'd need to do something like RPITs do, +// where nested associated constants have early-bound versions of their captured +// late-bound vars inserted into their generics. This gives us substitutable +// lifetimes to actually use when borrow-checking the associated const, which is +// lowered as a totally separate body from its parent. Since this doesn't exist, +// we should just error rather than resolving this late-bound var with no +// binder to actually attach it to, or worse, as a free region that can't even be +// substituted correctly, and ICEing. - @compiler-errors #![feature(generic_const_exprs)] #![allow(incomplete_features)] diff --git a/tests/ui/const-generics/late-bound-vars/simple.stderr b/tests/ui/const-generics/late-bound-vars/simple.stderr index c9f2164b63519..e72e373630daa 100644 --- a/tests/ui/const-generics/late-bound-vars/simple.stderr +++ b/tests/ui/const-generics/late-bound-vars/simple.stderr @@ -1,12 +1,19 @@ -error: query stack during panic: -#0 [mir_borrowck] borrow-checking `test::{constant#1}` -#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{constant#1}` -#2 [mir_for_ctfe] caching mir of `test::{constant#1}` for CTFE -#3 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}` -#4 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}` -#5 [eval_to_valtree] evaluating type-level constant -#6 [typeck] type-checking `test` -#7 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to previous error +error: cannot capture late-bound lifetime in constant + --> $DIR/simple.rs:20:25 + | +LL | fn test<'a>() { + | -- lifetime defined here +LL | let _: [u8; inner::<'a>()]; + | ^^ + +error: cannot capture late-bound lifetime in constant + --> $DIR/simple.rs:21:25 + | +LL | fn test<'a>() { + | -- lifetime defined here +LL | let _: [u8; inner::<'a>()]; +LL | let _ = [0; inner::<'a>()]; + | ^^ + +error: aborting due to 2 previous errors diff --git a/tests/ui/consts/escaping-bound-var.rs b/tests/ui/consts/escaping-bound-var.rs new file mode 100644 index 0000000000000..7c1fbd24f5558 --- /dev/null +++ b/tests/ui/consts/escaping-bound-var.rs @@ -0,0 +1,13 @@ +#![feature(generic_const_exprs)] +//~^ WARN the feature `generic_const_exprs` is incomplete + +fn test<'a>( + _: &'a (), +) -> [(); { + let x: &'a (); + //~^ ERROR cannot capture late-bound lifetime in constant + 1 +}] { +} + +fn main() {} diff --git a/tests/ui/consts/escaping-bound-var.stderr b/tests/ui/consts/escaping-bound-var.stderr new file mode 100644 index 0000000000000..d26ae2cee1c92 --- /dev/null +++ b/tests/ui/consts/escaping-bound-var.stderr @@ -0,0 +1,20 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/escaping-bound-var.rs:1:12 + | +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: cannot capture late-bound lifetime in constant + --> $DIR/escaping-bound-var.rs:7:13 + | +LL | fn test<'a>( + | -- lifetime defined here +... +LL | let x: &'a (); + | ^^ + +error: aborting due to previous error; 1 warning emitted + diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs index 91c6dfb8e0a92..bbae67f0bad41 100644 --- a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs +++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.rs @@ -4,7 +4,7 @@ fn b() where for [(); C]: Copy, - //~^ ERROR cannot capture late-bound const parameter in a constant + //~^ ERROR cannot capture late-bound const parameter in constant { } diff --git a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr index 69bb605bf41ca..d65892ec6dffb 100644 --- a/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr +++ b/tests/ui/traits/non_lifetime_binders/capture-late-ct-in-anon.stderr @@ -7,7 +7,7 @@ LL | #![feature(non_lifetime_binders)] = note: see issue #108185 for more information = note: `#[warn(incomplete_features)]` on by default -error: cannot capture late-bound const parameter in a constant +error: cannot capture late-bound const parameter in constant --> $DIR/capture-late-ct-in-anon.rs:6:30 | LL | for [(); C]: Copy, diff --git a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs index 3903bfe9bcf57..64f09f823fc29 100644 --- a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs +++ b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.rs @@ -5,7 +5,7 @@ fn foo() -> usize where for [i32; { let _: T = todo!(); 0 }]:, - //~^ ERROR cannot capture late-bound type parameter in a constant + //~^ ERROR cannot capture late-bound type parameter in constant {} fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr index fafff02dea6ee..dc54e1acc392c 100644 --- a/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr +++ b/tests/ui/traits/non_lifetime_binders/late-bound-in-anon-ct.stderr @@ -15,7 +15,7 @@ LL | #![feature(non_lifetime_binders, generic_const_exprs)] | = note: see issue #76560 for more information -error: cannot capture late-bound type parameter in a constant +error: cannot capture late-bound type parameter in constant --> $DIR/late-bound-in-anon-ct.rs:7:27 | LL | for [i32; { let _: T = todo!(); 0 }]:, diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs new file mode 100644 index 0000000000000..bf27e76db2b4d --- /dev/null +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -0,0 +1,22 @@ +#![feature(type_alias_impl_trait)] + +pub trait Trait<'a> { + type Assoc; +} + +trait Test<'a> {} + +pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; +//~^ ERROR cannot capture late-bound lifetime in type alias impl trait + +impl Trait<'_> for () { + type Assoc = (); +} + +impl Test<'_> for () {} + +fn constrain() -> Foo { + () +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr new file mode 100644 index 0000000000000..8205a60ccdd7b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr @@ -0,0 +1,8 @@ +error: cannot capture late-bound lifetime in type alias impl trait + --> $DIR/escaping-bound-var.rs:9:57 + | +LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; + | -- lifetime defined here ^^ + +error: aborting due to previous error + diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs index eba4816003ba1..e92cf2513e731 100644 --- a/tests/ui/type-alias-impl-trait/variance.rs +++ b/tests/ui/type-alias-impl-trait/variance.rs @@ -9,42 +9,36 @@ type NotCapturedEarly<'a> = impl Sized; //~ [o] type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o] +// TAIT does *not* capture `'b` type NotCapturedLate<'a> = dyn for<'b> Iterator; //~ [o] -type CapturedLate<'a> = dyn for<'b> Iterator>; //~ [o] - -type Captured<'a> = dyn for<'b> Iterator + Captures<'b>>; //~ [o] +// TAIT does *not* capture `'b` +type Captured<'a> = dyn for<'b> Iterator>; //~ [o] type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o] trait Foo<'i> { - type ImplicitCapturedEarly<'a>; - - type ExplicitCaptureEarly<'a>; + type ImplicitCapture<'a>; - type ImplicitCaptureLate<'a>; + type ExplicitCaptureFromHeader<'a>; - type ExplicitCaptureLate<'a>; + type ExplicitCaptureFromGat<'a>; } impl<'i> Foo<'i> for &'i () { - type ImplicitCapturedEarly<'a> = impl Sized; //~ [o, o] + type ImplicitCapture<'a> = impl Sized; //~ [o, o] - type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; //~ [o, o] + type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o] - type ImplicitCaptureLate<'a> = impl Sized; //~ [o, o] - - type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o] + type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o] } impl<'i> Foo<'i> for () { - type ImplicitCapturedEarly<'a> = impl Sized; //~ [o, o] - - type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; //~ [o, o] + type ImplicitCapture<'a> = impl Sized; //~ [o, o] - type ImplicitCaptureLate<'a> = impl Sized; //~ [o, o] + type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o] - type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o] + type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o] } fn main() {} diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr index f73cf617a4c96..1794447c89a20 100644 --- a/tests/ui/type-alias-impl-trait/variance.stderr +++ b/tests/ui/type-alias-impl-trait/variance.stderr @@ -11,22 +11,16 @@ LL | type CapturedEarly<'a> = impl Sized + Captures<'a>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o] - --> $DIR/variance.rs:12:56 + --> $DIR/variance.rs:13:56 | LL | type NotCapturedLate<'a> = dyn for<'b> Iterator; | ^^^^^^^^^^ -error: [o] - --> $DIR/variance.rs:14:53 - | -LL | type CapturedLate<'a> = dyn for<'b> Iterator>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - error: [o] --> $DIR/variance.rs:16:49 | -LL | type Captured<'a> = dyn for<'b> Iterator + Captures<'b>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type Captured<'a> = dyn for<'b> Iterator>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o, o] --> $DIR/variance.rs:18:27 @@ -35,52 +29,40 @@ LL | type Bar<'a, 'b: 'b, T> = impl Sized; | ^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:31:38 - | -LL | type ImplicitCapturedEarly<'a> = impl Sized; - | ^^^^^^^^^^ - -error: [o, o] - --> $DIR/variance.rs:33:37 - | -LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: [o, o] - --> $DIR/variance.rs:35:36 + --> $DIR/variance.rs:29:32 | -LL | type ImplicitCaptureLate<'a> = impl Sized; - | ^^^^^^^^^^ +LL | type ImplicitCapture<'a> = impl Sized; + | ^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:37:36 + --> $DIR/variance.rs:31:42 | -LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:41:38 + --> $DIR/variance.rs:33:39 | -LL | type ImplicitCapturedEarly<'a> = impl Sized; - | ^^^^^^^^^^ +LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:43:37 + --> $DIR/variance.rs:37:32 | -LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ImplicitCapture<'a> = impl Sized; + | ^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:45:36 + --> $DIR/variance.rs:39:42 | -LL | type ImplicitCaptureLate<'a> = impl Sized; - | ^^^^^^^^^^ +LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: [o, o] - --> $DIR/variance.rs:47:36 + --> $DIR/variance.rs:41:39 | -LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 14 previous errors +error: aborting due to 11 previous errors