diff options
Diffstat (limited to 'compiler/rustc_ast_lowering/src/path.rs')
| -rw-r--r-- | compiler/rustc_ast_lowering/src/path.rs | 80 |
1 files changed, 69 insertions, 11 deletions
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 2ab30eff6d8..03c8097e4c3 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -5,6 +5,7 @@ use rustc_hir::def::{DefKind, PartialRes, Res}; use rustc_hir::def_id::DefId; use rustc_hir::GenericArg; use rustc_middle::span_bug; +use rustc_session::parse::add_feature_diagnostics; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, DesugaringKind, Span, Symbol, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; @@ -15,10 +16,9 @@ use super::errors::{ GenericTypeWithParentheses, UseAngleBrackets, }; use super::{ - GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode, - ResolverAstLoweringExt, + AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition, + LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt, }; -use crate::ImplTraitPosition; impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "trace", skip(self))] @@ -28,6 +28,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { qself: &Option<ptr::P<QSelf>>, p: &Path, param_mode: ParamMode, + allow_return_type_notation: AllowReturnTypeNotation, itctx: ImplTraitContext, // modifiers of the impl/bound if this is a trait path modifiers: Option<ast::TraitBoundModifiers>, @@ -103,8 +104,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { { GenericArgsMode::ParenSugar } + Res::Def(DefKind::AssocFn, _) if i + 1 == proj_start => { + match allow_return_type_notation { + AllowReturnTypeNotation::Yes => GenericArgsMode::ReturnTypeNotation, + AllowReturnTypeNotation::No => GenericArgsMode::Err, + } + } // Avoid duplicated errors. - Res::Err => GenericArgsMode::ParenSugar, + Res::Err => GenericArgsMode::Silence, // An error _ => GenericArgsMode::Err, }; @@ -164,11 +171,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // 3. `<<std::vec::Vec<T>>::IntoIter>::Item` // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone` for (i, segment) in p.segments.iter().enumerate().skip(proj_start) { + // If this is a type-dependent `T::method(..)`. + let generic_args_mode = if i + 1 == p.segments.len() + && matches!(allow_return_type_notation, AllowReturnTypeNotation::Yes) + { + GenericArgsMode::ReturnTypeNotation + } else { + GenericArgsMode::Err + }; + let hir_segment = self.arena.alloc(self.lower_path_segment( p.span, segment, param_mode, - GenericArgsMode::Err, + generic_args_mode, itctx, None, )); @@ -238,11 +254,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) } GenericArgs::Parenthesized(data) => match generic_args_mode { - GenericArgsMode::ParenSugar => self.lower_parenthesized_parameter_data( - data, - itctx, - bound_modifier_allowed_features, - ), + GenericArgsMode::ReturnTypeNotation => { + let mut err = if !data.inputs.is_empty() { + self.dcx().create_err(BadReturnTypeNotation::Inputs { + span: data.inputs_span, + }) + } else if let FnRetTy::Ty(ty) = &data.output { + self.dcx().create_err(BadReturnTypeNotation::Output { + span: data.inputs_span.shrink_to_hi().to(ty.span), + }) + } else { + self.dcx().create_err(BadReturnTypeNotation::NeedsDots { + span: data.inputs_span, + }) + }; + if !self.tcx.features().return_type_notation + && self.tcx.sess.is_nightly_build() + { + add_feature_diagnostics( + &mut err, + &self.tcx.sess, + sym::return_type_notation, + ); + } + err.emit(); + ( + GenericArgsCtor { + args: Default::default(), + constraints: &[], + parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation, + span: path_span, + }, + false, + ) + } + GenericArgsMode::ParenSugar | GenericArgsMode::Silence => self + .lower_parenthesized_parameter_data( + data, + itctx, + bound_modifier_allowed_features, + ), GenericArgsMode::Err => { // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>` let sub = if !data.inputs.is_empty() { @@ -279,7 +330,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } }, GenericArgs::ParenthesizedElided(span) => { - self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span }); + match generic_args_mode { + GenericArgsMode::ReturnTypeNotation | GenericArgsMode::Silence => { + // Ok + } + GenericArgsMode::ParenSugar | GenericArgsMode::Err => { + self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span }); + } + } ( GenericArgsCtor { args: Default::default(), |
