about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-04-14 09:10:57 -0400
committerMichael Goulet <michael@errs.io>2024-04-14 09:42:53 -0400
commitd6ac50e54722efc02cec9d06037e004d14881e64 (patch)
tree01b8f1c4d0a94b8a7db461c0931b71623809c363 /compiler/rustc_trait_selection/src
parent78bc0a5656337478cb4163d01ee4429bab5087a9 (diff)
downloadrust-d6ac50e54722efc02cec9d06037e004d14881e64.tar.gz
rust-d6ac50e54722efc02cec9d06037e004d14881e64.zip
Consolidate two copies of ty_kind_suggestion
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs58
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.