1
Fork 0

Store impl_trait_fn inside OpaqueTyOrigin.

This commit is contained in:
Camille GILLOT 2021-11-30 19:11:35 +01:00
parent 72b6f7049c
commit 8576ab45e4
13 changed files with 119 additions and 97 deletions

View file

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

View file

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

View file

@ -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 => {}
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 => {}
} }

View file

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

View file

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