about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2024-04-10 20:55:23 +0000
committerEsteban Küber <esteban@kuber.com.ar>2024-04-10 23:58:36 +0000
commit1eda0565fa024a7bbb753c0a5a534b75428dd196 (patch)
treeda409135908036eb5f51653cf16e803d0ee7ffb2
parente17388b8097e48d25ccdde4cf5738d73b9a38052 (diff)
downloadrust-1eda0565fa024a7bbb753c0a5a534b75428dd196.tar.gz
rust-1eda0565fa024a7bbb753c0a5a534b75428dd196.zip
Handle more cases of "values to suggest" given a type
Add handling for `String`, `Box`, `Option` and `Result`.
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs19
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs12
-rw-r--r--tests/ui/asm/aarch64/type-check-2-2.stderr8
-rw-r--r--tests/ui/borrowck/borrowck-uninit-ref-chain.stderr4
-rw-r--r--tests/ui/borrowck/issue-103250.stderr4
-rw-r--r--tests/ui/loops/loop-break-value.stderr4
6 files changed, 38 insertions, 13 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 55c434078db..272fb6c608c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -655,8 +655,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
     fn ty_kind_suggestion(&self, ty: Ty<'tcx>) -> Option<String> {
         // Keep in sync with `rustc_hir_analysis/src/check/mod.rs:ty_kind_suggestion`.
         // FIXME: deduplicate the above.
+        let tcx = self.infcx.tcx;
         let implements_default = |ty| {
-            let Some(default_trait) = self.infcx.tcx.get_diagnostic_item(sym::Default) else {
+            let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
                 return false;
             };
             self.infcx
@@ -671,9 +672,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             ty::Int(_) | ty::Uint(_) => "42".into(),
             ty::Float(_) => "3.14159".into(),
             ty::Slice(_) => "[]".to_string(),
-            ty::Adt(def, _) if Some(def.did()) == self.infcx.tcx.get_diagnostic_item(sym::Vec) => {
+            ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => {
                 "vec![]".to_string()
             }
+            ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::String) => {
+                "String::new()".to_string()
+            }
+            ty::Adt(def, args) if def.is_box() => {
+                format!("Box::new({})", self.ty_kind_suggestion(args[0].expect_ty())?)
+            }
+            ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Option) => {
+                "None".to_string()
+            }
+            ty::Adt(def, args) if Some(def.did()) == tcx.get_diagnostic_item(sym::Result) => {
+                format!("Ok({})", self.ty_kind_suggestion(args[0].expect_ty())?)
+            }
             ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
             ty::Ref(_, ty, mutability) => {
                 if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) {
@@ -688,7 +701,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             ty::Array(ty, len) => format!(
                 "[{}; {}]",
                 self.ty_kind_suggestion(*ty)?,
-                len.eval_target_usize(self.infcx.tcx, ty::ParamEnv::reveal_all()),
+                len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()),
             ),
             ty::Tuple(tys) => format!(
                 "({})",
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 11217c2796c..938c0a19e33 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -490,6 +490,18 @@ pub fn ty_kind_suggestion<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Strin
         ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => {
             "vec![]".to_string()
         }
+        ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::String) => {
+            "String::new()".to_string()
+        }
+        ty::Adt(def, args) if def.is_box() => {
+            format!("Box::new({})", ty_kind_suggestion(args[0].expect_ty(), tcx)?)
+        }
+        ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Option) => {
+            "None".to_string()
+        }
+        ty::Adt(def, args) if Some(def.did()) == tcx.get_diagnostic_item(sym::Result) => {
+            format!("Ok({})", ty_kind_suggestion(args[0].expect_ty(), tcx)?)
+        }
         ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
         ty::Ref(_, ty, mutability) => {
             if let (ty::Str, Mutability::Not) = (ty.kind(), mutability) {
diff --git a/tests/ui/asm/aarch64/type-check-2-2.stderr b/tests/ui/asm/aarch64/type-check-2-2.stderr
index 41f7c01dc82..760aaefac83 100644
--- a/tests/ui/asm/aarch64/type-check-2-2.stderr
+++ b/tests/ui/asm/aarch64/type-check-2-2.stderr
@@ -8,8 +8,8 @@ LL |         asm!("{}", in(reg) x);
    |
 help: consider assigning a value
    |
-LL |         let x: u64 = 0;
-   |                    +++
+LL |         let x: u64 = 42;
+   |                    ++++
 
 error[E0381]: used binding `y` isn't initialized
   --> $DIR/type-check-2-2.rs:22:9
@@ -21,8 +21,8 @@ LL |         asm!("{}", inout(reg) y);
    |
 help: consider assigning a value
    |
-LL |         let mut y: u64 = 0;
-   |                        +++
+LL |         let mut y: u64 = 42;
+   |                        ++++
 
 error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
   --> $DIR/type-check-2-2.rs:28:13
diff --git a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr
index f3a7f155591..d6759b8e1cf 100644
--- a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr
+++ b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr
@@ -8,8 +8,8 @@ LL |     let _y = &**x;
    |
 help: consider assigning a value
    |
-LL |     let x: &&Box<i32> = &&Default::default();
-   |                       ++++++++++++++++++++++
+LL |     let x: &&Box<i32> = &&Box::new(42);
+   |                       ++++++++++++++++
 
 error[E0381]: used binding `x` isn't initialized
   --> $DIR/borrowck-uninit-ref-chain.rs:11:14
diff --git a/tests/ui/borrowck/issue-103250.stderr b/tests/ui/borrowck/issue-103250.stderr
index 479c61631ba..104bded5b0b 100644
--- a/tests/ui/borrowck/issue-103250.stderr
+++ b/tests/ui/borrowck/issue-103250.stderr
@@ -9,8 +9,8 @@ LL |         Err(last_error)
    |
 help: consider assigning a value
    |
-LL |         let mut last_error: Box<dyn std::error::Error> = value;
-   |                                                        +++++++
+LL |         let mut last_error: Box<dyn std::error::Error> = Box::new(value);
+   |                                                        +++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/loops/loop-break-value.stderr b/tests/ui/loops/loop-break-value.stderr
index 6d148f0bfc0..0093182422e 100644
--- a/tests/ui/loops/loop-break-value.stderr
+++ b/tests/ui/loops/loop-break-value.stderr
@@ -204,8 +204,8 @@ LL |         break;
            found unit type `()`
 help: give the `break` a value of the expected type
    |
-LL |         break Default::default();
-   |               ++++++++++++++++++
+LL |         break None;
+   |               ++++
 
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:77:26