Handle more cases of "values to suggest" given a type
Add handling for `String`, `Box`, `Option` and `Result`.
This commit is contained in:
parent
e17388b809
commit
1eda0565fa
6 changed files with 38 additions and 13 deletions
|
@ -655,8 +655,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
fn ty_kind_suggestion(&self, ty: Ty<'tcx>) -> Option<String> {
|
fn ty_kind_suggestion(&self, ty: Ty<'tcx>) -> Option<String> {
|
||||||
// Keep in sync with `rustc_hir_analysis/src/check/mod.rs:ty_kind_suggestion`.
|
// Keep in sync with `rustc_hir_analysis/src/check/mod.rs:ty_kind_suggestion`.
|
||||||
// FIXME: deduplicate the above.
|
// FIXME: deduplicate the above.
|
||||||
|
let tcx = self.infcx.tcx;
|
||||||
let implements_default = |ty| {
|
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;
|
return false;
|
||||||
};
|
};
|
||||||
self.infcx
|
self.infcx
|
||||||
|
@ -671,9 +672,21 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
ty::Int(_) | ty::Uint(_) => "42".into(),
|
ty::Int(_) | ty::Uint(_) => "42".into(),
|
||||||
ty::Float(_) => "3.14159".into(),
|
ty::Float(_) => "3.14159".into(),
|
||||||
ty::Slice(_) => "[]".to_string(),
|
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()
|
"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::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
|
||||||
ty::Ref(_, ty, mutability) => {
|
ty::Ref(_, ty, mutability) => {
|
||||||
if let (ty::Str, hir::Mutability::Not) = (ty.kind(), 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!(
|
ty::Array(ty, len) => format!(
|
||||||
"[{}; {}]",
|
"[{}; {}]",
|
||||||
self.ty_kind_suggestion(*ty)?,
|
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!(
|
ty::Tuple(tys) => format!(
|
||||||
"({})",
|
"({})",
|
||||||
|
|
|
@ -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) => {
|
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => {
|
||||||
"vec![]".to_string()
|
"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::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
|
||||||
ty::Ref(_, ty, mutability) => {
|
ty::Ref(_, ty, mutability) => {
|
||||||
if let (ty::Str, Mutability::Not) = (ty.kind(), mutability) {
|
if let (ty::Str, Mutability::Not) = (ty.kind(), mutability) {
|
||||||
|
|
|
@ -8,8 +8,8 @@ LL | asm!("{}", in(reg) x);
|
||||||
|
|
|
|
||||||
help: consider assigning a value
|
help: consider assigning a value
|
||||||
|
|
|
|
||||||
LL | let x: u64 = 0;
|
LL | let x: u64 = 42;
|
||||||
| +++
|
| ++++
|
||||||
|
|
||||||
error[E0381]: used binding `y` isn't initialized
|
error[E0381]: used binding `y` isn't initialized
|
||||||
--> $DIR/type-check-2-2.rs:22:9
|
--> $DIR/type-check-2-2.rs:22:9
|
||||||
|
@ -21,8 +21,8 @@ LL | asm!("{}", inout(reg) y);
|
||||||
|
|
|
|
||||||
help: consider assigning a value
|
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
|
error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
|
||||||
--> $DIR/type-check-2-2.rs:28:13
|
--> $DIR/type-check-2-2.rs:28:13
|
||||||
|
|
|
@ -8,8 +8,8 @@ LL | let _y = &**x;
|
||||||
|
|
|
|
||||||
help: consider assigning a value
|
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
|
error[E0381]: used binding `x` isn't initialized
|
||||||
--> $DIR/borrowck-uninit-ref-chain.rs:11:14
|
--> $DIR/borrowck-uninit-ref-chain.rs:11:14
|
||||||
|
|
|
@ -9,8 +9,8 @@ LL | Err(last_error)
|
||||||
|
|
|
|
||||||
help: consider assigning a value
|
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
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -204,8 +204,8 @@ LL | break;
|
||||||
found unit type `()`
|
found unit type `()`
|
||||||
help: give the `break` a value of the expected type
|
help: give the `break` a value of the expected type
|
||||||
|
|
|
|
||||||
LL | break Default::default();
|
LL | break None;
|
||||||
| ++++++++++++++++++
|
| ++++
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/loop-break-value.rs:77:26
|
--> $DIR/loop-break-value.rs:77:26
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue