Handle more cases of value suggestions
This commit is contained in:
parent
a983dd8563
commit
e17388b809
42 changed files with 273 additions and 133 deletions
|
@ -652,6 +652,55 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
err
|
||||
}
|
||||
|
||||
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 implements_default = |ty| {
|
||||
let Some(default_trait) = self.infcx.tcx.get_diagnostic_item(sym::Default) else {
|
||||
return false;
|
||||
};
|
||||
self.infcx
|
||||
.type_implements_trait(default_trait, [ty], self.param_env)
|
||||
.must_apply_modulo_regions()
|
||||
};
|
||||
|
||||
Some(match ty.kind() {
|
||||
ty::Never | ty::Error(_) => return None,
|
||||
ty::Bool => "false".to_string(),
|
||||
ty::Char => "\'x\'".to_string(),
|
||||
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) => {
|
||||
"vec![]".to_string()
|
||||
}
|
||||
ty::Adt(_, _) if implements_default(ty) => "Default::default()".to_string(),
|
||||
ty::Ref(_, ty, mutability) => {
|
||||
if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) {
|
||||
"\"\"".to_string()
|
||||
} else {
|
||||
let Some(ty) = self.ty_kind_suggestion(*ty) else {
|
||||
return None;
|
||||
};
|
||||
format!("&{}{ty}", mutability.prefix_str())
|
||||
}
|
||||
}
|
||||
ty::Array(ty, len) => format!(
|
||||
"[{}; {}]",
|
||||
self.ty_kind_suggestion(*ty)?,
|
||||
len.eval_target_usize(self.infcx.tcx, ty::ParamEnv::reveal_all()),
|
||||
),
|
||||
ty::Tuple(tys) => format!(
|
||||
"({})",
|
||||
tys.iter()
|
||||
.map(|ty| self.ty_kind_suggestion(ty))
|
||||
.collect::<Option<Vec<String>>>()?
|
||||
.join(", ")
|
||||
),
|
||||
_ => "value".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
fn suggest_assign_value(
|
||||
&self,
|
||||
err: &mut Diag<'_>,
|
||||
|
@ -661,24 +710,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||
let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
|
||||
debug!("ty: {:?}, kind: {:?}", ty, ty.kind());
|
||||
|
||||
let tcx = self.infcx.tcx;
|
||||
let implements_default = |ty, param_env| {
|
||||
let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else {
|
||||
return false;
|
||||
};
|
||||
self.infcx
|
||||
.type_implements_trait(default_trait, [ty], param_env)
|
||||
.must_apply_modulo_regions()
|
||||
};
|
||||
|
||||
let assign_value = match ty.kind() {
|
||||
ty::Never | ty::Error(_) => return,
|
||||
ty::Bool => "false",
|
||||
ty::Float(_) => "0.0",
|
||||
ty::Int(_) | ty::Uint(_) => "0",
|
||||
ty::Adt(def, _) if Some(def.did()) == tcx.get_diagnostic_item(sym::Vec) => "vec![]",
|
||||
ty::Adt(_, _) if implements_default(ty, self.param_env) => "Default::default()",
|
||||
_ => "value",
|
||||
let Some(assign_value) = self.ty_kind_suggestion(ty) else {
|
||||
return;
|
||||
};
|
||||
|
||||
err.span_suggestion_verbose(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue