Add help for #![feature(impl_trait_in_fn_trait_return)]
This adds a new variant `ImplTraitContext::FeatureGated`, so we can generalize the help for `return_position_impl_trait_in_trait` to also work for `impl_trait_in_fn_trait_return`.
This commit is contained in:
parent
b28d30e1e3
commit
e9dd59131b
@ -259,6 +259,8 @@ enum ImplTraitContext {
|
||||
},
|
||||
/// Impl trait in type aliases.
|
||||
TypeAliasesOpaqueTy,
|
||||
/// `impl Trait` is unstably accepted in this position.
|
||||
FeatureGated(ImplTraitPosition, Symbol),
|
||||
/// `impl Trait` is not accepted in this position.
|
||||
Disallowed(ImplTraitPosition),
|
||||
}
|
||||
@ -1372,17 +1374,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
}
|
||||
path
|
||||
}
|
||||
ImplTraitContext::Disallowed(
|
||||
position @ (ImplTraitPosition::TraitReturn | ImplTraitPosition::ImplReturn),
|
||||
) => {
|
||||
ImplTraitContext::FeatureGated(position, feature) => {
|
||||
self.tcx
|
||||
.sess
|
||||
.create_feature_err(
|
||||
MisplacedImplTrait {
|
||||
span: t.span,
|
||||
position: DiagnosticArgFromDisplay(&position),
|
||||
position: DiagnosticArgFromDisplay(position),
|
||||
},
|
||||
sym::return_position_impl_trait_in_trait,
|
||||
*feature,
|
||||
)
|
||||
.emit();
|
||||
hir::TyKind::Err
|
||||
@ -1390,7 +1390,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
ImplTraitContext::Disallowed(position) => {
|
||||
self.tcx.sess.emit_err(MisplacedImplTrait {
|
||||
span: t.span,
|
||||
position: DiagnosticArgFromDisplay(&position),
|
||||
position: DiagnosticArgFromDisplay(position),
|
||||
});
|
||||
hir::TyKind::Err
|
||||
}
|
||||
@ -1739,14 +1739,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
} else {
|
||||
match &decl.output {
|
||||
FnRetTy::Ty(ty) => {
|
||||
let mut context = if kind.return_impl_trait_allowed(self.tcx) {
|
||||
let context = if kind.return_impl_trait_allowed(self.tcx) {
|
||||
let fn_def_id = self.local_def_id(fn_node_id);
|
||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||
in_trait: matches!(kind, FnDeclKind::Trait),
|
||||
}
|
||||
} else {
|
||||
ImplTraitContext::Disallowed(match kind {
|
||||
let position = match kind {
|
||||
FnDeclKind::Fn | FnDeclKind::Inherent => {
|
||||
unreachable!("fn should allow in-band lifetimes")
|
||||
}
|
||||
@ -1755,9 +1755,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
|
||||
FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
|
||||
FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
|
||||
})
|
||||
};
|
||||
match kind {
|
||||
FnDeclKind::Trait | FnDeclKind::Impl => ImplTraitContext::FeatureGated(
|
||||
position,
|
||||
sym::return_position_impl_trait_in_trait,
|
||||
),
|
||||
_ => ImplTraitContext::Disallowed(position),
|
||||
}
|
||||
};
|
||||
hir::FnRetTy::Return(self.lower_ty(ty, &mut context))
|
||||
hir::FnRetTy::Return(self.lower_ty(ty, &context))
|
||||
}
|
||||
FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
|
||||
}
|
||||
@ -1938,7 +1945,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
output,
|
||||
span,
|
||||
if in_trait && !this.tcx.features().return_position_impl_trait_in_trait {
|
||||
ImplTraitContext::Disallowed(ImplTraitPosition::TraitReturn)
|
||||
ImplTraitContext::FeatureGated(
|
||||
ImplTraitPosition::TraitReturn,
|
||||
sym::return_position_impl_trait_in_trait,
|
||||
)
|
||||
} else {
|
||||
ImplTraitContext::ReturnPositionOpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
|
||||
|
@ -9,7 +9,7 @@ use rustc_ast::{self as ast, *};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, PartialRes, Res};
|
||||
use rustc_hir::GenericArg;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
@ -352,11 +352,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// fn f(_: impl Fn() -> impl Debug) -> impl Fn() -> impl Debug
|
||||
// // disallowed --^^^^^^^^^^ allowed --^^^^^^^^^^
|
||||
// ```
|
||||
FnRetTy::Ty(ty)
|
||||
if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. })
|
||||
&& self.tcx.features().impl_trait_in_fn_trait_return =>
|
||||
{
|
||||
self.lower_ty(&ty, itctx)
|
||||
FnRetTy::Ty(ty) if matches!(itctx, ImplTraitContext::ReturnPositionOpaqueTy { .. }) => {
|
||||
if self.tcx.features().impl_trait_in_fn_trait_return {
|
||||
self.lower_ty(&ty, itctx)
|
||||
} else {
|
||||
self.lower_ty(
|
||||
&ty,
|
||||
&ImplTraitContext::FeatureGated(
|
||||
ImplTraitPosition::FnTraitReturn,
|
||||
sym::impl_trait_in_fn_trait_return,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
FnRetTy::Ty(ty) => {
|
||||
self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
|
||||
|
@ -3,12 +3,18 @@ error[E0562]: `impl Trait` only allowed in function and inherent method return t
|
||||
|
|
||||
LL | fn f() -> impl Fn() -> impl Sized { || () }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information
|
||||
= help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable
|
||||
|
||||
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return
|
||||
--> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32
|
||||
|
|
||||
LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () }
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information
|
||||
= help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user