Store impl_trait_fn inside OpaqueTyOrigin.
This commit is contained in:
parent
72b6f7049c
commit
8576ab45e4
13 changed files with 119 additions and 97 deletions
|
@ -247,12 +247,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
AnonymousLifetimeMode::PassThrough,
|
AnonymousLifetimeMode::PassThrough,
|
||||||
|this, idty| {
|
|this, idty| {
|
||||||
let ret_id = asyncness.opt_return_id();
|
let ret_id = asyncness.opt_return_id();
|
||||||
this.lower_fn_decl(
|
this.lower_fn_decl(&decl, Some((fn_def_id, idty)), true, ret_id)
|
||||||
&decl,
|
|
||||||
Some((fn_def_id.to_def_id(), idty)),
|
|
||||||
true,
|
|
||||||
ret_id,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let sig = hir::FnSig {
|
let sig = hir::FnSig {
|
||||||
|
@ -1264,7 +1259,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
|this, idty| {
|
|this, idty| {
|
||||||
this.lower_fn_decl(
|
this.lower_fn_decl(
|
||||||
&sig.decl,
|
&sig.decl,
|
||||||
Some((fn_def_id.to_def_id(), idty)),
|
Some((fn_def_id, idty)),
|
||||||
impl_trait_return_allow,
|
impl_trait_return_allow,
|
||||||
is_async,
|
is_async,
|
||||||
)
|
)
|
||||||
|
|
|
@ -228,7 +228,7 @@ enum ImplTraitContext<'b, 'a> {
|
||||||
ReturnPositionOpaqueTy {
|
ReturnPositionOpaqueTy {
|
||||||
/// `DefId` for the parent function, used to look up necessary
|
/// `DefId` for the parent function, used to look up necessary
|
||||||
/// information later.
|
/// information later.
|
||||||
fn_def_id: DefId,
|
fn_def_id: LocalDefId,
|
||||||
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
/// Origin: Either OpaqueTyOrigin::FnReturn or OpaqueTyOrigin::AsyncFn,
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
},
|
},
|
||||||
|
@ -1377,7 +1377,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
fn lower_opaque_impl_trait(
|
fn lower_opaque_impl_trait(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
fn_def_id: Option<DefId>,
|
fn_def_id: Option<LocalDefId>,
|
||||||
origin: hir::OpaqueTyOrigin,
|
origin: hir::OpaqueTyOrigin,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
|
capturable_lifetimes: Option<&FxHashSet<hir::LifetimeName>>,
|
||||||
|
@ -1449,7 +1449,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
span: lctx.lower_span(span),
|
span: lctx.lower_span(span),
|
||||||
},
|
},
|
||||||
bounds: hir_bounds,
|
bounds: hir_bounds,
|
||||||
impl_trait_fn: fn_def_id,
|
|
||||||
origin,
|
origin,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1519,7 +1518,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
fn lower_fn_decl(
|
fn lower_fn_decl(
|
||||||
&mut self,
|
&mut self,
|
||||||
decl: &FnDecl,
|
decl: &FnDecl,
|
||||||
mut in_band_ty_params: Option<(DefId, &mut Vec<hir::GenericParam<'hir>>)>,
|
mut in_band_ty_params: Option<(LocalDefId, &mut Vec<hir::GenericParam<'hir>>)>,
|
||||||
impl_trait_return_allow: bool,
|
impl_trait_return_allow: bool,
|
||||||
make_ret_async: Option<NodeId>,
|
make_ret_async: Option<NodeId>,
|
||||||
) -> &'hir hir::FnDecl<'hir> {
|
) -> &'hir hir::FnDecl<'hir> {
|
||||||
|
@ -1577,7 +1576,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
Some((def_id, _)) if impl_trait_return_allow => {
|
Some((def_id, _)) if impl_trait_return_allow => {
|
||||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||||
fn_def_id: def_id,
|
fn_def_id: def_id,
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn,
|
origin: hir::OpaqueTyOrigin::FnReturn(def_id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => ImplTraitContext::disallowed(),
|
_ => ImplTraitContext::disallowed(),
|
||||||
|
@ -1632,7 +1631,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
fn lower_async_fn_ret_ty(
|
fn lower_async_fn_ret_ty(
|
||||||
&mut self,
|
&mut self,
|
||||||
output: &FnRetTy,
|
output: &FnRetTy,
|
||||||
fn_def_id: DefId,
|
fn_def_id: LocalDefId,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
) -> hir::FnRetTy<'hir> {
|
) -> hir::FnRetTy<'hir> {
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -1747,8 +1746,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
span: this.lower_span(span),
|
span: this.lower_span(span),
|
||||||
},
|
},
|
||||||
bounds: arena_vec![this; future_bound],
|
bounds: arena_vec![this; future_bound],
|
||||||
impl_trait_fn: Some(fn_def_id),
|
origin: hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
||||||
origin: hir::OpaqueTyOrigin::AsyncFn,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
|
trace!("exist ty from async fn def id: {:#?}", opaque_ty_def_id);
|
||||||
|
@ -1794,7 +1792,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
fn lower_async_fn_output_type_to_future_bound(
|
fn lower_async_fn_output_type_to_future_bound(
|
||||||
&mut self,
|
&mut self,
|
||||||
output: &FnRetTy,
|
output: &FnRetTy,
|
||||||
fn_def_id: DefId,
|
fn_def_id: LocalDefId,
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> hir::GenericBound<'hir> {
|
) -> hir::GenericBound<'hir> {
|
||||||
// Compute the `T` in `Future<Output = T>` from the return type.
|
// Compute the `T` in `Future<Output = T>` from the return type.
|
||||||
|
@ -1805,7 +1803,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
// generates.
|
// generates.
|
||||||
let context = ImplTraitContext::ReturnPositionOpaqueTy {
|
let context = ImplTraitContext::ReturnPositionOpaqueTy {
|
||||||
fn_def_id,
|
fn_def_id,
|
||||||
origin: hir::OpaqueTyOrigin::FnReturn,
|
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||||
};
|
};
|
||||||
self.lower_ty(ty, context)
|
self.lower_ty(ty, context)
|
||||||
}
|
}
|
||||||
|
@ -2442,17 +2440,12 @@ impl<'hir> GenericArgsCtor<'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(level = "debug")]
|
||||||
fn lifetimes_from_impl_trait_bounds(
|
fn lifetimes_from_impl_trait_bounds(
|
||||||
opaque_ty_id: NodeId,
|
opaque_ty_id: NodeId,
|
||||||
bounds: hir::GenericBounds<'_>,
|
bounds: hir::GenericBounds<'_>,
|
||||||
lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
|
lifetimes_to_include: Option<&FxHashSet<hir::LifetimeName>>,
|
||||||
) -> Vec<(hir::LifetimeName, Span)> {
|
) -> Vec<(hir::LifetimeName, Span)> {
|
||||||
debug!(
|
|
||||||
"lifetimes_from_impl_trait_bounds(opaque_ty_id={:?}, \
|
|
||||||
bounds={:#?})",
|
|
||||||
opaque_ty_id, bounds,
|
|
||||||
);
|
|
||||||
|
|
||||||
// This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
|
// This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that
|
||||||
// appear in the bounds, excluding lifetimes that are created within the bounds.
|
// appear in the bounds, excluding lifetimes that are created within the bounds.
|
||||||
// E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
|
// E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`.
|
||||||
|
|
|
@ -173,7 +173,7 @@ fn check_opaque_type_parameter_valid(
|
||||||
// fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
|
// fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>.
|
||||||
//
|
//
|
||||||
// which would error here on all of the `'static` args.
|
// which would error here on all of the `'static` args.
|
||||||
OpaqueTyOrigin::FnReturn | OpaqueTyOrigin::AsyncFn => return true,
|
OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true,
|
||||||
// Check these
|
// Check these
|
||||||
OpaqueTyOrigin::TyAlias => {}
|
OpaqueTyOrigin::TyAlias => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2248,7 +2248,6 @@ pub struct BareFnTy<'hir> {
|
||||||
pub struct OpaqueTy<'hir> {
|
pub struct OpaqueTy<'hir> {
|
||||||
pub generics: Generics<'hir>,
|
pub generics: Generics<'hir>,
|
||||||
pub bounds: GenericBounds<'hir>,
|
pub bounds: GenericBounds<'hir>,
|
||||||
pub impl_trait_fn: Option<DefId>,
|
|
||||||
pub origin: OpaqueTyOrigin,
|
pub origin: OpaqueTyOrigin,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2256,9 +2255,9 @@ pub struct OpaqueTy<'hir> {
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)]
|
||||||
pub enum OpaqueTyOrigin {
|
pub enum OpaqueTyOrigin {
|
||||||
/// `-> impl Trait`
|
/// `-> impl Trait`
|
||||||
FnReturn,
|
FnReturn(LocalDefId),
|
||||||
/// `async fn`
|
/// `async fn`
|
||||||
AsyncFn,
|
AsyncFn(LocalDefId),
|
||||||
/// type aliases: `type Foo = impl Trait;`
|
/// type aliases: `type Foo = impl Trait;`
|
||||||
TyAlias,
|
TyAlias,
|
||||||
}
|
}
|
||||||
|
@ -2809,7 +2808,9 @@ impl ItemKind<'_> {
|
||||||
Some(match *self {
|
Some(match *self {
|
||||||
ItemKind::Fn(_, ref generics, _)
|
ItemKind::Fn(_, ref generics, _)
|
||||||
| ItemKind::TyAlias(_, ref generics)
|
| ItemKind::TyAlias(_, ref generics)
|
||||||
| ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
|
| ItemKind::OpaqueTy(OpaqueTy {
|
||||||
|
ref generics, origin: OpaqueTyOrigin::TyAlias, ..
|
||||||
|
})
|
||||||
| ItemKind::Enum(_, ref generics)
|
| ItemKind::Enum(_, ref generics)
|
||||||
| ItemKind::Struct(_, ref generics)
|
| ItemKind::Struct(_, ref generics)
|
||||||
| ItemKind::Union(_, ref generics)
|
| ItemKind::Union(_, ref generics)
|
||||||
|
|
|
@ -107,7 +107,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
kind:
|
kind:
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
bounds,
|
bounds,
|
||||||
origin: hir::OpaqueTyOrigin::AsyncFn,
|
origin: hir::OpaqueTyOrigin::AsyncFn(..),
|
||||||
..
|
..
|
||||||
}),
|
}),
|
||||||
..
|
..
|
||||||
|
|
|
@ -276,7 +276,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
debug!(?concrete_ty);
|
debug!(?concrete_ty);
|
||||||
|
|
||||||
let first_own_region = match opaque_defn.origin {
|
let first_own_region = match opaque_defn.origin {
|
||||||
hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => {
|
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {
|
||||||
// We lower
|
// We lower
|
||||||
//
|
//
|
||||||
// fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
|
// fn foo<'l0..'ln>() -> impl Trait<'l0..'lm>
|
||||||
|
@ -463,20 +463,24 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
|
||||||
let parent_def_id = self.infcx.defining_use_anchor;
|
let parent_def_id = self.infcx.defining_use_anchor;
|
||||||
let (in_definition_scope, origin) = match tcx.hir().expect_item(def_id).kind
|
let (in_definition_scope, origin) = match tcx.hir().expect_item(def_id).kind
|
||||||
{
|
{
|
||||||
|
// Async `impl Trait`
|
||||||
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::AsyncFn(parent),
|
||||||
|
..
|
||||||
|
}) => (parent == parent_def_id, hir::OpaqueTyOrigin::AsyncFn(parent)),
|
||||||
// Anonymous `impl Trait`
|
// Anonymous `impl Trait`
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
impl_trait_fn: Some(parent),
|
origin: hir::OpaqueTyOrigin::FnReturn(parent),
|
||||||
origin,
|
|
||||||
..
|
..
|
||||||
}) => (parent == parent_def_id.to_def_id(), origin),
|
}) => (parent == parent_def_id, hir::OpaqueTyOrigin::FnReturn(parent)),
|
||||||
// Named `type Foo = impl Bar;`
|
// Named `type Foo = impl Bar;`
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
impl_trait_fn: None,
|
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||||
origin,
|
|
||||||
..
|
..
|
||||||
}) => {
|
}) => (
|
||||||
(may_define_opaque_type(tcx, parent_def_id, opaque_hir_id), origin)
|
may_define_opaque_type(tcx, parent_def_id, opaque_hir_id),
|
||||||
}
|
hir::OpaqueTyOrigin::TyAlias,
|
||||||
|
),
|
||||||
ref itemkind => {
|
ref itemkind => {
|
||||||
span_bug!(
|
span_bug!(
|
||||||
self.value_span,
|
self.value_span,
|
||||||
|
|
|
@ -2055,13 +2055,17 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition.
|
/// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition.
|
||||||
pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
|
pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<LocalDefId> {
|
||||||
if let Some(def_id) = def_id.as_local() {
|
let def_id = def_id.as_local()?;
|
||||||
if let Node::Item(item) = tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) {
|
if let Node::Item(item) = tcx.hir().get(tcx.hir().local_def_id_to_hir_id(def_id)) {
|
||||||
if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind {
|
if let hir::ItemKind::OpaqueTy(ref opaque_ty) = item.kind {
|
||||||
return opaque_ty.impl_trait_fn;
|
return match opaque_ty.origin {
|
||||||
}
|
hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
|
||||||
|
Some(parent)
|
||||||
|
}
|
||||||
|
hir::OpaqueTyOrigin::TyAlias => None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
|
|
@ -968,7 +968,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
let (generics, bounds) = match opaque_ty.kind {
|
let (generics, bounds) = match opaque_ty.kind {
|
||||||
// Named opaque `impl Trait` types are reached via `TyKind::Path`.
|
// Named opaque `impl Trait` types are reached via `TyKind::Path`.
|
||||||
// This arm is for `impl Trait` in the types of statics, constants and locals.
|
// This arm is for `impl Trait` in the types of statics, constants and locals.
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: None, .. }) => {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||||
|
..
|
||||||
|
}) => {
|
||||||
intravisit::walk_ty(self, ty);
|
intravisit::walk_ty(self, ty);
|
||||||
|
|
||||||
// Elided lifetimes are not allowed in non-return
|
// Elided lifetimes are not allowed in non-return
|
||||||
|
@ -985,7 +988,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
// RPIT (return position impl trait)
|
// RPIT (return position impl trait)
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
impl_trait_fn: Some(_),
|
origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
|
||||||
ref generics,
|
ref generics,
|
||||||
bounds,
|
bounds,
|
||||||
..
|
..
|
||||||
|
@ -1695,7 +1698,11 @@ fn compute_object_lifetime_defaults(
|
||||||
hir::ItemKind::Struct(_, ref generics)
|
hir::ItemKind::Struct(_, ref generics)
|
||||||
| hir::ItemKind::Union(_, ref generics)
|
| hir::ItemKind::Union(_, ref generics)
|
||||||
| hir::ItemKind::Enum(_, ref generics)
|
| hir::ItemKind::Enum(_, ref generics)
|
||||||
| hir::ItemKind::OpaqueTy(hir::OpaqueTy { ref generics, impl_trait_fn: None, .. })
|
| hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
|
ref generics,
|
||||||
|
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||||
|
..
|
||||||
|
})
|
||||||
| hir::ItemKind::TyAlias(_, ref generics)
|
| hir::ItemKind::TyAlias(_, ref generics)
|
||||||
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
|
| hir::ItemKind::Trait(_, _, ref generics, ..) => {
|
||||||
let result = object_lifetime_defaults_for_item(tcx, generics);
|
let result = object_lifetime_defaults_for_item(tcx, generics);
|
||||||
|
@ -2067,7 +2074,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
..
|
..
|
||||||
}) = self.tcx.hir().get(parent_hir_id)
|
}) = self.tcx.hir().get(parent_hir_id)
|
||||||
{
|
{
|
||||||
if opaque.origin != hir::OpaqueTyOrigin::AsyncFn {
|
if !matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(..)) {
|
||||||
continue 'lifetimes;
|
continue 'lifetimes;
|
||||||
}
|
}
|
||||||
// We want to do this only if the liftime identifier is already defined
|
// We want to do this only if the liftime identifier is already defined
|
||||||
|
|
|
@ -248,7 +248,7 @@ fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
|
||||||
fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
// The param_env of an impl Trait type is its defining function's param_env
|
// The param_env of an impl Trait type is its defining function's param_env
|
||||||
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
||||||
return param_env(tcx, parent);
|
return param_env(tcx, parent.to_def_id());
|
||||||
}
|
}
|
||||||
// Compute the bounds on Self and the type parameters.
|
// Compute the bounds on Self and the type parameters.
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ fn well_formed_types_in_env<'tcx>(
|
||||||
|
|
||||||
// The environment of an impl Trait type is its defining function's environment.
|
// The environment of an impl Trait type is its defining function's environment.
|
||||||
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
||||||
return well_formed_types_in_env(tcx, parent);
|
return well_formed_types_in_env(tcx, parent.to_def_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the bounds on `Self` and the type parameters.
|
// Compute the bounds on `Self` and the type parameters.
|
||||||
|
|
|
@ -2336,9 +2336,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
let def_id = item_id.def_id.to_def_id();
|
let def_id = item_id.def_id.to_def_id();
|
||||||
|
|
||||||
match opaque_ty.kind {
|
match opaque_ty.kind {
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => self
|
||||||
self.impl_trait_ty_to_ty(def_id, lifetimes, impl_trait_fn.is_some())
|
.impl_trait_ty_to_ty(
|
||||||
}
|
def_id,
|
||||||
|
lifetimes,
|
||||||
|
matches!(
|
||||||
|
origin,
|
||||||
|
hir::OpaqueTyOrigin::FnReturn(..)
|
||||||
|
| hir::OpaqueTyOrigin::AsyncFn(..)
|
||||||
|
),
|
||||||
|
),
|
||||||
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -541,7 +541,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ItemKind::OpaqueTy(hir::OpaqueTy {
|
if let ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
origin: hir::OpaqueTyOrigin::AsyncFn | hir::OpaqueTyOrigin::FnReturn,
|
origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
|
||||||
..
|
..
|
||||||
}) = item.kind
|
}) = item.kind
|
||||||
{
|
{
|
||||||
|
@ -567,7 +567,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes(
|
||||||
visitor.visit_item(&item);
|
visitor.visit_item(&item);
|
||||||
let is_async = match item.kind {
|
let is_async = match item.kind {
|
||||||
ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
|
ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
|
||||||
matches!(origin, hir::OpaqueTyOrigin::AsyncFn)
|
matches!(origin, hir::OpaqueTyOrigin::AsyncFn(..))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -604,7 +604,7 @@ pub(super) fn check_opaque_for_cycles<'tcx>(
|
||||||
) -> Result<(), ErrorReported> {
|
) -> Result<(), ErrorReported> {
|
||||||
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
|
if tcx.try_expand_impl_trait_type(def_id.to_def_id(), substs).is_err() {
|
||||||
match origin {
|
match origin {
|
||||||
hir::OpaqueTyOrigin::AsyncFn => async_opaque_type_cycle_error(tcx, span),
|
hir::OpaqueTyOrigin::AsyncFn(..) => async_opaque_type_cycle_error(tcx, span),
|
||||||
_ => opaque_type_cycle_error(tcx, def_id, span),
|
_ => opaque_type_cycle_error(tcx, def_id, span),
|
||||||
}
|
}
|
||||||
Err(ErrorReported)
|
Err(ErrorReported)
|
||||||
|
@ -635,7 +635,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
) {
|
) {
|
||||||
match origin {
|
match origin {
|
||||||
// Checked when type checking the function containing them.
|
// Checked when type checking the function containing them.
|
||||||
hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => return,
|
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => return,
|
||||||
// Can have different predicates to their defining use
|
// Can have different predicates to their defining use
|
||||||
hir::OpaqueTyOrigin::TyAlias => {}
|
hir::OpaqueTyOrigin::TyAlias => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -594,7 +594,11 @@ fn type_param_predicates(
|
||||||
ItemKind::Fn(.., ref generics, _)
|
ItemKind::Fn(.., ref generics, _)
|
||||||
| ItemKind::Impl(hir::Impl { ref generics, .. })
|
| ItemKind::Impl(hir::Impl { ref generics, .. })
|
||||||
| ItemKind::TyAlias(_, ref generics)
|
| ItemKind::TyAlias(_, ref generics)
|
||||||
| ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. })
|
| ItemKind::OpaqueTy(OpaqueTy {
|
||||||
|
ref generics,
|
||||||
|
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||||
|
..
|
||||||
|
})
|
||||||
| ItemKind::Enum(_, ref generics)
|
| ItemKind::Enum(_, ref generics)
|
||||||
| ItemKind::Struct(_, ref generics)
|
| ItemKind::Struct(_, ref generics)
|
||||||
| ItemKind::Union(_, ref generics) => generics,
|
| ItemKind::Union(_, ref generics) => generics,
|
||||||
|
@ -793,7 +797,10 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desugared from `impl Trait`, so visited by the function's return type.
|
// Desugared from `impl Trait`, so visited by the function's return type.
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) => {}
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
|
origin: hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..),
|
||||||
|
..
|
||||||
|
}) => {}
|
||||||
|
|
||||||
// Don't call `type_of` on opaque types, since that depends on type
|
// Don't call `type_of` on opaque types, since that depends on type
|
||||||
// checking function bodies. `check_item_type` ensures that it's called
|
// checking function bodies. `check_item_type` ensures that it's called
|
||||||
|
@ -1488,15 +1495,18 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
|
||||||
Some(tcx.typeck_root_def_id(def_id))
|
Some(tcx.typeck_root_def_id(def_id))
|
||||||
}
|
}
|
||||||
Node::Item(item) => match item.kind {
|
Node::Item(item) => match item.kind {
|
||||||
ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => {
|
ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
impl_trait_fn.or_else(|| {
|
origin:
|
||||||
let parent_id = tcx.hir().get_parent_item(hir_id);
|
hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id),
|
||||||
assert!(parent_id != hir_id && parent_id != CRATE_HIR_ID);
|
..
|
||||||
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
|
}) => Some(fn_def_id.to_def_id()),
|
||||||
// Opaque types are always nested within another item, and
|
ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
|
||||||
// inherit the generics of the item.
|
let parent_id = tcx.hir().get_parent_item(hir_id);
|
||||||
Some(tcx.hir().local_def_id(parent_id).to_def_id())
|
assert!(parent_id != hir_id && parent_id != CRATE_HIR_ID);
|
||||||
})
|
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
|
||||||
|
// Opaque types are always nested within another item, and
|
||||||
|
// inherit the generics of the item.
|
||||||
|
Some(tcx.hir().local_def_id(parent_id).to_def_id())
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
|
@ -2051,31 +2061,32 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||||
generics
|
generics
|
||||||
}
|
}
|
||||||
ItemKind::OpaqueTy(OpaqueTy {
|
ItemKind::OpaqueTy(OpaqueTy {
|
||||||
bounds: _,
|
origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
|
||||||
impl_trait_fn,
|
..
|
||||||
ref generics,
|
|
||||||
origin: _,
|
|
||||||
}) => {
|
}) => {
|
||||||
if impl_trait_fn.is_some() {
|
// return-position impl trait
|
||||||
// return-position impl trait
|
//
|
||||||
//
|
// We don't inherit predicates from the parent here:
|
||||||
// We don't inherit predicates from the parent here:
|
// If we have, say `fn f<'a, T: 'a>() -> impl Sized {}`
|
||||||
// If we have, say `fn f<'a, T: 'a>() -> impl Sized {}`
|
// then the return type is `f::<'static, T>::{{opaque}}`.
|
||||||
// then the return type is `f::<'static, T>::{{opaque}}`.
|
//
|
||||||
//
|
// If we inherited the predicates of `f` then we would
|
||||||
// If we inherited the predicates of `f` then we would
|
// require that `T: 'static` to show that the return
|
||||||
// require that `T: 'static` to show that the return
|
// type is well-formed.
|
||||||
// type is well-formed.
|
//
|
||||||
//
|
// The only way to have something with this opaque type
|
||||||
// The only way to have something with this opaque type
|
// is from the return type of the containing function,
|
||||||
// is from the return type of the containing function,
|
// which will ensure that the function's predicates
|
||||||
// which will ensure that the function's predicates
|
// hold.
|
||||||
// hold.
|
return ty::GenericPredicates { parent: None, predicates: &[] };
|
||||||
return ty::GenericPredicates { parent: None, predicates: &[] };
|
}
|
||||||
} else {
|
ItemKind::OpaqueTy(OpaqueTy {
|
||||||
// type-alias impl trait
|
ref generics,
|
||||||
generics
|
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||||
}
|
..
|
||||||
|
}) => {
|
||||||
|
// type-alias impl trait
|
||||||
|
generics
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => NO_GENERICS,
|
_ => NO_GENERICS,
|
||||||
|
|
|
@ -394,13 +394,13 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||||
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
|
||||||
tcx.mk_adt(def, substs)
|
tcx.mk_adt(def, substs)
|
||||||
}
|
}
|
||||||
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: None, .. }) => {
|
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
|
||||||
find_opaque_ty_constraints(tcx, def_id)
|
find_opaque_ty_constraints(tcx, def_id)
|
||||||
}
|
}
|
||||||
// Opaque types desugared from `impl Trait`.
|
// Opaque types desugared from `impl Trait`.
|
||||||
ItemKind::OpaqueTy(OpaqueTy { impl_trait_fn: Some(owner), .. }) => {
|
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), .. }) => {
|
||||||
let concrete_ty = tcx
|
let concrete_ty = tcx
|
||||||
.mir_borrowck(owner.expect_local())
|
.mir_borrowck(owner)
|
||||||
.concrete_opaque_types
|
.concrete_opaque_types
|
||||||
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
|
.get_value_matching(|(key, _)| key.def_id == def_id.to_def_id())
|
||||||
.copied()
|
.copied()
|
||||||
|
@ -413,7 +413,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if let Some(ErrorReported) =
|
if let Some(ErrorReported) =
|
||||||
tcx.typeck(owner.expect_local()).tainted_by_errors
|
tcx.typeck(owner).tainted_by_errors
|
||||||
{
|
{
|
||||||
// Some error in the
|
// Some error in the
|
||||||
// owner fn prevented us from populating
|
// owner fn prevented us from populating
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue