diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 55c434078db93..272fb6c608c06 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 { // 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 11217c2796c74..938c0a19e338f 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 { "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/borrowck/borrowck-uninit-ref-chain.stderr b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr index f3a7f15559132..d6759b8e1cf45 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 = &&Default::default(); - | ++++++++++++++++++++++ +LL | let x: &&Box = &&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 479c61631baae..104bded5b0b53 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 = value; - | +++++++ +LL | let mut last_error: Box = 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 6d148f0bfc057..0093182422e1b 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