diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-04-11 09:31:50 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-11 09:31:50 +0200 |
| commit | 93645f481d3e3705ee6394413511ad50f1e442e2 (patch) | |
| tree | 110eabb745081481152b2cd0c2212e956e789ced /compiler/rustc_hir_analysis | |
| parent | f13f37fd7bbbc34c663311739176fe114ef51085 (diff) | |
| parent | 1eda0565fa024a7bbb753c0a5a534b75428dd196 (diff) | |
| download | rust-93645f481d3e3705ee6394413511ad50f1e442e2.tar.gz rust-93645f481d3e3705ee6394413511ad50f1e442e2.zip | |
Rollup merge of #123704 - estebank:diag-changes, r=compiler-errors
Tweak value suggestions in `borrowck` and `hir_analysis` Unify the output of `suggest_assign_value` and `ty_kind_suggestion`. Ideally we'd make these a single function, but doing so would likely require modify the crate dependency tree.
Diffstat (limited to 'compiler/rustc_hir_analysis')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/check.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/mod.rs | 72 |
2 files changed, 62 insertions, 11 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 8d4ae10d4bf..961b643fa25 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -22,7 +22,6 @@ use rustc_middle::ty::{ AdtDef, ParamEnv, RegionKind, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; -use rustc_span::symbol::sym; use rustc_target::abi::FieldIdx; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 8760901b71b..938c0a19e33 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -81,6 +81,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_errors::{pluralize, struct_span_code_err, Diag}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; +use rustc_hir::Mutability; use rustc_index::bit_set::BitSet; use rustc_infer::infer::error_reporting::ObligationCauseExt as _; use rustc_infer::infer::outlives::env::OutlivesEnvironment; @@ -91,10 +92,11 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_session::parse::feature_err; -use rustc_span::symbol::{kw, Ident}; -use rustc_span::{self, def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP}; +use rustc_span::symbol::{kw, sym, Ident}; +use rustc_span::{def_id::CRATE_DEF_ID, BytePos, Span, Symbol, DUMMY_SP}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; +use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::ObligationCtxt; @@ -466,14 +468,64 @@ fn fn_sig_suggestion<'tcx>( ) } -pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> { +pub fn ty_kind_suggestion<'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Option<String> { + // Keep in sync with `rustc_borrowck/src/diagnostics/conflict_errors.rs:ty_kind_suggestion`. + // FIXME: deduplicate the above. + let implements_default = |ty| { + let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else { + return false; + }; + let infcx = tcx.infer_ctxt().build(); + infcx + .type_implements_trait(default_trait, [ty], ty::ParamEnv::reveal_all()) + .must_apply_modulo_regions() + }; Some(match ty.kind() { - ty::Bool => "true", - ty::Char => "'a'", - ty::Int(_) | ty::Uint(_) => "42", - ty::Float(_) => "3.14159", - ty::Error(_) | ty::Never => return None, - _ => "value", + 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({})", 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) { + "\"\"".to_string() + } else { + let Some(ty) = ty_kind_suggestion(*ty, tcx) else { + return None; + }; + format!("&{}{ty}", mutability.prefix_str()) + } + } + ty::Array(ty, len) => format!( + "[{}; {}]", + ty_kind_suggestion(*ty, tcx)?, + len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()), + ), + ty::Tuple(tys) => format!( + "({})", + tys.iter() + .map(|ty| ty_kind_suggestion(ty, tcx)) + .collect::<Option<Vec<String>>>()? + .join(", ") + ), + _ => "value".to_string(), }) } @@ -511,7 +563,7 @@ fn suggestion_signature<'tcx>( } ty::AssocKind::Const => { let ty = tcx.type_of(assoc.def_id).instantiate_identity(); - let val = ty_kind_suggestion(ty).unwrap_or("todo!()"); + let val = ty_kind_suggestion(ty, tcx).unwrap_or_else(|| "value".to_string()); format!("const {}: {} = {};", assoc.name, ty, val) } } |
