@@ -2725,6 +2725,20 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
27252725
27262726 let tcx = self . tcx ;
27272727 let predicate = predicate. upcast ( tcx) ;
2728+ let suggest_remove_deref = |err : & mut Diag < ' _ , G > , expr : & hir:: Expr < ' _ > | {
2729+ if let Some ( pred) = predicate. as_trait_clause ( )
2730+ && tcx. is_lang_item ( pred. def_id ( ) , LangItem :: Sized )
2731+ && let hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , inner) = expr. kind
2732+ {
2733+ err. span_suggestion_verbose (
2734+ expr. span . until ( inner. span ) ,
2735+ "references are always `Sized`, even if they point to unsized data; consider \
2736+ not dereferencing the expression",
2737+ String :: new ( ) ,
2738+ Applicability :: MaybeIncorrect ,
2739+ ) ;
2740+ }
2741+ } ;
27282742 match * cause_code {
27292743 ObligationCauseCode :: ExprAssignable
27302744 | ObligationCauseCode :: MatchExpressionArm { .. }
@@ -2771,6 +2785,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
27712785 | ObligationCauseCode :: WhereClauseInExpr ( item_def_id, span, ..)
27722786 if !span. is_dummy ( ) =>
27732787 {
2788+ if let ObligationCauseCode :: WhereClauseInExpr ( _, _, hir_id, pos) = & cause_code {
2789+ if let Node :: Expr ( expr) = tcx. parent_hir_node ( * hir_id)
2790+ && let hir:: ExprKind :: Call ( _, args) = expr. kind
2791+ && let Some ( expr) = args. get ( * pos)
2792+ {
2793+ suggest_remove_deref ( err, & expr) ;
2794+ } else if let Node :: Expr ( expr) = self . tcx . hir_node ( * hir_id)
2795+ && let hir:: ExprKind :: MethodCall ( _, _, args, _) = expr. kind
2796+ && let Some ( expr) = args. get ( * pos)
2797+ {
2798+ suggest_remove_deref ( err, & expr) ;
2799+ }
2800+ }
27742801 let item_name = tcx. def_path_str ( item_def_id) ;
27752802 let short_item_name = with_forced_trimmed_paths ! ( tcx. def_path_str( item_def_id) ) ;
27762803 let mut multispan = MultiSpan :: from ( span) ;
@@ -2968,6 +2995,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
29682995 ) ) ;
29692996 err. downgrade_to_delayed_bug ( ) ;
29702997 }
2998+ let mut local = true ;
29712999 match tcx. parent_hir_node ( hir_id) {
29723000 Node :: LetStmt ( hir:: LetStmt { ty : Some ( ty) , .. } ) => {
29733001 err. span_suggestion_verbose (
@@ -2976,7 +3004,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
29763004 "&" ,
29773005 Applicability :: MachineApplicable ,
29783006 ) ;
2979- err. note ( "all local variables must have a statically known size" ) ;
29803007 }
29813008 Node :: LetStmt ( hir:: LetStmt {
29823009 init : Some ( hir:: Expr { kind : hir:: ExprKind :: Index ( ..) , span, .. } ) ,
@@ -2991,7 +3018,11 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
29913018 "&" ,
29923019 Applicability :: MachineApplicable ,
29933020 ) ;
2994- err. note ( "all local variables must have a statically known size" ) ;
3021+ }
3022+ Node :: LetStmt ( hir:: LetStmt { init : Some ( expr) , .. } ) => {
3023+ // When encountering an assignment of an unsized trait, like `let x = *"";`,
3024+ // we check if the RHS is a deref operation, to suggest removing it.
3025+ suggest_remove_deref ( err, & expr) ;
29953026 }
29963027 Node :: Param ( param) => {
29973028 err. span_suggestion_verbose (
@@ -3001,10 +3032,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
30013032 "&" ,
30023033 Applicability :: MachineApplicable ,
30033034 ) ;
3035+ local = false ;
30043036 }
3005- _ => {
3006- err. note ( "all local variables must have a statically known size" ) ;
3007- }
3037+ _ => { }
3038+ }
3039+ if local {
3040+ err. note ( "all local variables must have a statically known size" ) ;
30083041 }
30093042 if !tcx. features ( ) . unsized_locals {
30103043 err. help ( "unsized locals are gated as an unstable feature" ) ;
@@ -3527,14 +3560,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
35273560 ) ;
35283561 }
35293562 ObligationCauseCode :: OpaqueReturnType ( expr_info) => {
3530- if let Some ( ( expr_ty, expr_span ) ) = expr_info {
3563+ if let Some ( ( expr_ty, hir_id ) ) = expr_info {
35313564 let expr_ty = self . tcx . short_ty_string ( expr_ty, & mut long_ty_file) ;
3565+ let expr = self . infcx . tcx . hir ( ) . expect_expr ( hir_id) ;
35323566 err. span_label (
3533- expr_span ,
3567+ expr . span ,
35343568 with_forced_trimmed_paths ! ( format!(
35353569 "return type was inferred to be `{expr_ty}` here" ,
35363570 ) ) ,
35373571 ) ;
3572+ suggest_remove_deref ( err, & expr) ;
35383573 }
35393574 }
35403575 }
0 commit comments