Make TAITs capture all higher-ranked lifetimes in scope
This commit is contained in:
parent
9823f17315
commit
cf299ddb6e
@ -275,7 +275,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
Some(ty) => this.lower_ty(
|
||||
ty,
|
||||
ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
|
||||
ImplTraitContext::TypeAliasesOpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias {
|
||||
parent: this.local_def_id(id),
|
||||
in_assoc_ty: false,
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
);
|
||||
@ -936,7 +941,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
Some(ty) => {
|
||||
let ty = this.lower_ty(
|
||||
ty,
|
||||
ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
|
||||
ImplTraitContext::TypeAliasesOpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias {
|
||||
parent: this.local_def_id(i.id),
|
||||
in_assoc_ty: true,
|
||||
},
|
||||
},
|
||||
);
|
||||
hir::ImplItemKind::Type(ty)
|
||||
}
|
||||
|
@ -271,7 +271,10 @@ enum ImplTraitContext {
|
||||
fn_kind: FnDeclKind,
|
||||
},
|
||||
/// Impl trait in type aliases.
|
||||
TypeAliasesOpaqueTy { in_assoc_ty: bool },
|
||||
TypeAliasesOpaqueTy {
|
||||
/// Origin: Always OpaqueTyOrigin::TypeAliasImplTrait
|
||||
origin: hir::OpaqueTyOrigin,
|
||||
},
|
||||
/// `impl Trait` is unstably accepted in this position.
|
||||
FeatureGated(ImplTraitPosition, Symbol),
|
||||
/// `impl Trait` is not accepted in this position.
|
||||
@ -1426,15 +1429,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
Some(fn_kind),
|
||||
itctx,
|
||||
),
|
||||
ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
|
||||
.lower_opaque_impl_trait(
|
||||
span,
|
||||
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty },
|
||||
*def_node_id,
|
||||
bounds,
|
||||
None,
|
||||
itctx,
|
||||
),
|
||||
ImplTraitContext::TypeAliasesOpaqueTy { origin } => self
|
||||
.lower_opaque_impl_trait(span, origin, *def_node_id, bounds, None, itctx),
|
||||
ImplTraitContext::Universal => {
|
||||
let span = t.span;
|
||||
|
||||
@ -1553,9 +1549,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
let captured_lifetimes_to_duplicate = match origin {
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||
// in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't duplicate any
|
||||
// lifetimes, since we don't have the issue that any are late-bound.
|
||||
Vec::new()
|
||||
// type alias impl trait and associated type position impl trait were
|
||||
// decided to capture all in-scope lifetimes, which we collect for
|
||||
// all opaques during resolution.
|
||||
self.resolver
|
||||
.take_extra_lifetime_params(opaque_ty_node_id)
|
||||
.into_iter()
|
||||
.map(|(ident, id, _)| Lifetime { id, ident })
|
||||
.collect()
|
||||
}
|
||||
hir::OpaqueTyOrigin::FnReturn(..) => {
|
||||
if matches!(
|
||||
|
@ -367,14 +367,17 @@ fn check_opaque_type_parameter_valid(
|
||||
span: Span,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id);
|
||||
let is_ty_alias = match opaque_ty_hir.expect_opaque_ty().origin {
|
||||
OpaqueTyOrigin::TyAlias { .. } => true,
|
||||
OpaqueTyOrigin::AsyncFn(..) | OpaqueTyOrigin::FnReturn(..) => false,
|
||||
let (parent, is_ty_alias) = match opaque_ty_hir.expect_opaque_ty().origin {
|
||||
OpaqueTyOrigin::TyAlias { parent, .. } => (parent, true),
|
||||
OpaqueTyOrigin::AsyncFn(parent) | OpaqueTyOrigin::FnReturn(parent) => (parent, false),
|
||||
};
|
||||
|
||||
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
|
||||
let parent_generics = tcx.generics_of(parent);
|
||||
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
|
||||
for (i, arg) in opaque_type_key.args.iter().enumerate() {
|
||||
|
||||
// Only check the parent generics, which will ignore any of the
|
||||
// duplicated lifetime args that come from reifying late-bounds.
|
||||
for (i, arg) in opaque_type_key.args.iter().take(parent_generics.count()).enumerate() {
|
||||
if let Err(guar) = arg.error_reported() {
|
||||
return Err(guar);
|
||||
}
|
||||
@ -395,7 +398,7 @@ fn check_opaque_type_parameter_valid(
|
||||
seen_params.entry(arg).or_default().push(i);
|
||||
} else {
|
||||
// Prevent `fn foo() -> Foo<u32>` from being defining.
|
||||
let opaque_param = opaque_generics.param_at(i, tcx);
|
||||
let opaque_param = parent_generics.param_at(i, tcx);
|
||||
let kind = opaque_param.kind.descr();
|
||||
|
||||
return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam {
|
||||
@ -409,10 +412,10 @@ fn check_opaque_type_parameter_valid(
|
||||
|
||||
for (_, indices) in seen_params {
|
||||
if indices.len() > 1 {
|
||||
let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
|
||||
let descr = parent_generics.param_at(indices[0], tcx).kind.descr();
|
||||
let spans: Vec<_> = indices
|
||||
.into_iter()
|
||||
.map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
|
||||
.map(|i| tcx.def_span(parent_generics.param_at(i, tcx).def_id))
|
||||
.collect();
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
|
@ -2562,6 +2562,8 @@ pub enum OpaqueTyOrigin {
|
||||
AsyncFn(LocalDefId),
|
||||
/// type aliases: `type Foo = impl Trait;`
|
||||
TyAlias {
|
||||
/// The type alias or associated type parent of the TAIT/ATPIT
|
||||
parent: LocalDefId,
|
||||
/// associated types in impl blocks for traits.
|
||||
in_assoc_ty: bool,
|
||||
},
|
||||
|
@ -339,8 +339,9 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
origin: &hir::OpaqueTyOrigin,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let defining_use_anchor = match *origin {
|
||||
hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id),
|
||||
hir::OpaqueTyOrigin::FnReturn(did)
|
||||
| hir::OpaqueTyOrigin::AsyncFn(did)
|
||||
| hir::OpaqueTyOrigin::TyAlias { parent: did, .. } => did,
|
||||
};
|
||||
let param_env = tcx.param_env(defining_use_anchor);
|
||||
|
||||
@ -351,14 +352,14 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
|
||||
let args = match *origin {
|
||||
hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
|
||||
GenericArgs::identity_for_item(tcx, parent).extend_to(
|
||||
tcx,
|
||||
def_id.to_def_id(),
|
||||
|param, _| tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into(),
|
||||
)
|
||||
}
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => GenericArgs::identity_for_item(tcx, def_id),
|
||||
hir::OpaqueTyOrigin::FnReturn(parent)
|
||||
| hir::OpaqueTyOrigin::AsyncFn(parent)
|
||||
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
|
||||
tcx, parent,
|
||||
)
|
||||
.extend_to(tcx, def_id.to_def_id(), |param, _| {
|
||||
tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into()
|
||||
}),
|
||||
};
|
||||
|
||||
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||
|
@ -514,38 +514,11 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||
// These sorts of items have no lifetime parameters at all.
|
||||
intravisit::walk_item(self, item);
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
}) => {
|
||||
// Opaque types are visited when we visit the
|
||||
// `TyKind::OpaqueDef`, so that they have the lifetimes from
|
||||
// their parent opaque_ty in scope.
|
||||
//
|
||||
// The core idea here is that since OpaqueTys are generated with the impl Trait as
|
||||
// their owner, we can keep going until we find the Item that owns that. We then
|
||||
// conservatively add all resolved lifetimes. Otherwise we run into problems in
|
||||
// cases like `type Foo<'a> = impl Bar<As = impl Baz + 'a>`.
|
||||
let parent_item = self.tcx.hir().get_parent_item(item.hir_id());
|
||||
let resolved_lifetimes: &ResolveBoundVars =
|
||||
self.tcx.resolve_bound_vars(parent_item);
|
||||
// We need to add *all* deps, since opaque tys may want them from *us*
|
||||
for (&owner, defs) in resolved_lifetimes.defs.iter() {
|
||||
defs.iter().for_each(|(&local_id, region)| {
|
||||
self.map.defs.insert(hir::HirId { owner, local_id }, *region);
|
||||
});
|
||||
}
|
||||
for (&owner, late_bound_vars) in resolved_lifetimes.late_bound_vars.iter() {
|
||||
late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| {
|
||||
self.record_late_bound_vars(
|
||||
hir::HirId { owner, local_id },
|
||||
late_bound_vars.clone(),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(&hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent),
|
||||
origin:
|
||||
hir::OpaqueTyOrigin::FnReturn(parent)
|
||||
| hir::OpaqueTyOrigin::AsyncFn(parent)
|
||||
| hir::OpaqueTyOrigin::TyAlias { parent, .. },
|
||||
generics,
|
||||
..
|
||||
}) => {
|
||||
@ -683,26 +656,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||
// the opaque_ty generics
|
||||
let opaque_ty = self.tcx.hir().item(item_id);
|
||||
match &opaque_ty.kind {
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
}) => {
|
||||
intravisit::walk_ty(self, ty);
|
||||
|
||||
// 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;
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
|
||||
..
|
||||
}) => {}
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin: _, .. }) => {}
|
||||
i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
||||
};
|
||||
|
||||
|
@ -553,11 +553,11 @@ pub(super) fn type_of_opaque(
|
||||
Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
|
||||
Node::Item(item) => match item.kind {
|
||||
ItemKind::OpaqueTy(OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false },
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: false, .. },
|
||||
..
|
||||
}) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
|
||||
ItemKind::OpaqueTy(OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true },
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { in_assoc_ty: true, .. },
|
||||
..
|
||||
}) => opaque::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id),
|
||||
// Opaque types desugared from `impl Trait`.
|
||||
|
@ -125,15 +125,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
||||
|
||||
// By default, RPIT are invariant wrt type and const generics, but they are bivariant wrt
|
||||
// lifetime generics.
|
||||
let variances = std::iter::repeat(ty::Invariant).take(generics.count());
|
||||
|
||||
let mut variances: Vec<_> = match tcx.opaque_type_origin(item_def_id) {
|
||||
rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {
|
||||
variances.collect()
|
||||
}
|
||||
// But TAIT are invariant for all generics
|
||||
rustc_hir::OpaqueTyOrigin::TyAlias { .. } => return tcx.arena.alloc_from_iter(variances),
|
||||
};
|
||||
let mut variances = vec![ty::Invariant; generics.count()];
|
||||
|
||||
// Mark all lifetimes from parent generics as unused (Bivariant).
|
||||
// This will be overridden later if required.
|
||||
|
@ -391,7 +391,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
// Anonymous `impl Trait`
|
||||
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
|
||||
// Named `type Foo = impl Bar;`
|
||||
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
|
||||
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
|
||||
if in_assoc_ty {
|
||||
self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
|
||||
} else {
|
||||
|
@ -1940,18 +1940,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
matches!(self.trait_of_item(def_id), Some(trait_id) if self.has_attr(trait_id, sym::const_trait))
|
||||
}
|
||||
|
||||
/// Returns the `DefId` of the item within which the `impl Trait` is declared.
|
||||
/// For type-alias-impl-trait this is the `type` alias.
|
||||
/// For impl-trait-in-assoc-type this is the assoc type.
|
||||
/// For return-position-impl-trait this is the function.
|
||||
pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId {
|
||||
// Find the surrounding item (type alias or assoc type)
|
||||
while let DefKind::OpaqueTy = self.def_kind(def_id) {
|
||||
def_id = self.local_parent(def_id);
|
||||
}
|
||||
def_id
|
||||
}
|
||||
|
||||
pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
|
||||
if self.def_kind(def_id) != DefKind::AssocFn {
|
||||
return false;
|
||||
|
@ -141,7 +141,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
|
||||
trace!(?origin);
|
||||
match origin {
|
||||
rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
|
||||
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
|
||||
rustc_hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
|
||||
if !in_assoc_ty {
|
||||
if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
|
||||
return;
|
||||
|
@ -7,7 +7,7 @@ pub trait Trait<'a> {
|
||||
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
|
||||
//~^ ERROR higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
|
||||
impl Trait<'_> for () {
|
||||
type Assoc = ();
|
||||
|
@ -1,8 +1,14 @@
|
||||
error: cannot capture late-bound lifetime in type alias impl trait
|
||||
--> $DIR/escaping-bound-var.rs:9:57
|
||||
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||
--> $DIR/escaping-bound-var.rs:9:25
|
||||
|
|
||||
LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
||||
| -- lifetime defined here ^^
|
||||
| ^^
|
||||
|
|
||||
note: lifetime declared here
|
||||
--> $DIR/escaping-bound-var.rs:9:25
|
||||
|
|
||||
LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
||||
| ^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
@ -12,14 +12,14 @@ fn bar<'a, 'b>(i: &'a i32) -> Bar<'a, 'b> {
|
||||
type Foo<'a, 'b> = (i32, impl PartialEq<Foo<'a, 'b>> + std::fmt::Debug);
|
||||
|
||||
fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
|
||||
//~^ ERROR can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0})`
|
||||
//~^ ERROR can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
|
||||
(42, i)
|
||||
}
|
||||
|
||||
type Moo<'a, 'b> = (i32, impl PartialEq<Moo<'b, 'a>> + std::fmt::Debug);
|
||||
|
||||
fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
|
||||
//~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
|
||||
//~^ ERROR can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
|
||||
(42, i)
|
||||
}
|
||||
|
||||
|
@ -10,28 +10,28 @@ LL | i
|
||||
= help: the trait `PartialEq<Bar<'b, 'a>>` is not implemented for `&i32`
|
||||
= help: the trait `PartialEq` is implemented for `i32`
|
||||
|
||||
error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0})`
|
||||
error[E0277]: can't compare `&i32` with `(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
|
||||
--> $DIR/self-referential.rs:14:31
|
||||
|
|
||||
LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
|
||||
| ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0})`
|
||||
| ^^^^^^^^^^^ no implementation for `&i32 == (i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)`
|
||||
LL |
|
||||
LL | (42, i)
|
||||
| ------- return type was inferred to be `(i32, &i32)` here
|
||||
|
|
||||
= help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0})>` is not implemented for `&i32`
|
||||
= help: the trait `PartialEq<(i32, Foo<'a, 'b>::{opaque#0}<'a, 'b>)>` is not implemented for `&i32`
|
||||
= help: the trait `PartialEq` is implemented for `i32`
|
||||
|
||||
error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0})`
|
||||
error[E0277]: can't compare `&i32` with `(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
|
||||
--> $DIR/self-referential.rs:21:31
|
||||
|
|
||||
LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
|
||||
| ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0})`
|
||||
| ^^^^^^^^^^^ no implementation for `&i32 == (i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)`
|
||||
LL |
|
||||
LL | (42, i)
|
||||
| ------- return type was inferred to be `(i32, &i32)` here
|
||||
|
|
||||
= help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0})>` is not implemented for `&i32`
|
||||
= help: the trait `PartialEq<(i32, Moo<'b, 'a>::{opaque#0}<'b, 'a>)>` is not implemented for `&i32`
|
||||
= help: the trait `PartialEq` is implemented for `i32`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -5,21 +5,21 @@
|
||||
trait Captures<'a> {}
|
||||
impl<T> Captures<'_> for T {}
|
||||
|
||||
type NotCapturedEarly<'a> = impl Sized; //~ [o]
|
||||
type NotCapturedEarly<'a> = impl Sized; //~ [*, o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o]
|
||||
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
// TAIT does *not* capture `'b`
|
||||
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [*, o, o]
|
||||
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
|
||||
//~| ERROR: unconstrained opaque type
|
||||
|
||||
// TAIT does *not* capture `'b`
|
||||
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [*, o, o]
|
||||
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
|
||||
//~| ERROR: unconstrained opaque type
|
||||
|
||||
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o]
|
||||
type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [*, *, o, o, o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
trait Foo<'i> {
|
||||
@ -31,24 +31,24 @@ trait Foo<'i> {
|
||||
}
|
||||
|
||||
impl<'i> Foo<'i> for &'i () {
|
||||
type ImplicitCapture<'a> = impl Sized; //~ [o, o]
|
||||
type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
|
||||
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
|
||||
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
}
|
||||
|
||||
impl<'i> Foo<'i> for () {
|
||||
type ImplicitCapture<'a> = impl Sized; //~ [o, o]
|
||||
type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
|
||||
type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [*, *, o, o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
|
||||
type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [*, *, o, o]
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,15 @@
|
||||
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
|
||||
--> $DIR/variance.rs:14:36
|
||||
|
|
||||
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
|
||||
| ^^
|
||||
|
||||
error[E0657]: `impl Trait` can only capture lifetimes bound at the fn or impl level
|
||||
--> $DIR/variance.rs:18:29
|
||||
|
|
||||
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
|
||||
| ^^
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/variance.rs:8:29
|
||||
|
|
||||
@ -15,7 +27,7 @@ LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
|
||||
= note: `CapturedEarly` must be used in combination with a concrete type within the same module
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/variance.rs:15:56
|
||||
--> $DIR/variance.rs:14:56
|
||||
|
|
||||
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
|
||||
| ^^^^^^^^^^
|
||||
@ -23,7 +35,7 @@ LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
|
||||
= note: `NotCapturedLate` must be used in combination with a concrete type within the same module
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/variance.rs:19:49
|
||||
--> $DIR/variance.rs:18:49
|
||||
|
|
||||
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -86,71 +98,72 @@ LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
|
||||
|
|
||||
= note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl
|
||||
|
||||
error: [o]
|
||||
error: [*, o]
|
||||
--> $DIR/variance.rs:8:29
|
||||
|
|
||||
LL | type NotCapturedEarly<'a> = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: [o]
|
||||
error: [*, o]
|
||||
--> $DIR/variance.rs:11:26
|
||||
|
|
||||
LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: [o]
|
||||
--> $DIR/variance.rs:15:56
|
||||
error: [*, o, o]
|
||||
--> $DIR/variance.rs:14:56
|
||||
|
|
||||
LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: [o]
|
||||
--> $DIR/variance.rs:19:49
|
||||
error: [*, o, o]
|
||||
--> $DIR/variance.rs:18:49
|
||||
|
|
||||
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: [o, o, o]
|
||||
error: [*, *, o, o, o]
|
||||
--> $DIR/variance.rs:22:27
|
||||
|
|
||||
LL | type Bar<'a, 'b: 'b, T> = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: [o, o]
|
||||
error: [*, *, o, o]
|
||||
--> $DIR/variance.rs:34:32
|
||||
|
|
||||
LL | type ImplicitCapture<'a> = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: [o, o]
|
||||
error: [*, *, o, o]
|
||||
--> $DIR/variance.rs:37:42
|
||||
|
|
||||
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: [o, o]
|
||||
error: [*, *, o, o]
|
||||
--> $DIR/variance.rs:40:39
|
||||
|
|
||||
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: [o, o]
|
||||
error: [*, *, o, o]
|
||||
--> $DIR/variance.rs:45:32
|
||||
|
|
||||
LL | type ImplicitCapture<'a> = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: [o, o]
|
||||
error: [*, *, o, o]
|
||||
--> $DIR/variance.rs:48:42
|
||||
|
|
||||
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: [o, o]
|
||||
error: [*, *, o, o]
|
||||
--> $DIR/variance.rs:51:39
|
||||
|
|
||||
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 22 previous errors
|
||||
error: aborting due to 24 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0657`.
|
||||
|
Loading…
x
Reference in New Issue
Block a user