Skip to content

Commit ab32548

Browse files
committed
Auto merge of #101224 - compiler-errors:rpitit, r=oli-obk
Initial implementation of return-position `impl Trait` in traits * Create a new item kind, called `ImplTraitPlaceholder`, which is used to lower `ast::TyKind::ImplTrait` in trait method returns. * This item is the child of the trait method, which simplifies the way we calculate bounds and stuff. * Use the def-id of this type to construct a projection type that we use during astconv for the return type of the trait method signature. * Implement logic to normalize this `ImplTraitPlaceholder` projection type when we know its concrete impl (this is pretty limited currently, but really there are no other selection candidates that make sense -- for now!) * Check that the `impl Trait`'s bounds are satisfied on the concrete type provided in the impl. This is obviously nowhere near complete, but I wanted to at least get some initial support landed so we can start playing around with it. What works: * async fn in trait and RPITIT, including multiple `impl Trait`s and `impl Trait` nested in associated type bindings, like `impl Future<Output = impl Sized>`
2 parents 7200da0 + 6876c94 commit ab32548

File tree

80 files changed

+1078
-304
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+1078
-304
lines changed

compiler/rustc_ast/src/ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2367,9 +2367,9 @@ impl Async {
23672367
}
23682368

23692369
/// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
2370-
pub fn opt_return_id(self) -> Option<NodeId> {
2370+
pub fn opt_return_id(self) -> Option<(NodeId, Span)> {
23712371
match self {
2372-
Async::Yes { return_impl_trait_id, .. } => Some(return_impl_trait_id),
2372+
Async::Yes { return_impl_trait_id, span, .. } => Some((return_impl_trait_id, span)),
23732373
Async::No => None,
23742374
}
23752375
}

compiler/rustc_ast_lowering/src/errors.rs

+11
Original file line numberDiff line numberDiff line change
@@ -334,3 +334,14 @@ pub struct InclusiveRangeWithNoEnd {
334334
#[primary_span]
335335
pub span: Span,
336336
}
337+
338+
#[derive(SessionDiagnostic, Clone, Copy)]
339+
#[diag(ast_lowering::trait_fn_async, code = "E0706")]
340+
#[note]
341+
#[note(ast_lowering::note2)]
342+
pub struct TraitFnAsync {
343+
#[primary_span]
344+
pub fn_span: Span,
345+
#[label]
346+
pub span: Span,
347+
}

compiler/rustc_ast_lowering/src/expr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
851851

852852
self.lower_lifetime_binder(closure_id, generic_params, |lctx, bound_generic_params| {
853853
// Lower outside new scope to preserve `is_in_loop_condition`.
854-
let fn_decl = lctx.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
854+
let fn_decl = lctx.lower_fn_decl(decl, None, fn_decl_span, FnDeclKind::Closure, None);
855855

856856
let c = lctx.arena.alloc(hir::Closure {
857857
binder: binder_clause,
@@ -955,7 +955,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
955955
// We need to lower the declaration outside the new scope, because we
956956
// have to conserve the state of being inside a loop condition for the
957957
// closure argument types.
958-
let fn_decl = lctx.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
958+
let fn_decl =
959+
lctx.lower_fn_decl(&outer_decl, None, fn_decl_span, FnDeclKind::Closure, None);
959960

960961
let c = lctx.arena.alloc(hir::Closure {
961962
binder: binder_clause,

compiler/rustc_ast_lowering/src/item.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
269269
let mut itctx = ImplTraitContext::Universal;
270270
let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| {
271271
let ret_id = asyncness.opt_return_id();
272-
this.lower_fn_decl(&decl, Some(id), FnDeclKind::Fn, ret_id)
272+
this.lower_fn_decl(&decl, Some(id), fn_sig_span, FnDeclKind::Fn, ret_id)
273273
});
274274
let sig = hir::FnSig {
275275
decl,
@@ -661,7 +661,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
661661
self.lower_generics(generics, i.id, &mut itctx, |this| {
662662
(
663663
// Disallow `impl Trait` in foreign items.
664-
this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
664+
this.lower_fn_decl(
665+
fdec,
666+
None,
667+
sig.span,
668+
FnDeclKind::ExternFn,
669+
None,
670+
),
665671
this.lower_fn_params_to_names(fdec),
666672
)
667673
});
@@ -771,9 +777,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
771777
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
772778
}
773779
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
780+
let asyncness = sig.header.asyncness;
774781
let names = self.lower_fn_params_to_names(&sig.decl);
775-
let (generics, sig) =
776-
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+
);
777789
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
778790
}
779791
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
@@ -1240,12 +1252,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
12401252
sig: &FnSig,
12411253
id: NodeId,
12421254
kind: FnDeclKind,
1243-
is_async: Option<NodeId>,
1255+
is_async: Option<(NodeId, Span)>,
12441256
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
12451257
let header = self.lower_fn_header(sig.header);
12461258
let mut itctx = ImplTraitContext::Universal;
12471259
let (generics, decl) = self.lower_generics(generics, id, &mut itctx, |this| {
1248-
this.lower_fn_decl(&sig.decl, Some(id), kind, is_async)
1260+
this.lower_fn_decl(&sig.decl, Some(id), sig.span, kind, is_async)
12491261
});
12501262
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
12511263
}

0 commit comments

Comments
 (0)