Skip to content

Commit 5762de5

Browse files
authored
Rollup 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 8928eb4 + 09430b7 commit 5762de5

File tree

80 files changed

+1076
-302
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

+1076
-302
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
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
853853
// Lower outside new scope to preserve `is_in_loop_condition`.
854-
let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
854+
let fn_decl = self.lower_fn_decl(decl, None, fn_decl_span, FnDeclKind::Closure, None);
855855

856856
let c = self.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 = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
958+
let fn_decl =
959+
self.lower_fn_decl(&outer_decl, None, fn_decl_span, FnDeclKind::Closure, None);
959960

960961
let c = self.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
@@ -267,7 +267,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
267267
let mut itctx = ImplTraitContext::Universal;
268268
let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| {
269269
let ret_id = asyncness.opt_return_id();
270-
this.lower_fn_decl(&decl, Some(id), FnDeclKind::Fn, ret_id)
270+
this.lower_fn_decl(&decl, Some(id), fn_sig_span, FnDeclKind::Fn, ret_id)
271271
});
272272
let sig = hir::FnSig {
273273
decl,
@@ -659,7 +659,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
659659
self.lower_generics(generics, i.id, &mut itctx, |this| {
660660
(
661661
// Disallow `impl Trait` in foreign items.
662-
this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
662+
this.lower_fn_decl(
663+
fdec,
664+
None,
665+
sig.span,
666+
FnDeclKind::ExternFn,
667+
None,
668+
),
663669
this.lower_fn_params_to_names(fdec),
664670
)
665671
});
@@ -769,9 +775,15 @@ impl<'hir> LoweringContext<'_, 'hir> {
769775
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
770776
}
771777
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
778+
let asyncness = sig.header.asyncness;
772779
let names = self.lower_fn_params_to_names(&sig.decl);
773-
let (generics, sig) =
774-
self.lower_method_sig(generics, sig, i.id, FnDeclKind::Trait, None);
780+
let (generics, sig) = self.lower_method_sig(
781+
generics,
782+
sig,
783+
i.id,
784+
FnDeclKind::Trait,
785+
asyncness.opt_return_id(),
786+
);
775787
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
776788
}
777789
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
@@ -1238,12 +1250,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
12381250
sig: &FnSig,
12391251
id: NodeId,
12401252
kind: FnDeclKind,
1241-
is_async: Option<NodeId>,
1253+
is_async: Option<(NodeId, Span)>,
12421254
) -> (&'hir hir::Generics<'hir>, hir::FnSig<'hir>) {
12431255
let header = self.lower_fn_header(sig.header);
12441256
let mut itctx = ImplTraitContext::Universal;
12451257
let (generics, decl) = self.lower_generics(generics, id, &mut itctx, |this| {
1246-
this.lower_fn_decl(&sig.decl, Some(id), kind, is_async)
1258+
this.lower_fn_decl(&sig.decl, Some(id), sig.span, kind, is_async)
12471259
});
12481260
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
12491261
}

0 commit comments

Comments
 (0)