@@ -36,37 +36,51 @@ use util::nodemap::{FnvHashMap, FnvHashSet};
3636use std:: cmp;
3737use std:: fmt;
3838use syntax:: attr:: { AttributeMethods , AttrMetaMethods } ;
39+ use syntax:: ast;
3940use syntax:: codemap:: Span ;
4041use syntax:: errors:: DiagnosticBuilder ;
4142
4243#[ derive( Debug , PartialEq , Eq , Hash ) ]
4344pub struct TraitErrorKey < ' tcx > {
4445 span : Span ,
46+ warning_node_id : Option < ast:: NodeId > ,
4547 predicate : ty:: Predicate < ' tcx >
4648}
4749
4850impl < ' tcx > TraitErrorKey < ' tcx > {
4951 fn from_error < ' a > ( infcx : & InferCtxt < ' a , ' tcx > ,
50- e : & FulfillmentError < ' tcx > ) -> Self {
52+ e : & FulfillmentError < ' tcx > ,
53+ warning_node_id : Option < ast:: NodeId > ) -> Self {
5154 let predicate =
5255 infcx. resolve_type_vars_if_possible ( & e. obligation . predicate ) ;
5356 TraitErrorKey {
5457 span : e. obligation . cause . span ,
55- predicate : infcx. tcx . erase_regions ( & predicate)
58+ predicate : infcx. tcx . erase_regions ( & predicate) ,
59+ warning_node_id : warning_node_id
5660 }
5761 }
5862}
5963
6064pub fn report_fulfillment_errors < ' a , ' tcx > ( infcx : & InferCtxt < ' a , ' tcx > ,
6165 errors : & Vec < FulfillmentError < ' tcx > > ) {
6266 for error in errors {
63- report_fulfillment_error ( infcx, error) ;
67+ report_fulfillment_error ( infcx, error, None ) ;
68+ }
69+ }
70+
71+ pub fn report_fulfillment_errors_as_warnings < ' a , ' tcx > ( infcx : & InferCtxt < ' a , ' tcx > ,
72+ errors : & Vec < FulfillmentError < ' tcx > > ,
73+ node_id : ast:: NodeId )
74+ {
75+ for error in errors {
76+ report_fulfillment_error ( infcx, error, Some ( node_id) ) ;
6477 }
6578}
6679
6780fn report_fulfillment_error < ' a , ' tcx > ( infcx : & InferCtxt < ' a , ' tcx > ,
68- error : & FulfillmentError < ' tcx > ) {
69- let error_key = TraitErrorKey :: from_error ( infcx, error) ;
81+ error : & FulfillmentError < ' tcx > ,
82+ warning_node_id : Option < ast:: NodeId > ) {
83+ let error_key = TraitErrorKey :: from_error ( infcx, error, warning_node_id) ;
7084 debug ! ( "report_fulfillment_errors({:?}) - key={:?}" ,
7185 error, error_key) ;
7286 if !infcx. reported_trait_errors . borrow_mut ( ) . insert ( error_key) {
@@ -75,10 +89,10 @@ fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
7589 }
7690 match error. code {
7791 FulfillmentErrorCode :: CodeSelectionError ( ref e) => {
78- report_selection_error ( infcx, & error. obligation , e) ;
92+ report_selection_error ( infcx, & error. obligation , e, warning_node_id ) ;
7993 }
8094 FulfillmentErrorCode :: CodeProjectionError ( ref e) => {
81- report_projection_error ( infcx, & error. obligation , e) ;
95+ report_projection_error ( infcx, & error. obligation , e, warning_node_id ) ;
8296 }
8397 FulfillmentErrorCode :: CodeAmbiguity => {
8498 maybe_report_ambiguity ( infcx, & error. obligation ) ;
@@ -88,18 +102,29 @@ fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
88102
89103pub fn report_projection_error < ' a , ' tcx > ( infcx : & InferCtxt < ' a , ' tcx > ,
90104 obligation : & PredicateObligation < ' tcx > ,
91- error : & MismatchedProjectionTypes < ' tcx > )
105+ error : & MismatchedProjectionTypes < ' tcx > ,
106+ warning_node_id : Option < ast:: NodeId > )
92107{
93108 let predicate =
94109 infcx. resolve_type_vars_if_possible ( & obligation. predicate ) ;
95110
96111 if !predicate. references_error ( ) {
97- let mut err = struct_span_err ! ( infcx. tcx. sess, obligation. cause. span, E0271 ,
98- "type mismatch resolving `{}`: {}" ,
99- predicate,
100- error. err) ;
101- note_obligation_cause ( infcx, & mut err, obligation) ;
102- err. emit ( ) ;
112+ if let Some ( warning_node_id) = warning_node_id {
113+ infcx. tcx . sess . add_lint (
114+ :: lint:: builtin:: UNSIZED_IN_TUPLE ,
115+ warning_node_id,
116+ obligation. cause . span ,
117+ format ! ( "type mismatch resolving `{}`: {}" ,
118+ predicate,
119+ error. err) ) ;
120+ } else {
121+ let mut err = struct_span_err ! ( infcx. tcx. sess, obligation. cause. span, E0271 ,
122+ "type mismatch resolving `{}`: {}" ,
123+ predicate,
124+ error. err) ;
125+ note_obligation_cause ( infcx, & mut err, obligation) ;
126+ err. emit ( ) ;
127+ }
103128 }
104129}
105130
@@ -383,7 +408,8 @@ pub fn recursive_type_with_infinite_size_error<'tcx>(tcx: &TyCtxt<'tcx>,
383408
384409pub fn report_selection_error < ' a , ' tcx > ( infcx : & InferCtxt < ' a , ' tcx > ,
385410 obligation : & PredicateObligation < ' tcx > ,
386- error : & SelectionError < ' tcx > )
411+ error : & SelectionError < ' tcx > ,
412+ warning_node_id : Option < ast:: NodeId > )
387413{
388414 match * error {
389415 SelectionError :: Unimplemented => {
@@ -401,6 +427,17 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
401427
402428 if !infcx. tcx . sess . has_errors ( ) || !trait_predicate. references_error ( ) {
403429 let trait_ref = trait_predicate. to_poly_trait_ref ( ) ;
430+
431+ if let Some ( warning_node_id) = warning_node_id {
432+ infcx. tcx . sess . add_lint (
433+ :: lint:: builtin:: UNSIZED_IN_TUPLE ,
434+ warning_node_id,
435+ obligation. cause . span ,
436+ format ! ( "the trait bound `{}` is not satisfied" ,
437+ trait_ref. to_predicate( ) ) ) ;
438+ return ;
439+ }
440+
404441 let mut err = struct_span_err ! (
405442 infcx. tcx. sess, obligation. cause. span, E0277 ,
406443 "the trait bound `{}` is not satisfied" ,
@@ -480,12 +517,15 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
480517 ty:: Predicate :: ObjectSafe ( trait_def_id) => {
481518 let violations = object_safety_violations (
482519 infcx. tcx , trait_def_id) ;
483- let mut err = report_object_safety_error ( infcx. tcx ,
484- obligation. cause . span ,
485- trait_def_id,
486- violations) ;
487- note_obligation_cause ( infcx, & mut err, obligation) ;
488- err. emit ( ) ;
520+ let err = report_object_safety_error ( infcx. tcx ,
521+ obligation. cause . span ,
522+ trait_def_id,
523+ warning_node_id,
524+ violations) ;
525+ if let Some ( mut err) = err {
526+ note_obligation_cause ( infcx, & mut err, obligation) ;
527+ err. emit ( ) ;
528+ }
489529 }
490530
491531 ty:: Predicate :: ClosureKind ( closure_def_id, kind) => {
@@ -514,6 +554,13 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
514554 "WF predicate not satisfied for {:?}" ,
515555 ty) ;
516556 }
557+
558+ ty:: Predicate :: Rfc1592 ( ref data) => {
559+ span_bug ! (
560+ obligation. cause. span,
561+ "RFC1592 predicate not satisfied for {:?}" ,
562+ data) ;
563+ }
517564 }
518565 }
519566 }
@@ -537,58 +584,84 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
537584
538585 TraitNotObjectSafe ( did) => {
539586 let violations = object_safety_violations ( infcx. tcx , did) ;
540- let mut err = report_object_safety_error ( infcx. tcx , obligation. cause . span , did,
541- violations) ;
542- note_obligation_cause ( infcx, & mut err, obligation) ;
543- err. emit ( ) ;
587+ let err = report_object_safety_error ( infcx. tcx , obligation. cause . span , did,
588+ warning_node_id,
589+ violations) ;
590+ if let Some ( mut err) = err {
591+ note_obligation_cause ( infcx, & mut err, obligation) ;
592+ err. emit ( ) ;
593+ }
544594 }
545595 }
546596}
547597
548598pub fn report_object_safety_error < ' tcx > ( tcx : & TyCtxt < ' tcx > ,
549599 span : Span ,
550600 trait_def_id : DefId ,
601+ warning_node_id : Option < ast:: NodeId > ,
551602 violations : Vec < ObjectSafetyViolation > )
552- -> DiagnosticBuilder < ' tcx >
603+ -> Option < DiagnosticBuilder < ' tcx > >
553604{
554- let mut err = struct_span_err ! (
555- tcx. sess, span, E0038 ,
556- "the trait `{}` cannot be made into an object" ,
557- tcx. item_path_str( trait_def_id) ) ;
605+ let mut err = match warning_node_id {
606+ Some ( _) => None ,
607+ None => {
608+ Some ( struct_span_err ! (
609+ tcx. sess, span, E0038 ,
610+ "the trait `{}` cannot be made into an object" ,
611+ tcx. item_path_str( trait_def_id) ) )
612+ }
613+ } ;
558614
559615 let mut reported_violations = FnvHashSet ( ) ;
560616 for violation in violations {
561617 if !reported_violations. insert ( violation. clone ( ) ) {
562618 continue ;
563619 }
564- match violation {
620+ let buf;
621+ let note = match violation {
565622 ObjectSafetyViolation :: SizedSelf => {
566- err . note ( "the trait cannot require that `Self : Sized`" ) ;
623+ "the trait cannot require that `Self : Sized`"
567624 }
568625
569626 ObjectSafetyViolation :: SupertraitSelf => {
570- err . note ( "the trait cannot use `Self` as a type parameter \
571- in the supertrait listing") ;
627+ "the trait cannot use `Self` as a type parameter \
628+ in the supertrait listing"
572629 }
573630
574631 ObjectSafetyViolation :: Method ( method,
575632 MethodViolationCode :: StaticMethod ) => {
576- err. note ( & format ! ( "method `{}` has no receiver" ,
577- method. name) ) ;
633+ buf = format ! ( "method `{}` has no receiver" ,
634+ method. name) ;
635+ & buf
578636 }
579637
580638 ObjectSafetyViolation :: Method ( method,
581639 MethodViolationCode :: ReferencesSelf ) => {
582- err . note ( & format ! ( "method `{}` references the `Self` type \
640+ buf = format ! ( "method `{}` references the `Self` type \
583641 in its arguments or return type",
584- method. name) ) ;
642+ method. name) ;
643+ & buf
585644 }
586645
587646 ObjectSafetyViolation :: Method ( method,
588647 MethodViolationCode :: Generic ) => {
589- err. note ( & format ! ( "method `{}` has generic type parameters" ,
590- method. name) ) ;
648+ buf = format ! ( "method `{}` has generic type parameters" ,
649+ method. name) ;
650+ & buf
591651 }
652+ } ;
653+ match ( warning_node_id, & mut err) {
654+ ( Some ( node_id) , & mut None ) => {
655+ tcx. sess . add_lint (
656+ :: lint:: builtin:: OBJECT_UNSAFE_FRAGMENT ,
657+ node_id,
658+ span,
659+ note. to_string ( ) ) ;
660+ }
661+ ( None , & mut Some ( ref mut err) ) => {
662+ err. note ( note) ;
663+ }
664+ _ => unreachable ! ( )
592665 }
593666 }
594667 err
@@ -764,6 +837,9 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>,
764837 ObligationCauseCode :: SliceOrArrayElem => {
765838 err. note ( "slice and array elements must have `Sized` type" ) ;
766839 }
840+ ObligationCauseCode :: TupleElem => {
841+ err. note ( "tuple elements must have `Sized` type" ) ;
842+ }
767843 ObligationCauseCode :: ProjectionWf ( data) => {
768844 err. note ( & format ! ( "required so that the projection `{}` is well-formed" ,
769845 data) ) ;
0 commit comments