@@ -30,11 +30,12 @@ use require_c_abi_if_variadic;
30
30
use util:: common:: ErrorReported ;
31
31
use util:: nodemap:: { FxHashSet , FxHashMap } ;
32
32
use errors:: { FatalError , DiagnosticId } ;
33
+ use lint;
33
34
34
35
use std:: iter;
35
36
use syntax:: ast;
36
37
use syntax:: feature_gate:: { GateIssue , emit_feature_err} ;
37
- use syntax_pos:: Span ;
38
+ use syntax_pos:: { Span , MultiSpan } ;
38
39
39
40
pub trait AstConv < ' gcx , ' tcx > {
40
41
fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' gcx , ' tcx > ;
@@ -172,21 +173,164 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
172
173
-> & ' tcx Substs < ' tcx >
173
174
{
174
175
175
- let ( substs, assoc_bindings) =
176
- item_segment . with_generic_args ( |generic_args| {
177
- self . create_substs_for_ast_path (
178
- span ,
179
- def_id ,
180
- generic_args ,
181
- item_segment . infer_types ,
182
- None )
183
- } ) ;
176
+ let ( substs, assoc_bindings) = item_segment . with_generic_args ( |generic_args| {
177
+ self . create_substs_for_ast_path (
178
+ span ,
179
+ def_id ,
180
+ generic_args ,
181
+ item_segment . infer_types ,
182
+ None ,
183
+ )
184
+ } ) ;
184
185
185
- assoc_bindings. first ( ) . map ( |b| self . prohibit_projection ( b. span ) ) ;
186
+ assoc_bindings. first ( ) . map ( |b| Self :: prohibit_assoc_ty_binding ( self . tcx ( ) , b. span ) ) ;
186
187
187
188
substs
188
189
}
189
190
191
+ /// Check that the correct number of generic arguments have been provided.
192
+ /// This is used both for type declarations and function calls.
193
+ pub fn check_generic_arg_count (
194
+ tcx : TyCtxt ,
195
+ span : Span ,
196
+ def : & ty:: Generics ,
197
+ args : & hir:: GenericArgs ,
198
+ is_declaration : bool ,
199
+ is_method_call : bool ,
200
+ has_self : bool ,
201
+ infer_types : bool ,
202
+ ) -> bool {
203
+ // At this stage we are guaranteed that the generic arguments are in the correct order, e.g.
204
+ // that lifetimes will proceed types. So it suffices to check the number of each generic
205
+ // arguments in order to validate them with respect to the generic parameters.
206
+ let param_counts = def. own_counts ( ) ;
207
+ let arg_counts = args. own_counts ( ) ;
208
+ let infer_lifetimes = !is_declaration && arg_counts. lifetimes == 0 ;
209
+
210
+ let mut defaults: ty:: GenericParamCount = Default :: default ( ) ;
211
+ for param in & def. params {
212
+ match param. kind {
213
+ GenericParamDefKind :: Lifetime => { }
214
+ GenericParamDefKind :: Type { has_default, .. } => {
215
+ defaults. types += has_default as usize
216
+ }
217
+ } ;
218
+ }
219
+
220
+ if !is_declaration && !args. bindings . is_empty ( ) {
221
+ AstConv :: prohibit_assoc_ty_binding ( tcx, args. bindings [ 0 ] . span ) ;
222
+ }
223
+
224
+ // Prohibit explicit lifetime arguments if late-bound lifetime parameters are present.
225
+ if !infer_lifetimes {
226
+ if let Some ( span_late) = def. has_late_bound_regions {
227
+ let msg = "cannot specify lifetime arguments explicitly \
228
+ if late bound lifetime parameters are present";
229
+ let note = "the late bound lifetime parameter is introduced here" ;
230
+ let span = args. args [ 0 ] . span ( ) ;
231
+ if !is_method_call && arg_counts. lifetimes != param_counts. lifetimes {
232
+ let mut err = tcx. sess . struct_span_err ( span, msg) ;
233
+ err. span_note ( span_late, note) ;
234
+ err. emit ( ) ;
235
+ return true ;
236
+ } else {
237
+ let mut multispan = MultiSpan :: from_span ( span) ;
238
+ multispan. push_span_label ( span_late, note. to_string ( ) ) ;
239
+ tcx. lint_node ( lint:: builtin:: LATE_BOUND_LIFETIME_ARGUMENTS ,
240
+ args. args [ 0 ] . id ( ) , multispan, msg) ;
241
+ return false ;
242
+ }
243
+ }
244
+ }
245
+
246
+ let check_kind_count = |error_code_less : & str ,
247
+ error_code_more : & str ,
248
+ kind,
249
+ required,
250
+ permitted,
251
+ provided| {
252
+ // We enforce the following: `required` <= `provided` <= `permitted`.
253
+ // For kinds without defaults (i.e. lifetimes), `required == permitted`.
254
+ // For other kinds (i.e. types), `permitted` may be greater than `required`.
255
+ if required <= provided && provided <= permitted {
256
+ return false ;
257
+ }
258
+
259
+ // Unfortunately lifetime and type parameter mismatches are typically styled
260
+ // differently in diagnostics, which means we have a few cases to consider here.
261
+ let ( bound, quantifier, suppress_error) = if required != permitted {
262
+ if provided < required {
263
+ ( required, "at least " , false )
264
+ } else { // provided > permitted
265
+ ( permitted, "at most " , true )
266
+ }
267
+ } else {
268
+ ( required, "" , false )
269
+ } ;
270
+ let label = if required == permitted && provided > permitted {
271
+ let diff = provided - permitted;
272
+ format ! (
273
+ "{}unexpected {} argument{}" ,
274
+ if diff != 1 { format!( "{} " , diff) } else { String :: new( ) } ,
275
+ kind,
276
+ if diff != 1 { "s" } else { "" } ,
277
+ )
278
+ } else {
279
+ format ! (
280
+ "expected {}{} {} argument{}" ,
281
+ quantifier,
282
+ bound,
283
+ kind,
284
+ if required != 1 { "s" } else { "" } ,
285
+ )
286
+ } ;
287
+
288
+ tcx. sess . struct_span_err_with_code (
289
+ span,
290
+ & format ! (
291
+ "wrong number of {} arguments: expected {}{}, found {}" ,
292
+ kind,
293
+ quantifier,
294
+ bound,
295
+ provided,
296
+ ) ,
297
+ DiagnosticId :: Error ( {
298
+ if provided <= permitted {
299
+ error_code_less
300
+ } else {
301
+ error_code_more
302
+ }
303
+ } . into ( ) )
304
+ ) . span_label ( span, label) . emit ( ) ;
305
+
306
+ suppress_error
307
+ } ;
308
+
309
+ if !infer_lifetimes || arg_counts. lifetimes > param_counts. lifetimes {
310
+ check_kind_count (
311
+ "E0107" ,
312
+ "E0107" ,
313
+ "lifetime" ,
314
+ param_counts. lifetimes ,
315
+ param_counts. lifetimes ,
316
+ arg_counts. lifetimes ,
317
+ ) ;
318
+ }
319
+ if !infer_types
320
+ || arg_counts. types > param_counts. types - defaults. types - has_self as usize {
321
+ check_kind_count (
322
+ "E0243" ,
323
+ "E0244" , // FIXME: E0243 and E0244 should be unified.
324
+ "type" ,
325
+ param_counts. types - defaults. types - has_self as usize ,
326
+ param_counts. types - has_self as usize ,
327
+ arg_counts. types ,
328
+ )
329
+ } else {
330
+ false
331
+ }
332
+ }
333
+
190
334
/// Creates the relevant generic argument substitutions
191
335
/// corresponding to a set of generic parameters.
192
336
pub fn create_substs_for_generic_args < ' a , ' b , A , P , I > (
@@ -355,7 +499,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
355
499
assert_eq ! ( generic_params. has_self, self_ty. is_some( ) ) ;
356
500
357
501
let has_self = generic_params. has_self ;
358
- check_generic_arg_count ( tcx, span, & generic_params, & generic_args, has_self, infer_types) ;
502
+ Self :: check_generic_arg_count (
503
+ self . tcx ( ) ,
504
+ span,
505
+ & generic_params,
506
+ & generic_args,
507
+ true , // `is_declaration`
508
+ false , // `is_method_call` (irrelevant here)
509
+ has_self,
510
+ infer_types,
511
+ ) ;
359
512
360
513
let is_object = self_ty. map_or ( false , |ty| ty. sty == TRAIT_OBJECT_DUMMY_SELF ) ;
361
514
let default_needs_object_self = |param : & ty:: GenericParamDef | {
@@ -548,7 +701,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
548
701
trait_def_id,
549
702
self_ty,
550
703
trait_segment) ;
551
- assoc_bindings. first ( ) . map ( |b| self . prohibit_projection ( b. span ) ) ;
704
+ assoc_bindings. first ( ) . map ( |b| AstConv :: prohibit_assoc_ty_binding ( self . tcx ( ) , b. span ) ) ;
552
705
ty:: TraitRef :: new ( trait_def_id, substs)
553
706
}
554
707
@@ -1113,15 +1266,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
1113
1266
}
1114
1267
}
1115
1268
for binding in & generic_args. bindings {
1116
- self . prohibit_projection ( binding. span ) ;
1269
+ Self :: prohibit_assoc_ty_binding ( self . tcx ( ) , binding. span ) ;
1117
1270
break ;
1118
1271
}
1119
1272
} )
1120
1273
}
1121
1274
}
1122
1275
1123
- pub fn prohibit_projection ( & self , span : Span ) {
1124
- let mut err = struct_span_err ! ( self . tcx( ) . sess, span, E0229 ,
1276
+ pub fn prohibit_assoc_ty_binding ( tcx : TyCtxt , span : Span ) {
1277
+ let mut err = struct_span_err ! ( tcx. sess, span, E0229 ,
1125
1278
"associated type bindings are not allowed here" ) ;
1126
1279
err. span_label ( span, "associated type not allowed here" ) . emit ( ) ;
1127
1280
}
@@ -1497,109 +1650,6 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
1497
1650
( auto_traits, trait_bounds)
1498
1651
}
1499
1652
1500
- pub fn check_generic_arg_count (
1501
- tcx : TyCtxt ,
1502
- span : Span ,
1503
- def : & ty:: Generics ,
1504
- args : & hir:: GenericArgs ,
1505
- has_self : bool ,
1506
- infer_types : bool ,
1507
- ) {
1508
- // At this stage we are guaranteed that the generic arguments are in the correct order, e.g.
1509
- // that lifetimes will proceed types. So it suffices to check the number of each generic
1510
- // arguments in order to validate them with respect to the generic parameters.
1511
- let param_counts = def. own_counts ( ) ;
1512
- let arg_counts = args. own_counts ( ) ;
1513
-
1514
- let mut defaults: ty:: GenericParamCount = Default :: default ( ) ;
1515
- for param in & def. params {
1516
- match param. kind {
1517
- GenericParamDefKind :: Lifetime => { }
1518
- GenericParamDefKind :: Type { has_default, .. } => defaults. types += has_default as usize ,
1519
- } ;
1520
- }
1521
-
1522
- let check_kind_count = |error_code_less : & str ,
1523
- error_code_more : & str ,
1524
- kind,
1525
- required,
1526
- permitted,
1527
- provided| {
1528
- // We enforce the following: `required` <= `provided` <= `permitted`.
1529
- // For kinds without defaults (i.e. lifetimes), `required == permitted`.
1530
- // For other kinds (i.e. types), `permitted` may be greater than `required`.
1531
- if required <= provided && provided <= permitted {
1532
- return ;
1533
- }
1534
-
1535
- // Unfortunately lifetime and type parameter mismatches are typically styled
1536
- // differently in diagnostics, which means we have a few cases to consider here.
1537
- let ( bound, quantifier) = if required != permitted {
1538
- if provided < required {
1539
- ( required, "at least " )
1540
- } else { // provided > permitted
1541
- ( permitted, "at most " )
1542
- }
1543
- } else {
1544
- ( required, "" )
1545
- } ;
1546
- let label = if required == permitted && provided > permitted {
1547
- let diff = provided - permitted;
1548
- format ! (
1549
- "{}unexpected {} argument{}" ,
1550
- if diff != 1 { format!( "{} " , diff) } else { String :: new( ) } ,
1551
- kind,
1552
- if diff != 1 { "s" } else { "" } ,
1553
- )
1554
- } else {
1555
- format ! (
1556
- "expected {}{} {} argument{}" ,
1557
- quantifier,
1558
- bound,
1559
- kind,
1560
- if required != 1 { "s" } else { "" } ,
1561
- )
1562
- } ;
1563
-
1564
- tcx. sess . struct_span_err_with_code (
1565
- span,
1566
- & format ! (
1567
- "wrong number of {} arguments: expected {}{}, found {}" ,
1568
- kind,
1569
- quantifier,
1570
- bound,
1571
- provided,
1572
- ) ,
1573
- DiagnosticId :: Error ( {
1574
- if provided <= permitted {
1575
- error_code_less
1576
- } else {
1577
- error_code_more
1578
- }
1579
- } . into ( ) )
1580
- ) . span_label ( span, label) . emit ( ) ;
1581
- } ;
1582
-
1583
- check_kind_count (
1584
- "E0107" ,
1585
- "E0107" ,
1586
- "lifetime" ,
1587
- param_counts. lifetimes ,
1588
- param_counts. lifetimes ,
1589
- arg_counts. lifetimes ,
1590
- ) ;
1591
- if !infer_types || arg_counts. types > param_counts. types - defaults. types - has_self as usize {
1592
- check_kind_count (
1593
- "E0243" ,
1594
- "E0244" , // FIXME: E0243 and E0244 should be unified.
1595
- "type" ,
1596
- param_counts. types - defaults. types - has_self as usize ,
1597
- param_counts. types - has_self as usize ,
1598
- arg_counts. types ,
1599
- ) ;
1600
- }
1601
- }
1602
-
1603
1653
// A helper struct for conveniently grouping a set of bounds which we pass to
1604
1654
// and return from functions in multiple places.
1605
1655
#[ derive( PartialEq , Eq , Clone , Debug ) ]
0 commit comments