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:
Josh Stone 2022-12-06 17:53:50 -08:00
parent b28d30e1e3
commit e9dd59131b
3 changed files with 40 additions and 17 deletions

View File

@ -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),

View File

@ -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))

View File

@ -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