@@ -5,6 +5,7 @@ use rustc_hir::def::{DefKind, PartialRes, Res};
5
5
use rustc_hir:: def_id:: DefId ;
6
6
use rustc_hir:: GenericArg ;
7
7
use rustc_middle:: span_bug;
8
+ use rustc_session:: parse:: add_feature_diagnostics;
8
9
use rustc_span:: symbol:: { kw, sym, Ident } ;
9
10
use rustc_span:: { BytePos , DesugaringKind , Span , Symbol , DUMMY_SP } ;
10
11
use smallvec:: { smallvec, SmallVec } ;
@@ -15,10 +16,9 @@ use super::errors::{
15
16
GenericTypeWithParentheses , UseAngleBrackets ,
16
17
} ;
17
18
use super :: {
18
- GenericArgsCtor , GenericArgsMode , ImplTraitContext , LifetimeRes , LoweringContext , ParamMode ,
19
- ResolverAstLoweringExt ,
19
+ AllowReturnTypeNotation , GenericArgsCtor , GenericArgsMode , ImplTraitContext , ImplTraitPosition ,
20
+ LifetimeRes , LoweringContext , ParamMode , ResolverAstLoweringExt ,
20
21
} ;
21
- use crate :: ImplTraitPosition ;
22
22
23
23
impl < ' a , ' hir > LoweringContext < ' a , ' hir > {
24
24
#[ instrument( level = "trace" , skip( self ) ) ]
@@ -28,6 +28,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
28
28
qself : & Option < ptr:: P < QSelf > > ,
29
29
p : & Path ,
30
30
param_mode : ParamMode ,
31
+ allow_return_type_notation : AllowReturnTypeNotation ,
31
32
itctx : ImplTraitContext ,
32
33
// modifiers of the impl/bound if this is a trait path
33
34
modifiers : Option < ast:: TraitBoundModifiers > ,
@@ -103,8 +104,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
103
104
{
104
105
GenericArgsMode :: ParenSugar
105
106
}
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
+ }
106
113
// Avoid duplicated errors.
107
- Res :: Err => GenericArgsMode :: ParenSugar ,
114
+ Res :: Err => GenericArgsMode :: Silence ,
108
115
// An error
109
116
_ => GenericArgsMode :: Err ,
110
117
} ;
@@ -164,11 +171,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
164
171
// 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
165
172
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
166
173
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
+
167
183
let hir_segment = self . arena . alloc ( self . lower_path_segment (
168
184
p. span ,
169
185
segment,
170
186
param_mode,
171
- GenericArgsMode :: Err ,
187
+ generic_args_mode ,
172
188
itctx,
173
189
None ,
174
190
) ) ;
@@ -238,11 +254,46 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
238
254
self . lower_angle_bracketed_parameter_data ( data, param_mode, itctx)
239
255
}
240
256
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
+ ) ,
246
297
GenericArgsMode :: Err => {
247
298
// Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
248
299
let sub = if !data. inputs . is_empty ( ) {
@@ -279,7 +330,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
279
330
}
280
331
} ,
281
332
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
+ }
283
341
(
284
342
GenericArgsCtor {
285
343
args : Default :: default ( ) ,
0 commit comments