@@ -5,6 +5,7 @@ use rustc_hir::def::{DefKind, PartialRes, Res};
55use rustc_hir:: def_id:: DefId ;
66use rustc_hir:: GenericArg ;
77use rustc_middle:: span_bug;
8+ use rustc_session:: parse:: add_feature_diagnostics;
89use rustc_span:: symbol:: { kw, sym, Ident } ;
910use rustc_span:: { BytePos , DesugaringKind , Span , Symbol , DUMMY_SP } ;
1011use smallvec:: { smallvec, SmallVec } ;
@@ -15,10 +16,9 @@ use super::errors::{
1516 GenericTypeWithParentheses , UseAngleBrackets ,
1617} ;
1718use super :: {
18- GenericArgsCtor , GenericArgsMode , ImplTraitContext , LifetimeRes , LoweringContext , ParamMode ,
19- ResolverAstLoweringExt ,
19+ AllowReturnTypeNotation , GenericArgsCtor , GenericArgsMode , ImplTraitContext , ImplTraitPosition ,
20+ LifetimeRes , LoweringContext , ParamMode , ResolverAstLoweringExt ,
2021} ;
21- use crate :: ImplTraitPosition ;
2222
2323impl < ' a , ' hir > LoweringContext < ' a , ' hir > {
2424 #[ instrument( level = "trace" , skip( self ) ) ]
@@ -28,6 +28,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2828 qself : & Option < ptr:: P < QSelf > > ,
2929 p : & Path ,
3030 param_mode : ParamMode ,
31+ allow_return_type_notation : AllowReturnTypeNotation ,
3132 itctx : ImplTraitContext ,
3233 // modifiers of the impl/bound if this is a trait path
3334 modifiers : Option < ast:: TraitBoundModifiers > ,
@@ -103,8 +104,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
103104 {
104105 GenericArgsMode :: ParenSugar
105106 }
107+ Res :: Def ( DefKind :: AssocFn , _) if i + 1 == proj_start => {
108+ match allow_return_type_notation {
109+ AllowReturnTypeNotation :: Yes => GenericArgsMode :: ReturnTypeNotation ,
110+ AllowReturnTypeNotation :: No => GenericArgsMode :: Err ,
111+ }
112+ }
106113 // Avoid duplicated errors.
107- Res :: Err => GenericArgsMode :: ParenSugar ,
114+ Res :: Err => GenericArgsMode :: Silence ,
108115 // An error
109116 _ => GenericArgsMode :: Err ,
110117 } ;
@@ -164,11 +171,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
164171 // 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
165172 // * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
166173 for ( i, segment) in p. segments . iter ( ) . enumerate ( ) . skip ( proj_start) {
174+ // If this is a type-dependent `T::method(..)`.
175+ let generic_args_mode = if i + 1 == p. segments . len ( )
176+ && matches ! ( allow_return_type_notation, AllowReturnTypeNotation :: Yes )
177+ {
178+ GenericArgsMode :: ReturnTypeNotation
179+ } else {
180+ GenericArgsMode :: Err
181+ } ;
182+
167183 let hir_segment = self . arena . alloc ( self . lower_path_segment (
168184 p. span ,
169185 segment,
170186 param_mode,
171- GenericArgsMode :: Err ,
187+ generic_args_mode ,
172188 itctx,
173189 None ,
174190 ) ) ;
@@ -238,11 +254,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
238254 self . lower_angle_bracketed_parameter_data ( data, param_mode, itctx)
239255 }
240256 GenericArgs :: Parenthesized ( data) => match generic_args_mode {
241- GenericArgsMode :: ParenSugar => self . lower_parenthesized_parameter_data (
242- data,
243- itctx,
244- bound_modifier_allowed_features,
245- ) ,
257+ GenericArgsMode :: ReturnTypeNotation => {
258+ let mut err = if !data. inputs . is_empty ( ) {
259+ self . dcx ( ) . create_err ( BadReturnTypeNotation :: Inputs {
260+ span : data. inputs_span ,
261+ } )
262+ } else if let FnRetTy :: Ty ( ty) = & data. output {
263+ self . dcx ( ) . create_err ( BadReturnTypeNotation :: Output {
264+ span : data. inputs_span . shrink_to_hi ( ) . to ( ty. span ) ,
265+ } )
266+ } else {
267+ self . dcx ( ) . create_err ( BadReturnTypeNotation :: NeedsDots {
268+ span : data. inputs_span ,
269+ } )
270+ } ;
271+ if !self . tcx . features ( ) . return_type_notation
272+ && self . tcx . sess . is_nightly_build ( )
273+ {
274+ add_feature_diagnostics (
275+ & mut err,
276+ & self . tcx . sess ,
277+ sym:: return_type_notation,
278+ ) ;
279+ }
280+ err. emit ( ) ;
281+ (
282+ GenericArgsCtor {
283+ args : Default :: default ( ) ,
284+ constraints : & [ ] ,
285+ parenthesized : hir:: GenericArgsParentheses :: ReturnTypeNotation ,
286+ span : path_span,
287+ } ,
288+ false ,
289+ )
290+ }
291+ GenericArgsMode :: ParenSugar | GenericArgsMode :: Silence => self
292+ . lower_parenthesized_parameter_data (
293+ data,
294+ itctx,
295+ bound_modifier_allowed_features,
296+ ) ,
246297 GenericArgsMode :: Err => {
247298 // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
248299 let sub = if !data. inputs . is_empty ( ) {
@@ -279,7 +330,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
279330 }
280331 } ,
281332 GenericArgs :: ParenthesizedElided ( span) => {
282- self . dcx ( ) . emit_err ( BadReturnTypeNotation :: Position { span : * span } ) ;
333+ match generic_args_mode {
334+ GenericArgsMode :: ReturnTypeNotation | GenericArgsMode :: Silence => {
335+ // Ok
336+ }
337+ GenericArgsMode :: ParenSugar | GenericArgsMode :: Err => {
338+ self . dcx ( ) . emit_err ( BadReturnTypeNotation :: Position { span : * span } ) ;
339+ }
340+ }
283341 (
284342 GenericArgsCtor {
285343 args : Default :: default ( ) ,
0 commit comments