@@ -47,7 +47,8 @@ use syntax_pos::{DUMMY_SP, Span};
47
47
impl < ' a , ' gcx , ' tcx > InferCtxt < ' a , ' gcx , ' tcx > {
48
48
pub fn report_fulfillment_errors ( & self ,
49
49
errors : & Vec < FulfillmentError < ' tcx > > ,
50
- body_id : Option < hir:: BodyId > ) {
50
+ body_id : Option < hir:: BodyId > ,
51
+ fallback_has_occurred : bool ) {
51
52
#[ derive( Debug ) ]
52
53
struct ErrorDescriptor < ' tcx > {
53
54
predicate : ty:: Predicate < ' tcx > ,
@@ -107,7 +108,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
107
108
108
109
for ( error, suppressed) in errors. iter ( ) . zip ( is_suppressed) {
109
110
if !suppressed {
110
- self . report_fulfillment_error ( error, body_id) ;
111
+ self . report_fulfillment_error ( error, body_id, fallback_has_occurred ) ;
111
112
}
112
113
}
113
114
}
@@ -151,11 +152,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
151
152
}
152
153
153
154
fn report_fulfillment_error ( & self , error : & FulfillmentError < ' tcx > ,
154
- body_id : Option < hir:: BodyId > ) {
155
+ body_id : Option < hir:: BodyId > ,
156
+ fallback_has_occurred : bool ) {
155
157
debug ! ( "report_fulfillment_errors({:?})" , error) ;
156
158
match error. code {
157
159
FulfillmentErrorCode :: CodeSelectionError ( ref e) => {
158
- self . report_selection_error ( & error. obligation , e) ;
160
+ self . report_selection_error ( & error. obligation , e, fallback_has_occurred ) ;
159
161
}
160
162
FulfillmentErrorCode :: CodeProjectionError ( ref e) => {
161
163
self . report_projection_error ( & error. obligation , e) ;
@@ -533,7 +535,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
533
535
534
536
pub fn report_selection_error ( & self ,
535
537
obligation : & PredicateObligation < ' tcx > ,
536
- error : & SelectionError < ' tcx > )
538
+ error : & SelectionError < ' tcx > ,
539
+ fallback_has_occurred : bool )
537
540
{
538
541
let span = obligation. cause . span ;
539
542
@@ -619,6 +622,39 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
619
622
self . report_similar_impl_candidates ( impl_candidates, & mut err) ;
620
623
}
621
624
625
+ // If this error is due to `!: Trait` not implemented but `(): Trait` is
626
+ // implemented, and fallback has occured, then it could be due to a
627
+ // variable that used to fallback to `()` now falling back to `!`. Issue a
628
+ // note informing about the change in behaviour.
629
+ if trait_predicate. skip_binder ( ) . self_ty ( ) . is_never ( )
630
+ && fallback_has_occurred
631
+ {
632
+ let predicate = trait_predicate. map_bound ( |mut trait_pred| {
633
+ {
634
+ let trait_ref = & mut trait_pred. trait_ref ;
635
+ let never_substs = trait_ref. substs ;
636
+ let mut unit_substs = Vec :: with_capacity ( never_substs. len ( ) ) ;
637
+ unit_substs. push ( self . tcx . mk_nil ( ) . into ( ) ) ;
638
+ unit_substs. extend ( & never_substs[ 1 ..] ) ;
639
+ trait_ref. substs = self . tcx . intern_substs ( & unit_substs) ;
640
+ }
641
+ trait_pred
642
+ } ) ;
643
+ let unit_obligation = Obligation {
644
+ predicate : ty:: Predicate :: Trait ( predicate) ,
645
+ .. obligation. clone ( )
646
+ } ;
647
+ let mut selcx = SelectionContext :: new ( self ) ;
648
+ if selcx. evaluate_obligation ( & unit_obligation) {
649
+ err. note ( "the trait is implemented for `()`. \
650
+ Possibly this error has been caused by changes to \
651
+ Rust's type-inference algorithm \
652
+ (see: https://github.com/rust-lang/rust/issues/48950 \
653
+ for more info). Consider whether you meant to use the \
654
+ type `()` here instead.") ;
655
+ }
656
+ }
657
+
622
658
err
623
659
}
624
660
@@ -729,14 +765,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
729
765
} ) . map ( |sp| self . tcx . sess . codemap ( ) . def_span ( sp) ) ; // the sp could be an fn def
730
766
731
767
let found = match found_trait_ref. skip_binder ( ) . substs . type_at ( 1 ) . sty {
732
- ty:: TyTuple ( ref tys, _ ) => tys. iter ( )
768
+ ty:: TyTuple ( ref tys) => tys. iter ( )
733
769
. map ( |_| ArgKind :: empty ( ) ) . collect :: < Vec < _ > > ( ) ,
734
770
_ => vec ! [ ArgKind :: empty( ) ] ,
735
771
} ;
736
772
let expected = match expected_trait_ref. skip_binder ( ) . substs . type_at ( 1 ) . sty {
737
- ty:: TyTuple ( ref tys, _ ) => tys. iter ( )
773
+ ty:: TyTuple ( ref tys) => tys. iter ( )
738
774
. map ( |t| match t. sty {
739
- ty:: TypeVariants :: TyTuple ( ref tys, _ ) => ArgKind :: Tuple (
775
+ ty:: TypeVariants :: TyTuple ( ref tys) => ArgKind :: Tuple (
740
776
Some ( span) ,
741
777
tys. iter ( )
742
778
. map ( |ty| ( "_" . to_owned ( ) , format ! ( "{}" , ty. sty) ) )
@@ -986,7 +1022,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
986
1022
fn build_fn_sig_string < ' a , ' gcx , ' tcx > ( tcx : ty:: TyCtxt < ' a , ' gcx , ' tcx > ,
987
1023
trait_ref : & ty:: TraitRef < ' tcx > ) -> String {
988
1024
let inputs = trait_ref. substs . type_at ( 1 ) ;
989
- let sig = if let ty:: TyTuple ( inputs, _ ) = inputs. sty {
1025
+ let sig = if let ty:: TyTuple ( inputs) = inputs. sty {
990
1026
tcx. mk_fn_sig (
991
1027
inputs. iter ( ) . map ( |& x| x) ,
992
1028
tcx. mk_infer ( ty:: TyVar ( ty:: TyVid { index : 0 } ) ) ,
@@ -1422,7 +1458,7 @@ impl ArgKind {
1422
1458
/// argument. This has no name (`_`) and no source spans..
1423
1459
pub fn from_expected_ty ( t : Ty < ' _ > ) -> ArgKind {
1424
1460
match t. sty {
1425
- ty:: TyTuple ( ref tys, _ ) => ArgKind :: Tuple (
1461
+ ty:: TyTuple ( ref tys) => ArgKind :: Tuple (
1426
1462
None ,
1427
1463
tys. iter ( )
1428
1464
. map ( |ty| ( "_" . to_owned ( ) , format ! ( "{}" , ty. sty) ) )
0 commit comments