mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-01 12:24:29 +00:00
Merge pull request #19330 from ChayimFriedman2/normalize-projection
fix: Normalize projections in evaluated const display and layout calculation
This commit is contained in:
commit
27a5b1ba0c
64 changed files with 887 additions and 521 deletions
|
|
@ -15,9 +15,10 @@ use stdx::never;
|
|||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase, generics::Generics, infer::InferenceContext, lower::ParamLoweringMode,
|
||||
mir::monomorphize_mir_body_bad, to_placeholder_idx, Const, ConstData, ConstScalar, ConstValue,
|
||||
GenericArg, Interner, MemoryMap, Substitution, TraitEnvironment, Ty, TyBuilder,
|
||||
db::HirDatabase, display::DisplayTarget, generics::Generics, infer::InferenceContext,
|
||||
lower::ParamLoweringMode, mir::monomorphize_mir_body_bad, to_placeholder_idx, Const, ConstData,
|
||||
ConstScalar, ConstValue, GenericArg, Interner, MemoryMap, Substitution, TraitEnvironment, Ty,
|
||||
TyBuilder,
|
||||
};
|
||||
|
||||
use super::mir::{interpret_mir, lower_to_mir, pad16, MirEvalError, MirLowerError};
|
||||
|
|
@ -62,11 +63,15 @@ impl ConstEvalError {
|
|||
f: &mut String,
|
||||
db: &dyn HirDatabase,
|
||||
span_formatter: impl Fn(span::FileId, span::TextRange) -> String,
|
||||
edition: span::Edition,
|
||||
display_target: DisplayTarget,
|
||||
) -> std::result::Result<(), std::fmt::Error> {
|
||||
match self {
|
||||
ConstEvalError::MirLowerError(e) => e.pretty_print(f, db, span_formatter, edition),
|
||||
ConstEvalError::MirEvalError(e) => e.pretty_print(f, db, span_formatter, edition),
|
||||
ConstEvalError::MirLowerError(e) => {
|
||||
e.pretty_print(f, db, span_formatter, display_target)
|
||||
}
|
||||
ConstEvalError::MirEvalError(e) => {
|
||||
e.pretty_print(f, db, span_formatter, display_target)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use test_fixture::WithFixture;
|
|||
use test_utils::skip_slow_tests;
|
||||
|
||||
use crate::{
|
||||
consteval::try_const_usize, db::HirDatabase, mir::pad16, test_db::TestDB, Const, ConstScalar,
|
||||
Interner, MemoryMap,
|
||||
consteval::try_const_usize, db::HirDatabase, display::DisplayTarget, mir::pad16,
|
||||
test_db::TestDB, Const, ConstScalar, Interner, MemoryMap,
|
||||
};
|
||||
|
||||
use super::{
|
||||
|
|
@ -101,11 +101,17 @@ fn check_answer(
|
|||
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.crate_graph().crates_in_topological_order().last().unwrap()].edition;
|
||||
let display_target = DisplayTarget::from_crate(
|
||||
&db,
|
||||
*db.crate_graph().crates_in_topological_order().last().unwrap(),
|
||||
);
|
||||
match e {
|
||||
ConstEvalError::MirLowerError(e) => e.pretty_print(&mut err, &db, span_formatter, edition),
|
||||
ConstEvalError::MirEvalError(e) => e.pretty_print(&mut err, &db, span_formatter, edition),
|
||||
ConstEvalError::MirLowerError(e) => {
|
||||
e.pretty_print(&mut err, &db, span_formatter, display_target)
|
||||
}
|
||||
ConstEvalError::MirEvalError(e) => {
|
||||
e.pretty_print(&mut err, &db, span_formatter, display_target)
|
||||
}
|
||||
}
|
||||
.unwrap();
|
||||
err
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ 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,
|
||||
|
|
@ -31,7 +30,7 @@ use crate::{
|
|||
self,
|
||||
pat_analysis::{self, DeconstructedPat, MatchCheckCtx, WitnessPat},
|
||||
},
|
||||
display::HirDisplay,
|
||||
display::{DisplayTarget, HirDisplay},
|
||||
Adjust, InferenceResult, Interner, Ty, TyExt, TyKind,
|
||||
};
|
||||
|
||||
|
|
@ -633,24 +632,24 @@ fn missing_match_arms<'p>(
|
|||
arms_is_empty: bool,
|
||||
krate: CrateId,
|
||||
) -> String {
|
||||
struct DisplayWitness<'a, 'p>(&'a WitnessPat<'p>, &'a MatchCheckCtx<'p>, Edition);
|
||||
struct DisplayWitness<'a, 'p>(&'a WitnessPat<'p>, &'a MatchCheckCtx<'p>, DisplayTarget);
|
||||
impl fmt::Display for DisplayWitness<'_, '_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let DisplayWitness(witness, cx, edition) = *self;
|
||||
let DisplayWitness(witness, cx, display_target) = *self;
|
||||
let pat = cx.hoist_witness_pat(witness);
|
||||
write!(f, "{}", pat.display(cx.db, edition))
|
||||
write!(f, "{}", pat.display(cx.db, display_target))
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
let display_target = DisplayTarget::from_crate(cx.db, krate);
|
||||
if arms_is_empty && !non_empty_enum {
|
||||
format!("type `{}` is non-empty", scrut_ty.display(cx.db, edition))
|
||||
format!("type `{}` is non-empty", scrut_ty.display(cx.db, display_target))
|
||||
} else {
|
||||
let pat_display = |witness| DisplayWitness(witness, cx, edition);
|
||||
let pat_display = |witness| DisplayWitness(witness, cx, display_target);
|
||||
const LIMIT: usize = 3;
|
||||
match &*witnesses {
|
||||
[witness] => format!("`{}` not covered", pat_display(witness)),
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ use crate::{
|
|||
db::{HirDatabase, InternedClosure},
|
||||
from_assoc_type_id, from_foreign_def_id, from_placeholder_idx,
|
||||
generics::generics,
|
||||
infer::normalize,
|
||||
layout::Layout,
|
||||
lt_from_placeholder_idx,
|
||||
mapping::from_chalk,
|
||||
|
|
@ -87,6 +88,7 @@ pub struct HirFormatter<'a> {
|
|||
show_container_bounds: bool,
|
||||
omit_verbose_types: bool,
|
||||
closure_style: ClosureStyle,
|
||||
display_kind: DisplayKind,
|
||||
display_target: DisplayTarget,
|
||||
bounds_formatting_ctx: BoundsFormattingCtx,
|
||||
}
|
||||
|
|
@ -164,6 +166,7 @@ pub trait HirDisplay {
|
|||
limited_size: Option<usize>,
|
||||
omit_verbose_types: bool,
|
||||
display_target: DisplayTarget,
|
||||
display_kind: DisplayKind,
|
||||
closure_style: ClosureStyle,
|
||||
show_container_bounds: bool,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
|
|
@ -171,7 +174,7 @@ pub trait HirDisplay {
|
|||
Self: Sized,
|
||||
{
|
||||
assert!(
|
||||
!matches!(display_target, DisplayTarget::SourceCode { .. }),
|
||||
!matches!(display_kind, DisplayKind::SourceCode { .. }),
|
||||
"HirDisplayWrapper cannot fail with DisplaySourceCodeError, use HirDisplay::hir_fmt directly instead"
|
||||
);
|
||||
HirDisplayWrapper {
|
||||
|
|
@ -181,6 +184,7 @@ pub trait HirDisplay {
|
|||
limited_size,
|
||||
omit_verbose_types,
|
||||
display_target,
|
||||
display_kind,
|
||||
closure_style,
|
||||
show_container_bounds,
|
||||
}
|
||||
|
|
@ -191,7 +195,7 @@ pub trait HirDisplay {
|
|||
fn display<'a>(
|
||||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
edition: Edition,
|
||||
display_target: DisplayTarget,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
|
@ -203,7 +207,8 @@ pub trait HirDisplay {
|
|||
limited_size: None,
|
||||
omit_verbose_types: false,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::Diagnostics { edition },
|
||||
display_target,
|
||||
display_kind: DisplayKind::Diagnostics,
|
||||
show_container_bounds: false,
|
||||
}
|
||||
}
|
||||
|
|
@ -214,7 +219,7 @@ pub trait HirDisplay {
|
|||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
max_size: Option<usize>,
|
||||
edition: Edition,
|
||||
display_target: DisplayTarget,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
|
@ -226,7 +231,8 @@ pub trait HirDisplay {
|
|||
limited_size: None,
|
||||
omit_verbose_types: true,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::Diagnostics { edition },
|
||||
display_target,
|
||||
display_kind: DisplayKind::Diagnostics,
|
||||
show_container_bounds: false,
|
||||
}
|
||||
}
|
||||
|
|
@ -237,7 +243,7 @@ pub trait HirDisplay {
|
|||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
limited_size: Option<usize>,
|
||||
edition: Edition,
|
||||
display_target: DisplayTarget,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
|
@ -249,7 +255,8 @@ pub trait HirDisplay {
|
|||
limited_size,
|
||||
omit_verbose_types: true,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::Diagnostics { edition },
|
||||
display_target,
|
||||
display_kind: DisplayKind::Diagnostics,
|
||||
show_container_bounds: false,
|
||||
}
|
||||
}
|
||||
|
|
@ -272,7 +279,8 @@ pub trait HirDisplay {
|
|||
entity_limit: None,
|
||||
omit_verbose_types: false,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::SourceCode { module_id, allow_opaque },
|
||||
display_target: DisplayTarget::from_crate(db, module_id.krate()),
|
||||
display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque },
|
||||
show_container_bounds: false,
|
||||
bounds_formatting_ctx: Default::default(),
|
||||
}) {
|
||||
|
|
@ -284,29 +292,10 @@ pub trait HirDisplay {
|
|||
}
|
||||
|
||||
/// Returns a String representation of `self` for test purposes
|
||||
fn display_test<'a>(&'a self, db: &'a dyn HirDatabase) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
HirDisplayWrapper {
|
||||
db,
|
||||
t: self,
|
||||
max_size: None,
|
||||
limited_size: None,
|
||||
omit_verbose_types: false,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::Test,
|
||||
show_container_bounds: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a String representation of `self` that shows the constraint from
|
||||
/// the container for functions
|
||||
fn display_with_container_bounds<'a>(
|
||||
fn display_test<'a>(
|
||||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
show_container_bounds: bool,
|
||||
edition: Edition,
|
||||
display_target: DisplayTarget,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
|
@ -318,21 +307,44 @@ pub trait HirDisplay {
|
|||
limited_size: None,
|
||||
omit_verbose_types: false,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target: DisplayTarget::Diagnostics { edition },
|
||||
display_target,
|
||||
display_kind: DisplayKind::Test,
|
||||
show_container_bounds: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a String representation of `self` that shows the constraint from
|
||||
/// the container for functions
|
||||
fn display_with_container_bounds<'a>(
|
||||
&'a self,
|
||||
db: &'a dyn HirDatabase,
|
||||
show_container_bounds: bool,
|
||||
display_target: DisplayTarget,
|
||||
) -> HirDisplayWrapper<'a, Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
HirDisplayWrapper {
|
||||
db,
|
||||
t: self,
|
||||
max_size: None,
|
||||
limited_size: None,
|
||||
omit_verbose_types: false,
|
||||
closure_style: ClosureStyle::ImplFn,
|
||||
display_target,
|
||||
display_kind: DisplayKind::Diagnostics,
|
||||
show_container_bounds,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HirFormatter<'_> {
|
||||
pub fn krate(&self) -> CrateId {
|
||||
self.display_target.krate
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
self.display_target.edition
|
||||
}
|
||||
|
||||
pub fn write_joined<T: HirDisplay>(
|
||||
|
|
@ -394,20 +406,33 @@ impl HirFormatter<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DisplayTarget {
|
||||
krate: CrateId,
|
||||
pub edition: Edition,
|
||||
}
|
||||
|
||||
impl DisplayTarget {
|
||||
pub fn from_crate(db: &dyn HirDatabase, krate: CrateId) -> Self {
|
||||
let edition = db.crate_graph()[krate].edition;
|
||||
Self { krate, edition }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum DisplayTarget {
|
||||
pub enum DisplayKind {
|
||||
/// 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 { edition: Edition },
|
||||
Diagnostics,
|
||||
/// 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 },
|
||||
SourceCode { target_module_id: ModuleId, allow_opaque: bool },
|
||||
/// Only for test purpose to keep real types
|
||||
Test,
|
||||
}
|
||||
|
||||
impl DisplayTarget {
|
||||
impl DisplayKind {
|
||||
fn is_source_code(self) -> bool {
|
||||
matches!(self, Self::SourceCode { .. })
|
||||
}
|
||||
|
|
@ -450,6 +475,7 @@ pub struct HirDisplayWrapper<'a, T> {
|
|||
limited_size: Option<usize>,
|
||||
omit_verbose_types: bool,
|
||||
closure_style: ClosureStyle,
|
||||
display_kind: DisplayKind,
|
||||
display_target: DisplayTarget,
|
||||
show_container_bounds: bool,
|
||||
}
|
||||
|
|
@ -479,6 +505,7 @@ impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
|
|||
max_size: self.max_size,
|
||||
entity_limit: self.limited_size,
|
||||
omit_verbose_types: self.omit_verbose_types,
|
||||
display_kind: self.display_kind,
|
||||
display_target: self.display_target,
|
||||
closure_style: self.closure_style,
|
||||
show_container_bounds: self.show_container_bounds,
|
||||
|
|
@ -533,7 +560,7 @@ impl HirDisplay for ProjectionTy {
|
|||
// if we are projection on a type parameter, check if the projection target has bounds
|
||||
// itself, if so, we render them directly as `impl Bound` instead of the less useful
|
||||
// `<Param as Trait>::Assoc`
|
||||
if !f.display_target.is_source_code() {
|
||||
if !f.display_kind.is_source_code() {
|
||||
if let TyKind::Placeholder(idx) = self_ty.kind(Interner) {
|
||||
if !f.bounds_formatting_ctx.contains(self) {
|
||||
let db = f.db;
|
||||
|
|
@ -653,10 +680,8 @@ fn render_const_scalar(
|
|||
memory_map: &MemoryMap,
|
||||
ty: &Ty,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
// FIXME: We need to get krate from the final callers of the hir display
|
||||
// infrastructure and have it here as a field on `f`.
|
||||
let trait_env =
|
||||
TraitEnvironment::empty(*f.db.crate_graph().crates_in_topological_order().last().unwrap());
|
||||
let trait_env = TraitEnvironment::empty(f.krate());
|
||||
let ty = normalize(f.db, trait_env.clone(), ty.clone());
|
||||
match ty.kind(Interner) {
|
||||
TyKind::Scalar(s) => match s {
|
||||
Scalar::Bool => write!(f, "{}", b[0] != 0),
|
||||
|
|
@ -1109,7 +1134,7 @@ impl HirDisplay for Ty {
|
|||
let def = from_chalk(db, *def);
|
||||
let sig = db.callable_item_signature(def).substitute(Interner, parameters);
|
||||
|
||||
if f.display_target.is_source_code() {
|
||||
if f.display_kind.is_source_code() {
|
||||
// `FnDef` is anonymous and there's no surface syntax for it. Show it as a
|
||||
// function pointer type.
|
||||
return sig.hir_fmt(f);
|
||||
|
|
@ -1198,8 +1223,8 @@ 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 => {
|
||||
match f.display_kind {
|
||||
DisplayKind::Diagnostics { .. } | DisplayKind::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(),
|
||||
|
|
@ -1207,7 +1232,7 @@ impl HirDisplay for Ty {
|
|||
};
|
||||
write!(f, "{}", name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
DisplayTarget::SourceCode { module_id, allow_opaque: _ } => {
|
||||
DisplayKind::SourceCode { target_module_id: module_id, allow_opaque: _ } => {
|
||||
if let Some(path) = find_path::find_path(
|
||||
db.upcast(),
|
||||
ItemInNs::Types((*def_id).into()),
|
||||
|
|
@ -1246,7 +1271,7 @@ impl HirDisplay for Ty {
|
|||
let type_alias_data = db.type_alias_data(type_alias);
|
||||
|
||||
// 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() {
|
||||
if f.display_kind.is_test() {
|
||||
f.start_location_link(trait_.into());
|
||||
write!(f, "{}", trait_data.name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
|
|
@ -1275,7 +1300,7 @@ impl HirDisplay for Ty {
|
|||
f.end_location_link();
|
||||
}
|
||||
TyKind::OpaqueType(opaque_ty_id, parameters) => {
|
||||
if !f.display_target.allows_opaque() {
|
||||
if !f.display_kind.allows_opaque() {
|
||||
return Err(HirDisplayError::DisplaySourceCodeError(
|
||||
DisplaySourceCodeError::OpaqueType,
|
||||
));
|
||||
|
|
@ -1344,8 +1369,8 @@ impl HirDisplay for Ty {
|
|||
}
|
||||
}
|
||||
TyKind::Closure(id, substs) => {
|
||||
if f.display_target.is_source_code() {
|
||||
if !f.display_target.allows_opaque() {
|
||||
if f.display_kind.is_source_code() {
|
||||
if !f.display_kind.allows_opaque() {
|
||||
return Err(HirDisplayError::DisplaySourceCodeError(
|
||||
DisplaySourceCodeError::OpaqueType,
|
||||
));
|
||||
|
|
@ -1465,7 +1490,7 @@ impl HirDisplay for Ty {
|
|||
}
|
||||
TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
|
||||
TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
|
||||
if !f.display_target.allows_opaque() {
|
||||
if !f.display_kind.allows_opaque() {
|
||||
return Err(HirDisplayError::DisplaySourceCodeError(
|
||||
DisplaySourceCodeError::OpaqueType,
|
||||
));
|
||||
|
|
@ -1508,7 +1533,7 @@ impl HirDisplay for Ty {
|
|||
};
|
||||
}
|
||||
TyKind::Error => {
|
||||
if f.display_target.is_source_code() {
|
||||
if f.display_kind.is_source_code() {
|
||||
f.write_char('_')?;
|
||||
} else {
|
||||
write!(f, "{{unknown}}")?;
|
||||
|
|
@ -1516,7 +1541,7 @@ impl HirDisplay for Ty {
|
|||
}
|
||||
TyKind::InferenceVar(..) => write!(f, "_")?,
|
||||
TyKind::Coroutine(_, subst) => {
|
||||
if f.display_target.is_source_code() {
|
||||
if f.display_kind.is_source_code() {
|
||||
return Err(HirDisplayError::DisplaySourceCodeError(
|
||||
DisplaySourceCodeError::Coroutine,
|
||||
));
|
||||
|
|
@ -1573,7 +1598,7 @@ fn generic_args_sans_defaults<'ga>(
|
|||
generic_def: Option<hir_def::GenericDefId>,
|
||||
parameters: &'ga [GenericArg],
|
||||
) -> &'ga [GenericArg] {
|
||||
if f.display_target.is_source_code() || f.omit_verbose_types() {
|
||||
if f.display_kind.is_source_code() || f.omit_verbose_types() {
|
||||
match generic_def
|
||||
.map(|generic_def_id| f.db.generic_defaults(generic_def_id))
|
||||
.filter(|it| !it.is_empty())
|
||||
|
|
@ -1958,7 +1983,7 @@ impl HirDisplay for LifetimeData {
|
|||
write!(f, "{}", param_data.name.display(f.db.upcast(), f.edition()))?;
|
||||
Ok(())
|
||||
}
|
||||
_ if f.display_target.is_source_code() => write!(f, "'_"),
|
||||
_ if f.display_kind.is_source_code() => write!(f, "'_"),
|
||||
LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
|
||||
LifetimeData::InferenceVar(_) => write!(f, "_"),
|
||||
LifetimeData::Static => write!(f, "'static"),
|
||||
|
|
|
|||
|
|
@ -435,6 +435,9 @@ pub fn layout_of_ty_query(
|
|||
TyKind::Error => return Err(LayoutError::HasErrorType),
|
||||
TyKind::AssociatedType(id, subst) => {
|
||||
// Try again with `TyKind::Alias` to normalize the associated type.
|
||||
// Usually we should not try to normalize `TyKind::AssociatedType`, but layout calculation is used
|
||||
// in monomorphized MIR where this is okay. If outside monomorphization, this will lead to cycle,
|
||||
// which we will recover from with an error.
|
||||
let ty = TyKind::Alias(chalk_ir::AliasTy::Projection(ProjectionTy {
|
||||
associated_ty_id: *id,
|
||||
substitution: subst.clone(),
|
||||
|
|
|
|||
|
|
@ -76,13 +76,15 @@ use intern::{sym, Symbol};
|
|||
use la_arena::{Arena, Idx};
|
||||
use mir::{MirEvalError, VTableMap};
|
||||
use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
|
||||
use span::Edition;
|
||||
use syntax::ast::{make, ConstArg};
|
||||
use traits::FnTrait;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
consteval::unknown_const, db::HirDatabase, display::HirDisplay, generics::Generics,
|
||||
consteval::unknown_const,
|
||||
db::HirDatabase,
|
||||
display::{DisplayTarget, HirDisplay},
|
||||
generics::Generics,
|
||||
infer::unify::InferenceTable,
|
||||
};
|
||||
|
||||
|
|
@ -1044,7 +1046,7 @@ where
|
|||
pub fn known_const_to_ast(
|
||||
konst: &Const,
|
||||
db: &dyn HirDatabase,
|
||||
edition: Edition,
|
||||
display_target: DisplayTarget,
|
||||
) -> Option<ConstArg> {
|
||||
if let ConstValue::Concrete(c) = &konst.interned().value {
|
||||
match c.interned {
|
||||
|
|
@ -1055,7 +1057,7 @@ pub fn known_const_to_ast(
|
|||
_ => (),
|
||||
}
|
||||
}
|
||||
Some(make::expr_const_value(konst.display(db, edition).to_string().as_str()))
|
||||
Some(make::expr_const_value(konst.display(db, display_target).to_string().as_str()))
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use std::{collections::hash_map::Entry, fmt::Display, iter};
|
|||
use crate::{
|
||||
consteval::usize_const,
|
||||
db::HirDatabase,
|
||||
display::HirDisplay,
|
||||
display::{DisplayTarget, HirDisplay},
|
||||
infer::{normalize, PointerCast},
|
||||
lang_items::is_box,
|
||||
mapping::ToChalk,
|
||||
|
|
@ -168,7 +168,7 @@ impl<V, T> ProjectionElem<V, T> {
|
|||
_ => {
|
||||
never!(
|
||||
"Overloaded deref on type {} is not a projection",
|
||||
base.display(db, db.crate_graph()[krate].edition)
|
||||
base.display(db, DisplayTarget::from_crate(db, krate))
|
||||
);
|
||||
TyKind::Error.intern(Interner)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use triomphe::Arc;
|
|||
|
||||
use crate::{
|
||||
db::{HirDatabase, InternedClosure},
|
||||
display::DisplayTarget,
|
||||
mir::Operand,
|
||||
utils::ClosureSubst,
|
||||
ClosureId, Interner, Substitution, Ty, TyExt, TypeFlags,
|
||||
|
|
@ -422,7 +423,10 @@ fn ever_initialized_map(
|
|||
let Some(terminator) = &block.terminator else {
|
||||
never!(
|
||||
"Terminator should be none only in construction.\nThe body:\n{}",
|
||||
body.pretty_print(db)
|
||||
body.pretty_print(
|
||||
db,
|
||||
DisplayTarget::from_crate(db, body.owner.krate(db.upcast()))
|
||||
)
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use rustc_apfloat::{
|
|||
Float,
|
||||
};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use span::{Edition, FileId};
|
||||
use span::FileId;
|
||||
use stdx::never;
|
||||
use syntax::{SyntaxNodePtr, TextRange};
|
||||
use triomphe::Arc;
|
||||
|
|
@ -32,7 +32,7 @@ use triomphe::Arc;
|
|||
use crate::{
|
||||
consteval::{intern_const_scalar, try_const_usize, ConstEvalError},
|
||||
db::{HirDatabase, InternedClosure},
|
||||
display::{ClosureStyle, HirDisplay},
|
||||
display::{ClosureStyle, DisplayTarget, HirDisplay},
|
||||
infer::PointerCast,
|
||||
layout::{Layout, LayoutError, RustcEnumVariantIdx},
|
||||
mapping::from_chalk,
|
||||
|
|
@ -359,7 +359,7 @@ impl MirEvalError {
|
|||
f: &mut String,
|
||||
db: &dyn HirDatabase,
|
||||
span_formatter: impl Fn(FileId, TextRange) -> String,
|
||||
edition: Edition,
|
||||
display_target: DisplayTarget,
|
||||
) -> std::result::Result<(), std::fmt::Error> {
|
||||
writeln!(f, "Mir eval error:")?;
|
||||
let mut err = self;
|
||||
|
|
@ -372,7 +372,7 @@ impl MirEvalError {
|
|||
writeln!(
|
||||
f,
|
||||
"In function {} ({:?})",
|
||||
function_name.name.display(db.upcast(), edition),
|
||||
function_name.name.display(db.upcast(), display_target.edition),
|
||||
func
|
||||
)?;
|
||||
}
|
||||
|
|
@ -417,7 +417,7 @@ impl MirEvalError {
|
|||
write!(
|
||||
f,
|
||||
"Layout for type `{}` is not available due {err:?}",
|
||||
ty.display(db, edition).with_closure_style(ClosureStyle::ClosureWithId)
|
||||
ty.display(db, display_target).with_closure_style(ClosureStyle::ClosureWithId)
|
||||
)?;
|
||||
}
|
||||
MirEvalError::MirLowerError(func, err) => {
|
||||
|
|
@ -428,12 +428,15 @@ impl MirEvalError {
|
|||
let substs = generics.placeholder_subst(db);
|
||||
db.impl_self_ty(impl_id)
|
||||
.substitute(Interner, &substs)
|
||||
.display(db, edition)
|
||||
.display(db, display_target)
|
||||
.to_string()
|
||||
}),
|
||||
ItemContainerId::TraitId(it) => {
|
||||
Some(db.trait_data(it).name.display(db.upcast(), edition).to_string())
|
||||
}
|
||||
ItemContainerId::TraitId(it) => Some(
|
||||
db.trait_data(it)
|
||||
.name
|
||||
.display(db.upcast(), display_target.edition)
|
||||
.to_string(),
|
||||
),
|
||||
_ => None,
|
||||
};
|
||||
writeln!(
|
||||
|
|
@ -441,17 +444,17 @@ impl MirEvalError {
|
|||
"MIR lowering for function `{}{}{}` ({:?}) failed due:",
|
||||
self_.as_deref().unwrap_or_default(),
|
||||
if self_.is_some() { "::" } else { "" },
|
||||
function_name.name.display(db.upcast(), edition),
|
||||
function_name.name.display(db.upcast(), display_target.edition),
|
||||
func
|
||||
)?;
|
||||
err.pretty_print(f, db, span_formatter, edition)?;
|
||||
err.pretty_print(f, db, span_formatter, display_target)?;
|
||||
}
|
||||
MirEvalError::ConstEvalError(name, err) => {
|
||||
MirLowerError::ConstEvalError((**name).into(), err.clone()).pretty_print(
|
||||
f,
|
||||
db,
|
||||
span_formatter,
|
||||
edition,
|
||||
display_target,
|
||||
)?;
|
||||
}
|
||||
MirEvalError::UndefinedBehavior(_)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use intern::{sym, Symbol};
|
|||
use stdx::never;
|
||||
|
||||
use crate::{
|
||||
display::DisplayTarget,
|
||||
error_lifetime,
|
||||
mir::eval::{
|
||||
pad16, Address, AdtId, Arc, BuiltinType, Evaluator, FunctionId, HasModule, HirDisplay,
|
||||
|
|
@ -835,8 +836,7 @@ impl Evaluator<'_> {
|
|||
// render full paths.
|
||||
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()
|
||||
ty.display(self.db, DisplayTarget::from_crate(self.db, krate)).to_string()
|
||||
}
|
||||
};
|
||||
let len = ty_name.len();
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use span::{Edition, EditionedFileId};
|
|||
use syntax::{TextRange, TextSize};
|
||||
use test_fixture::WithFixture;
|
||||
|
||||
use crate::display::DisplayTarget;
|
||||
use crate::{db::HirDatabase, mir::MirLowerError, test_db::TestDB, Interner, Substitution};
|
||||
|
||||
use super::{interpret_mir, MirEvalError};
|
||||
|
|
@ -67,7 +68,9 @@ fn check_pass_and_stdio(
|
|||
let span_formatter = |file, range: TextRange| {
|
||||
format!("{:?} {:?}..{:?}", file, line_index(range.start()), line_index(range.end()))
|
||||
};
|
||||
e.pretty_print(&mut err, &db, span_formatter, Edition::CURRENT).unwrap();
|
||||
let krate = db.module_for_file(file_id).krate();
|
||||
e.pretty_print(&mut err, &db, span_formatter, DisplayTarget::from_crate(&db, krate))
|
||||
.unwrap();
|
||||
panic!("Error in interpreting: {err}");
|
||||
}
|
||||
Ok((stdout, stderr)) => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std::{fmt::Write, iter, mem};
|
||||
|
||||
use base_db::ra_salsa::Cycle;
|
||||
use base_db::{ra_salsa::Cycle, CrateId};
|
||||
use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind};
|
||||
use hir_def::{
|
||||
data::adt::{StructKind, VariantData},
|
||||
|
|
@ -29,7 +29,7 @@ use triomphe::Arc;
|
|||
use crate::{
|
||||
consteval::ConstEvalError,
|
||||
db::{HirDatabase, InternedClosure},
|
||||
display::{hir_display_with_types_map, HirDisplay},
|
||||
display::{hir_display_with_types_map, DisplayTarget, HirDisplay},
|
||||
error_lifetime,
|
||||
generics::generics,
|
||||
infer::{cast::CastTy, unify::InferenceTable, CaptureKind, CapturedItem, TypeMismatch},
|
||||
|
|
@ -160,17 +160,17 @@ impl MirLowerError {
|
|||
f: &mut String,
|
||||
db: &dyn HirDatabase,
|
||||
span_formatter: impl Fn(FileId, TextRange) -> String,
|
||||
edition: Edition,
|
||||
display_target: DisplayTarget,
|
||||
) -> 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, edition)?
|
||||
e.pretty_print(f, db, span_formatter, display_target)?
|
||||
}
|
||||
ConstEvalError::MirEvalError(e) => {
|
||||
e.pretty_print(f, db, span_formatter, edition)?
|
||||
e.pretty_print(f, db, span_formatter, display_target)?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -179,15 +179,15 @@ impl MirLowerError {
|
|||
writeln!(
|
||||
f,
|
||||
"Missing function definition for {}",
|
||||
body.pretty_print_expr(db.upcast(), *owner, *it, edition)
|
||||
body.pretty_print_expr(db.upcast(), *owner, *it, display_target.edition)
|
||||
)?;
|
||||
}
|
||||
MirLowerError::HasErrors => writeln!(f, "Type inference result contains errors")?,
|
||||
MirLowerError::TypeMismatch(e) => writeln!(
|
||||
f,
|
||||
"Type mismatch: Expected {}, found {}",
|
||||
e.expected.display(db, edition),
|
||||
e.actual.display(db, edition),
|
||||
e.expected.display(db, display_target),
|
||||
e.actual.display(db, display_target),
|
||||
)?,
|
||||
MirLowerError::GenericArgNotProvided(id, subst) => {
|
||||
let parent = id.parent;
|
||||
|
|
@ -195,11 +195,14 @@ impl MirLowerError {
|
|||
writeln!(
|
||||
f,
|
||||
"Generic arg not provided for {}",
|
||||
param.name().unwrap_or(&Name::missing()).display(db.upcast(), edition)
|
||||
param
|
||||
.name()
|
||||
.unwrap_or(&Name::missing())
|
||||
.display(db.upcast(), display_target.edition)
|
||||
)?;
|
||||
writeln!(f, "Provided args: [")?;
|
||||
for g in subst.iter(Interner) {
|
||||
write!(f, " {},", g.display(db, edition))?;
|
||||
write!(f, " {},", g.display(db, display_target))?;
|
||||
}
|
||||
writeln!(f, "]")?;
|
||||
}
|
||||
|
|
@ -251,11 +254,11 @@ impl MirLowerError {
|
|||
fn unresolved_path(
|
||||
db: &dyn HirDatabase,
|
||||
p: &Path,
|
||||
edition: Edition,
|
||||
display_target: DisplayTarget,
|
||||
types_map: &TypesMap,
|
||||
) -> Self {
|
||||
Self::UnresolvedName(
|
||||
hir_display_with_types_map(p, types_map).display(db, edition).to_string(),
|
||||
hir_display_with_types_map(p, types_map).display(db, display_target).to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -462,7 +465,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
MirLowerError::unresolved_path(
|
||||
self.db,
|
||||
p,
|
||||
self.edition(),
|
||||
DisplayTarget::from_crate(self.db, self.krate()),
|
||||
&self.body.types,
|
||||
)
|
||||
})?;
|
||||
|
|
@ -838,7 +841,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path {
|
||||
Some(p) => MirLowerError::UnresolvedName(
|
||||
hir_display_with_types_map(&**p, &self.body.types)
|
||||
.display(self.db, self.edition())
|
||||
.display(self.db, self.display_target())
|
||||
.to_string(),
|
||||
),
|
||||
None => MirLowerError::RecordLiteralWithoutPath,
|
||||
|
|
@ -1362,9 +1365,16 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
match &self.body.exprs[*loc] {
|
||||
Expr::Literal(l) => self.lower_literal_to_operand(ty, l),
|
||||
Expr::Path(c) => {
|
||||
let edition = self.edition();
|
||||
let unresolved_name =
|
||||
|| MirLowerError::unresolved_path(self.db, c, edition, &self.body.types);
|
||||
let owner = self.owner;
|
||||
let db = self.db;
|
||||
let unresolved_name = || {
|
||||
MirLowerError::unresolved_path(
|
||||
self.db,
|
||||
c,
|
||||
DisplayTarget::from_crate(db, owner.krate(db.upcast())),
|
||||
&self.body.types,
|
||||
)
|
||||
};
|
||||
let pr = self
|
||||
.resolver
|
||||
.resolve_path_in_value_ns(self.db.upcast(), c, HygieneId::ROOT)
|
||||
|
|
@ -1910,8 +1920,15 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
}
|
||||
|
||||
fn edition(&self) -> Edition {
|
||||
let krate = self.owner.krate(self.db.upcast());
|
||||
self.db.crate_graph()[krate].edition
|
||||
self.db.crate_graph()[self.krate()].edition
|
||||
}
|
||||
|
||||
fn krate(&self) -> CrateId {
|
||||
self.owner.krate(self.db.upcast())
|
||||
}
|
||||
|
||||
fn display_target(&self) -> DisplayTarget {
|
||||
DisplayTarget::from_crate(self.db, self.krate())
|
||||
}
|
||||
|
||||
fn drop_until_scope(
|
||||
|
|
|
|||
|
|
@ -350,7 +350,12 @@ impl MirLowerCtx<'_> {
|
|||
)?,
|
||||
None => {
|
||||
let unresolved_name = || {
|
||||
MirLowerError::unresolved_path(self.db, p, self.edition(), &self.body.types)
|
||||
MirLowerError::unresolved_path(
|
||||
self.db,
|
||||
p,
|
||||
self.display_target(),
|
||||
&self.body.types,
|
||||
)
|
||||
};
|
||||
let hygiene = self.body.pat_path_hygiene(pattern);
|
||||
let pr = self
|
||||
|
|
|
|||
|
|
@ -9,11 +9,10 @@ use either::Either;
|
|||
use hir_def::{expr_store::Body, hir::BindingId};
|
||||
use hir_expand::{name::Name, Lookup};
|
||||
use la_arena::ArenaMap;
|
||||
use span::Edition;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
display::{ClosureStyle, HirDisplay},
|
||||
display::{ClosureStyle, DisplayTarget, HirDisplay},
|
||||
mir::{PlaceElem, ProjectionElem, StatementKind, TerminatorKind},
|
||||
ClosureId,
|
||||
};
|
||||
|
|
@ -39,17 +38,21 @@ macro_rules! wln {
|
|||
}
|
||||
|
||||
impl MirBody {
|
||||
pub fn pretty_print(&self, db: &dyn HirDatabase) -> String {
|
||||
pub fn pretty_print(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
|
||||
let hir_body = db.body(self.owner);
|
||||
let mut ctx = MirPrettyCtx::new(self, &hir_body, db);
|
||||
let mut ctx = MirPrettyCtx::new(self, &hir_body, db, display_target);
|
||||
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(), Edition::LATEST));
|
||||
w!(this, "fn {}() ", data.name.display(db.upcast(), this.display_target.edition));
|
||||
}
|
||||
hir_def::DefWithBodyId::StaticId(id) => {
|
||||
let data = db.static_data(id);
|
||||
w!(this, "static {}: _ = ", data.name.display(db.upcast(), Edition::LATEST));
|
||||
w!(
|
||||
this,
|
||||
"static {}: _ = ",
|
||||
data.name.display(db.upcast(), this.display_target.edition)
|
||||
);
|
||||
}
|
||||
hir_def::DefWithBodyId::ConstId(id) => {
|
||||
let data = db.const_data(id);
|
||||
|
|
@ -59,7 +62,7 @@ impl MirBody {
|
|||
data.name
|
||||
.as_ref()
|
||||
.unwrap_or(&Name::missing())
|
||||
.display(db.upcast(), Edition::LATEST)
|
||||
.display(db.upcast(), this.display_target.edition)
|
||||
);
|
||||
}
|
||||
hir_def::DefWithBodyId::VariantId(id) => {
|
||||
|
|
@ -70,10 +73,10 @@ impl MirBody {
|
|||
"enum {}::{} = ",
|
||||
enum_loc.id.item_tree(db.upcast())[enum_loc.id.value]
|
||||
.name
|
||||
.display(db.upcast(), Edition::LATEST),
|
||||
.display(db.upcast(), this.display_target.edition),
|
||||
loc.id.item_tree(db.upcast())[loc.id.value]
|
||||
.name
|
||||
.display(db.upcast(), Edition::LATEST),
|
||||
.display(db.upcast(), this.display_target.edition),
|
||||
)
|
||||
}
|
||||
hir_def::DefWithBodyId::InTypeConstId(id) => {
|
||||
|
|
@ -85,14 +88,14 @@ impl MirBody {
|
|||
|
||||
// String with lines is rendered poorly in `dbg` macros, which I use very much, so this
|
||||
// function exists to solve that.
|
||||
pub fn dbg(&self, db: &dyn HirDatabase) -> impl Debug {
|
||||
pub fn dbg(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> impl Debug {
|
||||
struct StringDbg(String);
|
||||
impl Debug for StringDbg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_str(&self.0)
|
||||
}
|
||||
}
|
||||
StringDbg(self.pretty_print(db))
|
||||
StringDbg(self.pretty_print(db, display_target))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -103,6 +106,7 @@ struct MirPrettyCtx<'a> {
|
|||
result: String,
|
||||
indent: String,
|
||||
local_to_binding: ArenaMap<LocalId, BindingId>,
|
||||
display_target: DisplayTarget,
|
||||
}
|
||||
|
||||
impl Write for MirPrettyCtx<'_> {
|
||||
|
|
@ -182,7 +186,12 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
wln!(self, "}}");
|
||||
}
|
||||
|
||||
fn new(body: &'a MirBody, hir_body: &'a Body, db: &'a dyn HirDatabase) -> Self {
|
||||
fn new(
|
||||
body: &'a MirBody,
|
||||
hir_body: &'a Body,
|
||||
db: &'a dyn HirDatabase,
|
||||
display_target: DisplayTarget,
|
||||
) -> Self {
|
||||
let local_to_binding = body.local_to_binding_map();
|
||||
MirPrettyCtx {
|
||||
body,
|
||||
|
|
@ -191,6 +200,7 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
indent: String::new(),
|
||||
local_to_binding,
|
||||
hir_body,
|
||||
display_target,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -208,7 +218,7 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
wln!(
|
||||
self,
|
||||
"let {}: {};",
|
||||
self.local_name(id).display_test(self.db),
|
||||
self.local_name(id).display_test(self.db, self.display_target),
|
||||
self.hir_display(&local.ty)
|
||||
);
|
||||
}
|
||||
|
|
@ -242,14 +252,14 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
wln!(
|
||||
this,
|
||||
"StorageDead({})",
|
||||
this.local_name(*p).display_test(self.db)
|
||||
this.local_name(*p).display_test(this.db, this.display_target)
|
||||
);
|
||||
}
|
||||
StatementKind::StorageLive(p) => {
|
||||
wln!(
|
||||
this,
|
||||
"StorageLive({})",
|
||||
this.local_name(*p).display_test(self.db)
|
||||
this.local_name(*p).display_test(this.db, this.display_target)
|
||||
);
|
||||
}
|
||||
StatementKind::Deinit(p) => {
|
||||
|
|
@ -313,7 +323,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_test(this.db));
|
||||
w!(this, "{}", this.local_name(local).display_test(this.db, this.display_target));
|
||||
return;
|
||||
};
|
||||
match last {
|
||||
|
|
@ -333,13 +343,17 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
w!(
|
||||
this,
|
||||
" as {}).{}",
|
||||
variant_name.display(this.db.upcast(), Edition::LATEST),
|
||||
name.display(this.db.upcast(), Edition::LATEST)
|
||||
variant_name.display(this.db.upcast(), this.display_target.edition),
|
||||
name.display(this.db.upcast(), this.display_target.edition)
|
||||
);
|
||||
}
|
||||
hir_def::VariantId::StructId(_) | hir_def::VariantId::UnionId(_) => {
|
||||
f(this, local, head);
|
||||
w!(this, ".{}", name.display(this.db.upcast(), Edition::LATEST));
|
||||
w!(
|
||||
this,
|
||||
".{}",
|
||||
name.display(this.db.upcast(), this.display_target.edition)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -353,7 +367,11 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
}
|
||||
ProjectionElem::Index(l) => {
|
||||
f(this, local, head);
|
||||
w!(this, "[{}]", this.local_name(*l).display_test(this.db));
|
||||
w!(
|
||||
this,
|
||||
"[{}]",
|
||||
this.local_name(*l).display_test(this.db, this.display_target)
|
||||
);
|
||||
}
|
||||
it => {
|
||||
f(this, local, head);
|
||||
|
|
@ -403,7 +421,7 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
Rvalue::Repeat(op, len) => {
|
||||
w!(self, "[");
|
||||
self.operand(op);
|
||||
w!(self, "; {}]", len.display_test(self.db));
|
||||
w!(self, "; {}]", len.display_test(self.db, self.display_target));
|
||||
}
|
||||
Rvalue::Aggregate(AggregateKind::Adt(_, _), it) => {
|
||||
w!(self, "Adt(");
|
||||
|
|
@ -478,6 +496,7 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
}
|
||||
|
||||
fn hir_display<T: HirDisplay>(&self, ty: &'a T) -> impl Display + 'a {
|
||||
ty.display_test(self.db).with_closure_style(ClosureStyle::ClosureWithSubst)
|
||||
ty.display_test(self.db, self.display_target)
|
||||
.with_closure_style(ClosureStyle::ClosureWithSubst)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ mod type_alias_impl_traits;
|
|||
use std::env;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use base_db::SourceDatabaseFileInputExt as _;
|
||||
use base_db::{CrateId, SourceDatabaseFileInputExt as _};
|
||||
use expect_test::Expect;
|
||||
use hir_def::{
|
||||
db::DefDatabase,
|
||||
|
|
@ -41,7 +41,7 @@ use triomphe::Arc;
|
|||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
display::HirDisplay,
|
||||
display::{DisplayTarget, HirDisplay},
|
||||
infer::{Adjustment, TypeMismatch},
|
||||
test_db::TestDB,
|
||||
InferenceResult, Ty,
|
||||
|
|
@ -124,7 +124,7 @@ fn check_impl(
|
|||
}
|
||||
assert!(had_annotations || allow_none, "no `//^` annotations found");
|
||||
|
||||
let mut defs: Vec<DefWithBodyId> = Vec::new();
|
||||
let mut defs: Vec<(DefWithBodyId, CrateId)> = Vec::new();
|
||||
for file_id in files {
|
||||
let module = db.module_for_file_opt(file_id);
|
||||
let module = match module {
|
||||
|
|
@ -133,16 +133,17 @@ fn check_impl(
|
|||
};
|
||||
let def_map = module.def_map(&db);
|
||||
visit_module(&db, &def_map, module.local_id, &mut |it| {
|
||||
defs.push(match it {
|
||||
let def = match it {
|
||||
ModuleDefId::FunctionId(it) => it.into(),
|
||||
ModuleDefId::EnumVariantId(it) => it.into(),
|
||||
ModuleDefId::ConstId(it) => it.into(),
|
||||
ModuleDefId::StaticId(it) => it.into(),
|
||||
_ => return,
|
||||
})
|
||||
};
|
||||
defs.push((def, module.krate()))
|
||||
});
|
||||
}
|
||||
defs.sort_by_key(|def| match def {
|
||||
defs.sort_by_key(|(def, _)| match def {
|
||||
DefWithBodyId::FunctionId(it) => {
|
||||
let loc = it.lookup(&db);
|
||||
loc.source(&db).value.syntax().text_range().start()
|
||||
|
|
@ -162,7 +163,8 @@ fn check_impl(
|
|||
DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(),
|
||||
});
|
||||
let mut unexpected_type_mismatches = String::new();
|
||||
for def in defs {
|
||||
for (def, krate) in defs {
|
||||
let display_target = DisplayTarget::from_crate(&db, krate);
|
||||
let (body, body_source_map) = db.body_with_source_map(def);
|
||||
let inference_result = db.infer(def);
|
||||
|
||||
|
|
@ -179,7 +181,7 @@ fn check_impl(
|
|||
let actual = if display_source {
|
||||
ty.display_source_code(&db, def.module(&db), true).unwrap()
|
||||
} else {
|
||||
ty.display_test(&db).to_string()
|
||||
ty.display_test(&db, display_target).to_string()
|
||||
};
|
||||
assert_eq!(actual, expected, "type annotation differs at {:#?}", range.range);
|
||||
}
|
||||
|
|
@ -195,7 +197,7 @@ fn check_impl(
|
|||
let actual = if display_source {
|
||||
ty.display_source_code(&db, def.module(&db), true).unwrap()
|
||||
} else {
|
||||
ty.display_test(&db).to_string()
|
||||
ty.display_test(&db, display_target).to_string()
|
||||
};
|
||||
assert_eq!(actual, expected, "type annotation differs at {:#?}", range.range);
|
||||
}
|
||||
|
|
@ -224,8 +226,8 @@ fn check_impl(
|
|||
let range = node.as_ref().original_file_range_rooted(&db);
|
||||
let actual = format!(
|
||||
"expected {}, got {}",
|
||||
mismatch.expected.display_test(&db),
|
||||
mismatch.actual.display_test(&db)
|
||||
mismatch.expected.display_test(&db, display_target),
|
||||
mismatch.actual.display_test(&db, display_target)
|
||||
);
|
||||
match mismatches.remove(&range) {
|
||||
Some(annotation) => assert_eq!(actual, annotation),
|
||||
|
|
@ -299,7 +301,9 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
|||
|
||||
let mut infer_def = |inference_result: Arc<InferenceResult>,
|
||||
body: Arc<Body>,
|
||||
body_source_map: Arc<BodySourceMap>| {
|
||||
body_source_map: Arc<BodySourceMap>,
|
||||
krate: CrateId| {
|
||||
let display_target = DisplayTarget::from_crate(&db, krate);
|
||||
let mut types: Vec<(InFile<SyntaxNode>, &Ty)> = Vec::new();
|
||||
let mut mismatches: Vec<(InFile<SyntaxNode>, &TypeMismatch)> = Vec::new();
|
||||
|
||||
|
|
@ -361,7 +365,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
|||
macro_prefix,
|
||||
range,
|
||||
ellipsize(text, 15),
|
||||
ty.display_test(&db)
|
||||
ty.display_test(&db, display_target)
|
||||
);
|
||||
}
|
||||
if include_mismatches {
|
||||
|
|
@ -377,8 +381,8 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
|||
"{}{:?}: expected {}, got {}\n",
|
||||
macro_prefix,
|
||||
range,
|
||||
mismatch.expected.display_test(&db),
|
||||
mismatch.actual.display_test(&db),
|
||||
mismatch.expected.display_test(&db, display_target),
|
||||
mismatch.actual.display_test(&db, display_target),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -387,17 +391,18 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
|||
let module = db.module_for_file(file_id);
|
||||
let def_map = module.def_map(&db);
|
||||
|
||||
let mut defs: Vec<DefWithBodyId> = Vec::new();
|
||||
let mut defs: Vec<(DefWithBodyId, CrateId)> = Vec::new();
|
||||
visit_module(&db, &def_map, module.local_id, &mut |it| {
|
||||
defs.push(match it {
|
||||
let def = match it {
|
||||
ModuleDefId::FunctionId(it) => it.into(),
|
||||
ModuleDefId::EnumVariantId(it) => it.into(),
|
||||
ModuleDefId::ConstId(it) => it.into(),
|
||||
ModuleDefId::StaticId(it) => it.into(),
|
||||
_ => return,
|
||||
})
|
||||
};
|
||||
defs.push((def, module.krate()))
|
||||
});
|
||||
defs.sort_by_key(|def| match def {
|
||||
defs.sort_by_key(|(def, _)| match def {
|
||||
DefWithBodyId::FunctionId(it) => {
|
||||
let loc = it.lookup(&db);
|
||||
loc.source(&db).value.syntax().text_range().start()
|
||||
|
|
@ -416,10 +421,10 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
|||
}
|
||||
DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(),
|
||||
});
|
||||
for def in defs {
|
||||
for (def, krate) in defs {
|
||||
let (body, source_map) = db.body_with_source_map(def);
|
||||
let infer = db.infer(def);
|
||||
infer_def(infer, body, source_map);
|
||||
infer_def(infer, body, source_map, krate);
|
||||
}
|
||||
|
||||
buf.truncate(buf.trim_end().len());
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use syntax::{AstNode, AstPtr};
|
|||
use test_fixture::WithFixture;
|
||||
|
||||
use crate::db::{HirDatabase, InternedClosureId};
|
||||
use crate::display::HirDisplay;
|
||||
use crate::display::{DisplayTarget, HirDisplay};
|
||||
use crate::mir::MirSpan;
|
||||
use crate::test_db::TestDB;
|
||||
|
||||
|
|
@ -66,7 +66,11 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec
|
|||
.join(", "),
|
||||
};
|
||||
let place = capture.display_place(closure.0, db);
|
||||
let capture_ty = capture.ty.skip_binders().display_test(db).to_string();
|
||||
let capture_ty = capture
|
||||
.ty
|
||||
.skip_binders()
|
||||
.display_test(db, DisplayTarget::from_crate(db, module.krate()))
|
||||
.to_string();
|
||||
let spans = capture
|
||||
.spans()
|
||||
.iter()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue