@@ -76,6 +76,7 @@ use rustc::ty::relate::RelateResult;
76
76
use rustc:: ty:: subst:: Subst ;
77
77
use errors:: DiagnosticBuilder ;
78
78
use syntax:: abi;
79
+ use syntax:: feature_gate;
79
80
use syntax:: ptr:: P ;
80
81
use syntax_pos;
81
82
@@ -520,14 +521,24 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
520
521
coerce_source,
521
522
& [ coerce_target] ) ) ;
522
523
524
+ let mut has_unsized_tuple_coercion = false ;
525
+
523
526
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
524
527
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
525
528
// inference might unify those two inner type variables later.
526
529
let traits = [ coerce_unsized_did, unsize_did] ;
527
530
while let Some ( obligation) = queue. pop_front ( ) {
528
531
debug ! ( "coerce_unsized resolve step: {:?}" , obligation) ;
529
532
let trait_ref = match obligation. predicate {
530
- ty:: Predicate :: Trait ( ref tr) if traits. contains ( & tr. def_id ( ) ) => tr. clone ( ) ,
533
+ ty:: Predicate :: Trait ( ref tr) if traits. contains ( & tr. def_id ( ) ) => {
534
+ if unsize_did == tr. def_id ( ) {
535
+ if let ty:: TyTuple ( ..) = tr. 0 . input_types ( ) . nth ( 1 ) . unwrap ( ) . sty {
536
+ debug ! ( "coerce_unsized: found unsized tuple coercion" ) ;
537
+ has_unsized_tuple_coercion = true ;
538
+ }
539
+ }
540
+ tr. clone ( )
541
+ }
531
542
_ => {
532
543
coercion. obligations . push ( obligation) ;
533
544
continue ;
@@ -557,6 +568,14 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
557
568
}
558
569
}
559
570
571
+ if has_unsized_tuple_coercion && !self . tcx . sess . features . borrow ( ) . unsized_tuple_coercion {
572
+ feature_gate:: emit_feature_err ( & self . tcx . sess . parse_sess ,
573
+ "unsized_tuple_coercion" ,
574
+ self . cause . span ,
575
+ feature_gate:: GateIssue :: Language ,
576
+ feature_gate:: EXPLAIN_UNSIZED_TUPLE_COERCION ) ;
577
+ }
578
+
560
579
Ok ( coercion)
561
580
}
562
581
0 commit comments