Rollup merge of #122103 - compiler-errors:taits-capture-everything, r=oli-obk
Make TAITs and ATPITs capture late-bound lifetimes in scope This generalizes the behavior that RPITs have, where they duplicate their in-scope lifetimes so that they will always *reify* late-bound lifetimes that they capture. This allows TAITs and ATPITs to properly error when they capture in-scope late-bound lifetimes. r? `@oli-obk` cc `@aliemjay` Fixes #122093 and therefore https://github.com/rust-lang/rust/pull/120700#issuecomment-1981213868
This commit is contained in:
commit
d4d18d240b
21 changed files with 148 additions and 185 deletions
|
@ -275,7 +275,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
}
|
}
|
||||||
Some(ty) => this.lower_ty(
|
Some(ty) => this.lower_ty(
|
||||||
ty,
|
ty,
|
||||||
ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
|
ImplTraitContext::OpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::TyAlias {
|
||||||
|
parent: this.local_def_id(id),
|
||||||
|
in_assoc_ty: false,
|
||||||
|
},
|
||||||
|
fn_kind: None,
|
||||||
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -936,7 +942,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
Some(ty) => {
|
Some(ty) => {
|
||||||
let ty = this.lower_ty(
|
let ty = this.lower_ty(
|
||||||
ty,
|
ty,
|
||||||
ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
|
ImplTraitContext::OpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::TyAlias {
|
||||||
|
parent: this.local_def_id(i.id),
|
||||||
|
in_assoc_ty: true,
|
||||||
|
},
|
||||||
|
fn_kind: None,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
hir::ImplItemKind::Type(ty)
|
hir::ImplItemKind::Type(ty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -265,13 +265,12 @@ enum ImplTraitContext {
|
||||||
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
|
/// Example: `fn foo() -> impl Debug`, where `impl Debug` is conceptually
|
||||||
/// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
|
/// equivalent to a new opaque type like `type T = impl Debug; fn foo() -> T`.
|
||||||
///
|
///
|
||||||
ReturnPositionOpaqueTy {
|
OpaqueTy {
|
||||||
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
fn_kind: FnDeclKind,
|
/// Only used to change the lifetime capture rules, since
|
||||||
|
/// RPITIT captures all in scope, RPIT does not.
|
||||||
|
fn_kind: Option<FnDeclKind>,
|
||||||
},
|
},
|
||||||
/// Impl trait in type aliases.
|
|
||||||
TypeAliasesOpaqueTy { in_assoc_ty: bool },
|
|
||||||
/// `impl Trait` is unstably accepted in this position.
|
/// `impl Trait` is unstably accepted in this position.
|
||||||
FeatureGated(ImplTraitPosition, Symbol),
|
FeatureGated(ImplTraitPosition, Symbol),
|
||||||
/// `impl Trait` is not accepted in this position.
|
/// `impl Trait` is not accepted in this position.
|
||||||
|
@ -1075,9 +1074,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// Disallow ATB in dyn types
|
// Disallow ATB in dyn types
|
||||||
if self.is_in_dyn_type {
|
if self.is_in_dyn_type {
|
||||||
let suggestion = match itctx {
|
let suggestion = match itctx {
|
||||||
ImplTraitContext::ReturnPositionOpaqueTy { .. }
|
ImplTraitContext::OpaqueTy { .. } | ImplTraitContext::Universal => {
|
||||||
| ImplTraitContext::TypeAliasesOpaqueTy { .. }
|
|
||||||
| ImplTraitContext::Universal => {
|
|
||||||
let bound_end_span = constraint
|
let bound_end_span = constraint
|
||||||
.gen_args
|
.gen_args
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -1417,24 +1414,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
TyKind::ImplTrait(def_node_id, bounds) => {
|
TyKind::ImplTrait(def_node_id, bounds) => {
|
||||||
let span = t.span;
|
let span = t.span;
|
||||||
match itctx {
|
match itctx {
|
||||||
ImplTraitContext::ReturnPositionOpaqueTy { origin, fn_kind } => self
|
ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait(
|
||||||
.lower_opaque_impl_trait(
|
span,
|
||||||
span,
|
origin,
|
||||||
origin,
|
*def_node_id,
|
||||||
*def_node_id,
|
bounds,
|
||||||
bounds,
|
fn_kind,
|
||||||
Some(fn_kind),
|
itctx,
|
||||||
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::Universal => {
|
ImplTraitContext::Universal => {
|
||||||
let span = t.span;
|
let span = t.span;
|
||||||
|
|
||||||
|
@ -1553,9 +1540,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
|
|
||||||
let captured_lifetimes_to_duplicate = match origin {
|
let captured_lifetimes_to_duplicate = match origin {
|
||||||
hir::OpaqueTyOrigin::TyAlias { .. } => {
|
hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||||
// in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't duplicate any
|
// type alias impl trait and associated type position impl trait were
|
||||||
// lifetimes, since we don't have the issue that any are late-bound.
|
// decided to capture all in-scope lifetimes, which we collect for
|
||||||
Vec::new()
|
// 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(..) => {
|
hir::OpaqueTyOrigin::FnReturn(..) => {
|
||||||
if matches!(
|
if matches!(
|
||||||
|
@ -1823,9 +1815,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
FnDeclKind::Fn
|
FnDeclKind::Fn
|
||||||
| FnDeclKind::Inherent
|
| FnDeclKind::Inherent
|
||||||
| FnDeclKind::Trait
|
| FnDeclKind::Trait
|
||||||
| FnDeclKind::Impl => ImplTraitContext::ReturnPositionOpaqueTy {
|
| FnDeclKind::Impl => ImplTraitContext::OpaqueTy {
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)),
|
origin: hir::OpaqueTyOrigin::FnReturn(self.local_def_id(fn_node_id)),
|
||||||
fn_kind: kind,
|
fn_kind: Some(kind),
|
||||||
},
|
},
|
||||||
FnDeclKind::ExternFn => {
|
FnDeclKind::ExternFn => {
|
||||||
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
|
ImplTraitContext::Disallowed(ImplTraitPosition::ExternFnReturn)
|
||||||
|
@ -1919,9 +1911,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
output,
|
output,
|
||||||
coro,
|
coro,
|
||||||
opaque_ty_span,
|
opaque_ty_span,
|
||||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
ImplTraitContext::OpaqueTy {
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||||
fn_kind,
|
fn_kind: Some(fn_kind),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
arena_vec![this; bound]
|
arena_vec![this; bound]
|
||||||
|
|
|
@ -423,7 +423,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
|
// fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
|
||||||
// // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^
|
// // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^
|
||||||
// ```
|
// ```
|
||||||
FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. }) => {
|
FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::OpaqueTy { .. }) => {
|
||||||
if self.tcx.features().impl_trait_in_fn_trait_return {
|
if self.tcx.features().impl_trait_in_fn_trait_return {
|
||||||
self.lower_ty(ty, itctx)
|
self.lower_ty(ty, itctx)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -367,14 +367,17 @@ fn check_opaque_type_parameter_valid(
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let opaque_ty_hir = tcx.hir().expect_item(opaque_type_key.def_id);
|
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 {
|
let (parent, is_ty_alias) = match opaque_ty_hir.expect_opaque_ty().origin {
|
||||||
OpaqueTyOrigin::TyAlias { .. } => true,
|
OpaqueTyOrigin::TyAlias { parent, .. } => (parent, true),
|
||||||
OpaqueTyOrigin::AsyncFn(..) | OpaqueTyOrigin::FnReturn(..) => false,
|
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();
|
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() {
|
if let Err(guar) = arg.error_reported() {
|
||||||
return Err(guar);
|
return Err(guar);
|
||||||
}
|
}
|
||||||
|
@ -395,7 +398,7 @@ fn check_opaque_type_parameter_valid(
|
||||||
seen_params.entry(arg).or_default().push(i);
|
seen_params.entry(arg).or_default().push(i);
|
||||||
} else {
|
} else {
|
||||||
// Prevent `fn foo() -> Foo<u32>` from being defining.
|
// 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();
|
let kind = opaque_param.kind.descr();
|
||||||
|
|
||||||
return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam {
|
return Err(tcx.dcx().emit_err(NonGenericOpaqueTypeParam {
|
||||||
|
@ -409,10 +412,10 @@ fn check_opaque_type_parameter_valid(
|
||||||
|
|
||||||
for (_, indices) in seen_params {
|
for (_, indices) in seen_params {
|
||||||
if indices.len() > 1 {
|
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
|
let spans: Vec<_> = indices
|
||||||
.into_iter()
|
.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();
|
.collect();
|
||||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||||
#[allow(rustc::untranslatable_diagnostic)]
|
#[allow(rustc::untranslatable_diagnostic)]
|
||||||
|
|
|
@ -2562,6 +2562,8 @@ pub enum OpaqueTyOrigin {
|
||||||
AsyncFn(LocalDefId),
|
AsyncFn(LocalDefId),
|
||||||
/// type aliases: `type Foo = impl Trait;`
|
/// type aliases: `type Foo = impl Trait;`
|
||||||
TyAlias {
|
TyAlias {
|
||||||
|
/// The type alias or associated type parent of the TAIT/ATPIT
|
||||||
|
parent: LocalDefId,
|
||||||
/// associated types in impl blocks for traits.
|
/// associated types in impl blocks for traits.
|
||||||
in_assoc_ty: bool,
|
in_assoc_ty: bool,
|
||||||
},
|
},
|
||||||
|
|
|
@ -339,8 +339,9 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
origin: &hir::OpaqueTyOrigin,
|
origin: &hir::OpaqueTyOrigin,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let defining_use_anchor = match *origin {
|
let defining_use_anchor = match *origin {
|
||||||
hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
|
hir::OpaqueTyOrigin::FnReturn(did)
|
||||||
hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id),
|
| hir::OpaqueTyOrigin::AsyncFn(did)
|
||||||
|
| hir::OpaqueTyOrigin::TyAlias { parent: did, .. } => did,
|
||||||
};
|
};
|
||||||
let param_env = tcx.param_env(defining_use_anchor);
|
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 ocx = ObligationCtxt::new(&infcx);
|
||||||
|
|
||||||
let args = match *origin {
|
let args = match *origin {
|
||||||
hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
|
hir::OpaqueTyOrigin::FnReturn(parent)
|
||||||
GenericArgs::identity_for_item(tcx, parent).extend_to(
|
| hir::OpaqueTyOrigin::AsyncFn(parent)
|
||||||
tcx,
|
| hir::OpaqueTyOrigin::TyAlias { parent, .. } => GenericArgs::identity_for_item(
|
||||||
def_id.to_def_id(),
|
tcx, parent,
|
||||||
|param, _| tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local()).into(),
|
)
|
||||||
)
|
.extend_to(tcx, def_id.to_def_id(), |param, _| {
|
||||||
}
|
tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()).into()
|
||||||
hir::OpaqueTyOrigin::TyAlias { .. } => GenericArgs::identity_for_item(tcx, def_id),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
|
||||||
|
|
|
@ -339,7 +339,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
|
||||||
predicates: &mut Vec<(ty::Clause<'tcx>, Span)>,
|
predicates: &mut Vec<(ty::Clause<'tcx>, Span)>,
|
||||||
) {
|
) {
|
||||||
for param in opaque_own_params {
|
for param in opaque_own_params {
|
||||||
let orig_lifetime = tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
|
let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
|
||||||
if let ty::ReEarlyParam(..) = *orig_lifetime {
|
if let ty::ReEarlyParam(..) = *orig_lifetime {
|
||||||
let dup_lifetime = ty::Region::new_early_param(
|
let dup_lifetime = ty::Region::new_early_param(
|
||||||
tcx,
|
tcx,
|
||||||
|
|
|
@ -514,38 +514,11 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
// These sorts of items have no lifetime parameters at all.
|
// These sorts of items have no lifetime parameters at all.
|
||||||
intravisit::walk_item(self, item);
|
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 {
|
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,
|
generics,
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -683,26 +656,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
// the opaque_ty generics
|
// the opaque_ty generics
|
||||||
let opaque_ty = self.tcx.hir().item(item_id);
|
let opaque_ty = self.tcx.hir().item(item_id);
|
||||||
match &opaque_ty.kind {
|
match &opaque_ty.kind {
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin: _, .. }) => {}
|
||||||
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(..),
|
|
||||||
..
|
|
||||||
}) => {}
|
|
||||||
i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
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) {
|
Ok(ty::EarlyBinder::bind(match tcx.hir_node_by_def_id(def_id) {
|
||||||
Node::Item(item) => match item.kind {
|
Node::Item(item) => match item.kind {
|
||||||
ItemKind::OpaqueTy(OpaqueTy {
|
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),
|
}) => opaque::find_opaque_ty_constraints_for_tait(tcx, def_id),
|
||||||
ItemKind::OpaqueTy(OpaqueTy {
|
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::find_opaque_ty_constraints_for_impl_trait_in_assoc_type(tcx, def_id),
|
||||||
// Opaque types desugared from `impl Trait`.
|
// 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
|
// By default, RPIT are invariant wrt type and const generics, but they are bivariant wrt
|
||||||
// lifetime generics.
|
// lifetime generics.
|
||||||
let variances = std::iter::repeat(ty::Invariant).take(generics.count());
|
let mut variances = vec![ty::Invariant; 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),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mark all lifetimes from parent generics as unused (Bivariant).
|
// Mark all lifetimes from parent generics as unused (Bivariant).
|
||||||
// This will be overridden later if required.
|
// This will be overridden later if required.
|
||||||
|
|
|
@ -391,7 +391,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
// Anonymous `impl Trait`
|
// Anonymous `impl Trait`
|
||||||
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
|
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
|
||||||
// Named `type Foo = impl Bar;`
|
// Named `type Foo = impl Bar;`
|
||||||
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
|
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty, .. } => {
|
||||||
if in_assoc_ty {
|
if in_assoc_ty {
|
||||||
self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
|
self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1254,7 +1254,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
if self.def_kind(scope) == DefKind::OpaqueTy {
|
if self.def_kind(scope) == DefKind::OpaqueTy {
|
||||||
// Lifetime params of opaque types are synthetic and thus irrelevant to
|
// Lifetime params of opaque types are synthetic and thus irrelevant to
|
||||||
// diagnostics. Map them back to their origin!
|
// diagnostics. Map them back to their origin!
|
||||||
region = self.map_rpit_lifetime_to_fn_lifetime(def_id);
|
region = self.map_opaque_lifetime_to_parent_lifetime(def_id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
|
break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
|
||||||
|
@ -2219,31 +2219,31 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given the def-id of an early-bound lifetime on an RPIT corresponding to
|
/// Given the def-id of an early-bound lifetime on an opaque corresponding to
|
||||||
/// a duplicated captured lifetime, map it back to the early- or late-bound
|
/// a duplicated captured lifetime, map it back to the early- or late-bound
|
||||||
/// lifetime of the function from which it originally as captured. If it is
|
/// lifetime of the function from which it originally as captured. If it is
|
||||||
/// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
|
/// a late-bound lifetime, this will represent the liberated (`ReLateParam`) lifetime
|
||||||
/// of the signature.
|
/// of the signature.
|
||||||
// FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
|
// FIXME(RPITIT): if we ever synthesize new lifetimes for RPITITs and not just
|
||||||
// re-use the generics of the opaque, this function will need to be tweaked slightly.
|
// re-use the generics of the opaque, this function will need to be tweaked slightly.
|
||||||
pub fn map_rpit_lifetime_to_fn_lifetime(
|
pub fn map_opaque_lifetime_to_parent_lifetime(
|
||||||
self,
|
self,
|
||||||
mut rpit_lifetime_param_def_id: LocalDefId,
|
mut opaque_lifetime_param_def_id: LocalDefId,
|
||||||
) -> ty::Region<'tcx> {
|
) -> ty::Region<'tcx> {
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
matches!(self.def_kind(rpit_lifetime_param_def_id), DefKind::LifetimeParam),
|
matches!(self.def_kind(opaque_lifetime_param_def_id), DefKind::LifetimeParam),
|
||||||
"{rpit_lifetime_param_def_id:?} is a {}",
|
"{opaque_lifetime_param_def_id:?} is a {}",
|
||||||
self.def_descr(rpit_lifetime_param_def_id.to_def_id())
|
self.def_descr(opaque_lifetime_param_def_id.to_def_id())
|
||||||
);
|
);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let parent = self.local_parent(rpit_lifetime_param_def_id);
|
let parent = self.local_parent(opaque_lifetime_param_def_id);
|
||||||
let hir::OpaqueTy { lifetime_mapping, .. } =
|
let hir::OpaqueTy { lifetime_mapping, .. } =
|
||||||
self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
|
self.hir_node_by_def_id(parent).expect_item().expect_opaque_ty();
|
||||||
|
|
||||||
let Some((lifetime, _)) = lifetime_mapping
|
let Some((lifetime, _)) = lifetime_mapping
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, duplicated_param)| *duplicated_param == rpit_lifetime_param_def_id)
|
.find(|(_, duplicated_param)| *duplicated_param == opaque_lifetime_param_def_id)
|
||||||
else {
|
else {
|
||||||
bug!("duplicated lifetime param should be present");
|
bug!("duplicated lifetime param should be present");
|
||||||
};
|
};
|
||||||
|
@ -2256,7 +2256,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
// of the opaque we mapped from. Continue mapping.
|
// of the opaque we mapped from. Continue mapping.
|
||||||
if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
|
if matches!(self.def_kind(new_parent), DefKind::OpaqueTy) {
|
||||||
debug_assert_eq!(self.parent(parent.to_def_id()), new_parent);
|
debug_assert_eq!(self.parent(parent.to_def_id()), new_parent);
|
||||||
rpit_lifetime_param_def_id = ebv.expect_local();
|
opaque_lifetime_param_def_id = ebv.expect_local();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
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 {
|
pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
|
||||||
if self.def_kind(def_id) != DefKind::AssocFn {
|
if self.def_kind(def_id) != DefKind::AssocFn {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -71,7 +71,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
|
||||||
// the end of the list corresponding to the opaque's generics.
|
// the end of the list corresponding to the opaque's generics.
|
||||||
for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] {
|
for param in &generics.params[tcx.generics_of(fn_def_id).params.len()..] {
|
||||||
let orig_lt =
|
let orig_lt =
|
||||||
tcx.map_rpit_lifetime_to_fn_lifetime(param.def_id.expect_local());
|
tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
|
||||||
if matches!(*orig_lt, ty::ReLateParam(..)) {
|
if matches!(*orig_lt, ty::ReLateParam(..)) {
|
||||||
mapping.insert(
|
mapping.insert(
|
||||||
orig_lt,
|
orig_lt,
|
||||||
|
|
|
@ -141,7 +141,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
|
||||||
trace!(?origin);
|
trace!(?origin);
|
||||||
match origin {
|
match origin {
|
||||||
rustc_hir::OpaqueTyOrigin::FnReturn(_) | rustc_hir::OpaqueTyOrigin::AsyncFn(_) => {}
|
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 !in_assoc_ty {
|
||||||
if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
|
if !self.check_tait_defining_scope(alias_ty.def_id.expect_local()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -7,7 +7,7 @@ pub trait Trait<'a> {
|
||||||
trait Test<'a> {}
|
trait Test<'a> {}
|
||||||
|
|
||||||
pub type Foo = impl for<'a> Trait<'a, Assoc = impl 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 () {
|
impl Trait<'_> for () {
|
||||||
type Assoc = ();
|
type Assoc = ();
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
error: cannot capture late-bound lifetime in type alias impl trait
|
error: higher kinded lifetime bounds on nested opaque types are not supported yet
|
||||||
--> $DIR/escaping-bound-var.rs:9:57
|
--> $DIR/escaping-bound-var.rs:9:25
|
||||||
|
|
|
|
||||||
LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>;
|
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
|
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);
|
type Foo<'a, 'b> = (i32, impl PartialEq<Foo<'a, 'b>> + std::fmt::Debug);
|
||||||
|
|
||||||
fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
|
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)
|
(42, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Moo<'a, 'b> = (i32, impl PartialEq<Moo<'b, 'a>> + std::fmt::Debug);
|
type Moo<'a, 'b> = (i32, impl PartialEq<Moo<'b, 'a>> + std::fmt::Debug);
|
||||||
|
|
||||||
fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
|
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)
|
(42, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,28 +10,28 @@ LL | i
|
||||||
= help: the trait `PartialEq<Bar<'b, 'a>>` is not implemented for `&i32`
|
= help: the trait `PartialEq<Bar<'b, 'a>>` is not implemented for `&i32`
|
||||||
= help: the trait `PartialEq` is 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
|
--> $DIR/self-referential.rs:14:31
|
||||||
|
|
|
|
||||||
LL | fn foo<'a, 'b>(i: &'a i32) -> Foo<'a, 'b> {
|
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 |
|
||||||
LL | (42, i)
|
LL | (42, i)
|
||||||
| ------- return type was inferred to be `(i32, &i32)` here
|
| ------- 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`
|
= 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
|
--> $DIR/self-referential.rs:21:31
|
||||||
|
|
|
|
||||||
LL | fn moo<'a, 'b>(i: &'a i32) -> Moo<'a, 'b> {
|
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 |
|
||||||
LL | (42, i)
|
LL | (42, i)
|
||||||
| ------- return type was inferred to be `(i32, &i32)` here
|
| ------- 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`
|
= help: the trait `PartialEq` is implemented for `i32`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
|
@ -5,21 +5,21 @@
|
||||||
trait Captures<'a> {}
|
trait Captures<'a> {}
|
||||||
impl<T> Captures<'_> for T {}
|
impl<T> Captures<'_> for T {}
|
||||||
|
|
||||||
type NotCapturedEarly<'a> = impl Sized; //~ [o]
|
type NotCapturedEarly<'a> = impl Sized; //~ [*, o]
|
||||||
//~^ ERROR: unconstrained opaque type
|
//~^ ERROR: unconstrained opaque type
|
||||||
|
|
||||||
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o]
|
type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [*, o]
|
||||||
//~^ ERROR: unconstrained opaque type
|
//~^ ERROR: unconstrained opaque type
|
||||||
|
|
||||||
// TAIT does *not* capture `'b`
|
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [*, o, o]
|
||||||
type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o]
|
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
|
||||||
//~^ ERROR: unconstrained opaque type
|
//~| ERROR: unconstrained opaque type
|
||||||
|
|
||||||
// TAIT does *not* capture `'b`
|
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [*, o, o]
|
||||||
type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [o]
|
//~^ ERROR `impl Trait` can only capture lifetimes bound at the fn or impl level
|
||||||
//~^ ERROR: unconstrained opaque type
|
//~| 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
|
//~^ ERROR: unconstrained opaque type
|
||||||
|
|
||||||
trait Foo<'i> {
|
trait Foo<'i> {
|
||||||
|
@ -31,24 +31,24 @@ trait Foo<'i> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'i> Foo<'i> for &'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
|
//~^ 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
|
//~^ 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
|
//~^ ERROR: unconstrained opaque type
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'i> Foo<'i> for () {
|
impl<'i> Foo<'i> for () {
|
||||||
type ImplicitCapture<'a> = impl Sized; //~ [o, o]
|
type ImplicitCapture<'a> = impl Sized; //~ [*, *, o, o]
|
||||||
//~^ ERROR: unconstrained opaque type
|
//~^ 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
|
//~^ 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
|
//~^ 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
|
error: unconstrained opaque type
|
||||||
--> $DIR/variance.rs:8:29
|
--> $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
|
= note: `CapturedEarly` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
error: unconstrained opaque type
|
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>;
|
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
|
= note: `NotCapturedLate` must be used in combination with a concrete type within the same module
|
||||||
|
|
||||||
error: unconstrained opaque type
|
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>>;
|
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
|
= note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl
|
||||||
|
|
||||||
error: [o]
|
error: [*, o]
|
||||||
--> $DIR/variance.rs:8:29
|
--> $DIR/variance.rs:8:29
|
||||||
|
|
|
|
||||||
LL | type NotCapturedEarly<'a> = impl Sized;
|
LL | type NotCapturedEarly<'a> = impl Sized;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: [o]
|
error: [*, o]
|
||||||
--> $DIR/variance.rs:11:26
|
--> $DIR/variance.rs:11:26
|
||||||
|
|
|
|
||||||
LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
|
LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o]
|
error: [*, o, o]
|
||||||
--> $DIR/variance.rs:15:56
|
--> $DIR/variance.rs:14: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]
|
error: [*, o, o]
|
||||||
--> $DIR/variance.rs:19:49
|
--> $DIR/variance.rs:18:49
|
||||||
|
|
|
|
||||||
LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
|
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
|
--> $DIR/variance.rs:22:27
|
||||||
|
|
|
|
||||||
LL | type Bar<'a, 'b: 'b, T> = impl Sized;
|
LL | type Bar<'a, 'b: 'b, T> = impl Sized;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [*, *, o, o]
|
||||||
--> $DIR/variance.rs:34:32
|
--> $DIR/variance.rs:34:32
|
||||||
|
|
|
|
||||||
LL | type ImplicitCapture<'a> = impl Sized;
|
LL | type ImplicitCapture<'a> = impl Sized;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [*, *, o, o]
|
||||||
--> $DIR/variance.rs:37:42
|
--> $DIR/variance.rs:37:42
|
||||||
|
|
|
|
||||||
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
|
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [*, *, o, o]
|
||||||
--> $DIR/variance.rs:40:39
|
--> $DIR/variance.rs:40:39
|
||||||
|
|
|
|
||||||
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
|
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [*, *, o, o]
|
||||||
--> $DIR/variance.rs:45:32
|
--> $DIR/variance.rs:45:32
|
||||||
|
|
|
|
||||||
LL | type ImplicitCapture<'a> = impl Sized;
|
LL | type ImplicitCapture<'a> = impl Sized;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [*, *, o, o]
|
||||||
--> $DIR/variance.rs:48:42
|
--> $DIR/variance.rs:48:42
|
||||||
|
|
|
|
||||||
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
|
LL | type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: [o, o]
|
error: [*, *, o, o]
|
||||||
--> $DIR/variance.rs:51:39
|
--> $DIR/variance.rs:51:39
|
||||||
|
|
|
|
||||||
LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
|
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…
Add table
Add a link
Reference in a new issue