Skip to content

Commit 249ede4

Browse files
Address rebase issues, make async fn in trait work
1 parent 5be30f9 commit 249ede4

File tree

3 files changed

+89
-19
lines changed

3 files changed

+89
-19
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -777,9 +777,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
777777
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
778778
}
779779
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
780+
let asyncness = sig.header.asyncness;
780781
let names = self.lower_fn_params_to_names(&sig.decl);
781-
let (generics, sig) =
782-
self.lower_method_sig(generics, sig, i.id, FnDeclKind::Trait, None);
782+
let (generics, sig) = self.lower_method_sig(
783+
generics,
784+
sig,
785+
i.id,
786+
FnDeclKind::Trait,
787+
asyncness.opt_return_id(),
788+
);
783789
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
784790
}
785791
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,7 +1358,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13581358
}
13591359
ImplTraitContext::InTrait => {
13601360
// FIXME(RPITIT): Should we use def_node_id here?
1361-
self.lower_impl_trait_in_trait(span, def_node_id, bounds)
1361+
self.lower_impl_trait_in_trait(span, def_node_id, |lctx| {
1362+
lctx.lower_param_bounds(
1363+
bounds,
1364+
ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
1365+
)
1366+
})
13621367
}
13631368
ImplTraitContext::Universal => {
13641369
let span = t.span;
@@ -1546,19 +1551,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
15461551
hir::TyKind::OpaqueDef(hir::ItemId { def_id: opaque_ty_def_id }, lifetimes)
15471552
}
15481553

1549-
#[tracing::instrument(level = "debug", skip(self))]
1554+
#[instrument(level = "debug", skip(self, lower_bounds))]
15501555
fn lower_impl_trait_in_trait(
15511556
&mut self,
15521557
span: Span,
15531558
opaque_ty_node_id: NodeId,
1554-
bounds: &GenericBounds,
1559+
lower_bounds: impl FnOnce(&mut Self) -> hir::GenericBounds<'hir>,
15551560
) -> hir::TyKind<'hir> {
15561561
let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id);
15571562
self.with_hir_id_owner(opaque_ty_node_id, |lctx| {
15581563
// FIXME(RPITIT): This should be a more descriptive ImplTraitPosition, i.e. nested RPITIT
15591564
// FIXME(RPITIT): We _also_ should support this eventually
1560-
let hir_bounds = lctx
1561-
.lower_param_bounds(bounds, ImplTraitContext::Disallowed(ImplTraitPosition::Trait));
1565+
let hir_bounds = lower_bounds(lctx);
15621566
let rpitit_placeholder = hir::ImplTraitPlaceholder { bounds: hir_bounds };
15631567
let rpitit_item = hir::Item {
15641568
def_id: opaque_ty_def_id,
@@ -1719,18 +1723,44 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17191723
}));
17201724

17211725
let output = if let Some((ret_id, span)) = make_ret_async {
1722-
if !self.tcx.features().return_position_impl_trait_in_trait {
1723-
self.tcx.sess.emit_feature_err(
1724-
TraitFnAsync { fn_span, span },
1725-
sym::return_position_impl_trait_in_trait,
1726-
);
1726+
match kind {
1727+
FnDeclKind::Trait => {
1728+
if !kind.impl_trait_in_trait_allowed(self.tcx) {
1729+
self.tcx
1730+
.sess
1731+
.create_feature_err(
1732+
TraitFnAsync { fn_span, span },
1733+
sym::return_position_impl_trait_in_trait,
1734+
)
1735+
.emit();
1736+
}
1737+
self.lower_async_fn_ret_ty_in_trait(
1738+
&decl.output,
1739+
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
1740+
ret_id,
1741+
)
1742+
}
1743+
_ => {
1744+
if !kind.impl_trait_return_allowed(self.tcx) {
1745+
if kind == FnDeclKind::Impl {
1746+
self.tcx
1747+
.sess
1748+
.create_feature_err(
1749+
TraitFnAsync { fn_span, span },
1750+
sym::return_position_impl_trait_in_trait,
1751+
)
1752+
.emit();
1753+
} else {
1754+
self.tcx.sess.emit_err(TraitFnAsync { fn_span, span });
1755+
}
1756+
}
1757+
self.lower_async_fn_ret_ty(
1758+
&decl.output,
1759+
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
1760+
ret_id,
1761+
)
1762+
}
17271763
}
1728-
1729-
self.lower_async_fn_ret_ty(
1730-
&decl.output,
1731-
fn_node_id.expect("`make_ret_async` but no `fn_def_id`"),
1732-
ret_id,
1733-
)
17341764
} else {
17351765
match decl.output {
17361766
FnRetTy::Ty(ref ty) => {
@@ -2020,6 +2050,36 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
20202050
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
20212051
}
20222052

2053+
// Transforms `-> T` for `async fn` into `-> OpaqueTy { .. }`
2054+
// combined with the following definition of `OpaqueTy`:
2055+
//
2056+
// type OpaqueTy<generics_from_parent_fn> = impl Future<Output = T>;
2057+
//
2058+
// `output`: unlowered output type (`T` in `-> T`)
2059+
// `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition)
2060+
// `opaque_ty_node_id`: `NodeId` of the opaque `impl Trait` type that should be created
2061+
#[instrument(level = "debug", skip(self))]
2062+
fn lower_async_fn_ret_ty_in_trait(
2063+
&mut self,
2064+
output: &FnRetTy,
2065+
fn_node_id: NodeId,
2066+
opaque_ty_node_id: NodeId,
2067+
) -> hir::FnRetTy<'hir> {
2068+
let span = output.span();
2069+
2070+
let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None);
2071+
2072+
let fn_def_id = self.local_def_id(fn_node_id);
2073+
2074+
let kind = self.lower_impl_trait_in_trait(output.span(), opaque_ty_node_id, |lctx| {
2075+
let bound =
2076+
lctx.lower_async_fn_output_type_to_future_bound(output, fn_def_id, output.span());
2077+
arena_vec![lctx; bound]
2078+
});
2079+
let opaque_ty = self.ty(opaque_ty_span, kind);
2080+
hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
2081+
}
2082+
20232083
/// Transforms `-> T` into `Future<Output = T>`.
20242084
fn lower_async_fn_output_type_to_future_bound(
20252085
&mut self,

compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
10361036
| DefKind::Static(..)
10371037
| DefKind::TyAlias
10381038
| DefKind::OpaqueTy
1039+
| DefKind::ImplTraitPlaceholder
10391040
| DefKind::ForeignTy
10401041
| DefKind::Impl
10411042
| DefKind::AssocFn
@@ -1085,6 +1086,7 @@ fn should_encode_const(def_kind: DefKind) -> bool {
10851086
| DefKind::Static(..)
10861087
| DefKind::TyAlias
10871088
| DefKind::OpaqueTy
1089+
| DefKind::ImplTraitPlaceholder
10881090
| DefKind::ForeignTy
10891091
| DefKind::Impl
10901092
| DefKind::AssocFn
@@ -1497,7 +1499,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
14971499
}
14981500
hir::ItemKind::OpaqueTy(..) => {
14991501
self.encode_explicit_item_bounds(def_id);
1500-
EntryKind::OpaqueTy
1502+
}
1503+
hir::ItemKind::ImplTraitPlaceholder(..) => {
1504+
self.encode_explicit_item_bounds(def_id);
15011505
}
15021506
hir::ItemKind::Enum(..) => {
15031507
let adt_def = self.tcx.adt_def(def_id);

0 commit comments

Comments
 (0)