@@ -2725,6 +2725,31 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
2725
2725
2726
2726
let tcx = self . tcx ;
2727
2727
let predicate = predicate. upcast ( tcx) ;
2728
+ info ! ( ?predicate, ?cause_code) ;
2729
+ let suggest_remove_deref = |err : & mut Diag < ' _ , G > , expr : & hir:: Expr < ' _ > | {
2730
+ if let Some ( pred) = predicate. as_trait_clause ( )
2731
+ && tcx. is_lang_item ( pred. def_id ( ) , LangItem :: Sized )
2732
+ && let hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , inner) = expr. kind
2733
+ {
2734
+ let like_ty = match self
2735
+ . typeck_results
2736
+ . as_ref ( )
2737
+ . and_then ( |t| t. expr_ty_adjusted_opt ( inner) )
2738
+ {
2739
+ Some ( ty) => format ! ( " like `{}`" , self . tcx. erase_regions( ty) ) ,
2740
+ None => String :: new ( ) ,
2741
+ } ;
2742
+ err. span_suggestion_verbose (
2743
+ expr. span . until ( inner. span ) ,
2744
+ format ! (
2745
+ "references to `!Sized` types{like_ty} are `Sized`; consider not \
2746
+ dereferencing the expression",
2747
+ ) ,
2748
+ String :: new ( ) ,
2749
+ Applicability :: MaybeIncorrect ,
2750
+ ) ;
2751
+ }
2752
+ } ;
2728
2753
match * cause_code {
2729
2754
ObligationCauseCode :: ExprAssignable
2730
2755
| ObligationCauseCode :: MatchExpressionArm { .. }
@@ -2771,6 +2796,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
2771
2796
| ObligationCauseCode :: WhereClauseInExpr ( item_def_id, span, ..)
2772
2797
if !span. is_dummy ( ) =>
2773
2798
{
2799
+ if let ObligationCauseCode :: WhereClauseInExpr ( _, _, hir_id, pos) = & cause_code {
2800
+ if let Node :: Expr ( expr) = tcx. parent_hir_node ( * hir_id)
2801
+ && let hir:: ExprKind :: Call ( _, args) = expr. kind
2802
+ && let Some ( expr) = args. get ( * pos)
2803
+ {
2804
+ suggest_remove_deref ( err, & expr) ;
2805
+ } else if let Node :: Expr ( expr) = self . tcx . hir_node ( * hir_id)
2806
+ && let hir:: ExprKind :: MethodCall ( _, _, args, _) = expr. kind
2807
+ && let Some ( expr) = args. get ( * pos)
2808
+ {
2809
+ suggest_remove_deref ( err, & expr) ;
2810
+ }
2811
+ }
2774
2812
let item_name = tcx. def_path_str ( item_def_id) ;
2775
2813
let short_item_name = with_forced_trimmed_paths ! ( tcx. def_path_str( item_def_id) ) ;
2776
2814
let mut multispan = MultiSpan :: from ( span) ;
@@ -2968,6 +3006,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
2968
3006
) ) ;
2969
3007
err. downgrade_to_delayed_bug ( ) ;
2970
3008
}
3009
+ let mut local = true ;
2971
3010
match tcx. parent_hir_node ( hir_id) {
2972
3011
Node :: LetStmt ( hir:: LetStmt { ty : Some ( ty) , .. } ) => {
2973
3012
err. span_suggestion_verbose (
@@ -2976,7 +3015,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
2976
3015
"&" ,
2977
3016
Applicability :: MachineApplicable ,
2978
3017
) ;
2979
- err. note ( "all local variables must have a statically known size" ) ;
2980
3018
}
2981
3019
Node :: LetStmt ( hir:: LetStmt {
2982
3020
init : Some ( hir:: Expr { kind : hir:: ExprKind :: Index ( ..) , span, .. } ) ,
@@ -2991,7 +3029,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
2991
3029
"&" ,
2992
3030
Applicability :: MachineApplicable ,
2993
3031
) ;
2994
- err. note ( "all local variables must have a statically known size" ) ;
3032
+ }
3033
+ Node :: LetStmt ( hir:: LetStmt { init : Some ( expr) , .. } ) => {
3034
+ // When encountering an assignment of an unsized trait, like `let x = *"";`,
3035
+ // we check if the RHS is a deref operation, to suggest removing it.
3036
+ suggest_remove_deref ( err, & expr) ;
2995
3037
}
2996
3038
Node :: Param ( param) => {
2997
3039
err. span_suggestion_verbose (
@@ -3001,10 +3043,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
3001
3043
"&" ,
3002
3044
Applicability :: MachineApplicable ,
3003
3045
) ;
3046
+ local = false ;
3004
3047
}
3005
- _ => {
3006
- err. note ( "all local variables must have a statically known size" ) ;
3007
- }
3048
+ _ => { }
3049
+ }
3050
+ if local {
3051
+ err. note ( "all local variables must have a statically known size" ) ;
3008
3052
}
3009
3053
if !tcx. features ( ) . unsized_locals {
3010
3054
err. help ( "unsized locals are gated as an unstable feature" ) ;
@@ -3527,14 +3571,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
3527
3571
) ;
3528
3572
}
3529
3573
ObligationCauseCode :: OpaqueReturnType ( expr_info) => {
3530
- if let Some ( ( expr_ty, expr_span ) ) = expr_info {
3574
+ if let Some ( ( expr_ty, hir_id ) ) = expr_info {
3531
3575
let expr_ty = self . tcx . short_ty_string ( expr_ty, & mut long_ty_file) ;
3576
+ let expr = self . infcx . tcx . hir ( ) . expect_expr ( hir_id) ;
3532
3577
err. span_label (
3533
- expr_span ,
3578
+ expr . span ,
3534
3579
with_forced_trimmed_paths ! ( format!(
3535
3580
"return type was inferred to be `{expr_ty}` here" ,
3536
3581
) ) ,
3537
3582
) ;
3583
+ suggest_remove_deref ( err, & expr) ;
3538
3584
}
3539
3585
}
3540
3586
}
0 commit comments