@@ -81,6 +81,7 @@ use rustc_errors::ErrorGuaranteed;
81
81
use rustc_errors:: { pluralize, struct_span_code_err, Diag } ;
82
82
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
83
83
use rustc_hir:: intravisit:: Visitor ;
84
+ use rustc_hir:: Mutability ;
84
85
use rustc_index:: bit_set:: BitSet ;
85
86
use rustc_infer:: infer:: error_reporting:: ObligationCauseExt as _;
86
87
use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
@@ -91,10 +92,11 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
91
92
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
92
93
use rustc_middle:: ty:: { GenericArgs , GenericArgsRef } ;
93
94
use rustc_session:: parse:: feature_err;
94
- use rustc_span:: symbol:: { kw, Ident } ;
95
- use rustc_span:: { self , def_id:: CRATE_DEF_ID , BytePos , Span , Symbol , DUMMY_SP } ;
95
+ use rustc_span:: symbol:: { kw, sym , Ident } ;
96
+ use rustc_span:: { def_id:: CRATE_DEF_ID , BytePos , Span , Symbol , DUMMY_SP } ;
96
97
use rustc_target:: abi:: VariantIdx ;
97
98
use rustc_target:: spec:: abi:: Abi ;
99
+ use rustc_trait_selection:: infer:: InferCtxtExt ;
98
100
use rustc_trait_selection:: traits:: error_reporting:: suggestions:: ReturnsVisitor ;
99
101
use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
100
102
use rustc_trait_selection:: traits:: ObligationCtxt ;
@@ -466,14 +468,64 @@ fn fn_sig_suggestion<'tcx>(
466
468
)
467
469
}
468
470
469
- pub fn ty_kind_suggestion ( ty : Ty < ' _ > ) -> Option < & ' static str > {
471
+ pub fn ty_kind_suggestion < ' tcx > ( ty : Ty < ' tcx > , tcx : TyCtxt < ' tcx > ) -> Option < String > {
472
+ // Keep in sync with `rustc_borrowck/src/diagnostics/conflict_errors.rs:ty_kind_suggestion`.
473
+ // FIXME: deduplicate the above.
474
+ let implements_default = |ty| {
475
+ let Some ( default_trait) = tcx. get_diagnostic_item ( sym:: Default ) else {
476
+ return false ;
477
+ } ;
478
+ let infcx = tcx. infer_ctxt ( ) . build ( ) ;
479
+ infcx
480
+ . type_implements_trait ( default_trait, [ ty] , ty:: ParamEnv :: reveal_all ( ) )
481
+ . must_apply_modulo_regions ( )
482
+ } ;
470
483
Some ( match ty. kind ( ) {
471
- ty:: Bool => "true" ,
472
- ty:: Char => "'a'" ,
473
- ty:: Int ( _) | ty:: Uint ( _) => "42" ,
474
- ty:: Float ( _) => "3.14159" ,
475
- ty:: Error ( _) | ty:: Never => return None ,
476
- _ => "value" ,
484
+ ty:: Never | ty:: Error ( _) => return None ,
485
+ ty:: Bool => "false" . to_string ( ) ,
486
+ ty:: Char => "\' x\' " . to_string ( ) ,
487
+ ty:: Int ( _) | ty:: Uint ( _) => "42" . into ( ) ,
488
+ ty:: Float ( _) => "3.14159" . into ( ) ,
489
+ ty:: Slice ( _) => "[]" . to_string ( ) ,
490
+ ty:: Adt ( def, _) if Some ( def. did ( ) ) == tcx. get_diagnostic_item ( sym:: Vec ) => {
491
+ "vec![]" . to_string ( )
492
+ }
493
+ ty:: Adt ( def, _) if Some ( def. did ( ) ) == tcx. get_diagnostic_item ( sym:: String ) => {
494
+ "String::new()" . to_string ( )
495
+ }
496
+ ty:: Adt ( def, args) if def. is_box ( ) => {
497
+ format ! ( "Box::new({})" , ty_kind_suggestion( args[ 0 ] . expect_ty( ) , tcx) ?)
498
+ }
499
+ ty:: Adt ( def, _) if Some ( def. did ( ) ) == tcx. get_diagnostic_item ( sym:: Option ) => {
500
+ "None" . to_string ( )
501
+ }
502
+ ty:: Adt ( def, args) if Some ( def. did ( ) ) == tcx. get_diagnostic_item ( sym:: Result ) => {
503
+ format ! ( "Ok({})" , ty_kind_suggestion( args[ 0 ] . expect_ty( ) , tcx) ?)
504
+ }
505
+ ty:: Adt ( _, _) if implements_default ( ty) => "Default::default()" . to_string ( ) ,
506
+ ty:: Ref ( _, ty, mutability) => {
507
+ if let ( ty:: Str , Mutability :: Not ) = ( ty. kind ( ) , mutability) {
508
+ "\" \" " . to_string ( )
509
+ } else {
510
+ let Some ( ty) = ty_kind_suggestion ( * ty, tcx) else {
511
+ return None ;
512
+ } ;
513
+ format ! ( "&{}{ty}" , mutability. prefix_str( ) )
514
+ }
515
+ }
516
+ ty:: Array ( ty, len) => format ! (
517
+ "[{}; {}]" ,
518
+ ty_kind_suggestion( * ty, tcx) ?,
519
+ len. eval_target_usize( tcx, ty:: ParamEnv :: reveal_all( ) ) ,
520
+ ) ,
521
+ ty:: Tuple ( tys) => format ! (
522
+ "({})" ,
523
+ tys. iter( )
524
+ . map( |ty| ty_kind_suggestion( ty, tcx) )
525
+ . collect:: <Option <Vec <String >>>( ) ?
526
+ . join( ", " )
527
+ ) ,
528
+ _ => "value" . to_string ( ) ,
477
529
} )
478
530
}
479
531
@@ -511,7 +563,7 @@ fn suggestion_signature<'tcx>(
511
563
}
512
564
ty:: AssocKind :: Const => {
513
565
let ty = tcx. type_of ( assoc. def_id ) . instantiate_identity ( ) ;
514
- let val = ty_kind_suggestion ( ty) . unwrap_or ( "todo!()" ) ;
566
+ let val = ty_kind_suggestion ( ty, tcx ) . unwrap_or_else ( || "value" . to_string ( ) ) ;
515
567
format ! ( "const {}: {} = {};" , assoc. name, ty, val)
516
568
}
517
569
}
0 commit comments