@@ -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,8 +16,8 @@ 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 , LifetimeRes ,
20
+ LoweringContext , ParamMode , ResolverAstLoweringExt ,
20
21
} ;
21
22
use crate :: ImplTraitPosition ;
22
23
@@ -28,6 +29,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
28
29
qself : & Option < ptr:: P < QSelf > > ,
29
30
p : & Path ,
30
31
param_mode : ParamMode ,
32
+ allow_return_type_notation : AllowReturnTypeNotation ,
31
33
itctx : ImplTraitContext ,
32
34
// modifiers of the impl/bound if this is a trait path
33
35
modifiers : Option < ast:: TraitBoundModifiers > ,
@@ -103,6 +105,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
103
105
{
104
106
GenericArgsMode :: ParenSugar
105
107
}
108
+ Res :: Def ( DefKind :: AssocFn , _) if i + 1 == proj_start => {
109
+ match allow_return_type_notation {
110
+ AllowReturnTypeNotation :: Yes => GenericArgsMode :: ReturnTypeNotation ,
111
+ AllowReturnTypeNotation :: No => GenericArgsMode :: Err ,
112
+ }
113
+ }
106
114
// Avoid duplicated errors.
107
115
Res :: Err => GenericArgsMode :: ParenSugar ,
108
116
// An error
@@ -164,11 +172,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
164
172
// 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
165
173
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
166
174
for ( i, segment) in p. segments . iter ( ) . enumerate ( ) . skip ( proj_start) {
175
+ // If this is a type-dependent `T::method(..)`.
176
+ let generic_args_mode = if i + 1 == p. segments . len ( )
177
+ && matches ! ( allow_return_type_notation, AllowReturnTypeNotation :: Yes )
178
+ {
179
+ GenericArgsMode :: ReturnTypeNotation
180
+ } else {
181
+ GenericArgsMode :: Err
182
+ } ;
183
+
167
184
let hir_segment = self . arena . alloc ( self . lower_path_segment (
168
185
p. span ,
169
186
segment,
170
187
param_mode,
171
- GenericArgsMode :: Err ,
188
+ generic_args_mode ,
172
189
itctx,
173
190
None ,
174
191
) ) ;
@@ -238,6 +255,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
238
255
self . lower_angle_bracketed_parameter_data ( data, param_mode, itctx)
239
256
}
240
257
GenericArgs :: Parenthesized ( data) => match generic_args_mode {
258
+ GenericArgsMode :: ReturnTypeNotation => {
259
+ let mut err = if !data. inputs . is_empty ( ) {
260
+ self . dcx ( ) . create_err ( BadReturnTypeNotation :: Inputs {
261
+ span : data. inputs_span ,
262
+ } )
263
+ } else if let FnRetTy :: Ty ( ty) = & data. output {
264
+ self . dcx ( ) . create_err ( BadReturnTypeNotation :: Output {
265
+ span : data. inputs_span . shrink_to_hi ( ) . to ( ty. span ) ,
266
+ } )
267
+ } else {
268
+ self . dcx ( ) . create_err ( BadReturnTypeNotation :: NeedsDots {
269
+ span : data. inputs_span ,
270
+ } )
271
+ } ;
272
+ if !self . tcx . features ( ) . return_type_notation
273
+ && self . tcx . sess . is_nightly_build ( )
274
+ {
275
+ add_feature_diagnostics (
276
+ & mut err,
277
+ & self . tcx . sess ,
278
+ sym:: return_type_notation,
279
+ ) ;
280
+ }
281
+ err. emit ( ) ;
282
+ (
283
+ GenericArgsCtor {
284
+ args : Default :: default ( ) ,
285
+ constraints : & [ ] ,
286
+ parenthesized : hir:: GenericArgsParentheses :: ReturnTypeNotation ,
287
+ span : path_span,
288
+ } ,
289
+ false ,
290
+ )
291
+ }
241
292
GenericArgsMode :: ParenSugar => self . lower_parenthesized_parameter_data (
242
293
data,
243
294
itctx,
@@ -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 => {
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