Address rebase issues, make async fn in trait work
This commit is contained in:
parent
5be30f9d79
commit
249ede4195
3 changed files with 89 additions and 19 deletions
|
@ -777,9 +777,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
|
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
|
||||||
}
|
}
|
||||||
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
|
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
|
||||||
|
let asyncness = sig.header.asyncness;
|
||||||
let names = self.lower_fn_params_to_names(&sig.decl);
|
let names = self.lower_fn_params_to_names(&sig.decl);
|
||||||
let (generics, sig) =
|
let (generics, sig) = self.lower_method_sig(
|
||||||
self.lower_method_sig(generics, sig, i.id, FnDeclKind::Trait, None);
|
generics,
|
||||||
|
sig,
|
||||||
|
i.id,
|
||||||
|
FnDeclKind::Trait,
|
||||||
|
asyncness.opt_return_id(),
|
||||||
|
);
|
||||||
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
|
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
|
||||||
}
|
}
|
||||||
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
|
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
|
||||||
|
|
|
@ -1358,7 +1358,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}
|
}
|
||||||
ImplTraitContext::InTrait => {
|
ImplTraitContext::InTrait => {
|
||||||
// FIXME(RPITIT): Should we use def_node_id here?
|
// FIXME(RPITIT): Should we use def_node_id here?
|
||||||
self.lower_impl_trait_in_trait(span, def_node_id, bounds)
|
self.lower_impl_trait_in_trait(span, def_node_id, |lctx| {
|
||||||
|
lctx.lower_param_bounds(
|
||||||
|
bounds,
|
||||||
|
ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
ImplTraitContext::Universal => {
|
ImplTraitContext::Universal => {
|
||||||
let span = t.span;
|
let span = t.span;
|
||||||
|
@ -1546,19 +1551,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
|
hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self, lower_bounds))]
|
||||||
fn lower_impl_trait_in_trait(
|
fn lower_impl_trait_in_trait(
|
||||||
&mut self,
|
&mut self,
|
||||||
span: Span,
|
span: Span,
|
||||||
opaque_ty_node_id: NodeId,
|
opaque_ty_node_id: NodeId,
|
||||||
bounds: &GenericBounds,
|
lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
|
||||||
) -> hir::TyKind<'hir> {
|
) -> hir::TyKind<'hir> {
|
||||||
let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
|
let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
|
||||||
self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
|
self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
|
||||||
// FIXME(RPITIT): This should be a more descriptive ImplTraitPosition, i.e. nested RPITIT
|
// FIXME(RPITIT): This should be a more descriptive ImplTraitPosition, i.e. nested RPITIT
|
||||||
// FIXME(RPITIT): We _also_ should support this eventually
|
// FIXME(RPITIT): We _also_ should support this eventually
|
||||||
let hir_bounds = lctx
|
let hir_bounds = lower_bounds(lctx);
|
||||||
.lower_param_bounds(bounds, ImplTraitContext::Disallowed(ImplTraitPosition::Trait));
|
|
||||||
let rpitit_placeholder = hir::ImplTraitPlaceholder { bounds: hir_bounds };
|
let rpitit_placeholder = hir::ImplTraitPlaceholder { bounds: hir_bounds };
|
||||||
let rpitit_item = hir::Item {
|
let rpitit_item = hir::Item {
|
||||||
def_id: opaque_ty_def_id,
|
def_id: opaque_ty_def_id,
|
||||||
|
@ -1719,18 +1723,44 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let output = if let Some((ret_id, span)) = make_ret_async {
|
let output = if let Some((ret_id, span)) = make_ret_async {
|
||||||
if !self.tcx.features().return_position_impl_trait_in_trait {
|
match kind {
|
||||||
self.tcx.sess.emit_feature_err(
|
FnDeclKind::Trait => {
|
||||||
TraitFnAsync { fn_span, span },
|
if !kind.impl_trait_in_trait_allowed(self.tcx) {
|
||||||
sym::return_position_impl_trait_in_trait,
|
self.tcx
|
||||||
);
|
.sess
|
||||||
|
.create_feature_err(
|
||||||
|
TraitFnAsync { fn_span, span },
|
||||||
|
sym::return_position_impl_trait_in_trait,
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
self.lower_async_fn_ret_ty_in_trait(
|
||||||
|
&decl.output,
|
||||||
|
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
|
||||||
|
ret_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if !kind.impl_trait_return_allowed(self.tcx) {
|
||||||
|
if kind == FnDeclKind::Impl {
|
||||||
|
self.tcx
|
||||||
|
.sess
|
||||||
|
.create_feature_err(
|
||||||
|
TraitFnAsync { fn_span, span },
|
||||||
|
sym::return_position_impl_trait_in_trait,
|
||||||
|
)
|
||||||
|
.emit();
|
||||||
|
} else {
|
||||||
|
self.tcx.sess.emit_err(TraitFnAsync { fn_span, span });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.lower_async_fn_ret_ty(
|
||||||
|
&decl.output,
|
||||||
|
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
|
||||||
|
ret_id,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.lower_async_fn_ret_ty(
|
|
||||||
&decl.output,
|
|
||||||
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
|
|
||||||
ret_id,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
match decl.output {
|
match decl.output {
|
||||||
FnRetTy::Ty(ref ty) => {
|
FnRetTy::Ty(ref ty) => {
|
||||||
|
@ -2020,6 +2050,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
|
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
|
||||||
|
// combined with the following definition of `OpaqueTy`:
|
||||||
|
//
|
||||||
|
// type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
|
||||||
|
//
|
||||||
|
// `output`: unlowered output type (`T` in `-> T`)
|
||||||
|
// `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
|
||||||
|
// `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
|
||||||
|
#[instrument(level = "debug", skip(self))]
|
||||||
|
fn lower_async_fn_ret_ty_in_trait(
|
||||||
|
&mut self,
|
||||||
|
output: &FnRetTy,
|
||||||
|
fn_node_id: NodeId,
|
||||||
|
opaque_ty_node_id: NodeId,
|
||||||
|
) -> hir::FnRetTy<'hir> {
|
||||||
|
let span = output.span();
|
||||||
|
|
||||||
|
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
|
||||||
|
|
||||||
|
let fn_def_id = self.local_def_id(fn_node_id);
|
||||||
|
|
||||||
|
let kind = self.lower_impl_trait_in_trait(output.span(), opaque_ty_node_id, |lctx| {
|
||||||
|
let bound =
|
||||||
|
lctx.lower_async_fn_output_type_to_future_bound(output, fn_def_id, output.span());
|
||||||
|
arena_vec![lctx; bound]
|
||||||
|
});
|
||||||
|
let opaque_ty = self.ty(opaque_ty_span, kind);
|
||||||
|
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
|
||||||
|
}
|
||||||
|
|
||||||
/// Transforms `-> T` into `Future<Output = T>`.
|
/// Transforms `-> T` into `Future<Output = T>`.
|
||||||
fn lower_async_fn_output_type_to_future_bound(
|
fn lower_async_fn_output_type_to_future_bound(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -1036,6 +1036,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
|
||||||
| DefKind::Static(..)
|
| DefKind::Static(..)
|
||||||
| DefKind::TyAlias
|
| DefKind::TyAlias
|
||||||
| DefKind::OpaqueTy
|
| DefKind::OpaqueTy
|
||||||
|
| DefKind::ImplTraitPlaceholder
|
||||||
| DefKind::ForeignTy
|
| DefKind::ForeignTy
|
||||||
| DefKind::Impl
|
| DefKind::Impl
|
||||||
| DefKind::AssocFn
|
| DefKind::AssocFn
|
||||||
|
@ -1085,6 +1086,7 @@ fn should_encode_const(def_kind: DefKind) -> bool {
|
||||||
| DefKind::Static(..)
|
| DefKind::Static(..)
|
||||||
| DefKind::TyAlias
|
| DefKind::TyAlias
|
||||||
| DefKind::OpaqueTy
|
| DefKind::OpaqueTy
|
||||||
|
| DefKind::ImplTraitPlaceholder
|
||||||
| DefKind::ForeignTy
|
| DefKind::ForeignTy
|
||||||
| DefKind::Impl
|
| DefKind::Impl
|
||||||
| DefKind::AssocFn
|
| DefKind::AssocFn
|
||||||
|
@ -1497,7 +1499,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
hir::ItemKind::OpaqueTy(..) => {
|
hir::ItemKind::OpaqueTy(..) => {
|
||||||
self.encode_explicit_item_bounds(def_id);
|
self.encode_explicit_item_bounds(def_id);
|
||||||
EntryKind::OpaqueTy
|
}
|
||||||
|
hir::ItemKind::ImplTraitPlaceholder(..) => {
|
||||||
|
self.encode_explicit_item_bounds(def_id);
|
||||||
}
|
}
|
||||||
hir::ItemKind::Enum(..) => {
|
hir::ItemKind::Enum(..) => {
|
||||||
let adt_def = self.tcx.adt_def(def_id);
|
let adt_def = self.tcx.adt_def(def_id);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue