From f04f732503a239b3fac22be2238d21971aa03dce Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 11 Jan 2022 19:00:34 -0800 Subject: Add more information to `impl Trait` deny error --- compiler/rustc_ast_lowering/src/block.rs | 4 +- compiler/rustc_ast_lowering/src/expr.rs | 26 +++--- compiler/rustc_ast_lowering/src/item.rs | 148 +++++++++++++++++++++---------- compiler/rustc_ast_lowering/src/lib.rs | 129 +++++++++++++++++++++------ compiler/rustc_ast_lowering/src/pat.rs | 8 +- compiler/rustc_ast_lowering/src/path.rs | 16 ++-- 6 files changed, 241 insertions(+), 90 deletions(-) (limited to 'compiler/rustc_ast_lowering/src') diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs index 082c5bb7833..3a7e0a70585 100644 --- a/compiler/rustc_ast_lowering/src/block.rs +++ b/compiler/rustc_ast_lowering/src/block.rs @@ -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); diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 17bc8d7591b..d48ff10b97d 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -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) => { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index f48cf212a98..6489c729cfe 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -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, ) -> (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), }) } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 60b5aeb52b1..803c93c259e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -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>)>, - impl_trait_return_allow: bool, + kind: FnDeclKind, make_ret_async: Option, ) -> &'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(¶m.ty, ImplTraitContext::disallowed()) + this.lower_ty_direct( + ¶m.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)); ( diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index ebae7798433..2c331767b89 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -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 { diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 79262235cd9..b35e3a07161 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -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))]; -- cgit 1.4.1-3-g733a5