Correctly deny late-bound lifetimes from parent in anon consts and TAITs

This commit is contained in:
Michael Goulet 2023-09-02 21:29:27 +00:00
parent ab45885dec
commit 52aff53812
18 changed files with 230 additions and 150 deletions

View File

@ -21,12 +21,16 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh
.label = deref recursion limit reached .label = deref recursion limit reached
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) .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 = hir_analysis_cannot_capture_late_bound_const =
cannot capture late-bound const parameter in a constant cannot capture late-bound const parameter in {$what}
.label = parameter defined here .label = parameter defined here
hir_analysis_cannot_capture_late_bound_ty_in_anon_const = hir_analysis_cannot_capture_late_bound_lifetime =
cannot capture late-bound type parameter in a constant 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 .label = parameter defined here
hir_analysis_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_ty}` to fat pointer `{$cast_ty}` hir_analysis_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr_ty}` to fat pointer `{$cast_ty}`

View File

@ -268,9 +268,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// (*) -- not late-bound, won't change // (*) -- not late-bound, won't change
} }
Some(rbv::ResolvedArg::Error(_)) => { Some(rbv::ResolvedArg::Error(guar)) => ty::Region::new_error(tcx, guar),
bug!("only ty/ct should resolve as ResolvedArg::Error")
}
None => { None => {
self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| { self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| {

View File

@ -158,13 +158,14 @@ enum Scope<'a> {
s: ScopeRef<'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<T> [(); { /* references T */ }]:`, /// This is necessary for something like `for<T> [(); { /* references T */ }]:`,
/// since we don't do something more correct like replacing any captured /// 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. /// late-bound vars with early-bound params in the const's own generics.
AnonConstBoundary { LateBoundary {
s: ScopeRef<'a>, s: ScopeRef<'a>,
what: &'static str,
}, },
Root { Root {
@ -216,7 +217,9 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
.field("s", &"..") .field("s", &"..")
.finish(), .finish(),
Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").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 } => { Scope::Root { opt_parent_item } => {
f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish() 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); break (vec![], BinderScopeType::Normal);
} }
Scope::ObjectLifetimeDefault { s, .. } | Scope::AnonConstBoundary { s } => { Scope::ObjectLifetimeDefault { s, .. } | Scope::LateBoundary { s, .. } => {
scope = s; scope = s;
} }
@ -697,9 +700,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
}) => { }) => {
intravisit::walk_ty(self, ty); intravisit::walk_ty(self, ty);
// Elided lifetimes are not allowed in non-return // Elided lifetimes and late-bound lifetimes (from the parent)
// position impl Trait // are not allowed in non-return position impl Trait
let scope = Scope::TraitRefBoundary { s: self.scope }; 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)); self.with(scope, |this| intravisit::walk_item(this, opaque_ty));
return; return;
@ -979,7 +985,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
} }
fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) { 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); intravisit::walk_anon_const(this, c);
}); });
} }
@ -1174,6 +1180,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
let mut late_depth = 0; let mut late_depth = 0;
let mut scope = self.scope; let mut scope = self.scope;
let mut outermost_body = None; let mut outermost_body = None;
let mut crossed_late_boundary = None;
let result = loop { let result = loop {
match *scope { match *scope {
Scope::Body { id, s } => { Scope::Body { id, s } => {
@ -1258,8 +1265,12 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
Scope::ObjectLifetimeDefault { s, .. } Scope::ObjectLifetimeDefault { s, .. }
| Scope::Supertrait { s, .. } | Scope::Supertrait { s, .. }
| Scope::TraitRefBoundary { s, .. } | Scope::TraitRefBoundary { s, .. } => {
| Scope::AnonConstBoundary { s } => { scope = s;
}
Scope::LateBoundary { s, what } => {
crossed_late_boundary = Some(what);
scope = s; scope = s;
} }
} }
@ -1268,6 +1279,22 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
if let Some(mut def) = result { if let Some(mut def) = result {
if let ResolvedArg::EarlyBound(..) = def { if let ResolvedArg::EarlyBound(..) = def {
// Do not free early-bound regions, only late-bound ones. // 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 { } else if let Some(body_id) = outermost_body {
let fn_id = self.tcx.hir().body_owner(body_id); let fn_id = self.tcx.hir().body_owner(body_id);
match self.tcx.hir().get(fn_id) { match self.tcx.hir().get(fn_id) {
@ -1322,7 +1349,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
| Scope::ObjectLifetimeDefault { s, .. } | Scope::ObjectLifetimeDefault { s, .. }
| Scope::Supertrait { s, .. } | Scope::Supertrait { s, .. }
| Scope::TraitRefBoundary { s, .. } | Scope::TraitRefBoundary { s, .. }
| Scope::AnonConstBoundary { s } => { | Scope::LateBoundary { s, .. } => {
scope = s; scope = s;
} }
} }
@ -1341,7 +1368,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
// search. // search.
let mut late_depth = 0; let mut late_depth = 0;
let mut scope = self.scope; let mut scope = self.scope;
let mut crossed_anon_const = false; let mut crossed_late_boundary = None;
let result = loop { let result = loop {
match *scope { match *scope {
@ -1376,28 +1403,32 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
scope = s; scope = s;
} }
Scope::AnonConstBoundary { s } => { Scope::LateBoundary { s, what } => {
crossed_anon_const = true; crossed_late_boundary = Some(what);
scope = s; scope = s;
} }
} }
}; };
if let Some(def) = result { 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 use_span = self.tcx.hir().span(hir_id);
let def_span = self.tcx.def_span(param_def_id); let def_span = self.tcx.def_span(param_def_id);
let guar = match self.tcx.def_kind(param_def_id) { let guar = match self.tcx.def_kind(param_def_id) {
DefKind::ConstParam => { DefKind::ConstParam => {
self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Const { self.tcx.sess.emit_err(errors::CannotCaptureLateBound::Const {
use_span, use_span,
def_span, def_span,
what,
}) })
} }
DefKind::TyParam => { DefKind::TyParam => {
self.tcx.sess.emit_err(errors::CannotCaptureLateBoundInAnonConst::Type { self.tcx.sess.emit_err(errors::CannotCaptureLateBound::Type {
use_span, use_span,
def_span, def_span,
what,
}) })
} }
_ => unreachable!(), _ => unreachable!(),
@ -1446,7 +1477,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
| Scope::ObjectLifetimeDefault { s, .. } | Scope::ObjectLifetimeDefault { s, .. }
| Scope::Supertrait { s, .. } | Scope::Supertrait { s, .. }
| Scope::TraitRefBoundary { s, .. } | Scope::TraitRefBoundary { s, .. }
| Scope::AnonConstBoundary { s } => { | Scope::LateBoundary { s, .. } => {
scope = s; scope = s;
} }
} }
@ -1526,7 +1557,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
| Scope::ObjectLifetimeDefault { s, .. } | Scope::ObjectLifetimeDefault { s, .. }
| Scope::Supertrait { s, .. } | Scope::Supertrait { s, .. }
| Scope::TraitRefBoundary { s, .. } | Scope::TraitRefBoundary { s, .. }
| Scope::AnonConstBoundary { s } => { | Scope::LateBoundary { s, .. } => {
scope = s; scope = s;
} }
} }
@ -1831,7 +1862,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
Scope::Supertrait { s, .. } Scope::Supertrait { s, .. }
| Scope::TraitRefBoundary { s, .. } | Scope::TraitRefBoundary { s, .. }
| Scope::AnonConstBoundary { s } => { | Scope::LateBoundary { s, .. } => {
scope = s; scope = s;
} }
} }

View File

@ -430,20 +430,30 @@ pub(crate) struct VariadicFunctionCompatibleConvention<'a> {
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
pub(crate) enum CannotCaptureLateBoundInAnonConst { pub(crate) enum CannotCaptureLateBound {
#[diag(hir_analysis_cannot_capture_late_bound_ty_in_anon_const)] #[diag(hir_analysis_cannot_capture_late_bound_ty)]
Type { Type {
#[primary_span] #[primary_span]
use_span: Span, use_span: Span,
#[label] #[label]
def_span: Span, 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 { Const {
#[primary_span] #[primary_span]
use_span: Span, use_span: Span,
#[label] #[label]
def_span: Span, 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,
}, },
} }

View File

@ -1,23 +1,13 @@
// failure-status: 1
// known-bug: unknown // known-bug: unknown
// error-pattern:internal compiler error
// normalize-stderr-test "internal compiler error.*" -> "" // If we want this to compile, then we'd need to do something like RPITs do,
// normalize-stderr-test "DefId\([^)]*\)" -> "..." // where nested associated constants have early-bound versions of their captured
// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" // late-bound vars inserted into their generics. This gives us substitutable
// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" // lifetimes to actually use when borrow-checking the associated const, which is
// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" // lowered as a totally separate body from its parent. Since this doesn't exist,
// normalize-stderr-test "note: compiler flags.*\n\n" -> "" // so we should just error rather than resolving this late-bound var with no
// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" // binder to actually attach it to, or worse, as a free region that can't even be
// normalize-stderr-test "thread.*panicked.*:\n.*\n" -> "" // substituted correctly, and ICEing. - @compiler-errors
// 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
#![feature(generic_const_exprs)] #![feature(generic_const_exprs)]
#![allow(incomplete_features)] #![allow(incomplete_features)]

View File

@ -1,10 +1,20 @@
#0 [mir_borrowck] borrow-checking `test::{closure#0}::{constant#1}` error: cannot capture late-bound lifetime in constant
#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test::{closure#0}::{constant#1}` --> $DIR/in_closure.rs:24:29
#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}` LL | fn test<'a>() {
#4 [eval_to_allocation_raw] const-evaluating + checking `test::{closure#0}::{constant#1}` | -- lifetime defined here
#5 [eval_to_valtree] evaluating type-level constant LL | let _ = || {
#6 [typeck] type-checking `test` LL | let _: [u8; inner::<'a>()];
#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/in_closure.rs:25:29
|
LL | fn test<'a>() {
| -- lifetime defined here
...
LL | let _ = [0; inner::<'a>()];
| ^^
error: aborting due to 2 previous errors

View File

@ -1,22 +1,13 @@
// failure-status: 101
// known-bug: unknown // known-bug: unknown
// error-pattern:internal compiler error
// normalize-stderr-test "internal compiler error.*" -> "" // If we want this to compile, then we'd need to do something like RPITs do,
// normalize-stderr-test "DefId\([^)]*\)" -> "..." // where nested associated constants have early-bound versions of their captured
// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" // late-bound vars inserted into their generics. This gives us substitutable
// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" // lifetimes to actually use when borrow-checking the associated const, which is
// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" // lowered as a totally separate body from its parent. Since this doesn't exist,
// normalize-stderr-test "note: compiler flags.*\n\n" -> "" // so we should just error rather than resolving this late-bound var with no
// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" // binder to actually attach it to, or worse, as a free region that can't even be
// normalize-stderr-test "thread.*panicked.*:\n.*\n" -> "" // substituted correctly, and ICEing. - @compiler-errors
// 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"
#![feature(generic_const_exprs)] #![feature(generic_const_exprs)]
#![allow(incomplete_features)] #![allow(incomplete_features)]

View File

@ -1,12 +1,19 @@
error: query stack during panic: error: cannot capture late-bound lifetime in constant
#0 [mir_borrowck] borrow-checking `test::{constant#1}` --> $DIR/simple.rs:20:25
#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 LL | fn test<'a>() {
#3 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}` | -- lifetime defined here
#4 [eval_to_allocation_raw] const-evaluating + checking `test::{constant#1}` LL | let _: [u8; inner::<'a>()];
#5 [eval_to_valtree] evaluating type-level constant | ^^
#6 [typeck] type-checking `test`
#7 [analysis] running analysis passes on this crate error: cannot capture late-bound lifetime in constant
end of query stack --> $DIR/simple.rs:21:25
error: aborting due to previous error |
LL | fn test<'a>() {
| -- lifetime defined here
LL | let _: [u8; inner::<'a>()];
LL | let _ = [0; inner::<'a>()];
| ^^
error: aborting due to 2 previous errors

View File

@ -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() {}

View File

@ -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 <https://github.com/rust-lang/rust/issues/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

View File

@ -4,7 +4,7 @@
fn b() fn b()
where where
for<const C: usize> [(); C]: Copy, for<const C: usize> [(); C]: Copy,
//~^ ERROR cannot capture late-bound const parameter in a constant //~^ ERROR cannot capture late-bound const parameter in constant
{ {
} }

View File

@ -7,7 +7,7 @@ LL | #![feature(non_lifetime_binders)]
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
= note: `#[warn(incomplete_features)]` on by default = 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 --> $DIR/capture-late-ct-in-anon.rs:6:30
| |
LL | for<const C: usize> [(); C]: Copy, LL | for<const C: usize> [(); C]: Copy,

View File

@ -5,7 +5,7 @@
fn foo() -> usize fn foo() -> usize
where where
for<T> [i32; { let _: T = todo!(); 0 }]:, for<T> [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() {} fn main() {}

View File

@ -15,7 +15,7 @@ LL | #![feature(non_lifetime_binders, generic_const_exprs)]
| |
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information = note: see issue #76560 <https://github.com/rust-lang/rust/issues/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 --> $DIR/late-bound-in-anon-ct.rs:7:27
| |
LL | for<T> [i32; { let _: T = todo!(); 0 }]:, LL | for<T> [i32; { let _: T = todo!(); 0 }]:,

View File

@ -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() {}

View File

@ -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

View File

@ -9,42 +9,36 @@ type NotCapturedEarly<'a> = impl Sized; //~ [o]
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o] type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o]
// TAIT does *not* capture `'b`
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o] type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o]
type CapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'b>>; //~ [o] // TAIT does *not* capture `'b`
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [o]
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a> + Captures<'b>>; //~ [o]
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o] type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o]
trait Foo<'i> { trait Foo<'i> {
type ImplicitCapturedEarly<'a>; type ImplicitCapture<'a>;
type ExplicitCaptureEarly<'a>; type ExplicitCaptureFromHeader<'a>;
type ImplicitCaptureLate<'a>; type ExplicitCaptureFromGat<'a>;
type ExplicitCaptureLate<'a>;
} }
impl<'i> Foo<'i> for &'i () { 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 ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o]
} }
impl<'i> Foo<'i> for () { impl<'i> Foo<'i> for () {
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 ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; //~ [o, o]
} }
fn main() {} fn main() {}

View File

@ -11,22 +11,16 @@ LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o] error: [o]
--> $DIR/variance.rs:12:56 --> $DIR/variance.rs:13:56
| |
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [o]
--> $DIR/variance.rs:14:53
|
LL | type CapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'b>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o] error: [o]
--> $DIR/variance.rs:16:49 --> $DIR/variance.rs:16:49
| |
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a> + Captures<'b>>; LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o, o] error: [o, o, o]
--> $DIR/variance.rs:18:27 --> $DIR/variance.rs:18:27
@ -35,52 +29,40 @@ LL | type Bar<'a, 'b: 'b, T> = impl Sized;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [o, o] error: [o, o]
--> $DIR/variance.rs:31:38 --> $DIR/variance.rs:29:32
| |
LL | type ImplicitCapturedEarly<'a> = impl Sized; LL | type ImplicitCapture<'a> = impl Sized;
| ^^^^^^^^^^ | ^^^^^^^^^^
error: [o, o] error: [o, o]
--> $DIR/variance.rs:33:37 --> $DIR/variance.rs:31:42
| |
LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o] error: [o, o]
--> $DIR/variance.rs:35:36 --> $DIR/variance.rs:33:39
| |
LL | type ImplicitCaptureLate<'a> = impl Sized; LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o] error: [o, o]
--> $DIR/variance.rs:37:36 --> $DIR/variance.rs:37:32
| |
LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>; LL | type ImplicitCapture<'a> = impl Sized;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^
error: [o, o] error: [o, o]
--> $DIR/variance.rs:41:38 --> $DIR/variance.rs:39:42
| |
LL | type ImplicitCapturedEarly<'a> = impl Sized; LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
| ^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o] error: [o, o]
--> $DIR/variance.rs:43:37 --> $DIR/variance.rs:41:39
| |
LL | type ExplicitCaptureEarly<'a> = impl Sized + Captures<'i>; LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
error: [o, o] error: aborting due to 11 previous errors
--> $DIR/variance.rs:45:36
|
LL | type ImplicitCaptureLate<'a> = impl Sized;
| ^^^^^^^^^^
error: [o, o]
--> $DIR/variance.rs:47:36
|
LL | type ExplicitCaptureLate<'a> = impl Sized + Captures<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 14 previous errors