mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 14:51:48 +00:00
Auto merge of #17905 - ChayimFriedman2:edition-dependent-raw-keyword, r=Veykril
fix: Properly account for editions in names This PR touches a lot of parts. But the main changes are changing `hir_expand::Name` to be raw edition-dependently and only when necessary (unrelated to how the user originally wrote the identifier), and changing `is_keyword()` and `is_raw_identifier()` to be edition-aware (this was done in #17896, but the FIXMEs were fixed here). It is possible that I missed some cases, but most IDE parts should properly escape (or not escape) identifiers now. The rules of thumb are: - If we show the identifier to the user, its rawness should be determined by the edition of the edited crate. This is nice for IDE features, but really important for changes we insert to the source code. - For tests, I chose `Edition::CURRENT` (so we only have to (maybe) update tests when an edition becomes stable, to avoid churn). - For debugging tools (helper methods and logs), I used `Edition::LATEST`. Reviewing notes: This is a really big PR but most of it is mechanical translation. I changed `Name` displayers to require an edition, and followed the compiler errors. Most methods just propagate the edition requirement. The interesting cases are mostly in `ide-assists`, as sometimes the correct crate to fetch the edition from requires awareness (there may be two). `ide-completions` and `ide-diagnostics` were solved pretty easily by introducing an edition field to their context. `ide` contains many features, for most of them it was propagated to the top level function and there the edition was fetched based on the file. I also fixed all FIXMEs from #17896. Some required introducing an edition parameter (usually not for many methods after the changes to `Name`), some were changed to a new method `is_any_identifier()` because they really want any possible keyword. Fixes #17895. Fixes #17774.
This commit is contained in:
commit
c9ee892263
179 changed files with 2485 additions and 1250 deletions
|
@ -5,6 +5,7 @@ use std::{iter, ops::ControlFlow, sync::Arc};
|
|||
|
||||
use hir_expand::name::Name;
|
||||
use intern::sym;
|
||||
use span::Edition;
|
||||
use tracing::debug;
|
||||
|
||||
use chalk_ir::{cast::Caster, fold::shift::Shift, CanonicalVarKinds};
|
||||
|
@ -424,18 +425,19 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
|||
|
||||
fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
|
||||
let id = from_chalk_trait_id(trait_id);
|
||||
self.db.trait_data(id).name.display(self.db.upcast()).to_string()
|
||||
self.db.trait_data(id).name.display(self.db.upcast(), self.edition()).to_string()
|
||||
}
|
||||
fn adt_name(&self, chalk_ir::AdtId(adt_id): AdtId) -> String {
|
||||
let edition = self.edition();
|
||||
match adt_id {
|
||||
hir_def::AdtId::StructId(id) => {
|
||||
self.db.struct_data(id).name.display(self.db.upcast()).to_string()
|
||||
self.db.struct_data(id).name.display(self.db.upcast(), edition).to_string()
|
||||
}
|
||||
hir_def::AdtId::EnumId(id) => {
|
||||
self.db.enum_data(id).name.display(self.db.upcast()).to_string()
|
||||
self.db.enum_data(id).name.display(self.db.upcast(), edition).to_string()
|
||||
}
|
||||
hir_def::AdtId::UnionId(id) => {
|
||||
self.db.union_data(id).name.display(self.db.upcast()).to_string()
|
||||
self.db.union_data(id).name.display(self.db.upcast(), edition).to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -445,7 +447,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
|||
}
|
||||
fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String {
|
||||
let id = self.db.associated_ty_data(assoc_ty_id).name;
|
||||
self.db.type_alias_data(id).name.display(self.db.upcast()).to_string()
|
||||
self.db.type_alias_data(id).name.display(self.db.upcast(), self.edition()).to_string()
|
||||
}
|
||||
fn opaque_type_name(&self, opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String {
|
||||
format!("Opaque_{}", opaque_ty_id.0)
|
||||
|
@ -519,6 +521,10 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
|||
}
|
||||
|
||||
impl<'a> ChalkContext<'a> {
|
||||
fn edition(&self) -> Edition {
|
||||
self.db.crate_graph()[self.krate].edition
|
||||
}
|
||||
|
||||
fn for_trait_impls(
|
||||
&self,
|
||||
trait_id: hir_def::TraitId,
|
||||
|
@ -843,7 +849,7 @@ fn impl_def_datum(
|
|||
"impl {:?}: {}{} where {:?}",
|
||||
chalk_id,
|
||||
if negative { "!" } else { "" },
|
||||
trait_ref.display(db),
|
||||
trait_ref.display(db, db.crate_graph()[krate].edition),
|
||||
where_clauses
|
||||
);
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use base_db::SourceDatabase;
|
||||
use chalk_ir::Substitution;
|
||||
use hir_def::db::DefDatabase;
|
||||
use rustc_apfloat::{
|
||||
|
@ -94,9 +95,10 @@ fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8], &MemoryMap)) {
|
|||
fn pretty_print_err(e: ConstEvalError, db: TestDB) -> String {
|
||||
let mut err = String::new();
|
||||
let span_formatter = |file, range| format!("{file:?} {range:?}");
|
||||
let edition = db.crate_graph()[db.test_crate()].edition;
|
||||
match e {
|
||||
ConstEvalError::MirLowerError(e) => e.pretty_print(&mut err, &db, span_formatter),
|
||||
ConstEvalError::MirEvalError(e) => e.pretty_print(&mut err, &db, span_formatter),
|
||||
ConstEvalError::MirLowerError(e) => e.pretty_print(&mut err, &db, span_formatter, edition),
|
||||
ConstEvalError::MirEvalError(e) => e.pretty_print(&mut err, &db, span_formatter, edition),
|
||||
}
|
||||
.unwrap();
|
||||
err
|
||||
|
@ -110,7 +112,9 @@ fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const, ConstEvalEr
|
|||
.declarations()
|
||||
.find_map(|x| match x {
|
||||
hir_def::ModuleDefId::ConstId(x) => {
|
||||
if db.const_data(x).name.as_ref()?.display(db).to_string() == "GOAL" {
|
||||
if db.const_data(x).name.as_ref()?.display(db, file_id.edition()).to_string()
|
||||
== "GOAL"
|
||||
{
|
||||
Some(x)
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -17,17 +17,18 @@ use std::fmt;
|
|||
|
||||
use hir_def::{
|
||||
data::adt::VariantData, db::DefDatabase, hir::Pat, src::HasSource, AdtId, AttrDefId, ConstId,
|
||||
EnumId, EnumVariantId, FunctionId, ItemContainerId, Lookup, ModuleDefId, ModuleId, StaticId,
|
||||
StructId, TraitId, TypeAliasId,
|
||||
EnumId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, ModuleDefId, ModuleId,
|
||||
StaticId, StructId, TraitId, TypeAliasId,
|
||||
};
|
||||
use hir_expand::{
|
||||
name::{AsName, Name},
|
||||
HirFileId, MacroFileIdExt,
|
||||
HirFileId, HirFileIdExt, MacroFileIdExt,
|
||||
};
|
||||
use intern::sym;
|
||||
use stdx::{always, never};
|
||||
use syntax::{
|
||||
ast::{self, HasName},
|
||||
utils::is_raw_identifier,
|
||||
AstNode, AstPtr, ToSmolStr,
|
||||
};
|
||||
|
||||
|
@ -318,17 +319,21 @@ impl<'a> DeclValidator<'a> {
|
|||
/// This includes function parameters except for trait implementation associated functions.
|
||||
fn validate_func_body(&mut self, func: FunctionId) {
|
||||
let body = self.db.body(func.into());
|
||||
let edition = self.edition(func);
|
||||
let mut pats_replacements = body
|
||||
.pats
|
||||
.iter()
|
||||
.filter_map(|(pat_id, pat)| match pat {
|
||||
Pat::Bind { id, .. } => {
|
||||
let bind_name = &body.bindings[*id].name;
|
||||
let mut suggested_text =
|
||||
to_lower_snake_case(&bind_name.unescaped().display_no_db().to_smolstr())?;
|
||||
if is_raw_identifier(&suggested_text, edition) {
|
||||
suggested_text.insert_str(0, "r#");
|
||||
}
|
||||
let replacement = Replacement {
|
||||
current_name: bind_name.clone(),
|
||||
suggested_text: to_lower_snake_case(
|
||||
&bind_name.display_no_db().to_smolstr(),
|
||||
)?,
|
||||
suggested_text,
|
||||
expected_case: CaseType::LowerSnakeCase,
|
||||
};
|
||||
Some((pat_id, replacement))
|
||||
|
@ -377,6 +382,11 @@ impl<'a> DeclValidator<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn edition(&self, id: impl HasModule) -> span::Edition {
|
||||
let krate = id.krate(self.db.upcast());
|
||||
self.db.crate_graph()[krate].edition
|
||||
}
|
||||
|
||||
fn validate_struct(&mut self, struct_id: StructId) {
|
||||
// Check the structure name.
|
||||
let non_camel_case_allowed =
|
||||
|
@ -405,16 +415,17 @@ impl<'a> DeclValidator<'a> {
|
|||
let VariantData::Record(fields) = data.variant_data.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let edition = self.edition(struct_id);
|
||||
let mut struct_fields_replacements = fields
|
||||
.iter()
|
||||
.filter_map(|(_, field)| {
|
||||
to_lower_snake_case(&field.name.display_no_db().to_smolstr()).map(|new_name| {
|
||||
Replacement {
|
||||
to_lower_snake_case(&field.name.display_no_db(edition).to_smolstr()).map(
|
||||
|new_name| Replacement {
|
||||
current_name: field.name.clone(),
|
||||
suggested_text: new_name,
|
||||
expected_case: CaseType::LowerSnakeCase,
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
.peekable();
|
||||
|
||||
|
@ -498,14 +509,17 @@ impl<'a> DeclValidator<'a> {
|
|||
self.validate_enum_variant_fields(*variant_id);
|
||||
}
|
||||
|
||||
let edition = self.edition(enum_id);
|
||||
let mut enum_variants_replacements = data
|
||||
.variants
|
||||
.iter()
|
||||
.filter_map(|(_, name)| {
|
||||
to_camel_case(&name.display_no_db().to_smolstr()).map(|new_name| Replacement {
|
||||
current_name: name.clone(),
|
||||
suggested_text: new_name,
|
||||
expected_case: CaseType::UpperCamelCase,
|
||||
to_camel_case(&name.display_no_db(edition).to_smolstr()).map(|new_name| {
|
||||
Replacement {
|
||||
current_name: name.clone(),
|
||||
suggested_text: new_name,
|
||||
expected_case: CaseType::UpperCamelCase,
|
||||
}
|
||||
})
|
||||
})
|
||||
.peekable();
|
||||
|
@ -566,16 +580,17 @@ impl<'a> DeclValidator<'a> {
|
|||
let VariantData::Record(fields) = variant_data.variant_data.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let edition = self.edition(variant_id);
|
||||
let mut variant_field_replacements = fields
|
||||
.iter()
|
||||
.filter_map(|(_, field)| {
|
||||
to_lower_snake_case(&field.name.display_no_db().to_smolstr()).map(|new_name| {
|
||||
Replacement {
|
||||
to_lower_snake_case(&field.name.display_no_db(edition).to_smolstr()).map(
|
||||
|new_name| Replacement {
|
||||
current_name: field.name.clone(),
|
||||
suggested_text: new_name,
|
||||
expected_case: CaseType::LowerSnakeCase,
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
})
|
||||
.peekable();
|
||||
|
||||
|
@ -704,18 +719,22 @@ impl<'a> DeclValidator<'a> {
|
|||
) where
|
||||
N: AstNode + HasName + fmt::Debug,
|
||||
S: HasSource<Value = N>,
|
||||
L: Lookup<Data = S, Database<'a> = dyn DefDatabase + 'a>,
|
||||
L: Lookup<Data = S, Database<'a> = dyn DefDatabase + 'a> + HasModule + Copy,
|
||||
{
|
||||
let to_expected_case_type = match expected_case {
|
||||
CaseType::LowerSnakeCase => to_lower_snake_case,
|
||||
CaseType::UpperSnakeCase => to_upper_snake_case,
|
||||
CaseType::UpperCamelCase => to_camel_case,
|
||||
};
|
||||
let Some(replacement) =
|
||||
to_expected_case_type(&name.display(self.db.upcast()).to_smolstr()).map(|new_name| {
|
||||
Replacement { current_name: name.clone(), suggested_text: new_name, expected_case }
|
||||
})
|
||||
else {
|
||||
let edition = self.edition(item_id);
|
||||
let Some(replacement) = to_expected_case_type(
|
||||
&name.display(self.db.upcast(), edition).to_smolstr(),
|
||||
)
|
||||
.map(|new_name| Replacement {
|
||||
current_name: name.clone(),
|
||||
suggested_text: new_name,
|
||||
expected_case,
|
||||
}) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -748,12 +767,13 @@ impl<'a> DeclValidator<'a> {
|
|||
return;
|
||||
};
|
||||
|
||||
let edition = file_id.original_file(self.db.upcast()).edition();
|
||||
let diagnostic = IncorrectCase {
|
||||
file: file_id,
|
||||
ident_type,
|
||||
ident: AstPtr::new(&name_ast),
|
||||
expected_case: replacement.expected_case,
|
||||
ident_text: replacement.current_name.display(self.db.upcast()).to_string(),
|
||||
ident_text: replacement.current_name.display(self.db.upcast(), edition).to_string(),
|
||||
suggested_text: replacement.suggested_text,
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
use std::fmt;
|
||||
|
||||
use base_db::CrateId;
|
||||
use chalk_solve::rust_ir::AdtKind;
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
|
@ -15,6 +16,7 @@ use intern::sym;
|
|||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_pattern_analysis::constructor::Constructor;
|
||||
use span::Edition;
|
||||
use syntax::{
|
||||
ast::{self, UnaryOp},
|
||||
AstNode,
|
||||
|
@ -258,7 +260,13 @@ impl ExprValidator {
|
|||
if !witnesses.is_empty() {
|
||||
self.diagnostics.push(BodyValidationDiagnostic::MissingMatchArms {
|
||||
match_expr,
|
||||
uncovered_patterns: missing_match_arms(&cx, scrut_ty, witnesses, m_arms.is_empty()),
|
||||
uncovered_patterns: missing_match_arms(
|
||||
&cx,
|
||||
scrut_ty,
|
||||
witnesses,
|
||||
m_arms.is_empty(),
|
||||
self.owner.krate(db.upcast()),
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -345,7 +353,13 @@ impl ExprValidator {
|
|||
if !witnesses.is_empty() {
|
||||
self.diagnostics.push(BodyValidationDiagnostic::NonExhaustiveLet {
|
||||
pat,
|
||||
uncovered_patterns: missing_match_arms(&cx, ty, witnesses, false),
|
||||
uncovered_patterns: missing_match_arms(
|
||||
&cx,
|
||||
ty,
|
||||
witnesses,
|
||||
false,
|
||||
self.owner.krate(db.upcast()),
|
||||
),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -616,24 +630,26 @@ fn missing_match_arms<'p>(
|
|||
scrut_ty: &Ty,
|
||||
witnesses: Vec<WitnessPat<'p>>,
|
||||
arms_is_empty: bool,
|
||||
krate: CrateId,
|
||||
) -> String {
|
||||
struct DisplayWitness<'a, 'p>(&'a WitnessPat<'p>, &'a MatchCheckCtx<'p>);
|
||||
struct DisplayWitness<'a, 'p>(&'a WitnessPat<'p>, &'a MatchCheckCtx<'p>, Edition);
|
||||
impl fmt::Display for DisplayWitness<'_, '_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let DisplayWitness(witness, cx) = *self;
|
||||
let DisplayWitness(witness, cx, edition) = *self;
|
||||
let pat = cx.hoist_witness_pat(witness);
|
||||
write!(f, "{}", pat.display(cx.db))
|
||||
write!(f, "{}", pat.display(cx.db, edition))
|
||||
}
|
||||
}
|
||||
|
||||
let edition = cx.db.crate_graph()[krate].edition;
|
||||
let non_empty_enum = match scrut_ty.as_adt() {
|
||||
Some((AdtId::EnumId(e), _)) => !cx.db.enum_data(e).variants.is_empty(),
|
||||
_ => false,
|
||||
};
|
||||
if arms_is_empty && !non_empty_enum {
|
||||
format!("type `{}` is non-empty", scrut_ty.display(cx.db))
|
||||
format!("type `{}` is non-empty", scrut_ty.display(cx.db, edition))
|
||||
} else {
|
||||
let pat_display = |witness| DisplayWitness(witness, cx);
|
||||
let pat_display = |witness| DisplayWitness(witness, cx, edition);
|
||||
const LIMIT: usize = 3;
|
||||
match &*witnesses {
|
||||
[witness] => format!("`{}` not covered", pat_display(witness)),
|
||||
|
|
|
@ -14,6 +14,7 @@ use hir_def::{
|
|||
body::Body, data::adt::VariantData, hir::PatId, AdtId, EnumVariantId, LocalFieldId, VariantId,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use span::Edition;
|
||||
use stdx::{always, never};
|
||||
|
||||
use crate::{
|
||||
|
@ -151,7 +152,11 @@ impl<'a> PatCtxt<'a> {
|
|||
match (bm, ty.kind(Interner)) {
|
||||
(BindingMode::Ref(_), TyKind::Ref(.., rty)) => ty = rty,
|
||||
(BindingMode::Ref(_), _) => {
|
||||
never!("`ref {}` has wrong type {:?}", name.display(self.db.upcast()), ty);
|
||||
never!(
|
||||
"`ref {}` has wrong type {:?}",
|
||||
name.display(self.db.upcast(), Edition::LATEST),
|
||||
ty
|
||||
);
|
||||
self.errors.push(PatternError::UnexpectedType);
|
||||
return Pat { ty: ty.clone(), kind: PatKind::Wild.into() };
|
||||
}
|
||||
|
@ -297,7 +302,7 @@ impl HirDisplay for Pat {
|
|||
PatKind::Wild => write!(f, "_"),
|
||||
PatKind::Never => write!(f, "!"),
|
||||
PatKind::Binding { name, subpattern } => {
|
||||
write!(f, "{}", name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", name.display(f.db.upcast(), f.edition()))?;
|
||||
if let Some(subpattern) = subpattern {
|
||||
write!(f, " @ ")?;
|
||||
subpattern.hir_fmt(f)?;
|
||||
|
@ -317,14 +322,22 @@ impl HirDisplay for Pat {
|
|||
if let Some(variant) = variant {
|
||||
match variant {
|
||||
VariantId::EnumVariantId(v) => {
|
||||
write!(f, "{}", f.db.enum_variant_data(v).name.display(f.db.upcast()))?;
|
||||
}
|
||||
VariantId::StructId(s) => {
|
||||
write!(f, "{}", f.db.struct_data(s).name.display(f.db.upcast()))?
|
||||
}
|
||||
VariantId::UnionId(u) => {
|
||||
write!(f, "{}", f.db.union_data(u).name.display(f.db.upcast()))?
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.enum_variant_data(v).name.display(f.db.upcast(), f.edition())
|
||||
)?;
|
||||
}
|
||||
VariantId::StructId(s) => write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.struct_data(s).name.display(f.db.upcast(), f.edition())
|
||||
)?,
|
||||
VariantId::UnionId(u) => write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.union_data(u).name.display(f.db.upcast(), f.edition())
|
||||
)?,
|
||||
};
|
||||
|
||||
let variant_data = variant.variant_data(f.db.upcast());
|
||||
|
@ -341,7 +354,9 @@ impl HirDisplay for Pat {
|
|||
write!(
|
||||
f,
|
||||
"{}: ",
|
||||
rec_fields[p.field].name.display(f.db.upcast())
|
||||
rec_fields[p.field]
|
||||
.name
|
||||
.display(f.db.upcast(), f.edition())
|
||||
)?;
|
||||
p.pattern.hir_fmt(f)
|
||||
})
|
||||
|
|
|
@ -33,6 +33,7 @@ use rustc_apfloat::{
|
|||
Float,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use span::Edition;
|
||||
use stdx::{never, IsNoneOr};
|
||||
use triomphe::Arc;
|
||||
|
||||
|
@ -131,7 +132,11 @@ pub trait HirDisplay {
|
|||
|
||||
/// Returns a `Display`able type that is human-readable.
|
||||
/// Use this for showing types to the user (e.g. diagnostics)
|
||||
fn display<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
|
||||
fn display<'a>(
|
||||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
edition: Edition,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
|
@ -142,7 +147,7 @@ pub trait HirDisplay {
|
|||
limited_size: None,
|
||||
omit_verbose_types: false,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::Diagnostics,
|
||||
display_target: DisplayTarget::Diagnostics { edition },
|
||||
show_container_bounds: false,
|
||||
}
|
||||
}
|
||||
|
@ -153,6 +158,7 @@ pub trait HirDisplay {
|
|||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
max_size: Option<usize>,
|
||||
edition: Edition,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
@ -164,7 +170,7 @@ pub trait HirDisplay {
|
|||
limited_size: None,
|
||||
omit_verbose_types: true,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::Diagnostics,
|
||||
display_target: DisplayTarget::Diagnostics { edition },
|
||||
show_container_bounds: false,
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +181,7 @@ pub trait HirDisplay {
|
|||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
limited_size: Option<usize>,
|
||||
edition: Edition,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
@ -186,7 +193,7 @@ pub trait HirDisplay {
|
|||
limited_size,
|
||||
omit_verbose_types: true,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::Diagnostics,
|
||||
display_target: DisplayTarget::Diagnostics { edition },
|
||||
show_container_bounds: false,
|
||||
}
|
||||
}
|
||||
|
@ -242,6 +249,7 @@ pub trait HirDisplay {
|
|||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
show_container_bounds: bool,
|
||||
edition: Edition,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
@ -253,13 +261,23 @@ pub trait HirDisplay {
|
|||
limited_size: None,
|
||||
omit_verbose_types: false,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::Diagnostics,
|
||||
display_target: DisplayTarget::Diagnostics { edition },
|
||||
show_container_bounds,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HirFormatter<'_> {
|
||||
pub fn edition(&self) -> Edition {
|
||||
match self.display_target {
|
||||
DisplayTarget::Diagnostics { edition } => edition,
|
||||
DisplayTarget::SourceCode { module_id, .. } => {
|
||||
self.db.crate_graph()[module_id.krate()].edition
|
||||
}
|
||||
DisplayTarget::Test => Edition::CURRENT,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_joined<T: HirDisplay>(
|
||||
&mut self,
|
||||
iter: impl IntoIterator<Item = T>,
|
||||
|
@ -324,7 +342,7 @@ pub enum DisplayTarget {
|
|||
/// Display types for inlays, doc popups, autocompletion, etc...
|
||||
/// Showing `{unknown}` or not qualifying paths is fine here.
|
||||
/// There's no reason for this to fail.
|
||||
Diagnostics,
|
||||
Diagnostics { edition: Edition },
|
||||
/// Display types for inserting them in source files.
|
||||
/// The generated code should compile, so paths need to be qualified.
|
||||
SourceCode { module_id: ModuleId, allow_opaque: bool },
|
||||
|
@ -460,7 +478,7 @@ impl HirDisplay for ProjectionTy {
|
|||
">::{}",
|
||||
f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id))
|
||||
.name
|
||||
.display(f.db.upcast())
|
||||
.display(f.db.upcast(), f.edition())
|
||||
)?;
|
||||
let proj_params_count =
|
||||
self.substitution.len(Interner) - trait_ref.substitution.len(Interner);
|
||||
|
@ -499,7 +517,7 @@ impl HirDisplay for Const {
|
|||
let id = from_placeholder_idx(f.db, *idx);
|
||||
let generics = generics(f.db.upcast(), id.parent);
|
||||
let param_data = &generics[id.local_id];
|
||||
write!(f, "{}", param_data.name().unwrap().display(f.db.upcast()))?;
|
||||
write!(f, "{}", param_data.name().unwrap().display(f.db.upcast(), f.edition()))?;
|
||||
Ok(())
|
||||
}
|
||||
ConstValue::Concrete(c) => match &c.interned {
|
||||
|
@ -633,7 +651,7 @@ fn render_const_scalar(
|
|||
TyKind::Adt(adt, _) if b.len() == 2 * size_of::<usize>() => match adt.0 {
|
||||
hir_def::AdtId::StructId(s) => {
|
||||
let data = f.db.struct_data(s);
|
||||
write!(f, "&{}", data.name.display(f.db.upcast()))?;
|
||||
write!(f, "&{}", data.name.display(f.db.upcast(), f.edition()))?;
|
||||
Ok(())
|
||||
}
|
||||
_ => f.write_str("<unsized-enum-or-union>"),
|
||||
|
@ -691,7 +709,7 @@ fn render_const_scalar(
|
|||
match adt.0 {
|
||||
hir_def::AdtId::StructId(s) => {
|
||||
let data = f.db.struct_data(s);
|
||||
write!(f, "{}", data.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", data.name.display(f.db.upcast(), f.edition()))?;
|
||||
let field_types = f.db.field_types(s.into());
|
||||
render_variant_after_name(
|
||||
&data.variant_data,
|
||||
|
@ -705,7 +723,7 @@ fn render_const_scalar(
|
|||
)
|
||||
}
|
||||
hir_def::AdtId::UnionId(u) => {
|
||||
write!(f, "{}", f.db.union_data(u).name.display(f.db.upcast()))
|
||||
write!(f, "{}", f.db.union_data(u).name.display(f.db.upcast(), f.edition()))
|
||||
}
|
||||
hir_def::AdtId::EnumId(e) => {
|
||||
let Ok(target_data_layout) = f.db.target_data_layout(trait_env.krate) else {
|
||||
|
@ -717,7 +735,7 @@ fn render_const_scalar(
|
|||
return f.write_str("<failed-to-detect-variant>");
|
||||
};
|
||||
let data = f.db.enum_variant_data(var_id);
|
||||
write!(f, "{}", data.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", data.name.display(f.db.upcast(), f.edition()))?;
|
||||
let field_types = f.db.field_types(var_id.into());
|
||||
render_variant_after_name(
|
||||
&data.variant_data,
|
||||
|
@ -802,11 +820,11 @@ fn render_variant_after_name(
|
|||
if matches!(data, VariantData::Record(_)) {
|
||||
write!(f, " {{")?;
|
||||
if let Some((id, data)) = it.next() {
|
||||
write!(f, " {}: ", data.name.display(f.db.upcast()))?;
|
||||
write!(f, " {}: ", data.name.display(f.db.upcast(), f.edition()))?;
|
||||
render_field(f, id)?;
|
||||
}
|
||||
for (id, data) in it {
|
||||
write!(f, ", {}: ", data.name.display(f.db.upcast()))?;
|
||||
write!(f, ", {}: ", data.name.display(f.db.upcast(), f.edition()))?;
|
||||
render_field(f, id)?;
|
||||
}
|
||||
write!(f, " }}")?;
|
||||
|
@ -1000,15 +1018,23 @@ impl HirDisplay for Ty {
|
|||
CallableDefId::FunctionId(ff) => {
|
||||
write!(f, "fn ")?;
|
||||
f.start_location_link(def.into());
|
||||
write!(f, "{}", db.function_data(ff).name.display(f.db.upcast()))?
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
db.function_data(ff).name.display(f.db.upcast(), f.edition())
|
||||
)?
|
||||
}
|
||||
CallableDefId::StructId(s) => {
|
||||
f.start_location_link(def.into());
|
||||
write!(f, "{}", db.struct_data(s).name.display(f.db.upcast()))?
|
||||
write!(f, "{}", db.struct_data(s).name.display(f.db.upcast(), f.edition()))?
|
||||
}
|
||||
CallableDefId::EnumVariantId(e) => {
|
||||
f.start_location_link(def.into());
|
||||
write!(f, "{}", db.enum_variant_data(e).name.display(f.db.upcast()))?
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
db.enum_variant_data(e).name.display(f.db.upcast(), f.edition())
|
||||
)?
|
||||
}
|
||||
};
|
||||
f.end_location_link();
|
||||
|
@ -1053,13 +1079,13 @@ impl HirDisplay for Ty {
|
|||
TyKind::Adt(AdtId(def_id), parameters) => {
|
||||
f.start_location_link((*def_id).into());
|
||||
match f.display_target {
|
||||
DisplayTarget::Diagnostics | DisplayTarget::Test => {
|
||||
DisplayTarget::Diagnostics { .. } | DisplayTarget::Test => {
|
||||
let name = match *def_id {
|
||||
hir_def::AdtId::StructId(it) => db.struct_data(it).name.clone(),
|
||||
hir_def::AdtId::UnionId(it) => db.union_data(it).name.clone(),
|
||||
hir_def::AdtId::EnumId(it) => db.enum_data(it).name.clone(),
|
||||
};
|
||||
write!(f, "{}", name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
DisplayTarget::SourceCode { module_id, allow_opaque: _ } => {
|
||||
if let Some(path) = find_path::find_path(
|
||||
|
@ -1075,7 +1101,7 @@ impl HirDisplay for Ty {
|
|||
prefer_absolute: false,
|
||||
},
|
||||
) {
|
||||
write!(f, "{}", path.display(f.db.upcast()))?;
|
||||
write!(f, "{}", path.display(f.db.upcast(), f.edition()))?;
|
||||
} else {
|
||||
return Err(HirDisplayError::DisplaySourceCodeError(
|
||||
DisplaySourceCodeError::PathNotFound,
|
||||
|
@ -1101,12 +1127,12 @@ impl HirDisplay for Ty {
|
|||
// Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
|
||||
if f.display_target.is_test() {
|
||||
f.start_location_link(trait_.into());
|
||||
write!(f, "{}", trait_data.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", trait_data.name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
write!(f, "::")?;
|
||||
|
||||
f.start_location_link(type_alias.into());
|
||||
write!(f, "{}", type_alias_data.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", type_alias_data.name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
// Note that the generic args for the associated type come before those for the
|
||||
// trait (including the self type).
|
||||
|
@ -1124,7 +1150,7 @@ impl HirDisplay for Ty {
|
|||
let alias = from_foreign_def_id(*type_alias);
|
||||
let type_alias = db.type_alias_data(alias);
|
||||
f.start_location_link(alias.into());
|
||||
write!(f, "{}", type_alias.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", type_alias.name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
}
|
||||
TyKind::OpaqueType(opaque_ty_id, parameters) => {
|
||||
|
@ -1256,7 +1282,10 @@ impl HirDisplay for Ty {
|
|||
write!(
|
||||
f,
|
||||
"{}",
|
||||
p.name.clone().unwrap_or_else(Name::missing).display(f.db.upcast())
|
||||
p.name
|
||||
.clone()
|
||||
.unwrap_or_else(Name::missing)
|
||||
.display(f.db.upcast(), f.edition())
|
||||
)?
|
||||
}
|
||||
TypeParamProvenance::ArgumentImplTrait => {
|
||||
|
@ -1289,7 +1318,7 @@ impl HirDisplay for Ty {
|
|||
}
|
||||
},
|
||||
TypeOrConstParamData::ConstParamData(p) => {
|
||||
write!(f, "{}", p.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", p.name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1632,7 +1661,7 @@ fn write_bounds_like_dyn_trait(
|
|||
// existential) here, which is the only thing that's
|
||||
// possible in actual Rust, and hence don't print it
|
||||
f.start_location_link(trait_.into());
|
||||
write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
if is_fn_trait {
|
||||
if let [self_, params @ ..] = trait_ref.substitution.as_slice(Interner) {
|
||||
|
@ -1706,7 +1735,7 @@ fn write_bounds_like_dyn_trait(
|
|||
let assoc_ty_id = from_assoc_type_id(proj.associated_ty_id);
|
||||
let type_alias = f.db.type_alias_data(assoc_ty_id);
|
||||
f.start_location_link(assoc_ty_id.into());
|
||||
write!(f, "{}", type_alias.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", type_alias.name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
|
||||
let proj_arg_count = generics(f.db.upcast(), assoc_ty_id.into()).len_self();
|
||||
|
@ -1770,7 +1799,7 @@ fn fmt_trait_ref(
|
|||
}
|
||||
let trait_ = tr.hir_trait_id();
|
||||
f.start_location_link(trait_.into());
|
||||
write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
let substs = tr.substitution.as_slice(Interner);
|
||||
hir_fmt_generics(f, &substs[1..], None, substs[0].ty(Interner))
|
||||
|
@ -1796,7 +1825,11 @@ impl HirDisplay for WhereClause {
|
|||
write!(f, ">::",)?;
|
||||
let type_alias = from_assoc_type_id(projection_ty.associated_ty_id);
|
||||
f.start_location_link(type_alias.into());
|
||||
write!(f, "{}", f.db.type_alias_data(type_alias).name.display(f.db.upcast()),)?;
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.type_alias_data(type_alias).name.display(f.db.upcast(), f.edition()),
|
||||
)?;
|
||||
f.end_location_link();
|
||||
write!(f, " = ")?;
|
||||
ty.hir_fmt(f)?;
|
||||
|
@ -1832,7 +1865,7 @@ impl HirDisplay for LifetimeData {
|
|||
let id = lt_from_placeholder_idx(f.db, *idx);
|
||||
let generics = generics(f.db.upcast(), id.parent);
|
||||
let param_data = &generics[id.local_id];
|
||||
write!(f, "{}", param_data.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", param_data.name.display(f.db.upcast(), f.edition()))?;
|
||||
Ok(())
|
||||
}
|
||||
_ if f.display_target.is_source_code() => write!(f, "'_"),
|
||||
|
@ -1913,7 +1946,7 @@ impl HirDisplay for TypeRef {
|
|||
};
|
||||
write!(f, "&")?;
|
||||
if let Some(lifetime) = lifetime {
|
||||
write!(f, "{} ", lifetime.name.display(f.db.upcast()))?;
|
||||
write!(f, "{} ", lifetime.name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
write!(f, "{mutability}")?;
|
||||
inner.hir_fmt(f)?;
|
||||
|
@ -1921,7 +1954,7 @@ impl HirDisplay for TypeRef {
|
|||
TypeRef::Array(inner, len) => {
|
||||
write!(f, "[")?;
|
||||
inner.hir_fmt(f)?;
|
||||
write!(f, "; {}]", len.display(f.db.upcast()))?;
|
||||
write!(f, "; {}]", len.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
TypeRef::Slice(inner) => {
|
||||
write!(f, "[")?;
|
||||
|
@ -1942,7 +1975,7 @@ impl HirDisplay for TypeRef {
|
|||
for index in 0..function_parameters.len() {
|
||||
let (param_name, param_type) = &function_parameters[index];
|
||||
if let Some(name) = param_name {
|
||||
write!(f, "{}: ", name.display(f.db.upcast()))?;
|
||||
write!(f, "{}: ", name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
|
||||
param_type.hir_fmt(f)?;
|
||||
|
@ -2000,12 +2033,15 @@ impl HirDisplay for TypeBound {
|
|||
}
|
||||
path.hir_fmt(f)
|
||||
}
|
||||
TypeBound::Lifetime(lifetime) => write!(f, "{}", lifetime.name.display(f.db.upcast())),
|
||||
TypeBound::Lifetime(lifetime) => {
|
||||
write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
|
||||
}
|
||||
TypeBound::ForLifetime(lifetimes, path) => {
|
||||
let edition = f.edition();
|
||||
write!(
|
||||
f,
|
||||
"for<{}> ",
|
||||
lifetimes.iter().map(|it| it.display(f.db.upcast())).format(", ")
|
||||
lifetimes.iter().map(|it| it.display(f.db.upcast(), edition)).format(", ")
|
||||
)?;
|
||||
path.hir_fmt(f)
|
||||
}
|
||||
|
@ -2071,7 +2107,7 @@ impl HirDisplay for Path {
|
|||
if !matches!(self.kind(), PathKind::Plain) || seg_idx > 0 {
|
||||
write!(f, "::")?;
|
||||
}
|
||||
write!(f, "{}", segment.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", segment.name.display(f.db.upcast(), f.edition()))?;
|
||||
if let Some(generic_args) = segment.args_and_bindings {
|
||||
// We should be in type context, so format as `Foo<Bar>` instead of `Foo::<Bar>`.
|
||||
// Do we actually format expressions?
|
||||
|
@ -2116,7 +2152,7 @@ impl HirDisplay for Path {
|
|||
} else {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
write!(f, "{}", binding.name.display(f.db.upcast()))?;
|
||||
write!(f, "{}", binding.name.display(f.db.upcast(), f.edition()))?;
|
||||
match &binding.type_ref {
|
||||
Some(ty) => {
|
||||
write!(f, " = ")?;
|
||||
|
@ -2150,9 +2186,11 @@ impl HirDisplay for hir_def::path::GenericArg {
|
|||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||
match self {
|
||||
hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f),
|
||||
hir_def::path::GenericArg::Const(c) => write!(f, "{}", c.display(f.db.upcast())),
|
||||
hir_def::path::GenericArg::Const(c) => {
|
||||
write!(f, "{}", c.display(f.db.upcast(), f.edition()))
|
||||
}
|
||||
hir_def::path::GenericArg::Lifetime(lifetime) => {
|
||||
write!(f, "{}", lifetime.name.display(f.db.upcast()))
|
||||
write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -255,7 +255,9 @@ impl CapturedItem {
|
|||
|
||||
pub fn display_place(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String {
|
||||
let body = db.body(owner);
|
||||
let mut result = body[self.place.local].name.display(db.upcast()).to_string();
|
||||
let krate = owner.krate(db.upcast());
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
let mut result = body[self.place.local].name.display(db.upcast(), edition).to_string();
|
||||
let mut field_need_paren = false;
|
||||
for proj in &self.place.projections {
|
||||
match proj {
|
||||
|
|
|
@ -42,19 +42,20 @@ fn eval_goal(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
|
|||
hir_def::ModuleDefId::AdtId(x) => {
|
||||
let name = match x {
|
||||
hir_def::AdtId::StructId(x) => {
|
||||
db.struct_data(x).name.display_no_db().to_smolstr()
|
||||
db.struct_data(x).name.display_no_db(file_id.edition()).to_smolstr()
|
||||
}
|
||||
hir_def::AdtId::UnionId(x) => {
|
||||
db.union_data(x).name.display_no_db().to_smolstr()
|
||||
db.union_data(x).name.display_no_db(file_id.edition()).to_smolstr()
|
||||
}
|
||||
hir_def::AdtId::EnumId(x) => {
|
||||
db.enum_data(x).name.display_no_db().to_smolstr()
|
||||
db.enum_data(x).name.display_no_db(file_id.edition()).to_smolstr()
|
||||
}
|
||||
};
|
||||
(name == "Goal").then_some(Either::Left(x))
|
||||
}
|
||||
hir_def::ModuleDefId::TypeAliasId(x) => {
|
||||
let name = db.type_alias_data(x).name.display_no_db().to_smolstr();
|
||||
let name =
|
||||
db.type_alias_data(x).name.display_no_db(file_id.edition()).to_smolstr();
|
||||
(name == "Goal").then_some(Either::Right(x))
|
||||
}
|
||||
_ => None,
|
||||
|
@ -94,7 +95,7 @@ fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
|
|||
.declarations()
|
||||
.find_map(|x| match x {
|
||||
hir_def::ModuleDefId::FunctionId(x) => {
|
||||
let name = db.function_data(x).name.display_no_db().to_smolstr();
|
||||
let name = db.function_data(x).name.display_no_db(file_id.edition()).to_smolstr();
|
||||
(name == "main").then_some(x)
|
||||
}
|
||||
_ => None,
|
||||
|
@ -104,7 +105,7 @@ fn eval_expr(ra_fixture: &str, minicore: &str) -> Result<Arc<Layout>, LayoutErro
|
|||
let b = hir_body
|
||||
.bindings
|
||||
.iter()
|
||||
.find(|x| x.1.name.display_no_db().to_smolstr() == "goal")
|
||||
.find(|x| x.1.name.display_no_db(file_id.edition()).to_smolstr() == "goal")
|
||||
.unwrap()
|
||||
.0;
|
||||
let infer = db.infer(function_id.into());
|
||||
|
|
|
@ -66,6 +66,7 @@ use intern::{sym, Symbol};
|
|||
use la_arena::{Arena, Idx};
|
||||
use mir::{MirEvalError, VTableMap};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use span::Edition;
|
||||
use syntax::ast::{make, ConstArg};
|
||||
use traits::FnTrait;
|
||||
use triomphe::Arc;
|
||||
|
@ -1025,7 +1026,11 @@ where
|
|||
collector.placeholders.into_iter().collect()
|
||||
}
|
||||
|
||||
pub fn known_const_to_ast(konst: &Const, db: &dyn HirDatabase) -> Option<ConstArg> {
|
||||
pub fn known_const_to_ast(
|
||||
konst: &Const,
|
||||
db: &dyn HirDatabase,
|
||||
edition: Edition,
|
||||
) -> Option<ConstArg> {
|
||||
if let ConstValue::Concrete(c) = &konst.interned().value {
|
||||
match c.interned {
|
||||
ConstScalar::UnevaluatedConst(GeneralConstId::InTypeConstId(cid), _) => {
|
||||
|
@ -1035,5 +1040,5 @@ pub fn known_const_to_ast(konst: &Const, db: &dyn HirDatabase) -> Option<ConstAr
|
|||
_ => (),
|
||||
}
|
||||
}
|
||||
Some(make::expr_const_value(konst.display(db).to_string().as_str()))
|
||||
Some(make::expr_const_value(konst.display(db, edition).to_string().as_str()))
|
||||
}
|
||||
|
|
|
@ -158,7 +158,10 @@ impl<V, T> ProjectionElem<V, T> {
|
|||
subst.at(Interner, 0).assert_ty_ref(Interner).clone()
|
||||
}
|
||||
_ => {
|
||||
never!("Overloaded deref on type {} is not a projection", base.display(db));
|
||||
never!(
|
||||
"Overloaded deref on type {} is not a projection",
|
||||
base.display(db, db.crate_graph()[krate].edition)
|
||||
);
|
||||
TyKind::Error.intern(Interner)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -23,7 +23,7 @@ use rustc_apfloat::{
|
|||
Float,
|
||||
};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use span::FileId;
|
||||
use span::{Edition, FileId};
|
||||
use stdx::never;
|
||||
use syntax::{SyntaxNodePtr, TextRange};
|
||||
use triomphe::Arc;
|
||||
|
@ -358,6 +358,7 @@ impl MirEvalError {
|
|||
f: &mut String,
|
||||
db: &dyn HirDatabase,
|
||||
span_formatter: impl Fn(FileId, TextRange) -> String,
|
||||
edition: Edition,
|
||||
) -> std::result::Result<(), std::fmt::Error> {
|
||||
writeln!(f, "Mir eval error:")?;
|
||||
let mut err = self;
|
||||
|
@ -370,7 +371,7 @@ impl MirEvalError {
|
|||
writeln!(
|
||||
f,
|
||||
"In function {} ({:?})",
|
||||
function_name.name.display(db.upcast()),
|
||||
function_name.name.display(db.upcast(), edition),
|
||||
func
|
||||
)?;
|
||||
}
|
||||
|
@ -415,7 +416,7 @@ impl MirEvalError {
|
|||
write!(
|
||||
f,
|
||||
"Layout for type `{}` is not available due {err:?}",
|
||||
ty.display(db).with_closure_style(ClosureStyle::ClosureWithId)
|
||||
ty.display(db, edition).with_closure_style(ClosureStyle::ClosureWithId)
|
||||
)?;
|
||||
}
|
||||
MirEvalError::MirLowerError(func, err) => {
|
||||
|
@ -423,16 +424,17 @@ impl MirEvalError {
|
|||
writeln!(
|
||||
f,
|
||||
"MIR lowering for function `{}` ({:?}) failed due:",
|
||||
function_name.name.display(db.upcast()),
|
||||
function_name.name.display(db.upcast(), edition),
|
||||
func
|
||||
)?;
|
||||
err.pretty_print(f, db, span_formatter)?;
|
||||
err.pretty_print(f, db, span_formatter, edition)?;
|
||||
}
|
||||
MirEvalError::ConstEvalError(name, err) => {
|
||||
MirLowerError::ConstEvalError((**name).into(), err.clone()).pretty_print(
|
||||
f,
|
||||
db,
|
||||
span_formatter,
|
||||
edition,
|
||||
)?;
|
||||
}
|
||||
MirEvalError::UndefinedBehavior(_)
|
||||
|
@ -2675,10 +2677,11 @@ impl Evaluator<'_> {
|
|||
let db = self.db.upcast();
|
||||
let loc = variant.lookup(db);
|
||||
let enum_loc = loc.parent.lookup(db);
|
||||
let edition = self.db.crate_graph()[self.crate_id].edition;
|
||||
let name = format!(
|
||||
"{}::{}",
|
||||
enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db.upcast()),
|
||||
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast()),
|
||||
enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db.upcast(), edition),
|
||||
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast(), edition),
|
||||
);
|
||||
Err(MirEvalError::ConstEvalError(name, Box::new(e)))
|
||||
}
|
||||
|
|
|
@ -856,7 +856,11 @@ impl Evaluator<'_> {
|
|||
Ok(ty_name) => ty_name,
|
||||
// Fallback to human readable display in case of `Err`. Ideally we want to use `display_source_code` to
|
||||
// render full paths.
|
||||
Err(_) => ty.display(self.db).to_string(),
|
||||
Err(_) => {
|
||||
let krate = locals.body.owner.krate(self.db.upcast());
|
||||
let edition = self.db.crate_graph()[krate].edition;
|
||||
ty.display(self.db, edition).to_string()
|
||||
}
|
||||
};
|
||||
let len = ty_name.len();
|
||||
let addr = self.heap_allocate(len, 1)?;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use hir_def::db::DefDatabase;
|
||||
use span::EditionedFileId;
|
||||
use span::{Edition, EditionedFileId};
|
||||
use syntax::{TextRange, TextSize};
|
||||
use test_fixture::WithFixture;
|
||||
|
||||
|
@ -15,7 +15,7 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String),
|
|||
.declarations()
|
||||
.find_map(|x| match x {
|
||||
hir_def::ModuleDefId::FunctionId(x) => {
|
||||
if db.function_data(x).name.display(db).to_string() == "main" {
|
||||
if db.function_data(x).name.display(db, Edition::CURRENT).to_string() == "main" {
|
||||
Some(x)
|
||||
} else {
|
||||
None
|
||||
|
@ -63,7 +63,7 @@ fn check_pass_and_stdio(ra_fixture: &str, expected_stdout: &str, expected_stderr
|
|||
let span_formatter = |file, range: TextRange| {
|
||||
format!("{:?} {:?}..{:?}", file, line_index(range.start()), line_index(range.end()))
|
||||
};
|
||||
e.pretty_print(&mut err, &db, span_formatter).unwrap();
|
||||
e.pretty_print(&mut err, &db, span_formatter, Edition::CURRENT).unwrap();
|
||||
panic!("Error in interpreting: {err}");
|
||||
}
|
||||
Ok((stdout, stderr)) => {
|
||||
|
|
|
@ -21,7 +21,7 @@ use hir_expand::name::Name;
|
|||
use la_arena::ArenaMap;
|
||||
use rustc_apfloat::Float;
|
||||
use rustc_hash::FxHashMap;
|
||||
use span::FileId;
|
||||
use span::{Edition, FileId};
|
||||
use syntax::TextRange;
|
||||
use triomphe::Arc;
|
||||
|
||||
|
@ -157,13 +157,18 @@ impl MirLowerError {
|
|||
f: &mut String,
|
||||
db: &dyn HirDatabase,
|
||||
span_formatter: impl Fn(FileId, TextRange) -> String,
|
||||
edition: Edition,
|
||||
) -> std::result::Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
MirLowerError::ConstEvalError(name, e) => {
|
||||
writeln!(f, "In evaluating constant {name}")?;
|
||||
match &**e {
|
||||
ConstEvalError::MirLowerError(e) => e.pretty_print(f, db, span_formatter)?,
|
||||
ConstEvalError::MirEvalError(e) => e.pretty_print(f, db, span_formatter)?,
|
||||
ConstEvalError::MirLowerError(e) => {
|
||||
e.pretty_print(f, db, span_formatter, edition)?
|
||||
}
|
||||
ConstEvalError::MirEvalError(e) => {
|
||||
e.pretty_print(f, db, span_formatter, edition)?
|
||||
}
|
||||
}
|
||||
}
|
||||
MirLowerError::MissingFunctionDefinition(owner, it) => {
|
||||
|
@ -171,15 +176,15 @@ impl MirLowerError {
|
|||
writeln!(
|
||||
f,
|
||||
"Missing function definition for {}",
|
||||
body.pretty_print_expr(db.upcast(), *owner, *it)
|
||||
body.pretty_print_expr(db.upcast(), *owner, *it, edition)
|
||||
)?;
|
||||
}
|
||||
MirLowerError::TypeMismatch(e) => match e {
|
||||
Some(e) => writeln!(
|
||||
f,
|
||||
"Type mismatch: Expected {}, found {}",
|
||||
e.expected.display(db),
|
||||
e.actual.display(db),
|
||||
e.expected.display(db, edition),
|
||||
e.actual.display(db, edition),
|
||||
)?,
|
||||
None => writeln!(f, "Type mismatch: types mismatch with {{unknown}}",)?,
|
||||
},
|
||||
|
@ -189,11 +194,11 @@ impl MirLowerError {
|
|||
writeln!(
|
||||
f,
|
||||
"Generic arg not provided for {}",
|
||||
param.name().unwrap_or(&Name::missing()).display(db.upcast())
|
||||
param.name().unwrap_or(&Name::missing()).display(db.upcast(), edition)
|
||||
)?;
|
||||
writeln!(f, "Provided args: [")?;
|
||||
for g in subst.iter(Interner) {
|
||||
write!(f, " {},", g.display(db))?;
|
||||
write!(f, " {},", g.display(db, edition))?;
|
||||
}
|
||||
writeln!(f, "]")?;
|
||||
}
|
||||
|
@ -242,8 +247,8 @@ impl From<LayoutError> for MirLowerError {
|
|||
}
|
||||
|
||||
impl MirLowerError {
|
||||
fn unresolved_path(db: &dyn HirDatabase, p: &Path) -> Self {
|
||||
Self::UnresolvedName(p.display(db).to_string())
|
||||
fn unresolved_path(db: &dyn HirDatabase, p: &Path, edition: Edition) -> Self {
|
||||
Self::UnresolvedName(p.display(db, edition).to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,7 +441,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
VariantId::UnionId(_) => implementation_error!("Union variant as path"),
|
||||
}
|
||||
} else {
|
||||
let unresolved_name = || MirLowerError::unresolved_path(self.db, p);
|
||||
let unresolved_name =
|
||||
|| MirLowerError::unresolved_path(self.db, p, self.edition());
|
||||
let resolver = resolver_for_expr(self.db.upcast(), self.owner, expr_id);
|
||||
resolver
|
||||
.resolve_path_in_value_ns_fully(self.db.upcast(), p)
|
||||
|
@ -662,7 +668,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
let (func_id, generic_args) =
|
||||
self.infer.method_resolution(expr_id).ok_or_else(|| {
|
||||
MirLowerError::UnresolvedMethod(
|
||||
method_name.display(self.db.upcast()).to_string(),
|
||||
method_name.display(self.db.upcast(), self.edition()).to_string(),
|
||||
)
|
||||
})?;
|
||||
let func = Operand::from_fn(self.db, func_id, generic_args);
|
||||
|
@ -803,7 +809,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
};
|
||||
let variant_id =
|
||||
self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path {
|
||||
Some(p) => MirLowerError::UnresolvedName(p.display(self.db).to_string()),
|
||||
Some(p) => MirLowerError::UnresolvedName(
|
||||
p.display(self.db, self.edition()).to_string(),
|
||||
),
|
||||
None => MirLowerError::RecordLiteralWithoutPath,
|
||||
})?;
|
||||
let subst = match self.expr_ty_without_adjust(expr_id).kind(Interner) {
|
||||
|
@ -1378,7 +1386,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
"only `char` and numeric types are allowed in range patterns"
|
||||
),
|
||||
};
|
||||
let unresolved_name = || MirLowerError::unresolved_path(self.db, c.as_ref());
|
||||
let edition = self.edition();
|
||||
let unresolved_name =
|
||||
|| MirLowerError::unresolved_path(self.db, c.as_ref(), edition);
|
||||
let resolver = self.owner.resolver(self.db.upcast());
|
||||
let pr = resolver
|
||||
.resolve_path_in_value_ns(self.db.upcast(), c.as_ref())
|
||||
|
@ -1904,19 +1914,25 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
match r {
|
||||
Ok(r) => Ok(r),
|
||||
Err(e) => {
|
||||
let edition = self.edition();
|
||||
let db = self.db.upcast();
|
||||
let loc = variant.lookup(db);
|
||||
let enum_loc = loc.parent.lookup(db);
|
||||
let name = format!(
|
||||
"{}::{}",
|
||||
enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db.upcast()),
|
||||
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast()),
|
||||
enum_loc.id.item_tree(db)[enum_loc.id.value].name.display(db.upcast(), edition),
|
||||
loc.id.item_tree(db)[loc.id.value].name.display(db.upcast(), edition),
|
||||
);
|
||||
Err(MirLowerError::ConstEvalError(name.into(), Box::new(e)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn edition(&self) -> Edition {
|
||||
let krate = self.owner.krate(self.db.upcast());
|
||||
self.db.crate_graph()[krate].edition
|
||||
}
|
||||
|
||||
fn drop_until_scope(
|
||||
&mut self,
|
||||
scope_index: usize,
|
||||
|
@ -2121,18 +2137,24 @@ pub fn mir_body_for_closure_query(
|
|||
}
|
||||
|
||||
pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<MirBody>> {
|
||||
let krate = def.krate(db.upcast());
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
let detail = match def {
|
||||
DefWithBodyId::FunctionId(it) => db.function_data(it).name.display(db.upcast()).to_string(),
|
||||
DefWithBodyId::StaticId(it) => db.static_data(it).name.display(db.upcast()).to_string(),
|
||||
DefWithBodyId::FunctionId(it) => {
|
||||
db.function_data(it).name.display(db.upcast(), edition).to_string()
|
||||
}
|
||||
DefWithBodyId::StaticId(it) => {
|
||||
db.static_data(it).name.display(db.upcast(), edition).to_string()
|
||||
}
|
||||
DefWithBodyId::ConstId(it) => db
|
||||
.const_data(it)
|
||||
.name
|
||||
.clone()
|
||||
.unwrap_or_else(Name::missing)
|
||||
.display(db.upcast())
|
||||
.display(db.upcast(), edition)
|
||||
.to_string(),
|
||||
DefWithBodyId::VariantId(it) => {
|
||||
db.enum_variant_data(it).name.display(db.upcast()).to_string()
|
||||
db.enum_variant_data(it).name.display(db.upcast(), edition).to_string()
|
||||
}
|
||||
DefWithBodyId::InTypeConstId(it) => format!("in type const {it:?}"),
|
||||
};
|
||||
|
|
|
@ -347,7 +347,8 @@ impl MirLowerCtx<'_> {
|
|||
// A const don't bind anything. Only needs check.
|
||||
return Ok((current, current_else));
|
||||
}
|
||||
let unresolved_name = || MirLowerError::unresolved_path(self.db, p);
|
||||
let unresolved_name =
|
||||
|| MirLowerError::unresolved_path(self.db, p, self.edition());
|
||||
let resolver = self.owner.resolver(self.db.upcast());
|
||||
let pr = resolver
|
||||
.resolve_path_in_value_ns(self.db.upcast(), p)
|
||||
|
|
|
@ -9,6 +9,7 @@ use either::Either;
|
|||
use hir_def::{body::Body, hir::BindingId};
|
||||
use hir_expand::{name::Name, Lookup};
|
||||
use la_arena::ArenaMap;
|
||||
use span::Edition;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
|
@ -44,18 +45,21 @@ impl MirBody {
|
|||
ctx.for_body(|this| match ctx.body.owner {
|
||||
hir_def::DefWithBodyId::FunctionId(id) => {
|
||||
let data = db.function_data(id);
|
||||
w!(this, "fn {}() ", data.name.display(db.upcast()));
|
||||
w!(this, "fn {}() ", data.name.display(db.upcast(), Edition::LATEST));
|
||||
}
|
||||
hir_def::DefWithBodyId::StaticId(id) => {
|
||||
let data = db.static_data(id);
|
||||
w!(this, "static {}: _ = ", data.name.display(db.upcast()));
|
||||
w!(this, "static {}: _ = ", data.name.display(db.upcast(), Edition::LATEST));
|
||||
}
|
||||
hir_def::DefWithBodyId::ConstId(id) => {
|
||||
let data = db.const_data(id);
|
||||
w!(
|
||||
this,
|
||||
"const {}: _ = ",
|
||||
data.name.as_ref().unwrap_or(&Name::missing()).display(db.upcast())
|
||||
data.name
|
||||
.as_ref()
|
||||
.unwrap_or(&Name::missing())
|
||||
.display(db.upcast(), Edition::LATEST)
|
||||
);
|
||||
}
|
||||
hir_def::DefWithBodyId::VariantId(id) => {
|
||||
|
@ -64,8 +68,12 @@ impl MirBody {
|
|||
w!(
|
||||
this,
|
||||
"enum {}::{} = ",
|
||||
enum_loc.id.item_tree(db.upcast())[enum_loc.id.value].name.display(db.upcast()),
|
||||
loc.id.item_tree(db.upcast())[loc.id.value].name.display(db.upcast()),
|
||||
enum_loc.id.item_tree(db.upcast())[enum_loc.id.value]
|
||||
.name
|
||||
.display(db.upcast(), Edition::LATEST),
|
||||
loc.id.item_tree(db.upcast())[loc.id.value]
|
||||
.name
|
||||
.display(db.upcast(), Edition::LATEST),
|
||||
)
|
||||
}
|
||||
hir_def::DefWithBodyId::InTypeConstId(id) => {
|
||||
|
@ -122,7 +130,7 @@ impl HirDisplay for LocalName {
|
|||
match self {
|
||||
LocalName::Unknown(l) => write!(f, "_{}", u32::from(l.into_raw())),
|
||||
LocalName::Binding(n, l) => {
|
||||
write!(f, "{}_{}", n.display(f.db.upcast()), u32::from(l.into_raw()))
|
||||
write!(f, "{}_{}", n.display(f.db.upcast(), f.edition()), u32::from(l.into_raw()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,7 +208,7 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
wln!(
|
||||
self,
|
||||
"let {}: {};",
|
||||
self.local_name(id).display(self.db),
|
||||
self.local_name(id).display_test(self.db),
|
||||
self.hir_display(&local.ty)
|
||||
);
|
||||
}
|
||||
|
@ -231,10 +239,18 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
wln!(this, ";");
|
||||
}
|
||||
StatementKind::StorageDead(p) => {
|
||||
wln!(this, "StorageDead({})", this.local_name(*p).display(self.db));
|
||||
wln!(
|
||||
this,
|
||||
"StorageDead({})",
|
||||
this.local_name(*p).display_test(self.db)
|
||||
);
|
||||
}
|
||||
StatementKind::StorageLive(p) => {
|
||||
wln!(this, "StorageLive({})", this.local_name(*p).display(self.db));
|
||||
wln!(
|
||||
this,
|
||||
"StorageLive({})",
|
||||
this.local_name(*p).display_test(self.db)
|
||||
);
|
||||
}
|
||||
StatementKind::Deinit(p) => {
|
||||
w!(this, "Deinit(");
|
||||
|
@ -297,7 +313,7 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
fn f(this: &mut MirPrettyCtx<'_>, local: LocalId, projections: &[PlaceElem]) {
|
||||
let Some((last, head)) = projections.split_last() else {
|
||||
// no projection
|
||||
w!(this, "{}", this.local_name(local).display(this.db));
|
||||
w!(this, "{}", this.local_name(local).display_test(this.db));
|
||||
return;
|
||||
};
|
||||
match last {
|
||||
|
@ -317,13 +333,13 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
w!(
|
||||
this,
|
||||
" as {}).{}",
|
||||
variant_name.display(this.db.upcast()),
|
||||
name.display(this.db.upcast())
|
||||
variant_name.display(this.db.upcast(), Edition::LATEST),
|
||||
name.display(this.db.upcast(), Edition::LATEST)
|
||||
);
|
||||
}
|
||||
hir_def::VariantId::StructId(_) | hir_def::VariantId::UnionId(_) => {
|
||||
f(this, local, head);
|
||||
w!(this, ".{}", name.display(this.db.upcast()));
|
||||
w!(this, ".{}", name.display(this.db.upcast(), Edition::LATEST));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -337,7 +353,7 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
}
|
||||
ProjectionElem::Index(l) => {
|
||||
f(this, local, head);
|
||||
w!(this, "[{}]", this.local_name(*l).display(this.db));
|
||||
w!(this, "[{}]", this.local_name(*l).display_test(this.db));
|
||||
}
|
||||
it => {
|
||||
f(this, local, head);
|
||||
|
@ -387,7 +403,7 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
Rvalue::Repeat(op, len) => {
|
||||
w!(self, "[");
|
||||
self.operand(op);
|
||||
w!(self, "; {}]", len.display(self.db));
|
||||
w!(self, "; {}]", len.display_test(self.db));
|
||||
}
|
||||
Rvalue::Aggregate(AggregateKind::Adt(_, _), it) => {
|
||||
w!(self, "Adt(");
|
||||
|
@ -458,6 +474,6 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
}
|
||||
|
||||
fn hir_display<T: HirDisplay>(&self, ty: &'a T) -> impl Display + 'a {
|
||||
ty.display(self.db).with_closure_style(ClosureStyle::ClosureWithSubst)
|
||||
ty.display_test(self.db).with_closure_style(ClosureStyle::ClosureWithSubst)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
use std::fmt::{self, Display};
|
||||
|
||||
use itertools::Itertools;
|
||||
use span::Edition;
|
||||
|
||||
use crate::{
|
||||
chalk_db, db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, mapping::from_chalk,
|
||||
|
@ -24,7 +25,7 @@ impl DebugContext<'_> {
|
|||
AdtId::UnionId(it) => self.0.union_data(it).name.clone(),
|
||||
AdtId::EnumId(it) => self.0.enum_data(it).name.clone(),
|
||||
};
|
||||
name.display(self.0.upcast()).fmt(f)?;
|
||||
name.display(self.0.upcast(), Edition::LATEST).fmt(f)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -35,7 +36,7 @@ impl DebugContext<'_> {
|
|||
) -> Result<(), fmt::Error> {
|
||||
let trait_: hir_def::TraitId = from_chalk_trait_id(id);
|
||||
let trait_data = self.0.trait_data(trait_);
|
||||
trait_data.name.display(self.0.upcast()).fmt(f)?;
|
||||
trait_data.name.display(self.0.upcast(), Edition::LATEST).fmt(f)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -54,8 +55,8 @@ impl DebugContext<'_> {
|
|||
write!(
|
||||
fmt,
|
||||
"{}::{}",
|
||||
trait_data.name.display(self.0.upcast()),
|
||||
type_alias_data.name.display(self.0.upcast())
|
||||
trait_data.name.display(self.0.upcast(), Edition::LATEST),
|
||||
type_alias_data.name.display(self.0.upcast(), Edition::LATEST)
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -75,7 +76,7 @@ impl DebugContext<'_> {
|
|||
let trait_ref = projection_ty.trait_ref(self.0);
|
||||
let trait_params = trait_ref.substitution.as_slice(Interner);
|
||||
let self_ty = trait_ref.self_type_parameter(Interner);
|
||||
write!(fmt, "<{self_ty:?} as {}", trait_name.display(self.0.upcast()))?;
|
||||
write!(fmt, "<{self_ty:?} as {}", trait_name.display(self.0.upcast(), Edition::LATEST))?;
|
||||
if trait_params.len() > 1 {
|
||||
write!(
|
||||
fmt,
|
||||
|
@ -83,7 +84,7 @@ impl DebugContext<'_> {
|
|||
trait_params[1..].iter().format_with(", ", |x, f| f(&format_args!("{x:?}"))),
|
||||
)?;
|
||||
}
|
||||
write!(fmt, ">::{}", type_alias_data.name.display(self.0.upcast()))?;
|
||||
write!(fmt, ">::{}", type_alias_data.name.display(self.0.upcast(), Edition::LATEST))?;
|
||||
|
||||
let proj_params_count = projection_ty.substitution.len(Interner) - trait_params.len();
|
||||
let proj_params = &projection_ty.substitution.as_slice(Interner)[..proj_params_count];
|
||||
|
@ -110,9 +111,11 @@ impl DebugContext<'_> {
|
|||
CallableDefId::EnumVariantId(e) => self.0.enum_variant_data(e).name.clone(),
|
||||
};
|
||||
match def {
|
||||
CallableDefId::FunctionId(_) => write!(fmt, "{{fn {}}}", name.display(self.0.upcast())),
|
||||
CallableDefId::FunctionId(_) => {
|
||||
write!(fmt, "{{fn {}}}", name.display(self.0.upcast(), Edition::LATEST))
|
||||
}
|
||||
CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {
|
||||
write!(fmt, "{{ctor {}}}", name.display(self.0.upcast()))
|
||||
write!(fmt, "{{ctor {}}}", name.display(self.0.upcast(), Edition::LATEST))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ use hir_def::{
|
|||
};
|
||||
use hir_expand::name::Name;
|
||||
use intern::sym;
|
||||
use span::Edition;
|
||||
use stdx::{never, panic_context};
|
||||
use triomphe::Arc;
|
||||
|
||||
|
@ -114,7 +115,7 @@ pub(crate) fn trait_solve_query(
|
|||
) -> Option<Solution> {
|
||||
let detail = match &goal.value.goal.data(Interner) {
|
||||
GoalData::DomainGoal(DomainGoal::Holds(WhereClause::Implemented(it))) => {
|
||||
db.trait_data(it.hir_trait_id()).name.display(db.upcast()).to_string()
|
||||
db.trait_data(it.hir_trait_id()).name.display(db.upcast(), Edition::LATEST).to_string()
|
||||
}
|
||||
GoalData::DomainGoal(DomainGoal::Holds(WhereClause::AliasEq(_))) => "alias_eq".to_owned(),
|
||||
_ => "??".to_owned(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue