Skip to content

Commit ad8bfbf

Browse files
committed
Handle more cases of "values to suggest" given a type
Add handling for `String`, `Box`, `Option` and `Result`.
1 parent e17388b commit ad8bfbf

File tree

5 files changed

+34
-9
lines changed

5 files changed

+34
-9
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+16-3
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
655655
fn ty_kind_suggestion(&self, ty: Ty<'tcx>) -> Option<String> {
656656
// Keep in sync with `rustc_hir_analysis/src/check/mod.rs:ty_kind_suggestion`.
657657
// FIXME: deduplicate the above.
658+
let tcx = self.infcx.tcx;
658659
let implements_default = |ty| {
659-
let Some(default_trait) = self.infcx.tcx.get_diagnostic_item(sym::Default) else {
660+
let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
660661
return false;
661662
};
662663
self.infcx
@@ -671,9 +672,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
671672
ty::Int(_) | ty::Uint(_) => "42".into(),
672673
ty::Float(_) => "3.14159".into(),
673674
ty::Slice(_) => "[]".to_string(),
674-
ty::Adt(def, _) if Some(def.did()) == self.infcx.tcx.get_diagnostic_item(sym::Vec) => {
675+
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => {
675676
"vec![]".to_string()
676677
}
678+
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::String) => {
679+
"String::new()".to_string()
680+
}
681+
ty::Adt(def, args) if def.is_box() => {
682+
format!("Box::new({})", self.ty_kind_suggestion(args[0].expect_ty())?)
683+
}
684+
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Option) => {
685+
"None".to_string()
686+
}
687+
ty::Adt(def, args) if Some(def.did()) == tcx.get_diagnostic_item(sym::Result) => {
688+
format!("Ok({})", self.ty_kind_suggestion(args[0].expect_ty())?)
689+
}
677690
ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
678691
ty::Ref(_, ty, mutability) => {
679692
if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) {
@@ -688,7 +701,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
688701
ty::Array(ty, len) => format!(
689702
"[{}; {}]",
690703
self.ty_kind_suggestion(*ty)?,
691-
len.eval_target_usize(self.infcx.tcx, ty::ParamEnv::reveal_all()),
704+
len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()),
692705
),
693706
ty::Tuple(tys) => format!(
694707
"({})",

compiler/rustc_hir_analysis/src/check/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,18 @@ pub fn ty_kind_suggestion<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<Strin
490490
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => {
491491
"vec![]".to_string()
492492
}
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+
}
493505
ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
494506
ty::Ref(_, ty, mutability) => {
495507
if let (ty::Str, Mutability::Not) = (ty.kind(), mutability) {

tests/ui/borrowck/borrowck-uninit-ref-chain.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ LL | let _y = &**x;
88
|
99
help: consider assigning a value
1010
|
11-
LL | let x: &&Box<i32> = &&Default::default();
12-
| ++++++++++++++++++++++
11+
LL | let x: &&Box<i32> = &&Box::new(42);
12+
| ++++++++++++++++
1313

1414
error[E0381]: used binding `x` isn't initialized
1515
--> $DIR/borrowck-uninit-ref-chain.rs:11:14

tests/ui/borrowck/issue-103250.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ LL | Err(last_error)
99
|
1010
help: consider assigning a value
1111
|
12-
LL | let mut last_error: Box<dyn std::error::Error> = value;
13-
| +++++++
12+
LL | let mut last_error: Box<dyn std::error::Error> = Box::new(value);
13+
| +++++++++++++++++
1414

1515
error: aborting due to 1 previous error
1616

tests/ui/loops/loop-break-value.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ LL | break;
204204
found unit type `()`
205205
help: give the `break` a value of the expected type
206206
|
207-
LL | break Default::default();
208-
| ++++++++++++++++++
207+
LL | break None;
208+
| ++++
209209

210210
error[E0308]: mismatched types
211211
--> $DIR/loop-break-value.rs:77:26

0 commit comments

Comments
 (0)