Skip to content

Commit

Permalink
Handle more cases of "values to suggest" given a type
Browse files Browse the repository at this point in the history
Add handling for `String`, `Box`, `Option` and `Result`.
  • Loading branch information
estebank committed Apr 10, 2024
1 parent e17388b commit 6a1295c
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 7 deletions.
19 changes: 16 additions & 3 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) {
Expand All @@ -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!(
"({})",
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_hir_analysis/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/borrowck/borrowck-uninit-ref-chain.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/borrowck/issue-103250.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 6a1295c

Please sign in to comment.