@@ -9,9 +9,7 @@ use rustc_span::{ErrorGuaranteed, Span};
9
9
use rustc_trait_selection:: traits;
10
10
use smallvec:: SmallVec ;
11
11
12
- use crate :: astconv:: {
13
- AstConv , ConvertedBinding , ConvertedBindingKind , OnlySelfBounds , PredicateFilter ,
14
- } ;
12
+ use crate :: astconv:: { AstConv , OnlySelfBounds , PredicateFilter } ;
15
13
use crate :: bounds:: Bounds ;
16
14
use crate :: errors;
17
15
@@ -238,7 +236,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
238
236
& self ,
239
237
hir_ref_id : hir:: HirId ,
240
238
trait_ref : ty:: PolyTraitRef < ' tcx > ,
241
- binding : & ConvertedBinding < ' _ , ' tcx > ,
239
+ binding : & hir :: TypeBinding < ' tcx > ,
242
240
bounds : & mut Bounds < ' tcx > ,
243
241
speculative : bool ,
244
242
dup_bindings : & mut FxIndexMap < DefId , Span > ,
@@ -263,21 +261,20 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
263
261
264
262
let tcx = self . tcx ( ) ;
265
263
266
- let assoc_kind =
267
- if binding. gen_args . parenthesized == hir:: GenericArgsParentheses :: ReturnTypeNotation {
268
- ty:: AssocKind :: Fn
269
- } else if let ConvertedBindingKind :: Equality ( term) = binding. kind
270
- && let ty:: TermKind :: Const ( _) = term. node . unpack ( )
271
- {
272
- ty:: AssocKind :: Const
273
- } else {
274
- ty:: AssocKind :: Type
275
- } ;
264
+ let assoc_kind = if binding. gen_args . parenthesized
265
+ == hir:: GenericArgsParentheses :: ReturnTypeNotation
266
+ {
267
+ ty:: AssocKind :: Fn
268
+ } else if let hir:: TypeBindingKind :: Equality { term : hir:: Term :: Const ( _) } = binding. kind {
269
+ ty:: AssocKind :: Const
270
+ } else {
271
+ ty:: AssocKind :: Type
272
+ } ;
276
273
277
274
let candidate = if self . trait_defines_associated_item_named (
278
275
trait_ref. def_id ( ) ,
279
276
assoc_kind,
280
- binding. item_name ,
277
+ binding. ident ,
281
278
) {
282
279
// Simple case: The assoc item is defined in the current trait.
283
280
trait_ref
@@ -289,14 +286,14 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
289
286
trait_ref. skip_binder ( ) . print_only_trait_name ( ) ,
290
287
None ,
291
288
assoc_kind,
292
- binding. item_name ,
289
+ binding. ident ,
293
290
path_span,
294
- Some ( & binding) ,
291
+ Some ( binding) ,
295
292
) ?
296
293
} ;
297
294
298
295
let ( assoc_ident, def_scope) =
299
- tcx. adjust_ident_and_get_scope ( binding. item_name , candidate. def_id ( ) , hir_ref_id) ;
296
+ tcx. adjust_ident_and_get_scope ( binding. ident , candidate. def_id ( ) , hir_ref_id) ;
300
297
301
298
// We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
302
299
// instead of calling `filter_by_name_and_kind` which would needlessly normalize the
@@ -312,7 +309,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
312
309
. dcx ( )
313
310
. struct_span_err (
314
311
binding. span ,
315
- format ! ( "{} `{}` is private" , assoc_item. kind, binding. item_name ) ,
312
+ format ! ( "{} `{}` is private" , assoc_item. kind, binding. ident ) ,
316
313
)
317
314
. with_span_label ( binding. span , format ! ( "private {}" , assoc_item. kind) )
318
315
. emit ( ) ;
@@ -327,7 +324,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
327
324
tcx. dcx ( ) . emit_err ( errors:: ValueOfAssociatedStructAlreadySpecified {
328
325
span : binding. span ,
329
326
prev_span : * prev_span,
330
- item_name : binding. item_name ,
327
+ item_name : binding. ident ,
331
328
def_path : tcx. def_path_str ( assoc_item. container_id ( tcx) ) ,
332
329
} ) ;
333
330
} )
@@ -390,14 +387,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
390
387
{
391
388
alias_ty
392
389
} else {
393
- return Err ( self . tcx ( ) . dcx ( ) . emit_err (
394
- crate :: errors:: ReturnTypeNotationOnNonRpitit {
395
- span : binding. span ,
396
- ty : tcx. liberate_late_bound_regions ( assoc_item. def_id , output) ,
397
- fn_span : tcx. hir ( ) . span_if_local ( assoc_item. def_id ) ,
398
- note : ( ) ,
399
- } ,
400
- ) ) ;
390
+ return Err ( tcx. dcx ( ) . emit_err ( crate :: errors:: ReturnTypeNotationOnNonRpitit {
391
+ span : binding. span ,
392
+ ty : tcx. liberate_late_bound_regions ( assoc_item. def_id , output) ,
393
+ fn_span : tcx. hir ( ) . span_if_local ( assoc_item. def_id ) ,
394
+ note : ( ) ,
395
+ } ) ) ;
401
396
} ;
402
397
403
398
// Finally, move the fn return type's bound vars over to account for the early bound
@@ -410,9 +405,11 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
410
405
let bound_vars = tcx. late_bound_vars ( binding. hir_id ) ;
411
406
ty:: Binder :: bind_with_vars ( instantiation_output, bound_vars)
412
407
} else {
413
- // Append the generic arguments of the associated type to the `trait_ref`.
408
+ // Create the generic arguments for the associated type or constant by joining the
409
+ // parent arguments (the arguments of the trait) and the own arguments (the ones of
410
+ // the associated item itself) and construct an alias type using them.
414
411
candidate. map_bound ( |trait_ref| {
415
- let ident = Ident :: new ( assoc_item. name , binding. item_name . span ) ;
412
+ let ident = Ident :: new ( assoc_item. name , binding. ident . span ) ;
416
413
let item_segment = hir:: PathSegment {
417
414
ident,
418
415
hir_id : binding. hir_id ,
@@ -421,77 +418,82 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
421
418
infer_args : false ,
422
419
} ;
423
420
424
- let args_trait_ref_and_assoc_item = self . create_args_for_associated_item (
421
+ let alias_args = self . create_args_for_associated_item (
425
422
path_span,
426
423
assoc_item. def_id ,
427
424
& item_segment,
428
425
trait_ref. args ,
429
426
) ;
427
+ debug ! ( ?alias_args) ;
430
428
431
- debug ! ( ?args_trait_ref_and_assoc_item) ;
432
-
433
- ty:: AliasTy :: new ( tcx, assoc_item. def_id , args_trait_ref_and_assoc_item)
429
+ // Note that we're indeed also using `AliasTy` (alias *type*) for associated
430
+ // *constants* to represent *const projections*. Alias *term* would be a more
431
+ // appropriate name but alas.
432
+ ty:: AliasTy :: new ( tcx, assoc_item. def_id , alias_args)
434
433
} )
435
434
} ;
436
435
437
- if !speculative {
438
- // Find any late-bound regions declared in `ty` that are not
439
- // declared in the trait-ref or assoc_item. These are not well-formed.
440
- //
441
- // Example:
442
- //
443
- // for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
444
- // for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
445
- if let ConvertedBindingKind :: Equality ( ty) = binding. kind {
446
- let late_bound_in_trait_ref =
447
- tcx. collect_constrained_late_bound_regions ( & projection_ty) ;
448
- let late_bound_in_ty =
449
- tcx. collect_referenced_late_bound_regions ( & trait_ref. rebind ( ty. node ) ) ;
450
- debug ! ( ?late_bound_in_trait_ref) ;
451
- debug ! ( ?late_bound_in_ty) ;
452
-
453
- // FIXME: point at the type params that don't have appropriate lifetimes:
454
- // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
455
- // ---- ---- ^^^^^^^
456
- self . validate_late_bound_regions (
457
- late_bound_in_trait_ref,
458
- late_bound_in_ty,
459
- |br_name| {
460
- struct_span_code_err ! (
461
- tcx. dcx( ) ,
462
- binding. span,
463
- E0582 ,
464
- "binding for associated type `{}` references {}, \
465
- which does not appear in the trait input types",
466
- binding. item_name,
467
- br_name
468
- )
469
- } ,
470
- ) ;
471
- }
472
- }
473
-
474
436
match binding. kind {
475
- ConvertedBindingKind :: Equality ( .. ) if let ty:: AssocKind :: Fn = assoc_kind => {
476
- return Err ( self . tcx ( ) . dcx ( ) . emit_err (
477
- crate :: errors :: ReturnTypeNotationEqualityBound { span : binding. span } ,
478
- ) ) ;
437
+ hir :: TypeBindingKind :: Equality { .. } if let ty:: AssocKind :: Fn = assoc_kind => {
438
+ return Err ( tcx. dcx ( ) . emit_err ( crate :: errors :: ReturnTypeNotationEqualityBound {
439
+ span : binding. span ,
440
+ } ) ) ;
479
441
}
480
- ConvertedBindingKind :: Equality ( term) => {
442
+ hir:: TypeBindingKind :: Equality { term } => {
443
+ let term = match term {
444
+ hir:: Term :: Ty ( ty) => self . ast_ty_to_ty ( ty) . into ( ) ,
445
+ hir:: Term :: Const ( ct) => ty:: Const :: from_anon_const ( tcx, ct. def_id ) . into ( ) ,
446
+ } ;
447
+
448
+ if !speculative {
449
+ // Find any late-bound regions declared in `ty` that are not
450
+ // declared in the trait-ref or assoc_item. These are not well-formed.
451
+ //
452
+ // Example:
453
+ //
454
+ // for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
455
+ // for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
456
+ let late_bound_in_projection_ty =
457
+ tcx. collect_constrained_late_bound_regions ( & projection_ty) ;
458
+ let late_bound_in_term =
459
+ tcx. collect_referenced_late_bound_regions ( & trait_ref. rebind ( term) ) ;
460
+ debug ! ( ?late_bound_in_projection_ty) ;
461
+ debug ! ( ?late_bound_in_term) ;
462
+
463
+ // FIXME: point at the type params that don't have appropriate lifetimes:
464
+ // struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
465
+ // ---- ---- ^^^^^^^
466
+ // NOTE(associated_const_equality): This error should be impossible to trigger
467
+ // with associated const equality bounds.
468
+ self . validate_late_bound_regions (
469
+ late_bound_in_projection_ty,
470
+ late_bound_in_term,
471
+ |br_name| {
472
+ struct_span_code_err ! (
473
+ tcx. dcx( ) ,
474
+ binding. span,
475
+ E0582 ,
476
+ "binding for associated type `{}` references {}, \
477
+ which does not appear in the trait input types",
478
+ binding. ident,
479
+ br_name
480
+ )
481
+ } ,
482
+ ) ;
483
+ }
484
+
481
485
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
482
486
// the "projection predicate" for:
483
487
//
484
488
// `<T as Iterator>::Item = u32`
485
489
bounds. push_projection_bound (
486
490
tcx,
487
- projection_ty. map_bound ( |projection_ty| ty:: ProjectionPredicate {
488
- projection_ty,
489
- term : term. node ,
490
- } ) ,
491
+ projection_ty
492
+ . map_bound ( |projection_ty| ty:: ProjectionPredicate { projection_ty, term } ) ,
491
493
binding. span ,
492
494
) ;
493
495
}
494
- ConvertedBindingKind :: Constraint ( ast_bounds) => {
496
+ hir :: TypeBindingKind :: Constraint { bounds : ast_bounds } => {
495
497
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
496
498
//
497
499
// `<T as Iterator>::Item: Debug`
0 commit comments