@@ -83,7 +83,7 @@ use hir::def_id::DefId;
83
83
use infer:: { self , TypeOrigin } ;
84
84
use middle:: region;
85
85
use ty:: subst;
86
- use ty:: { self , Ty , TyCtxt , TypeFoldable } ;
86
+ use ty:: { self , TyCtxt , TypeFoldable } ;
87
87
use ty:: { Region , ReFree } ;
88
88
use ty:: error:: TypeError ;
89
89
@@ -462,52 +462,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
462
462
}
463
463
}
464
464
465
- fn report_type_error ( & self ,
466
- trace : TypeTrace < ' tcx > ,
467
- terr : & TypeError < ' tcx > )
468
- -> DiagnosticBuilder < ' tcx > {
469
- let ( expected, found) = match self . values_str ( & trace. values ) {
470
- Some ( v) => v,
471
- None => {
472
- return self . tcx . sess . diagnostic ( ) . struct_dummy ( ) ; /* derived error */
473
- }
474
- } ;
475
-
476
- let is_simple_error = if let & TypeError :: Sorts ( ref values) = terr {
477
- values. expected . is_primitive ( ) && values. found . is_primitive ( )
478
- } else {
479
- false
480
- } ;
481
-
482
- let mut err = struct_span_err ! ( self . tcx. sess,
483
- trace. origin. span( ) ,
484
- E0308 ,
485
- "{}" ,
486
- trace. origin) ;
487
-
488
- if !is_simple_error || check_old_school ( ) {
489
- err. note_expected_found ( & "type" , & expected, & found) ;
490
- }
491
-
492
- err. span_label ( trace. origin . span ( ) , & terr) ;
493
-
494
- self . check_and_note_conflicting_crates ( & mut err, terr, trace. origin . span ( ) ) ;
495
-
496
- match trace. origin {
497
- TypeOrigin :: MatchExpressionArm ( _, arm_span, source) => match source {
498
- hir:: MatchSource :: IfLetDesugar { ..} => {
499
- err. span_note ( arm_span, "`if let` arm with an incompatible type" ) ;
500
- }
501
- _ => {
502
- err. span_note ( arm_span, "match arm with an incompatible type" ) ;
503
- }
504
- } ,
505
- _ => ( )
506
- }
507
-
508
- err
509
- }
510
-
511
465
/// Adds a note if the types come from similarly named crates
512
466
fn check_and_note_conflicting_crates ( & self ,
513
467
err : & mut DiagnosticBuilder ,
@@ -550,43 +504,91 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
550
504
}
551
505
}
552
506
553
- pub fn report_and_explain_type_error ( & self ,
554
- trace : TypeTrace < ' tcx > ,
555
- terr : & TypeError < ' tcx > )
556
- -> DiagnosticBuilder < ' tcx > {
557
- let trace = self . resolve_type_vars_if_possible ( & trace) ;
507
+ fn note_error_origin ( & self ,
508
+ err : & mut DiagnosticBuilder < ' tcx > ,
509
+ origin : & TypeOrigin )
510
+ {
511
+ match origin {
512
+ & TypeOrigin :: MatchExpressionArm ( _, arm_span, source) => match source {
513
+ hir:: MatchSource :: IfLetDesugar { ..} => {
514
+ err. span_note ( arm_span, "`if let` arm with an incompatible type" ) ;
515
+ }
516
+ _ => {
517
+ err. span_note ( arm_span, "match arm with an incompatible type" ) ;
518
+ }
519
+ } ,
520
+ _ => ( )
521
+ }
522
+ }
523
+
524
+ pub fn report_and_explain_type_error_with_code ( & self ,
525
+ trace : TypeTrace < ' tcx > ,
526
+ terr : & TypeError < ' tcx > ,
527
+ message : & str ,
528
+ code : & str )
529
+ -> DiagnosticBuilder < ' tcx >
530
+ {
531
+ let ( expected, found) = match self . values_str ( & trace. values ) {
532
+ Some ( ( expected, found) ) => ( expected, found) ,
533
+ None => return self . tcx . sess . diagnostic ( ) . struct_dummy ( ) /* derived error */
534
+ } ;
535
+
558
536
let span = trace. origin . span ( ) ;
559
- let mut err = self . report_type_error ( trace, terr) ;
537
+
538
+ let is_simple_error = if let & TypeError :: Sorts ( ref values) = terr {
539
+ values. expected . is_primitive ( ) && values. found . is_primitive ( )
540
+ } else {
541
+ false
542
+ } ;
543
+
544
+ let mut err = self . tcx . sess . struct_span_err_with_code (
545
+ trace. origin . span ( ) ,
546
+ message,
547
+ code) ;
548
+
549
+ if !is_simple_error || check_old_school ( ) {
550
+ err. note_expected_found ( & "type" , & expected, & found) ;
551
+ }
552
+
553
+ err. span_label ( span, & terr) ;
554
+
555
+ self . note_error_origin ( & mut err, & trace. origin ) ;
556
+ self . check_and_note_conflicting_crates ( & mut err, terr, span) ;
560
557
self . tcx . note_and_explain_type_err ( & mut err, terr, span) ;
558
+
561
559
err
562
560
}
563
561
564
- /// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived
565
- /// error.
562
+ pub fn report_and_explain_type_error ( & self ,
563
+ trace : TypeTrace < ' tcx > ,
564
+ terr : & TypeError < ' tcx > )
565
+ -> DiagnosticBuilder < ' tcx >
566
+ {
567
+ // FIXME: do we want to use a different error code for each origin?
568
+ let failure_str = trace. origin . as_failure_str ( ) ;
569
+ type_err ! ( self , trace, terr, E0308 , "{}" , failure_str)
570
+ }
571
+
572
+ /// Returns a string of the form "expected `{}`, found `{}`".
566
573
fn values_str ( & self , values : & ValuePairs < ' tcx > ) -> Option < ( String , String ) > {
567
574
match * values {
568
575
infer:: Types ( ref exp_found) => self . expected_found_str ( exp_found) ,
569
576
infer:: TraitRefs ( ref exp_found) => self . expected_found_str ( exp_found) ,
570
- infer:: PolyTraitRefs ( ref exp_found) => self . expected_found_str ( exp_found)
577
+ infer:: PolyTraitRefs ( ref exp_found) => self . expected_found_str ( exp_found) ,
571
578
}
572
579
}
573
580
574
- fn expected_found_str < T : fmt:: Display + Resolvable < ' tcx > + TypeFoldable < ' tcx > > (
581
+ fn expected_found_str < T : fmt:: Display + TypeFoldable < ' tcx > > (
575
582
& self ,
576
583
exp_found : & ty:: error:: ExpectedFound < T > )
577
584
-> Option < ( String , String ) >
578
585
{
579
- let expected = exp_found . expected . resolve ( self ) ;
580
- if expected . references_error ( ) {
586
+ let exp_found = self . resolve_type_vars_if_possible ( exp_found ) ;
587
+ if exp_found . references_error ( ) {
581
588
return None ;
582
589
}
583
590
584
- let found = exp_found. found . resolve ( self ) ;
585
- if found. references_error ( ) {
586
- return None ;
587
- }
588
-
589
- Some ( ( format ! ( "{}" , expected) , format ! ( "{}" , found) ) )
591
+ Some ( ( format ! ( "{}" , exp_found. expected) , format ! ( "{}" , exp_found. found) ) )
590
592
}
591
593
592
594
fn report_generic_bound_failure ( & self ,
@@ -1609,68 +1611,21 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1609
1611
fn note_region_origin ( & self , err : & mut DiagnosticBuilder , origin : & SubregionOrigin < ' tcx > ) {
1610
1612
match * origin {
1611
1613
infer:: Subtype ( ref trace) => {
1612
- let desc = match trace. origin {
1613
- TypeOrigin :: Misc ( _) => {
1614
- "types are compatible"
1615
- }
1616
- TypeOrigin :: MethodCompatCheck ( _) => {
1617
- "method type is compatible with trait"
1618
- }
1619
- TypeOrigin :: ExprAssignable ( _) => {
1620
- "expression is assignable"
1621
- }
1622
- TypeOrigin :: RelateTraitRefs ( _) => {
1623
- "traits are compatible"
1624
- }
1625
- TypeOrigin :: RelateSelfType ( _) => {
1626
- "self type matches impl self type"
1627
- }
1628
- TypeOrigin :: RelateOutputImplTypes ( _) => {
1629
- "trait type parameters matches those \
1630
- specified on the impl"
1631
- }
1632
- TypeOrigin :: MatchExpressionArm ( _, _, _) => {
1633
- "match arms have compatible types"
1634
- }
1635
- TypeOrigin :: IfExpression ( _) => {
1636
- "if and else have compatible types"
1637
- }
1638
- TypeOrigin :: IfExpressionWithNoElse ( _) => {
1639
- "if may be missing an else clause"
1640
- }
1641
- TypeOrigin :: RangeExpression ( _) => {
1642
- "start and end of range have compatible types"
1643
- }
1644
- TypeOrigin :: EquatePredicate ( _) => {
1645
- "equality where clause is satisfied"
1646
- }
1647
- TypeOrigin :: MainFunctionType ( _) => {
1648
- "the `main` function has the correct type"
1649
- }
1650
- TypeOrigin :: StartFunctionType ( _) => {
1651
- "the `start` function has the correct type"
1652
- }
1653
- TypeOrigin :: IntrinsicType ( _) => {
1654
- "the intrinsic has the correct type"
1655
- }
1656
- } ;
1657
-
1658
- match self . values_str ( & trace. values ) {
1659
- Some ( ( expected, found) ) => {
1660
- err. span_note (
1661
- trace. origin . span ( ) ,
1662
- & format ! ( "...so that {} (expected {}, found {})" ,
1663
- desc, expected, found) ) ;
1664
- }
1665
- None => {
1666
- // Really should avoid printing this error at
1667
- // all, since it is derived, but that would
1668
- // require more refactoring than I feel like
1669
- // doing right now. - nmatsakis
1670
- err. span_note (
1671
- trace. origin . span ( ) ,
1672
- & format ! ( "...so that {}" , desc) ) ;
1673
- }
1614
+ if let Some ( ( expected, found) ) = self . values_str ( & trace. values ) {
1615
+ // FIXME: do we want a "the" here?
1616
+ err. span_note (
1617
+ trace. origin . span ( ) ,
1618
+ & format ! ( "...so that {} (expected {}, found {})" ,
1619
+ trace. origin. as_requirement_str( ) , expected, found) ) ;
1620
+ } else {
1621
+ // FIXME: this really should be handled at some earlier stage. Our
1622
+ // handling of region checking when type errors are present is
1623
+ // *terrible*.
1624
+
1625
+ err. span_note (
1626
+ trace. origin . span ( ) ,
1627
+ & format ! ( "...so that {}" ,
1628
+ trace. origin. as_requirement_str( ) ) ) ;
1674
1629
}
1675
1630
}
1676
1631
infer:: Reborrow ( span) => {
@@ -1813,32 +1768,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
1813
1768
}
1814
1769
}
1815
1770
1816
- pub trait Resolvable < ' tcx > {
1817
- fn resolve < ' a , ' gcx > ( & self , infcx : & InferCtxt < ' a , ' gcx , ' tcx > ) -> Self ;
1818
- }
1819
-
1820
- impl < ' tcx > Resolvable < ' tcx > for Ty < ' tcx > {
1821
- fn resolve < ' a , ' gcx > ( & self , infcx : & InferCtxt < ' a , ' gcx , ' tcx > ) -> Ty < ' tcx > {
1822
- infcx. resolve_type_vars_if_possible ( self )
1823
- }
1824
- }
1825
-
1826
- impl < ' tcx > Resolvable < ' tcx > for ty:: TraitRef < ' tcx > {
1827
- fn resolve < ' a , ' gcx > ( & self , infcx : & InferCtxt < ' a , ' gcx , ' tcx > )
1828
- -> ty:: TraitRef < ' tcx > {
1829
- infcx. resolve_type_vars_if_possible ( self )
1830
- }
1831
- }
1832
-
1833
- impl < ' tcx > Resolvable < ' tcx > for ty:: PolyTraitRef < ' tcx > {
1834
- fn resolve < ' a , ' gcx > ( & self ,
1835
- infcx : & InferCtxt < ' a , ' gcx , ' tcx > )
1836
- -> ty:: PolyTraitRef < ' tcx >
1837
- {
1838
- infcx. resolve_type_vars_if_possible ( self )
1839
- }
1840
- }
1841
-
1842
1771
fn lifetimes_in_scope < ' a , ' gcx , ' tcx > ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
1843
1772
scope_id : ast:: NodeId )
1844
1773
-> Vec < hir:: LifetimeDef > {
0 commit comments