@@ -18,13 +18,15 @@ use rustc_middle::infer::unify_key::{
18
18
} ;
19
19
use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AutoBorrow } ;
20
20
use rustc_middle:: ty:: print:: { FmtPrinter , PrettyPrinter , Print , Printer } ;
21
- use rustc_middle:: ty:: { self , InferConst } ;
22
- use rustc_middle:: ty:: { GenericArg , GenericArgKind , GenericArgsRef } ;
23
- use rustc_middle:: ty:: { IsSuggestable , Ty , TyCtxt , TypeckResults } ;
21
+ use rustc_middle:: ty:: {
22
+ self , GenericArg , GenericArgKind , GenericArgsRef , InferConst , IsSuggestable , Ty , TyCtxt ,
23
+ TypeFoldable , TypeFolder , TypeSuperFoldable , TypeckResults ,
24
+ } ;
24
25
use rustc_span:: symbol:: { kw, sym, Ident } ;
25
- use rustc_span:: { BytePos , Span } ;
26
+ use rustc_span:: { BytePos , Span , DUMMY_SP } ;
26
27
use std:: borrow:: Cow ;
27
28
use std:: iter;
29
+ use std:: path:: PathBuf ;
28
30
29
31
pub enum TypeAnnotationNeeded {
30
32
/// ```compile_fail,E0282
@@ -153,6 +155,29 @@ impl UnderspecifiedArgKind {
153
155
}
154
156
}
155
157
158
+ struct ClosureEraser < ' tcx > {
159
+ tcx : TyCtxt < ' tcx > ,
160
+ }
161
+
162
+ impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for ClosureEraser < ' tcx > {
163
+ fn interner ( & self ) -> TyCtxt < ' tcx > {
164
+ self . tcx
165
+ }
166
+
167
+ fn fold_ty ( & mut self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
168
+ match ty. kind ( ) {
169
+ ty:: Closure ( _, args) => {
170
+ let closure_sig = args. as_closure ( ) . sig ( ) ;
171
+ Ty :: new_fn_ptr (
172
+ self . tcx ,
173
+ self . tcx . signature_unclosure ( closure_sig, hir:: Unsafety :: Normal ) ,
174
+ )
175
+ }
176
+ _ => ty. super_fold_with ( self ) ,
177
+ }
178
+ }
179
+ }
180
+
156
181
fn fmt_printer < ' a , ' tcx > ( infcx : & ' a InferCtxt < ' tcx > , ns : Namespace ) -> FmtPrinter < ' a , ' tcx > {
157
182
let mut printer = FmtPrinter :: new ( infcx. tcx , ns) ;
158
183
let ty_getter = move |ty_vid| {
@@ -209,6 +234,10 @@ fn ty_to_string<'tcx>(
209
234
) -> String {
210
235
let mut printer = fmt_printer ( infcx, Namespace :: TypeNS ) ;
211
236
let ty = infcx. resolve_vars_if_possible ( ty) ;
237
+ // We use `fn` ptr syntax for closures, but this only works when the closure
238
+ // does not capture anything.
239
+ let ty = ty. fold_with ( & mut ClosureEraser { tcx : infcx. tcx } ) ;
240
+
212
241
match ( ty. kind ( ) , called_method_def_id) {
213
242
// We don't want the regular output for `fn`s because it includes its path in
214
243
// invalid pseudo-syntax, we want the `fn`-pointer output instead.
@@ -223,11 +252,6 @@ fn ty_to_string<'tcx>(
223
252
"Vec<_>" . to_string ( )
224
253
}
225
254
_ if ty. is_ty_or_numeric_infer ( ) => "/* Type */" . to_string ( ) ,
226
- // FIXME: The same thing for closures, but this only works when the closure
227
- // does not capture anything.
228
- //
229
- // We do have to hide the `extern "rust-call"` ABI in that case though,
230
- // which is too much of a bother for now.
231
255
_ => {
232
256
ty. print ( & mut printer) . unwrap ( ) ;
233
257
printer. into_buffer ( )
@@ -387,6 +411,8 @@ impl<'tcx> InferCtxt<'tcx> {
387
411
infer_subdiags,
388
412
multi_suggestions,
389
413
bad_label,
414
+ was_written : None ,
415
+ path : Default :: default ( ) ,
390
416
} ) ,
391
417
TypeAnnotationNeeded :: E0283 => self . dcx ( ) . create_err ( AmbiguousImpl {
392
418
span,
@@ -396,6 +422,8 @@ impl<'tcx> InferCtxt<'tcx> {
396
422
infer_subdiags,
397
423
multi_suggestions,
398
424
bad_label,
425
+ was_written : None ,
426
+ path : Default :: default ( ) ,
399
427
} ) ,
400
428
TypeAnnotationNeeded :: E0284 => self . dcx ( ) . create_err ( AmbiguousReturn {
401
429
span,
@@ -405,6 +433,8 @@ impl<'tcx> InferCtxt<'tcx> {
405
433
infer_subdiags,
406
434
multi_suggestions,
407
435
bad_label,
436
+ was_written : None ,
437
+ path : Default :: default ( ) ,
408
438
} ) ,
409
439
}
410
440
}
@@ -442,7 +472,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
442
472
return self . bad_inference_failure_err ( failure_span, arg_data, error_code) ;
443
473
} ;
444
474
445
- let ( source_kind, name) = kind. ty_localized_msg ( self ) ;
475
+ let ( source_kind, name, path ) = kind. ty_localized_msg ( self ) ;
446
476
let failure_span = if should_label_span && !failure_span. overlaps ( span) {
447
477
Some ( failure_span)
448
478
} else {
@@ -518,15 +548,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
518
548
GenericArgKind :: Lifetime ( _) => bug ! ( "unexpected lifetime" ) ,
519
549
GenericArgKind :: Type ( _) => self
520
550
. next_ty_var ( TypeVariableOrigin {
521
- span : rustc_span :: DUMMY_SP ,
551
+ span : DUMMY_SP ,
522
552
kind : TypeVariableOriginKind :: MiscVariable ,
523
553
} )
524
554
. into ( ) ,
525
555
GenericArgKind :: Const ( arg) => self
526
556
. next_const_var (
527
557
arg. ty ( ) ,
528
558
ConstVariableOrigin {
529
- span : rustc_span :: DUMMY_SP ,
559
+ span : DUMMY_SP ,
530
560
kind : ConstVariableOriginKind :: MiscVariable ,
531
561
} ,
532
562
)
@@ -547,7 +577,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
547
577
}
548
578
InferSourceKind :: FullyQualifiedMethodCall { receiver, successor, args, def_id } => {
549
579
let placeholder = Some ( self . next_ty_var ( TypeVariableOrigin {
550
- span : rustc_span :: DUMMY_SP ,
580
+ span : DUMMY_SP ,
551
581
kind : TypeVariableOriginKind :: MiscVariable ,
552
582
} ) ) ;
553
583
if let Some ( args) = args. make_suggestable ( self . infcx . tcx , true , placeholder) {
@@ -584,7 +614,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
584
614
}
585
615
InferSourceKind :: ClosureReturn { ty, data, should_wrap_expr } => {
586
616
let placeholder = Some ( self . next_ty_var ( TypeVariableOrigin {
587
- span : rustc_span :: DUMMY_SP ,
617
+ span : DUMMY_SP ,
588
618
kind : TypeVariableOriginKind :: MiscVariable ,
589
619
} ) ) ;
590
620
if let Some ( ty) = ty. make_suggestable ( self . infcx . tcx , true , placeholder) {
@@ -606,6 +636,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
606
636
infer_subdiags,
607
637
multi_suggestions,
608
638
bad_label : None ,
639
+ was_written : path. as_ref ( ) . map ( |_| ( ) ) ,
640
+ path : path. unwrap_or_default ( ) ,
609
641
} ) ,
610
642
TypeAnnotationNeeded :: E0283 => self . dcx ( ) . create_err ( AmbiguousImpl {
611
643
span,
@@ -615,6 +647,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
615
647
infer_subdiags,
616
648
multi_suggestions,
617
649
bad_label : None ,
650
+ was_written : path. as_ref ( ) . map ( |_| ( ) ) ,
651
+ path : path. unwrap_or_default ( ) ,
618
652
} ) ,
619
653
TypeAnnotationNeeded :: E0284 => self . dcx ( ) . create_err ( AmbiguousReturn {
620
654
span,
@@ -624,6 +658,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
624
658
infer_subdiags,
625
659
multi_suggestions,
626
660
bad_label : None ,
661
+ was_written : path. as_ref ( ) . map ( |_| ( ) ) ,
662
+ path : path. unwrap_or_default ( ) ,
627
663
} ) ,
628
664
}
629
665
}
@@ -688,22 +724,23 @@ impl<'tcx> InferSource<'tcx> {
688
724
}
689
725
690
726
impl < ' tcx > InferSourceKind < ' tcx > {
691
- fn ty_localized_msg ( & self , infcx : & InferCtxt < ' tcx > ) -> ( & ' static str , String ) {
727
+ fn ty_localized_msg ( & self , infcx : & InferCtxt < ' tcx > ) -> ( & ' static str , String , Option < PathBuf > ) {
728
+ let mut path = None ;
692
729
match * self {
693
730
InferSourceKind :: LetBinding { ty, .. }
694
731
| InferSourceKind :: ClosureArg { ty, .. }
695
732
| InferSourceKind :: ClosureReturn { ty, .. } => {
696
733
if ty. is_closure ( ) {
697
- ( "closure" , closure_as_fn_str ( infcx, ty) )
734
+ ( "closure" , closure_as_fn_str ( infcx, ty) , path )
698
735
} else if !ty. is_ty_or_numeric_infer ( ) {
699
- ( "normal" , ty_to_string ( infcx, ty, None ) )
736
+ ( "normal" , infcx. tcx . short_ty_string ( ty, & mut path ) , path )
700
737
} else {
701
- ( "other" , String :: new ( ) )
738
+ ( "other" , String :: new ( ) , path )
702
739
}
703
740
}
704
741
// FIXME: We should be able to add some additional info here.
705
742
InferSourceKind :: GenericArg { .. }
706
- | InferSourceKind :: FullyQualifiedMethodCall { .. } => ( "other" , String :: new ( ) ) ,
743
+ | InferSourceKind :: FullyQualifiedMethodCall { .. } => ( "other" , String :: new ( ) , path ) ,
707
744
}
708
745
}
709
746
}
0 commit comments