diff options
Diffstat (limited to 'compiler/rustc_trait_selection/src')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 2067956d0f5..6ae7cbf717b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4540,6 +4540,64 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { Applicability::MachineApplicable, ); } + + fn ty_kind_suggestion(&self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> Option<String> { + let tcx = self.infcx.tcx; + let implements_default = |ty| { + let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else { + return false; + }; + self.type_implements_trait(default_trait, [ty], 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()) == 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(param_env, 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(param_env, 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) { + "\"\"".to_string() + } else { + let Some(ty) = self.ty_kind_suggestion(param_env, *ty) else { + return None; + }; + format!("&{}{ty}", mutability.prefix_str()) + } + } + ty::Array(ty, len) => format!( + "[{}; {}]", + self.ty_kind_suggestion(param_env, *ty)?, + len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()), + ), + ty::Tuple(tys) => format!( + "({})", + tys.iter() + .map(|ty| self.ty_kind_suggestion(param_env, ty)) + .collect::<Option<Vec<String>>>()? + .join(", ") + ), + _ => "value".to_string(), + }) + } } /// Add a hint to add a missing borrow or remove an unnecessary one. |
