1
Fork 0

Add more information to impl Trait deny error

This commit is contained in:
Michael Goulet 2022-01-11 19:00:34 -08:00
parent 73a7423e77
commit f04f732503
34 changed files with 487 additions and 210 deletions

View file

@ -97,7 +97,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let ty = l
.ty
.as_ref()
.map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
.map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
let init = l.kind.init().map(|init| self.lower_expr(init));
let hir_id = self.lower_node_id(l.id);
let pat = self.lower_pat(&l.pat);
@ -127,7 +127,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let ty = local
.ty
.as_ref()
.map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Binding)));
.map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
let span = self.lower_span(local.span);
let span = self.mark_span_with_reason(DesugaringKind::LetElse, span, None);
let init = self.lower_expr(init);

View file

@ -1,3 +1,5 @@
use crate::{FnDeclKind, ImplTraitPosition};
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
use rustc_ast::attr;
@ -53,7 +55,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
ParamMode::Optional,
0,
ParenthesizedGenericArgs::Err,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
));
let args = self.lower_exprs(args);
hir::ExprKind::MethodCall(hir_seg, args, self.lower_span(span))
@ -74,12 +76,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
ExprKind::Cast(ref expr, ref ty) => {
let expr = self.lower_expr(expr);
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
let ty =
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
hir::ExprKind::Cast(expr, ty)
}
ExprKind::Type(ref expr, ref ty) => {
let expr = self.lower_expr(expr);
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
let ty =
self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
hir::ExprKind::Type(expr, ty)
}
ExprKind::AddrOf(k, m, ref ohs) => {
@ -203,7 +207,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
hir::ExprKind::Path(qpath)
}
@ -239,7 +243,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&se.qself,
&se.path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
)),
self.arena
.alloc_from_iter(se.fields.iter().map(|x| self.lower_expr_field(x))),
@ -538,7 +542,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
) -> hir::ExprKind<'hir> {
let output = match ret_ty {
Some(ty) => hir::FnRetTy::Return(self.lower_ty(&ty, ImplTraitContext::disallowed())),
Some(ty) => hir::FnRetTy::Return(
self.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)),
),
None => hir::FnRetTy::DefaultReturn(self.lower_span(span)),
};
@ -827,7 +833,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
});
// Lower outside new scope to preserve `is_in_loop_condition`.
let fn_decl = self.lower_fn_decl(decl, None, false, None);
let fn_decl = self.lower_fn_decl(decl, None, FnDeclKind::Closure, None);
hir::ExprKind::Closure(
capture_clause,
@ -919,7 +925,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// We need to lower the declaration outside the new scope, because we
// have to conserve the state of being inside a loop condition for the
// closure argument types.
let fn_decl = self.lower_fn_decl(&outer_decl, None, false, None);
let fn_decl = self.lower_fn_decl(&outer_decl, None, FnDeclKind::Closure, None);
hir::ExprKind::Closure(
capture_clause,
@ -1064,7 +1070,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
// Destructure like a tuple struct.
let tuple_struct_pat =
@ -1089,7 +1095,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&se.qself,
&se.path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
let fields_omitted = match &se.rest {
StructRest::Base(e) => {

View file

@ -1,6 +1,6 @@
use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
use super::{ImplTraitContext, ImplTraitPosition};
use crate::Arena;
use crate::{Arena, FnDeclKind};
use rustc_ast::ptr::P;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
@ -246,7 +246,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
AnonymousLifetimeMode::PassThrough,
|this, idty| {
let ret_id = asyncness.opt_return_id();
this.lower_fn_decl(&decl, Some((fn_def_id, idty)), true, ret_id)
this.lower_fn_decl(
&decl,
Some((fn_def_id, idty)),
FnDeclKind::Fn,
ret_id,
)
},
);
let sig = hir::FnSig {
@ -287,12 +292,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
capturable_lifetimes: &mut FxHashSet::default(),
},
);
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let generics = self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
);
hir::ItemKind::TyAlias(ty, generics)
}
ItemKind::TyAlias(box TyAlias { ref generics, ty: None, .. }) => {
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let generics = self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
);
hir::ItemKind::TyAlias(ty, generics)
}
ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
@ -301,20 +312,29 @@ impl<'hir> LoweringContext<'_, 'hir> {
enum_definition.variants.iter().map(|x| self.lower_variant(x)),
),
},
self.lower_generics(generics, ImplTraitContext::disallowed()),
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
),
ItemKind::Struct(ref struct_def, ref generics) => {
let struct_def = self.lower_variant_data(hir_id, struct_def);
hir::ItemKind::Struct(
struct_def,
self.lower_generics(generics, ImplTraitContext::disallowed()),
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
)
}
ItemKind::Union(ref vdata, ref generics) => {
let vdata = self.lower_variant_data(hir_id, vdata);
hir::ItemKind::Union(
vdata,
self.lower_generics(generics, ImplTraitContext::disallowed()),
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
)
}
ItemKind::Impl(box Impl {
@ -347,10 +367,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
AnonymousLifetimeMode::CreateParameter,
|this, _| {
let trait_ref = trait_ref.as_ref().map(|trait_ref| {
this.lower_trait_ref(trait_ref, ImplTraitContext::disallowed())
this.lower_trait_ref(
trait_ref,
ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
)
});
let lowered_ty = this.lower_ty(ty, ImplTraitContext::disallowed());
let lowered_ty = this
.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
(trait_ref, lowered_ty)
},
@ -390,21 +414,33 @@ impl<'hir> LoweringContext<'_, 'hir> {
ref bounds,
ref items,
}) => {
let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed());
let bounds = self.lower_param_bounds(
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
);
let items = self
.arena
.alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item)));
hir::ItemKind::Trait(
is_auto,
self.lower_unsafety(unsafety),
self.lower_generics(generics, ImplTraitContext::disallowed()),
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
bounds,
items,
)
}
ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemKind::TraitAlias(
self.lower_generics(generics, ImplTraitContext::disallowed()),
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
self.lower_param_bounds(
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
),
ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => {
let body = P(self.lower_mac_args(body));
@ -423,7 +459,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: Span,
body: Option<&Expr>,
) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Binding));
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
(ty, self.lower_const_body(span, body))
}
@ -667,7 +703,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|this, _| {
(
// Disallow `impl Trait` in foreign items.
this.lower_fn_decl(fdec, None, false, None),
this.lower_fn_decl(fdec, None, FnDeclKind::ExternFn, None),
this.lower_fn_params_to_names(fdec),
)
},
@ -676,7 +712,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
}
ForeignItemKind::Static(ref t, m, _) => {
let ty = self.lower_ty(t, ImplTraitContext::disallowed());
let ty =
self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
hir::ForeignItemKind::Static(ty, m)
}
ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
@ -744,11 +781,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
qself,
path,
ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
self.arena.alloc(t)
} else {
self.lower_ty(&f.ty, ImplTraitContext::disallowed())
self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
};
let hir_id = self.lower_node_id(f.id);
self.lower_attrs(hir_id, &f.attrs);
@ -771,14 +808,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, kind) = match i.kind {
AssocItemKind::Const(_, ref ty, ref default) => {
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body))
}
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
let names = self.lower_fn_params_to_names(&sig.decl);
let (generics, sig) =
self.lower_method_sig(generics, sig, trait_item_def_id, false, None);
let (generics, sig) = self.lower_method_sig(
generics,
sig,
trait_item_def_id,
FnDeclKind::Trait,
None,
);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)))
}
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
@ -789,16 +831,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
sig,
trait_item_def_id,
false,
FnDeclKind::Trait,
asyncness.opt_return_id(),
);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)))
}
AssocItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => {
let ty = ty.as_ref().map(|x| self.lower_ty(x, ImplTraitContext::disallowed()));
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let ty = ty.as_ref().map(|x| {
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
});
let generics = self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
);
let kind = hir::TraitItemKind::Type(
self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
self.lower_param_bounds(
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
ty,
);
@ -850,7 +900,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let (generics, kind) = match &i.kind {
AssocItemKind::Const(_, ty, expr) => {
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
(
hir::Generics::empty(),
hir::ImplItemKind::Const(ty, self.lower_const_body(i.span, expr.as_deref())),
@ -861,19 +911,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
let asyncness = sig.header.asyncness;
let body_id =
self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref());
let impl_trait_return_allow = !self.is_in_trait_impl;
let (generics, sig) = self.lower_method_sig(
generics,
sig,
impl_item_def_id,
impl_trait_return_allow,
if self.is_in_trait_impl { FnDeclKind::Impl } else { FnDeclKind::Inherent },
asyncness.opt_return_id(),
);
(generics, hir::ImplItemKind::Fn(sig, body_id))
}
AssocItemKind::TyAlias(box TyAlias { generics, ty, .. }) => {
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
let generics = self.lower_generics(
generics,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
);
let kind = match ty {
None => {
let ty = self.arena.alloc(self.ty(i.span, hir::TyKind::Err));
@ -1248,7 +1300,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics: &Generics,
sig: &FnSig,
fn_def_id: LocalDefId,
impl_trait_return_allow: bool,
kind: FnDeclKind,
is_async: Option<NodeId>,
) -> (hir::Generics<'hir>, hir::FnSig<'hir>) {
let header = self.lower_fn_header(sig.header);
@ -1256,14 +1308,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics,
fn_def_id,
AnonymousLifetimeMode::PassThrough,
|this, idty| {
this.lower_fn_decl(
&sig.decl,
Some((fn_def_id, idty)),
impl_trait_return_allow,
is_async,
)
},
|this, idty| this.lower_fn_decl(&sig.decl, Some((fn_def_id, idty)), kind, is_async),
);
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
}
@ -1409,11 +1454,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
span,
}) => self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
bound_generic_params: this
.lower_generic_params(bound_generic_params, ImplTraitContext::disallowed()),
bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
bound_generic_params: this.lower_generic_params(
bound_generic_params,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
bounded_ty: this.lower_ty(
bounded_ty,
ImplTraitContext::Disallowed(ImplTraitPosition::Type),
),
bounds: this.arena.alloc_from_iter(bounds.iter().map(|bound| {
this.lower_param_bound(bound, ImplTraitContext::disallowed())
this.lower_param_bound(
bound,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
)
})),
span: this.lower_span(span),
})
@ -1425,13 +1478,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
}) => hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
span: self.lower_span(span),
lifetime: self.lower_lifetime(lifetime),
bounds: self.lower_param_bounds(bounds, ImplTraitContext::disallowed()),
bounds: self.lower_param_bounds(
bounds,
ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
),
}),
WherePredicate::EqPredicate(WhereEqPredicate { id, ref lhs_ty, ref rhs_ty, span }) => {
hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
hir_id: self.lower_node_id(id),
lhs_ty: self.lower_ty(lhs_ty, ImplTraitContext::disallowed()),
rhs_ty: self.lower_ty(rhs_ty, ImplTraitContext::disallowed()),
lhs_ty: self
.lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
rhs_ty: self
.lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)),
span: self.lower_span(span),
})
}

View file

@ -256,19 +256,28 @@ enum ImplTraitContext<'b, 'a> {
/// Position in which `impl Trait` is disallowed.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum ImplTraitPosition {
/// Disallowed in `let` / `const` / `static` bindings.
Binding,
/// All other positions.
Other,
Path,
Variable,
Type,
Trait,
AsyncBlock,
Bound,
Generic,
ExternFnParam,
ClosureParam,
PointerParam,
FnTraitParam,
TraitParam,
ImplParam,
ExternFnReturn,
ClosureReturn,
PointerReturn,
FnTraitReturn,
TraitReturn,
ImplReturn,
}
impl<'a> ImplTraitContext<'_, 'a> {
#[inline]
fn disallowed() -> Self {
ImplTraitContext::Disallowed(ImplTraitPosition::Other)
}
fn reborrow<'this>(&'this mut self) -> ImplTraitContext<'this, 'a> {
use self::ImplTraitContext::*;
match self {
@ -284,6 +293,54 @@ impl<'a> ImplTraitContext<'_, 'a> {
}
}
impl std::fmt::Display for ImplTraitPosition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let name = match self {
ImplTraitPosition::Path => "path",
ImplTraitPosition::Variable => "variable",
ImplTraitPosition::Type => "type",
ImplTraitPosition::Trait => "trait",
ImplTraitPosition::AsyncBlock => "async block",
ImplTraitPosition::Bound => "bound",
ImplTraitPosition::Generic => "generic",
ImplTraitPosition::ExternFnParam => "`extern fn` param",
ImplTraitPosition::ClosureParam => "closure param",
ImplTraitPosition::PointerParam => "`fn` pointer param",
ImplTraitPosition::FnTraitParam => "`Fn` trait param",
ImplTraitPosition::TraitParam => "trait method param",
ImplTraitPosition::ImplParam => "`impl` method param",
ImplTraitPosition::ExternFnReturn => "`extern fn` return",
ImplTraitPosition::ClosureReturn => "closure return",
ImplTraitPosition::PointerReturn => "`fn` pointer return",
ImplTraitPosition::FnTraitReturn => "`Fn` trait return",
ImplTraitPosition::TraitReturn => "trait method return",
ImplTraitPosition::ImplReturn => "`impl` method return",
};
write!(f, "{}", name)
}
}
#[derive(Debug)]
enum FnDeclKind {
Fn,
Inherent,
ExternFn,
Closure,
Pointer,
Trait,
Impl,
}
impl FnDeclKind {
fn impl_trait_return_allowed(&self) -> bool {
match self {
FnDeclKind::Fn | FnDeclKind::Inherent => true,
_ => false,
}
}
}
pub fn lower_crate<'a, 'hir>(
sess: &'a Session,
krate: &'a Crate,
@ -1232,11 +1289,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
generic_params: this.lower_generic_params(
&f.generic_params,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
),
unsafety: this.lower_unsafety(f.unsafety),
abi: this.lower_extern(f.ext),
decl: this.lower_fn_decl(&f.decl, None, false, None),
decl: this.lower_fn_decl(&f.decl, None, FnDeclKind::Pointer, None),
param_names: this.lower_fn_params_to_names(&f.decl),
}))
})
@ -1357,14 +1414,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}),
))
}
ImplTraitContext::Disallowed(_) => {
ImplTraitContext::Disallowed(position) => {
let mut err = struct_span_err!(
self.sess,
t.span,
E0562,
"`impl Trait` not allowed outside of {}",
"function and method return types",
"`impl Trait` not allowed outside of \
function and inherent method return types",
);
err.note(&format!("found `impl Trait` in {}", position));
err.emit();
hir::TyKind::Err
}
@ -1528,16 +1586,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&mut self,
decl: &FnDecl,
mut in_band_ty_params: Option<(LocalDefId, &mut Vec<hir::GenericParam<'hir>>)>,
impl_trait_return_allow: bool,
kind: FnDeclKind,
make_ret_async: Option<NodeId>,
) -> &'hir hir::FnDecl<'hir> {
debug!(
"lower_fn_decl(\
fn_decl: {:?}, \
in_band_ty_params: {:?}, \
impl_trait_return_allow: {}, \
kind: {:?}, \
make_ret_async: {:?})",
decl, in_band_ty_params, impl_trait_return_allow, make_ret_async,
decl, in_band_ty_params, kind, make_ret_async,
);
let lt_mode = if make_ret_async.is_some() {
// In `async fn`, argument-position elided lifetimes
@ -1567,7 +1625,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::Universal(ibty, this.current_hir_id_owner),
)
} else {
this.lower_ty_direct(&param.ty, ImplTraitContext::disallowed())
this.lower_ty_direct(
&param.ty,
ImplTraitContext::Disallowed(match kind {
FnDeclKind::Fn | FnDeclKind::Inherent => {
unreachable!("fn should allow in-band lifetimes")
}
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnParam,
FnDeclKind::Closure => ImplTraitPosition::ClosureParam,
FnDeclKind::Pointer => ImplTraitPosition::PointerParam,
FnDeclKind::Trait => ImplTraitPosition::TraitParam,
FnDeclKind::Impl => ImplTraitPosition::ImplParam,
}),
)
}
}))
});
@ -1582,13 +1652,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
match decl.output {
FnRetTy::Ty(ref ty) => {
let context = match in_band_ty_params {
Some((def_id, _)) if impl_trait_return_allow => {
Some((def_id, _)) if kind.impl_trait_return_allowed() => {
ImplTraitContext::ReturnPositionOpaqueTy {
fn_def_id: def_id,
origin: hir::OpaqueTyOrigin::FnReturn(def_id),
}
}
_ => ImplTraitContext::disallowed(),
_ => ImplTraitContext::Disallowed(match kind {
FnDeclKind::Fn | FnDeclKind::Inherent => {
unreachable!("fn should allow in-band lifetimes")
}
FnDeclKind::ExternFn => ImplTraitPosition::ExternFnReturn,
FnDeclKind::Closure => ImplTraitPosition::ClosureReturn,
FnDeclKind::Pointer => ImplTraitPosition::PointerReturn,
FnDeclKind::Trait => ImplTraitPosition::TraitReturn,
FnDeclKind::Impl => ImplTraitPosition::ImplReturn,
}),
};
hir::FnRetTy::Return(self.lower_ty(ty, context))
}
@ -1915,7 +1994,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
GenericParamKind::Type { ref default, .. } => {
let kind = hir::GenericParamKind::Type {
default: default.as_ref().map(|x| {
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Other))
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
}),
synthetic: false,
};
@ -1923,9 +2002,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
(hir::ParamName::Plain(self.lower_ident(param.ident)), kind)
}
GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
let ty = self
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
this.lower_ty(&ty, ImplTraitContext::disallowed())
let ty =
self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
this.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type))
});
let default = default.as_ref().map(|def| self.lower_anon_const(def));
(

View file

@ -1,3 +1,5 @@
use crate::ImplTraitPosition;
use super::{ImplTraitContext, LoweringContext, ParamMode};
use rustc_ast::ptr::P;
@ -33,7 +35,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself,
path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
break hir::PatKind::TupleStruct(qpath, pats, ddpos);
@ -49,7 +51,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself,
path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
break hir::PatKind::Path(qpath);
}
@ -59,7 +61,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
qself,
path,
ParamMode::Optional,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
let fs = self.arena.alloc_from_iter(fields.iter().map(|f| hir::PatField {

View file

@ -1,3 +1,5 @@
use crate::ImplTraitPosition;
use super::{AnonymousLifetimeMode, ImplTraitContext, LoweringContext, ParamMode};
use super::{GenericArgsCtor, ParenthesizedGenericArgs};
@ -184,7 +186,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
param_mode,
0,
ParenthesizedGenericArgs::Err,
ImplTraitContext::disallowed(),
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
)
})),
span: self.lower_span(p.span),
@ -392,11 +394,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// we generally don't permit such things (see #51008).
self.with_anonymous_lifetime_mode(AnonymousLifetimeMode::PassThrough, |this| {
let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
let inputs = this.arena.alloc_from_iter(
inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())),
);
let inputs = this.arena.alloc_from_iter(inputs.iter().map(|ty| {
this.lower_ty_direct(
ty,
ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam),
)
}));
let output_ty = match output {
FnRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
FnRetTy::Ty(ty) => this
.lower_ty(&ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn)),
FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(*span, &[])),
};
let args = smallvec![GenericArg::Type(this.ty_tup(*inputs_span, inputs))];