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
.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}`

View File

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

View File

@ -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<T> [(); { /* 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;
}
}

View File

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

View File

@ -1,23 +1,13 @@
// 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
// 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,
// so 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)]

View File

@ -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
error: cannot capture late-bound lifetime in constant
--> $DIR/in_closure.rs:24: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: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
// 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,
// so 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)]

View File

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

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()
where
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: `#[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<const C: usize> [(); C]: Copy,

View File

@ -5,7 +5,7 @@
fn foo() -> usize
where
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() {}

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

View File

@ -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<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]
--> $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]
--> $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
--> $DIR/variance.rs:29:32
|
LL | type ImplicitCapturedEarly<'a> = impl Sized;
| ^^^^^^^^^^
LL | type ImplicitCapture<'a> = impl Sized;
| ^^^^^^^^^^
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]
--> $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]
--> $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]
--> $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]
--> $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]
--> $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
error: aborting due to 11 previous errors