mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-02 21:04:18 +00:00
Merge pull request #19462 from Veykril/push-ypvprvvwkyll
refactor: Lower type-refs before type inference
This commit is contained in:
commit
dc363f7f77
127 changed files with 6733 additions and 7993 deletions
|
|
@ -15,9 +15,9 @@ use base_db::Crate;
|
|||
use hir_def::{
|
||||
AssocItemId, BlockId, CallableDefId, GenericDefId, HasModule, ItemContainerId, Lookup,
|
||||
TypeAliasId, VariantId,
|
||||
data::{TraitFlags, adt::StructFlags},
|
||||
hir::Movability,
|
||||
lang_item::{LangItem, LangItemTarget},
|
||||
signatures::{ImplFlags, StructFlags, TraitFlags},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -68,7 +68,7 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
|||
fn discriminant_type(&self, ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
|
||||
if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner) {
|
||||
if let hir_def::AdtId::EnumId(e) = id.0 {
|
||||
let enum_data = self.db.enum_data(e);
|
||||
let enum_data = self.db.enum_signature(e);
|
||||
let ty = enum_data.repr.unwrap_or_default().discr_type();
|
||||
return chalk_ir::TyKind::Scalar(match ty {
|
||||
hir_def::layout::IntegerType::Pointer(is_signed) => match is_signed {
|
||||
|
|
@ -144,21 +144,21 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
|
|||
let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db);
|
||||
|
||||
let mut result = vec![];
|
||||
_ =
|
||||
if fps.is_empty() {
|
||||
debug!("Unrestricted search for {:?} impls...", trait_);
|
||||
self.for_trait_impls(trait_, self_ty_fp, |impls| {
|
||||
result.extend(impls.for_trait(trait_).map(id_to_chalk));
|
||||
ControlFlow::Continue(())
|
||||
})
|
||||
} else {
|
||||
if fps.is_empty() {
|
||||
debug!("Unrestricted search for {:?} impls...", trait_);
|
||||
_ = self.for_trait_impls(trait_, self_ty_fp, |impls| {
|
||||
result.extend(impls.for_trait(trait_).map(id_to_chalk));
|
||||
ControlFlow::Continue(())
|
||||
});
|
||||
} else {
|
||||
_ =
|
||||
self.for_trait_impls(trait_, self_ty_fp, |impls| {
|
||||
result.extend(fps.iter().flat_map(move |fp| {
|
||||
impls.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk)
|
||||
}));
|
||||
ControlFlow::Continue(())
|
||||
})
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
debug!("impls_for_trait returned {} impls", result.len());
|
||||
result
|
||||
|
|
@ -426,19 +426,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(), self.edition()).to_string()
|
||||
self.db.trait_signature(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(), edition).to_string()
|
||||
self.db.struct_signature(id).name.display(self.db.upcast(), edition).to_string()
|
||||
}
|
||||
hir_def::AdtId::EnumId(id) => {
|
||||
self.db.enum_data(id).name.display(self.db.upcast(), edition).to_string()
|
||||
self.db.enum_signature(id).name.display(self.db.upcast(), edition).to_string()
|
||||
}
|
||||
hir_def::AdtId::UnionId(id) => {
|
||||
self.db.union_data(id).name.display(self.db.upcast(), edition).to_string()
|
||||
self.db.union_signature(id).name.display(self.db.upcast(), edition).to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -448,7 +448,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(from_assoc_type_id(assoc_ty_id)).name;
|
||||
self.db.type_alias_data(id).name.display(self.db.upcast(), self.edition()).to_string()
|
||||
self.db.type_alias_signature(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)
|
||||
|
|
@ -611,11 +611,11 @@ pub(crate) fn associated_ty_data_query(
|
|||
};
|
||||
|
||||
// Lower bounds -- we could/should maybe move this to a separate query in `lower`
|
||||
let type_alias_data = db.type_alias_data(type_alias);
|
||||
let type_alias_data = db.type_alias_signature(type_alias);
|
||||
let generic_params = generics(db.upcast(), type_alias.into());
|
||||
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
|
||||
let mut ctx =
|
||||
crate::TyLoweringContext::new(db, &resolver, &type_alias_data.types_map, type_alias.into())
|
||||
crate::TyLoweringContext::new(db, &resolver, &type_alias_data.store, type_alias.into())
|
||||
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
|
||||
|
||||
let trait_subst = TyBuilder::subst_for_def(db, trait_, None)
|
||||
|
|
@ -669,7 +669,7 @@ pub(crate) fn trait_datum_query(
|
|||
) -> Arc<TraitDatum> {
|
||||
debug!("trait_datum {:?}", trait_id);
|
||||
let trait_ = from_chalk_trait_id(trait_id);
|
||||
let trait_data = db.trait_data(trait_);
|
||||
let trait_data = db.trait_signature(trait_);
|
||||
debug!("trait {:?} = {:?}", trait_id, trait_data.name);
|
||||
let generic_params = generics(db.upcast(), trait_.into());
|
||||
let bound_vars = generic_params.bound_vars_subst(db, DebruijnIndex::INNERMOST);
|
||||
|
|
@ -760,7 +760,7 @@ pub(crate) fn adt_datum_query(
|
|||
|
||||
let (fundamental, phantom_data) = match adt_id {
|
||||
hir_def::AdtId::StructId(s) => {
|
||||
let flags = db.struct_data(s).flags;
|
||||
let flags = db.struct_signature(s).flags;
|
||||
(
|
||||
flags.contains(StructFlags::IS_FUNDAMENTAL),
|
||||
flags.contains(StructFlags::IS_PHANTOM_DATA),
|
||||
|
|
@ -840,7 +840,7 @@ fn impl_def_datum(db: &dyn HirDatabase, krate: Crate, impl_id: hir_def::ImplId)
|
|||
.expect("invalid impl passed to Chalk")
|
||||
.into_value_and_skipped_binders()
|
||||
.0;
|
||||
let impl_data = db.impl_data(impl_id);
|
||||
let impl_data = db.impl_signature(impl_id);
|
||||
|
||||
let generic_params = generics(db.upcast(), impl_id.into());
|
||||
let bound_vars = generic_params.bound_vars_subst(db, DebruijnIndex::INNERMOST);
|
||||
|
|
@ -851,8 +851,7 @@ fn impl_def_datum(db: &dyn HirDatabase, krate: Crate, impl_id: hir_def::ImplId)
|
|||
rust_ir::ImplType::External
|
||||
};
|
||||
let where_clauses = convert_where_clauses(db, impl_id.into(), &bound_vars);
|
||||
let negative = impl_data.is_negative;
|
||||
|
||||
let negative = impl_data.flags.contains(ImplFlags::IS_NEGATIVE);
|
||||
let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive };
|
||||
|
||||
let impl_datum_bound = rust_ir::ImplDatumBound { trait_ref, where_clauses };
|
||||
|
|
@ -867,7 +866,7 @@ fn impl_def_datum(db: &dyn HirDatabase, krate: Crate, impl_id: hir_def::ImplId)
|
|||
})
|
||||
.filter(|&type_alias| {
|
||||
// don't include associated types that don't exist in the trait
|
||||
let name = &db.type_alias_data(type_alias).name;
|
||||
let name = &db.type_alias_signature(type_alias).name;
|
||||
trait_data.associated_type_by_name(name).is_some()
|
||||
})
|
||||
.map(|type_alias| TypeAliasAsValue(type_alias).to_chalk(db))
|
||||
|
|
@ -896,7 +895,7 @@ fn type_alias_associated_ty_value(
|
|||
_krate: Crate,
|
||||
type_alias: TypeAliasId,
|
||||
) -> Arc<AssociatedTyValue> {
|
||||
let type_alias_data = db.type_alias_data(type_alias);
|
||||
let type_alias_data = db.type_alias_signature(type_alias);
|
||||
let impl_id = match type_alias.lookup(db.upcast()).container {
|
||||
ItemContainerId::ImplId(it) => it,
|
||||
_ => panic!("assoc ty value should be in impl"),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use chalk_ir::{
|
|||
use hir_def::{
|
||||
DefWithBodyId, FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId,
|
||||
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType, BuiltinUint},
|
||||
generics::TypeOrConstParamData,
|
||||
hir::generics::{TypeOrConstParamData, TypeParamProvenance},
|
||||
lang_item::LangItem,
|
||||
type_ref::Rawness,
|
||||
};
|
||||
|
|
@ -314,7 +314,7 @@ impl TyExt for Ty {
|
|||
let param_data = &generic_params[id.local_id];
|
||||
match param_data {
|
||||
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
|
||||
hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
|
||||
TypeParamProvenance::ArgumentImplTrait => {
|
||||
let substs = TyBuilder::placeholder_subst(db, id.parent);
|
||||
let predicates = db
|
||||
.generic_predicates(id.parent)
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@
|
|||
use base_db::Crate;
|
||||
use chalk_ir::{BoundVar, DebruijnIndex, cast::Cast};
|
||||
use hir_def::{
|
||||
ConstBlockLoc, EnumVariantId, GeneralConstId, HasModule as _, StaticId,
|
||||
expr_store::{Body, HygieneId},
|
||||
EnumVariantId, GeneralConstId, HasModule as _, StaticId,
|
||||
expr_store::{Body, HygieneId, path::Path},
|
||||
hir::{Expr, ExprId},
|
||||
path::Path,
|
||||
resolver::{Resolver, ValueNs},
|
||||
type_ref::LiteralConstRef,
|
||||
};
|
||||
|
|
@ -23,7 +22,6 @@ use crate::{
|
|||
generics::Generics,
|
||||
infer::InferenceContext,
|
||||
lower::ParamLoweringMode,
|
||||
mir::monomorphize_mir_body_bad,
|
||||
to_placeholder_idx,
|
||||
};
|
||||
|
||||
|
|
@ -102,7 +100,7 @@ pub(crate) fn path_to_const<'g>(
|
|||
resolver: &Resolver,
|
||||
path: &Path,
|
||||
mode: ParamLoweringMode,
|
||||
args: impl FnOnce() -> Option<&'g Generics>,
|
||||
args: impl FnOnce() -> &'g Generics,
|
||||
debruijn: DebruijnIndex,
|
||||
expected_ty: Ty,
|
||||
) -> Option<Const> {
|
||||
|
|
@ -115,7 +113,7 @@ pub(crate) fn path_to_const<'g>(
|
|||
}
|
||||
ParamLoweringMode::Variable => {
|
||||
let args = args();
|
||||
match args.and_then(|args| args.type_or_const_param_idx(p.into())) {
|
||||
match args.type_or_const_param_idx(p.into()) {
|
||||
Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
|
||||
None => {
|
||||
never!(
|
||||
|
|
@ -165,15 +163,15 @@ pub fn intern_const_ref(
|
|||
ty: Ty,
|
||||
krate: Crate,
|
||||
) -> Const {
|
||||
let layout = db.layout_of_ty(ty.clone(), TraitEnvironment::empty(krate));
|
||||
let layout = || db.layout_of_ty(ty.clone(), TraitEnvironment::empty(krate));
|
||||
let bytes = match value {
|
||||
LiteralConstRef::Int(i) => {
|
||||
// FIXME: We should handle failure of layout better.
|
||||
let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16);
|
||||
let size = layout().map(|it| it.size.bytes_usize()).unwrap_or(16);
|
||||
ConstScalar::Bytes(i.to_le_bytes()[0..size].into(), MemoryMap::default())
|
||||
}
|
||||
LiteralConstRef::UInt(i) => {
|
||||
let size = layout.map(|it| it.size.bytes_usize()).unwrap_or(16);
|
||||
let size = layout().map(|it| it.size.bytes_usize()).unwrap_or(16);
|
||||
ConstScalar::Bytes(i.to_le_bytes()[0..size].into(), MemoryMap::default())
|
||||
}
|
||||
LiteralConstRef::Bool(b) => ConstScalar::Bytes(Box::new([*b as u8]), MemoryMap::default()),
|
||||
|
|
@ -268,18 +266,6 @@ pub(crate) fn const_eval_query(
|
|||
let krate = s.module(db.upcast()).krate();
|
||||
db.monomorphized_mir_body(s.into(), subst, TraitEnvironment::empty(krate))?
|
||||
}
|
||||
GeneralConstId::ConstBlockId(c) => {
|
||||
let ConstBlockLoc { parent, root } = db.lookup_intern_anonymous_const(c);
|
||||
let body = db.body(parent);
|
||||
let infer = db.infer(parent);
|
||||
Arc::new(monomorphize_mir_body_bad(
|
||||
db,
|
||||
lower_to_mir(db, parent, &body, &infer, root)?,
|
||||
subst,
|
||||
db.trait_environment_for_body(parent),
|
||||
)?)
|
||||
}
|
||||
GeneralConstId::InTypeConstId(c) => db.mir_body(c.into())?,
|
||||
};
|
||||
let c = interpret_mir(db, body, false, trait_env)?.0?;
|
||||
Ok(c)
|
||||
|
|
@ -318,7 +304,7 @@ pub(crate) fn const_eval_discriminant_variant(
|
|||
return Ok(value);
|
||||
}
|
||||
|
||||
let repr = db.enum_data(loc.parent).repr;
|
||||
let repr = db.enum_signature(loc.parent).repr;
|
||||
let is_signed = repr.and_then(|repr| repr.int).is_none_or(|int| int.is_signed());
|
||||
|
||||
let mir_body = db.monomorphized_mir_body(
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ 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, file_id.edition()).to_string()
|
||||
if db.const_signature(x).name.as_ref()?.display(db, file_id.edition()).to_string()
|
||||
== "GOAL"
|
||||
{
|
||||
Some(x)
|
||||
|
|
@ -2458,6 +2458,8 @@ fn extern_weak_statics() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
// FIXME
|
||||
#[should_panic]
|
||||
fn from_ne_bytes() {
|
||||
check_number(
|
||||
r#"
|
||||
|
|
@ -2534,6 +2536,8 @@ fn const_transfer_memory() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
// FIXME
|
||||
#[should_panic]
|
||||
fn anonymous_const_block() {
|
||||
check_number(
|
||||
r#"
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ use std::fmt;
|
|||
|
||||
use hir_def::{
|
||||
AdtId, ConstId, EnumId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup,
|
||||
ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, data::adt::VariantData,
|
||||
db::DefDatabase, hir::Pat, src::HasSource,
|
||||
ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, db::DefDatabase, hir::Pat,
|
||||
item_tree::FieldsShape, signatures::StaticFlags, src::HasSource,
|
||||
};
|
||||
use hir_expand::{
|
||||
HirFileId, HirFileIdExt,
|
||||
|
|
@ -178,7 +178,7 @@ impl<'a> DeclValidator<'a> {
|
|||
|
||||
fn validate_trait(&mut self, trait_id: TraitId) {
|
||||
// Check the trait name.
|
||||
let data = self.db.trait_data(trait_id);
|
||||
let data = self.db.trait_signature(trait_id);
|
||||
self.create_incorrect_case_diagnostic_for_item_name(
|
||||
trait_id,
|
||||
&data.name,
|
||||
|
|
@ -197,7 +197,7 @@ impl<'a> DeclValidator<'a> {
|
|||
// Check the function name.
|
||||
// Skipped if function is an associated item of a trait implementation.
|
||||
if !self.is_trait_impl_container(container) {
|
||||
let data = self.db.function_data(func);
|
||||
let data = self.db.function_signature(func);
|
||||
|
||||
// Don't run the lint on extern "[not Rust]" fn items with the
|
||||
// #[no_mangle] attribute.
|
||||
|
|
@ -293,7 +293,7 @@ impl<'a> DeclValidator<'a> {
|
|||
|
||||
fn validate_struct(&mut self, struct_id: StructId) {
|
||||
// Check the structure name.
|
||||
let data = self.db.struct_data(struct_id);
|
||||
let data = self.db.struct_signature(struct_id);
|
||||
self.create_incorrect_case_diagnostic_for_item_name(
|
||||
struct_id,
|
||||
&data.name,
|
||||
|
|
@ -307,12 +307,13 @@ impl<'a> DeclValidator<'a> {
|
|||
|
||||
/// Check incorrect names for struct fields.
|
||||
fn validate_struct_fields(&mut self, struct_id: StructId) {
|
||||
let data = self.db.variant_data(struct_id.into());
|
||||
let VariantData::Record { fields, .. } = data.as_ref() else {
|
||||
let data = self.db.variant_fields(struct_id.into());
|
||||
if data.shape != FieldsShape::Record {
|
||||
return;
|
||||
};
|
||||
let edition = self.edition(struct_id);
|
||||
let mut struct_fields_replacements = fields
|
||||
let mut struct_fields_replacements = data
|
||||
.fields()
|
||||
.iter()
|
||||
.filter_map(|(_, field)| {
|
||||
to_lower_snake_case(&field.name.display_no_db(edition).to_smolstr()).map(
|
||||
|
|
@ -378,7 +379,7 @@ impl<'a> DeclValidator<'a> {
|
|||
}
|
||||
|
||||
fn validate_enum(&mut self, enum_id: EnumId) {
|
||||
let data = self.db.enum_data(enum_id);
|
||||
let data = self.db.enum_signature(enum_id);
|
||||
|
||||
// Check the enum name.
|
||||
self.create_incorrect_case_diagnostic_for_item_name(
|
||||
|
|
@ -467,12 +468,13 @@ impl<'a> DeclValidator<'a> {
|
|||
|
||||
/// Check incorrect names for fields of enum variant.
|
||||
fn validate_enum_variant_fields(&mut self, variant_id: EnumVariantId) {
|
||||
let variant_data = self.db.variant_data(variant_id.into());
|
||||
let VariantData::Record { fields, .. } = variant_data.as_ref() else {
|
||||
let variant_data = self.db.variant_fields(variant_id.into());
|
||||
if variant_data.shape != FieldsShape::Record {
|
||||
return;
|
||||
};
|
||||
let edition = self.edition(variant_id);
|
||||
let mut variant_field_replacements = fields
|
||||
let mut variant_field_replacements = variant_data
|
||||
.fields()
|
||||
.iter()
|
||||
.filter_map(|(_, field)| {
|
||||
to_lower_snake_case(&field.name.display_no_db(edition).to_smolstr()).map(
|
||||
|
|
@ -544,7 +546,7 @@ impl<'a> DeclValidator<'a> {
|
|||
return;
|
||||
}
|
||||
|
||||
let data = self.db.const_data(const_id);
|
||||
let data = self.db.const_signature(const_id);
|
||||
let Some(name) = &data.name else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -557,8 +559,8 @@ impl<'a> DeclValidator<'a> {
|
|||
}
|
||||
|
||||
fn validate_static(&mut self, static_id: StaticId) {
|
||||
let data = self.db.static_data(static_id);
|
||||
if data.is_extern() {
|
||||
let data = self.db.static_signature(static_id);
|
||||
if data.flags.contains(StaticFlags::IS_EXTERN) {
|
||||
cov_mark::hit!(extern_static_incorrect_case_ignored);
|
||||
return;
|
||||
}
|
||||
|
|
@ -579,7 +581,7 @@ impl<'a> DeclValidator<'a> {
|
|||
}
|
||||
|
||||
// Check the type alias name.
|
||||
let data = self.db.type_alias_data(type_alias_id);
|
||||
let data = self.db.type_alias_signature(type_alias_id);
|
||||
self.create_incorrect_case_diagnostic_for_item_name(
|
||||
type_alias_id,
|
||||
&data.name,
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ pub(crate) mod pat_analysis;
|
|||
|
||||
use chalk_ir::Mutability;
|
||||
use hir_def::{
|
||||
AdtId, EnumVariantId, LocalFieldId, VariantId, data::adt::VariantData, expr_store::Body,
|
||||
AdtId, EnumVariantId, LocalFieldId, Lookup, VariantId,
|
||||
expr_store::{Body, path::Path},
|
||||
hir::PatId,
|
||||
item_tree::FieldsShape,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use span::Edition;
|
||||
|
|
@ -269,7 +271,7 @@ impl<'a> PatCtxt<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_path(&mut self, pat: PatId, _path: &hir_def::path::Path) -> Pat {
|
||||
fn lower_path(&mut self, pat: PatId, _path: &Path) -> Pat {
|
||||
let ty = &self.infer[pat];
|
||||
|
||||
let pat_from_kind = |kind| Pat { ty: ty.clone(), kind: Box::new(kind) };
|
||||
|
|
@ -322,26 +324,29 @@ impl HirDisplay for Pat {
|
|||
if let Some(variant) = variant {
|
||||
match variant {
|
||||
VariantId::EnumVariantId(v) => {
|
||||
let loc = v.lookup(f.db.upcast());
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.enum_variant_data(v).name.display(f.db.upcast(), f.edition())
|
||||
f.db.enum_variants(loc.parent).variants[loc.index as usize]
|
||||
.1
|
||||
.display(f.db.upcast(), f.edition())
|
||||
)?;
|
||||
}
|
||||
VariantId::StructId(s) => write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.struct_data(s).name.display(f.db.upcast(), f.edition())
|
||||
f.db.struct_signature(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())
|
||||
f.db.union_signature(u).name.display(f.db.upcast(), f.edition())
|
||||
)?,
|
||||
};
|
||||
|
||||
let variant_data = variant.variant_data(f.db.upcast());
|
||||
if let VariantData::Record { fields: rec_fields, .. } = &*variant_data {
|
||||
if variant_data.shape == FieldsShape::Record {
|
||||
write!(f, " {{ ")?;
|
||||
|
||||
let mut printed = 0;
|
||||
|
|
@ -350,11 +355,11 @@ impl HirDisplay for Pat {
|
|||
.filter(|p| !matches!(*p.pattern.kind, PatKind::Wild))
|
||||
.map(|p| {
|
||||
printed += 1;
|
||||
WriteWith(move |f| {
|
||||
WriteWith(|f| {
|
||||
write!(
|
||||
f,
|
||||
"{}: ",
|
||||
rec_fields[p.field]
|
||||
variant_data.fields()[p.field]
|
||||
.name
|
||||
.display(f.db.upcast(), f.edition())
|
||||
)?;
|
||||
|
|
@ -363,7 +368,7 @@ impl HirDisplay for Pat {
|
|||
});
|
||||
f.write_joined(subpats, ", ")?;
|
||||
|
||||
if printed < rec_fields.len() {
|
||||
if printed < variant_data.fields().len() {
|
||||
write!(f, "{}..", if printed > 0 { ", " } else { "" })?;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ use std::mem;
|
|||
use either::Either;
|
||||
use hir_def::{
|
||||
AdtId, DefWithBodyId, FieldId, FunctionId, VariantId,
|
||||
expr_store::Body,
|
||||
expr_store::{Body, path::Path},
|
||||
hir::{Expr, ExprId, ExprOrPatId, Pat, PatId, Statement, UnaryOp},
|
||||
path::Path,
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
||||
signatures::StaticFlags,
|
||||
type_ref::Rawness,
|
||||
};
|
||||
use span::Edition;
|
||||
|
|
@ -31,11 +31,10 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe
|
|||
let _p = tracing::info_span!("missing_unsafe").entered();
|
||||
|
||||
let is_unsafe = match def {
|
||||
DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe(),
|
||||
DefWithBodyId::StaticId(_)
|
||||
| DefWithBodyId::ConstId(_)
|
||||
| DefWithBodyId::VariantId(_)
|
||||
| DefWithBodyId::InTypeConstId(_) => false,
|
||||
DefWithBodyId::FunctionId(it) => db.function_signature(it).is_unsafe(),
|
||||
DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) | DefWithBodyId::VariantId(_) => {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
let mut res = MissingUnsafeResult { fn_is_unsafe: is_unsafe, ..MissingUnsafeResult::default() };
|
||||
|
|
@ -361,10 +360,12 @@ impl<'a> UnsafeVisitor<'a> {
|
|||
let value_or_partial =
|
||||
self.resolver.resolve_path_in_value_ns(self.db.upcast(), path, hygiene);
|
||||
if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
|
||||
let static_data = self.db.static_data(id);
|
||||
if static_data.mutable() {
|
||||
let static_data = self.db.static_signature(id);
|
||||
if static_data.flags.contains(StaticFlags::MUTABLE) {
|
||||
self.on_unsafe_op(node, UnsafetyReason::MutableStatic);
|
||||
} else if static_data.is_extern() && !static_data.has_safe_kw() {
|
||||
} else if static_data.flags.contains(StaticFlags::IS_EXTERN)
|
||||
&& !static_data.flags.contains(StaticFlags::HAS_SAFE)
|
||||
{
|
||||
self.on_unsafe_op(node, UnsafetyReason::ExternStatic);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,20 +13,21 @@ use either::Either;
|
|||
use hir_def::{
|
||||
GenericDefId, HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId,
|
||||
ModuleId, TraitId,
|
||||
data::adt::VariantData,
|
||||
db::DefDatabase,
|
||||
expr_store::{ExpressionStore, path::Path},
|
||||
find_path::{self, PrefixKind},
|
||||
generics::{TypeOrConstParamData, TypeParamProvenance},
|
||||
hir::generics::{
|
||||
TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
|
||||
},
|
||||
item_scope::ItemInNs,
|
||||
item_tree::FieldsShape,
|
||||
lang_item::{LangItem, LangItemTarget},
|
||||
nameres::DefMap,
|
||||
path::{Path, PathKind},
|
||||
type_ref::{
|
||||
TraitBoundModifier, TypeBound, TypeRef, TypeRefId, TypesMap, TypesSourceMap, UseArgRef,
|
||||
},
|
||||
signatures::VariantFields,
|
||||
type_ref::{ConstRef, TraitBoundModifier, TypeBound, TypeRef, TypeRefId, UseArgRef},
|
||||
visibility::Visibility,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use hir_expand::{mod_path::PathKind, name::Name};
|
||||
use intern::{Internable, Interned, sym};
|
||||
use itertools::Itertools;
|
||||
use la_arena::ArenaMap;
|
||||
|
|
@ -614,7 +615,7 @@ impl HirDisplay for ProjectionTy {
|
|||
write!(
|
||||
f,
|
||||
">::{}",
|
||||
f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id))
|
||||
f.db.type_alias_signature(from_assoc_type_id(self.associated_ty_id))
|
||||
.name
|
||||
.display(f.db.upcast(), f.edition())
|
||||
)?;
|
||||
|
|
@ -786,7 +787,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);
|
||||
let data = f.db.struct_signature(s);
|
||||
write!(f, "&{}", data.name.display(f.db.upcast(), f.edition()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -844,11 +845,11 @@ fn render_const_scalar(
|
|||
};
|
||||
match adt.0 {
|
||||
hir_def::AdtId::StructId(s) => {
|
||||
let data = f.db.struct_data(s);
|
||||
let data = f.db.struct_signature(s);
|
||||
write!(f, "{}", data.name.display(f.db.upcast(), f.edition()))?;
|
||||
let field_types = f.db.field_types(s.into());
|
||||
render_variant_after_name(
|
||||
&f.db.variant_data(s.into()),
|
||||
&f.db.variant_fields(s.into()),
|
||||
f,
|
||||
&field_types,
|
||||
f.db.trait_environment(adt.0.into()),
|
||||
|
|
@ -859,7 +860,11 @@ fn render_const_scalar(
|
|||
)
|
||||
}
|
||||
hir_def::AdtId::UnionId(u) => {
|
||||
write!(f, "{}", f.db.union_data(u).name.display(f.db.upcast(), f.edition()))
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.union_signature(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 {
|
||||
|
|
@ -870,11 +875,17 @@ fn render_const_scalar(
|
|||
else {
|
||||
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(), f.edition()))?;
|
||||
let loc = var_id.lookup(f.db.upcast());
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.enum_variants(loc.parent).variants[loc.index as usize]
|
||||
.1
|
||||
.display(f.db.upcast(), f.edition())
|
||||
)?;
|
||||
let field_types = f.db.field_types(var_id.into());
|
||||
render_variant_after_name(
|
||||
&f.db.variant_data(var_id.into()),
|
||||
&f.db.variant_fields(var_id.into()),
|
||||
f,
|
||||
&field_types,
|
||||
f.db.trait_environment(adt.0.into()),
|
||||
|
|
@ -932,7 +943,7 @@ fn render_const_scalar(
|
|||
}
|
||||
|
||||
fn render_variant_after_name(
|
||||
data: &VariantData,
|
||||
data: &VariantFields,
|
||||
f: &mut HirFormatter<'_>,
|
||||
field_types: &ArenaMap<LocalFieldId, Binders<Ty>>,
|
||||
trait_env: Arc<TraitEnvironment>,
|
||||
|
|
@ -941,8 +952,8 @@ fn render_variant_after_name(
|
|||
b: &[u8],
|
||||
memory_map: &MemoryMap,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match data {
|
||||
VariantData::Record { fields, .. } | VariantData::Tuple { fields, .. } => {
|
||||
match data.shape {
|
||||
FieldsShape::Record | FieldsShape::Tuple => {
|
||||
let render_field = |f: &mut HirFormatter<'_>, id: LocalFieldId| {
|
||||
let offset = layout.fields.offset(u32::from(id.into_raw()) as usize).bytes_usize();
|
||||
let ty = field_types[id].clone().substitute(Interner, subst);
|
||||
|
|
@ -952,8 +963,8 @@ fn render_variant_after_name(
|
|||
let size = layout.size.bytes_usize();
|
||||
render_const_scalar(f, &b[offset..offset + size], memory_map, &ty)
|
||||
};
|
||||
let mut it = fields.iter();
|
||||
if matches!(data, VariantData::Record { .. }) {
|
||||
let mut it = data.fields().iter();
|
||||
if matches!(data.shape, FieldsShape::Record) {
|
||||
write!(f, " {{")?;
|
||||
if let Some((id, data)) = it.next() {
|
||||
write!(f, " {}: ", data.name.display(f.db.upcast(), f.edition()))?;
|
||||
|
|
@ -978,7 +989,7 @@ fn render_variant_after_name(
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
VariantData::Unit => Ok(()),
|
||||
FieldsShape::Unit => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1156,16 +1167,23 @@ impl HirDisplay for Ty {
|
|||
CallableDefId::FunctionId(ff) => write!(
|
||||
f,
|
||||
"{}",
|
||||
db.function_data(ff).name.display(f.db.upcast(), f.edition())
|
||||
db.function_signature(ff).name.display(f.db.upcast(), f.edition())
|
||||
)?,
|
||||
CallableDefId::StructId(s) => {
|
||||
write!(f, "{}", db.struct_data(s).name.display(f.db.upcast(), f.edition()))?
|
||||
}
|
||||
CallableDefId::EnumVariantId(e) => write!(
|
||||
CallableDefId::StructId(s) => write!(
|
||||
f,
|
||||
"{}",
|
||||
db.enum_variant_data(e).name.display(f.db.upcast(), f.edition())
|
||||
db.struct_signature(s).name.display(f.db.upcast(), f.edition())
|
||||
)?,
|
||||
CallableDefId::EnumVariantId(e) => {
|
||||
let loc = e.lookup(db.upcast());
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
db.enum_variants(loc.parent).variants[loc.index as usize]
|
||||
.1
|
||||
.display(db.upcast(), f.edition())
|
||||
)?
|
||||
}
|
||||
};
|
||||
f.end_location_link();
|
||||
|
||||
|
|
@ -1228,9 +1246,9 @@ impl HirDisplay for Ty {
|
|||
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(),
|
||||
hir_def::AdtId::EnumId(it) => db.enum_data(it).name.clone(),
|
||||
hir_def::AdtId::StructId(it) => db.struct_signature(it).name.clone(),
|
||||
hir_def::AdtId::UnionId(it) => db.union_signature(it).name.clone(),
|
||||
hir_def::AdtId::EnumId(it) => db.enum_signature(it).name.clone(),
|
||||
};
|
||||
write!(f, "{}", name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
|
|
@ -1269,8 +1287,8 @@ impl HirDisplay for Ty {
|
|||
ItemContainerId::TraitId(it) => it,
|
||||
_ => panic!("not an associated type"),
|
||||
};
|
||||
let trait_data = db.trait_data(trait_);
|
||||
let type_alias_data = db.type_alias_data(type_alias);
|
||||
let trait_data = db.trait_signature(trait_);
|
||||
let type_alias_data = db.type_alias_signature(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_kind.is_test() {
|
||||
|
|
@ -1296,7 +1314,7 @@ impl HirDisplay for Ty {
|
|||
}
|
||||
TyKind::Foreign(type_alias) => {
|
||||
let alias = from_foreign_def_id(*type_alias);
|
||||
let type_alias = db.type_alias_data(alias);
|
||||
let type_alias = db.type_alias_signature(alias);
|
||||
f.start_location_link(alias.into());
|
||||
write!(f, "{}", type_alias.name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
|
|
@ -1789,7 +1807,11 @@ 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(), f.edition()))?;
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.trait_signature(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) {
|
||||
|
|
@ -1861,7 +1883,7 @@ fn write_bounds_like_dyn_trait(
|
|||
}
|
||||
if let AliasTy::Projection(proj) = alias {
|
||||
let assoc_ty_id = from_assoc_type_id(proj.associated_ty_id);
|
||||
let type_alias = f.db.type_alias_data(assoc_ty_id);
|
||||
let type_alias = f.db.type_alias_signature(assoc_ty_id);
|
||||
f.start_location_link(assoc_ty_id.into());
|
||||
write!(f, "{}", type_alias.name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
|
|
@ -1914,7 +1936,7 @@ impl HirDisplay for TraitRef {
|
|||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||
let trait_ = self.hir_trait_id();
|
||||
f.start_location_link(trait_.into());
|
||||
write!(f, "{}", f.db.trait_data(trait_).name.display(f.db.upcast(), f.edition()))?;
|
||||
write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db.upcast(), f.edition()))?;
|
||||
f.end_location_link();
|
||||
let substs = self.substitution.as_slice(Interner);
|
||||
hir_fmt_generics(f, &substs[1..], None, substs[0].ty(Interner))
|
||||
|
|
@ -1945,7 +1967,7 @@ impl HirDisplay for WhereClause {
|
|||
write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.type_alias_data(type_alias).name.display(f.db.upcast(), f.edition()),
|
||||
f.db.type_alias_signature(type_alias).name.display(f.db.upcast(), f.edition()),
|
||||
)?;
|
||||
f.end_location_link();
|
||||
write!(f, " = ")?;
|
||||
|
|
@ -2040,70 +2062,97 @@ pub fn write_visibility(
|
|||
}
|
||||
}
|
||||
|
||||
pub trait HirDisplayWithTypesMap {
|
||||
pub trait HirDisplayWithExpressionStore {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
store: &ExpressionStore,
|
||||
) -> Result<(), HirDisplayError>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + HirDisplayWithTypesMap> HirDisplayWithTypesMap for &'_ T {
|
||||
impl<T: ?Sized + HirDisplayWithExpressionStore> HirDisplayWithExpressionStore for &'_ T {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
store: &ExpressionStore,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
T::hir_fmt(&**self, f, types_map)
|
||||
T::hir_fmt(&**self, f, store)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hir_display_with_types_map<'a, T: HirDisplayWithTypesMap + 'a>(
|
||||
pub fn hir_display_with_store<'a, T: HirDisplayWithExpressionStore + 'a>(
|
||||
value: T,
|
||||
types_map: &'a TypesMap,
|
||||
store: &'a ExpressionStore,
|
||||
) -> impl HirDisplay + 'a {
|
||||
TypesMapAdapter(value, types_map)
|
||||
ExpressionStoreAdapter(value, store)
|
||||
}
|
||||
|
||||
struct TypesMapAdapter<'a, T>(T, &'a TypesMap);
|
||||
struct ExpressionStoreAdapter<'a, T>(T, &'a ExpressionStore);
|
||||
|
||||
impl<'a, T> TypesMapAdapter<'a, T> {
|
||||
fn wrap(types_map: &'a TypesMap) -> impl Fn(T) -> TypesMapAdapter<'a, T> {
|
||||
move |value| TypesMapAdapter(value, types_map)
|
||||
impl<'a, T> ExpressionStoreAdapter<'a, T> {
|
||||
fn wrap(store: &'a ExpressionStore) -> impl Fn(T) -> ExpressionStoreAdapter<'a, T> {
|
||||
move |value| ExpressionStoreAdapter(value, store)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: HirDisplayWithTypesMap> HirDisplay for TypesMapAdapter<'_, T> {
|
||||
impl<T: HirDisplayWithExpressionStore> HirDisplay for ExpressionStoreAdapter<'_, T> {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||
T::hir_fmt(&self.0, f, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl HirDisplayWithTypesMap for TypeRefId {
|
||||
impl HirDisplayWithExpressionStore for TypeRefId {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
store: &ExpressionStore,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match &types_map[*self] {
|
||||
match &store[*self] {
|
||||
TypeRef::Never => write!(f, "!")?,
|
||||
TypeRef::TypeParam(param) => {
|
||||
let generic_params = f.db.generic_params(param.parent());
|
||||
match generic_params[param.local_id()].name() {
|
||||
Some(name) => write!(f, "{}", name.display(f.db.upcast(), f.edition()))?,
|
||||
None => {
|
||||
write!(f, "impl ")?;
|
||||
f.write_joined(
|
||||
generic_params
|
||||
.where_predicates()
|
||||
.filter_map(|it| match it {
|
||||
WherePredicate::TypeBound {
|
||||
target: WherePredicateTypeTarget::TypeOrConstParam(p),
|
||||
bound,
|
||||
}
|
||||
| WherePredicate::ForLifetime {
|
||||
lifetimes: _,
|
||||
target: WherePredicateTypeTarget::TypeOrConstParam(p),
|
||||
bound,
|
||||
} if *p == param.local_id() => Some(bound),
|
||||
_ => None,
|
||||
})
|
||||
.map(ExpressionStoreAdapter::wrap(store)),
|
||||
" + ",
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
TypeRef::Placeholder => write!(f, "_")?,
|
||||
TypeRef::Tuple(elems) => {
|
||||
write!(f, "(")?;
|
||||
f.write_joined(elems.iter().map(TypesMapAdapter::wrap(types_map)), ", ")?;
|
||||
f.write_joined(elems.iter().map(ExpressionStoreAdapter::wrap(store)), ", ")?;
|
||||
if elems.len() == 1 {
|
||||
write!(f, ",")?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
}
|
||||
TypeRef::Path(path) => path.hir_fmt(f, types_map)?,
|
||||
TypeRef::Path(path) => path.hir_fmt(f, store)?,
|
||||
TypeRef::RawPtr(inner, mutability) => {
|
||||
let mutability = match mutability {
|
||||
hir_def::type_ref::Mutability::Shared => "*const ",
|
||||
hir_def::type_ref::Mutability::Mut => "*mut ",
|
||||
};
|
||||
write!(f, "{mutability}")?;
|
||||
inner.hir_fmt(f, types_map)?;
|
||||
inner.hir_fmt(f, store)?;
|
||||
}
|
||||
TypeRef::Reference(ref_) => {
|
||||
let mutability = match ref_.mutability {
|
||||
|
|
@ -2115,16 +2164,18 @@ impl HirDisplayWithTypesMap for TypeRefId {
|
|||
write!(f, "{} ", lifetime.name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
write!(f, "{mutability}")?;
|
||||
ref_.ty.hir_fmt(f, types_map)?;
|
||||
ref_.ty.hir_fmt(f, store)?;
|
||||
}
|
||||
TypeRef::Array(array) => {
|
||||
write!(f, "[")?;
|
||||
array.ty.hir_fmt(f, types_map)?;
|
||||
write!(f, "; {}]", array.len.display(f.db.upcast(), f.edition()))?;
|
||||
array.ty.hir_fmt(f, store)?;
|
||||
write!(f, "; ")?;
|
||||
array.len.hir_fmt(f, store)?;
|
||||
write!(f, "]")?;
|
||||
}
|
||||
TypeRef::Slice(inner) => {
|
||||
write!(f, "[")?;
|
||||
inner.hir_fmt(f, types_map)?;
|
||||
inner.hir_fmt(f, store)?;
|
||||
write!(f, "]")?;
|
||||
}
|
||||
TypeRef::Fn(fn_) => {
|
||||
|
|
@ -2144,7 +2195,7 @@ impl HirDisplayWithTypesMap for TypeRefId {
|
|||
write!(f, "{}: ", name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
|
||||
param_type.hir_fmt(f, types_map)?;
|
||||
param_type.hir_fmt(f, store)?;
|
||||
|
||||
if index != function_parameters.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
|
|
@ -2154,41 +2205,22 @@ impl HirDisplayWithTypesMap for TypeRefId {
|
|||
write!(f, "{}...", if fn_.params.len() == 1 { "" } else { ", " })?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
match &types_map[*return_type] {
|
||||
match &store[*return_type] {
|
||||
TypeRef::Tuple(tup) if tup.is_empty() => {}
|
||||
_ => {
|
||||
write!(f, " -> ")?;
|
||||
return_type.hir_fmt(f, types_map)?;
|
||||
return_type.hir_fmt(f, store)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TypeRef::ImplTrait(bounds) => {
|
||||
write!(f, "impl ")?;
|
||||
f.write_joined(bounds.iter().map(TypesMapAdapter::wrap(types_map)), " + ")?;
|
||||
f.write_joined(bounds.iter().map(ExpressionStoreAdapter::wrap(store)), " + ")?;
|
||||
}
|
||||
TypeRef::DynTrait(bounds) => {
|
||||
write!(f, "dyn ")?;
|
||||
f.write_joined(bounds.iter().map(TypesMapAdapter::wrap(types_map)), " + ")?;
|
||||
}
|
||||
TypeRef::Macro(macro_call) => {
|
||||
let (mut types_map, mut types_source_map) =
|
||||
(TypesMap::default(), TypesSourceMap::default());
|
||||
let mut ctx = hir_def::lower::LowerCtx::new(
|
||||
f.db.upcast(),
|
||||
macro_call.file_id,
|
||||
&mut types_map,
|
||||
&mut types_source_map,
|
||||
);
|
||||
let macro_call = macro_call.to_node(f.db.upcast());
|
||||
match macro_call.path() {
|
||||
Some(path) => match Path::from_src(&mut ctx, path) {
|
||||
Some(path) => path.hir_fmt(f, &types_map)?,
|
||||
None => write!(f, "{{macro}}")?,
|
||||
},
|
||||
None => write!(f, "{{macro}}")?,
|
||||
}
|
||||
write!(f, "!(..)")?;
|
||||
f.write_joined(bounds.iter().map(ExpressionStoreAdapter::wrap(store)), " + ")?;
|
||||
}
|
||||
TypeRef::Error => write!(f, "{{error}}")?,
|
||||
}
|
||||
|
|
@ -2196,11 +2228,24 @@ impl HirDisplayWithTypesMap for TypeRefId {
|
|||
}
|
||||
}
|
||||
|
||||
impl HirDisplayWithTypesMap for TypeBound {
|
||||
impl HirDisplayWithExpressionStore for ConstRef {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
_store: &ExpressionStore,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
// FIXME
|
||||
write!(f, "{{const}}")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl HirDisplayWithExpressionStore for TypeBound {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
store: &ExpressionStore,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match self {
|
||||
&TypeBound::Path(path, modifier) => {
|
||||
|
|
@ -2208,7 +2253,7 @@ impl HirDisplayWithTypesMap for TypeBound {
|
|||
TraitBoundModifier::None => (),
|
||||
TraitBoundModifier::Maybe => write!(f, "?")?,
|
||||
}
|
||||
types_map[path].hir_fmt(f, types_map)
|
||||
store[path].hir_fmt(f, store)
|
||||
}
|
||||
TypeBound::Lifetime(lifetime) => {
|
||||
write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
|
||||
|
|
@ -2220,7 +2265,7 @@ impl HirDisplayWithTypesMap for TypeBound {
|
|||
"for<{}> ",
|
||||
lifetimes.iter().map(|it| it.display(f.db.upcast(), edition)).format(", ")
|
||||
)?;
|
||||
types_map[*path].hir_fmt(f, types_map)
|
||||
store[*path].hir_fmt(f, store)
|
||||
}
|
||||
TypeBound::Use(args) => {
|
||||
let edition = f.edition();
|
||||
|
|
@ -2240,16 +2285,16 @@ impl HirDisplayWithTypesMap for TypeBound {
|
|||
}
|
||||
}
|
||||
|
||||
impl HirDisplayWithTypesMap for Path {
|
||||
impl HirDisplayWithExpressionStore for Path {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
store: &ExpressionStore,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match (self.type_anchor(), self.kind()) {
|
||||
(Some(anchor), _) => {
|
||||
write!(f, "<")?;
|
||||
anchor.hir_fmt(f, types_map)?;
|
||||
anchor.hir_fmt(f, store)?;
|
||||
write!(f, ">")?;
|
||||
}
|
||||
(_, PathKind::Plain) => {}
|
||||
|
|
@ -2292,7 +2337,7 @@ impl HirDisplayWithTypesMap for Path {
|
|||
});
|
||||
if let Some(ty) = trait_self_ty {
|
||||
write!(f, "<")?;
|
||||
ty.hir_fmt(f, types_map)?;
|
||||
ty.hir_fmt(f, store)?;
|
||||
write!(f, " as ")?;
|
||||
// Now format the path of the trait...
|
||||
}
|
||||
|
|
@ -2306,14 +2351,14 @@ impl HirDisplayWithTypesMap for Path {
|
|||
// We should be in type context, so format as `Foo<Bar>` instead of `Foo::<Bar>`.
|
||||
// Do we actually format expressions?
|
||||
match generic_args.parenthesized {
|
||||
hir_def::path::GenericArgsParentheses::ReturnTypeNotation => {
|
||||
hir_def::expr_store::path::GenericArgsParentheses::ReturnTypeNotation => {
|
||||
write!(f, "(..)")?;
|
||||
}
|
||||
hir_def::path::GenericArgsParentheses::ParenSugar => {
|
||||
hir_def::expr_store::path::GenericArgsParentheses::ParenSugar => {
|
||||
// First argument will be a tuple, which already includes the parentheses.
|
||||
// If the tuple only contains 1 item, write it manually to avoid the trailing `,`.
|
||||
let tuple = match generic_args.args[0] {
|
||||
hir_def::path::GenericArg::Type(ty) => match &types_map[ty] {
|
||||
hir_def::expr_store::path::GenericArg::Type(ty) => match &store[ty] {
|
||||
TypeRef::Tuple(it) => Some(it),
|
||||
_ => None,
|
||||
},
|
||||
|
|
@ -2322,20 +2367,20 @@ impl HirDisplayWithTypesMap for Path {
|
|||
if let Some(v) = tuple {
|
||||
if v.len() == 1 {
|
||||
write!(f, "(")?;
|
||||
v[0].hir_fmt(f, types_map)?;
|
||||
v[0].hir_fmt(f, store)?;
|
||||
write!(f, ")")?;
|
||||
} else {
|
||||
generic_args.args[0].hir_fmt(f, types_map)?;
|
||||
generic_args.args[0].hir_fmt(f, store)?;
|
||||
}
|
||||
}
|
||||
if let Some(ret) = generic_args.bindings[0].type_ref {
|
||||
if !matches!(&types_map[ret], TypeRef::Tuple(v) if v.is_empty()) {
|
||||
if !matches!(&store[ret], TypeRef::Tuple(v) if v.is_empty()) {
|
||||
write!(f, " -> ")?;
|
||||
ret.hir_fmt(f, types_map)?;
|
||||
ret.hir_fmt(f, store)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
hir_def::path::GenericArgsParentheses::No => {
|
||||
hir_def::expr_store::path::GenericArgsParentheses::No => {
|
||||
let mut first = true;
|
||||
// Skip the `Self` bound if exists. It's handled outside the loop.
|
||||
for arg in &generic_args.args[generic_args.has_self_type as usize..] {
|
||||
|
|
@ -2345,7 +2390,7 @@ impl HirDisplayWithTypesMap for Path {
|
|||
} else {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
arg.hir_fmt(f, types_map)?;
|
||||
arg.hir_fmt(f, store)?;
|
||||
}
|
||||
for binding in generic_args.bindings.iter() {
|
||||
if first {
|
||||
|
|
@ -2358,12 +2403,15 @@ impl HirDisplayWithTypesMap for Path {
|
|||
match &binding.type_ref {
|
||||
Some(ty) => {
|
||||
write!(f, " = ")?;
|
||||
ty.hir_fmt(f, types_map)?
|
||||
ty.hir_fmt(f, store)?
|
||||
}
|
||||
None => {
|
||||
write!(f, ": ")?;
|
||||
f.write_joined(
|
||||
binding.bounds.iter().map(TypesMapAdapter::wrap(types_map)),
|
||||
binding
|
||||
.bounds
|
||||
.iter()
|
||||
.map(ExpressionStoreAdapter::wrap(store)),
|
||||
" + ",
|
||||
)?;
|
||||
}
|
||||
|
|
@ -2389,18 +2437,19 @@ impl HirDisplayWithTypesMap for Path {
|
|||
}
|
||||
}
|
||||
|
||||
impl HirDisplayWithTypesMap for hir_def::path::GenericArg {
|
||||
impl HirDisplayWithExpressionStore for hir_def::expr_store::path::GenericArg {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
store: &ExpressionStore,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match self {
|
||||
hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f, types_map),
|
||||
hir_def::path::GenericArg::Const(c) => {
|
||||
write!(f, "{}", c.display(f.db.upcast(), f.edition()))
|
||||
hir_def::expr_store::path::GenericArg::Type(ty) => ty.hir_fmt(f, store),
|
||||
hir_def::expr_store::path::GenericArg::Const(_c) => {
|
||||
// write!(f, "{}", c.display(f.db.upcast(), f.edition()))
|
||||
write!(f, "<expr>")
|
||||
}
|
||||
hir_def::path::GenericArg::Lifetime(lifetime) => {
|
||||
hir_def::expr_store::path::GenericArg::Lifetime(lifetime) => {
|
||||
write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
use chalk_ir::cast::Cast;
|
||||
use hir_def::AdtId;
|
||||
use hir_def::data::adt::StructFlags;
|
||||
use hir_def::lang_item::LangItem;
|
||||
use hir_def::signatures::StructFlags;
|
||||
use stdx::never;
|
||||
use triomphe::Arc;
|
||||
|
||||
|
|
@ -32,7 +32,6 @@ fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
|
|||
},
|
||||
None => db.trait_impls_in_crate(module.krate()),
|
||||
};
|
||||
|
||||
impls.for_trait_and_self_ty(drop_trait, TyFingerprint::Adt(adt)).next().is_some()
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +54,7 @@ pub(crate) fn has_drop_glue(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironm
|
|||
}
|
||||
match adt.0 {
|
||||
AdtId::StructId(id) => {
|
||||
if db.struct_data(id).flags.contains(StructFlags::IS_MANUALLY_DROP) {
|
||||
if db.struct_signature(id).flags.contains(StructFlags::IS_MANUALLY_DROP) {
|
||||
return DropGlue::None;
|
||||
}
|
||||
db.field_types(id.into())
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use chalk_ir::{
|
|||
use chalk_solve::rust_ir::InlineBound;
|
||||
use hir_def::{
|
||||
AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId, TypeAliasId,
|
||||
data::TraitFlags, lang_item::LangItem,
|
||||
lang_item::LangItem, signatures::TraitFlags,
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
use smallvec::SmallVec;
|
||||
|
|
@ -369,7 +369,7 @@ fn virtual_call_violations_for_method<F>(
|
|||
where
|
||||
F: FnMut(MethodViolationCode) -> ControlFlow<()>,
|
||||
{
|
||||
let func_data = db.function_data(func);
|
||||
let func_data = db.function_signature(func);
|
||||
if !func_data.has_self_param() {
|
||||
cb(MethodViolationCode::StaticMethod)?;
|
||||
}
|
||||
|
|
@ -429,7 +429,7 @@ where
|
|||
|
||||
// Allow `impl AutoTrait` predicates
|
||||
if let WhereClause::Implemented(TraitRef { trait_id, substitution }) = pred {
|
||||
let trait_data = db.trait_data(from_chalk_trait_id(*trait_id));
|
||||
let trait_data = db.trait_signature(from_chalk_trait_id(*trait_id));
|
||||
if trait_data.flags.contains(TraitFlags::IS_AUTO)
|
||||
&& substitution
|
||||
.as_slice(Interner)
|
||||
|
|
|
|||
|
|
@ -40,8 +40,11 @@ fn check_dyn_compatibility<'a>(
|
|||
.declarations()
|
||||
.filter_map(|def| {
|
||||
if let hir_def::ModuleDefId::TraitId(trait_id) = def {
|
||||
let name =
|
||||
db.trait_data(trait_id).name.display_no_db(file_id.edition()).to_smolstr();
|
||||
let name = db
|
||||
.trait_signature(trait_id)
|
||||
.name
|
||||
.display_no_db(file_id.edition())
|
||||
.to_smolstr();
|
||||
Some((trait_id, name))
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -11,14 +11,14 @@ use std::ops;
|
|||
|
||||
use chalk_ir::{BoundVar, DebruijnIndex, cast::Cast as _};
|
||||
use hir_def::{
|
||||
ConstParamId, GenericDefId, GenericParamId, ItemContainerId, LifetimeParamId,
|
||||
LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
|
||||
ConstParamId, GenericDefId, GenericParamId, ItemContainerId, LifetimeParamId, Lookup,
|
||||
TypeOrConstParamId, TypeParamId,
|
||||
db::DefDatabase,
|
||||
generics::{
|
||||
GenericParamDataRef, GenericParams, LifetimeParamData, TypeOrConstParamData,
|
||||
TypeParamProvenance,
|
||||
expr_store::ExpressionStore,
|
||||
hir::generics::{
|
||||
GenericParamDataRef, GenericParams, LifetimeParamData, LocalLifetimeParamId,
|
||||
LocalTypeOrConstParamId, TypeOrConstParamData, TypeParamProvenance, WherePredicate,
|
||||
},
|
||||
type_ref::TypesMap,
|
||||
};
|
||||
use itertools::chain;
|
||||
use stdx::TupleExt;
|
||||
|
|
@ -28,14 +28,15 @@ use crate::{Interner, Substitution, db::HirDatabase, lt_to_placeholder_idx, to_p
|
|||
|
||||
pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
|
||||
let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
|
||||
let params = db.generic_params(def);
|
||||
let (params, store) = db.generic_params_and_store(def);
|
||||
let has_trait_self_param = params.trait_self_param().is_some();
|
||||
Generics { def, params, parent_generics, has_trait_self_param }
|
||||
Generics { def, params, parent_generics, has_trait_self_param, store }
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Generics {
|
||||
def: GenericDefId,
|
||||
params: Arc<GenericParams>,
|
||||
store: Arc<ExpressionStore>,
|
||||
parent_generics: Option<Box<Generics>>,
|
||||
has_trait_self_param: bool,
|
||||
}
|
||||
|
|
@ -55,8 +56,12 @@ impl Generics {
|
|||
self.def
|
||||
}
|
||||
|
||||
pub(crate) fn self_types_map(&self) -> &TypesMap {
|
||||
&self.params.types_map
|
||||
pub(crate) fn store(&self) -> &ExpressionStore {
|
||||
&self.store
|
||||
}
|
||||
|
||||
pub(crate) fn where_predicates(&self) -> impl Iterator<Item = &WherePredicate> {
|
||||
self.params.where_predicates()
|
||||
}
|
||||
|
||||
pub(crate) fn iter_id(&self) -> impl Iterator<Item = GenericParamId> + '_ {
|
||||
|
|
@ -71,12 +76,6 @@ impl Generics {
|
|||
self.iter_parent().map(|(id, _)| id)
|
||||
}
|
||||
|
||||
pub(crate) fn iter_self_type_or_consts(
|
||||
&self,
|
||||
) -> impl DoubleEndedIterator<Item = (LocalTypeOrConstParamId, &TypeOrConstParamData)> {
|
||||
self.params.iter_type_or_consts()
|
||||
}
|
||||
|
||||
pub(crate) fn iter_self_type_or_consts_id(
|
||||
&self,
|
||||
) -> impl DoubleEndedIterator<Item = GenericParamId> + '_ {
|
||||
|
|
@ -90,14 +89,12 @@ impl Generics {
|
|||
self.iter_self().chain(self.iter_parent())
|
||||
}
|
||||
|
||||
pub(crate) fn iter_parents_with_types_map(
|
||||
pub(crate) fn iter_parents_with_store(
|
||||
&self,
|
||||
) -> impl Iterator<Item = ((GenericParamId, GenericParamDataRef<'_>), &TypesMap)> + '_ {
|
||||
self.iter_parent().zip(
|
||||
self.parent_generics()
|
||||
.into_iter()
|
||||
.flat_map(|it| std::iter::repeat(&it.params.types_map)),
|
||||
)
|
||||
) -> impl Iterator<Item = ((GenericParamId, GenericParamDataRef<'_>), &ExpressionStore)> + '_
|
||||
{
|
||||
self.iter_parent()
|
||||
.zip(self.parent_generics().into_iter().flat_map(|it| std::iter::repeat(&*it.store)))
|
||||
}
|
||||
|
||||
/// Iterate over the params without parent params.
|
||||
|
|
@ -160,7 +157,12 @@ impl Generics {
|
|||
fn find_type_or_const_param(&self, param: TypeOrConstParamId) -> Option<usize> {
|
||||
if param.parent == self.def {
|
||||
let idx = param.local_id.into_raw().into_u32() as usize;
|
||||
debug_assert!(idx <= self.params.len_type_or_consts());
|
||||
debug_assert!(
|
||||
idx <= self.params.len_type_or_consts(),
|
||||
"idx: {} len: {}",
|
||||
idx,
|
||||
self.params.len_type_or_consts()
|
||||
);
|
||||
if self.params.trait_self_param() == Some(param.local_id) {
|
||||
return Some(idx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,19 +34,18 @@ use chalk_ir::{
|
|||
};
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ImplId, ItemContainerId, Lookup,
|
||||
TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId,
|
||||
AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, GenericDefId, ImplId, ItemContainerId,
|
||||
Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId,
|
||||
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
|
||||
data::{ConstData, StaticData},
|
||||
expr_store::{Body, HygieneId},
|
||||
expr_store::{Body, ExpressionStore, HygieneId, path::Path},
|
||||
hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
|
||||
lang_item::{LangItem, LangItemTarget},
|
||||
layout::Integer,
|
||||
path::{ModPath, Path},
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
|
||||
type_ref::{LifetimeRef, TypeRefId, TypesMap},
|
||||
signatures::{ConstSignature, StaticSignature},
|
||||
type_ref::{ConstRef, LifetimeRef, TypeRefId},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use hir_expand::{mod_path::ModPath, name::Name};
|
||||
use indexmap::IndexSet;
|
||||
use intern::sym;
|
||||
use la_arena::{ArenaMap, Entry};
|
||||
|
|
@ -71,7 +70,7 @@ use crate::{
|
|||
mir::MirSpan,
|
||||
to_assoc_type_id,
|
||||
traits::FnTrait,
|
||||
utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
|
||||
utils::UnevaluatedConstEvaluatorFolder,
|
||||
};
|
||||
|
||||
// This lint has a false positive here. See the link below for details.
|
||||
|
|
@ -96,11 +95,11 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
|
|||
DefWithBodyId::FunctionId(f) => {
|
||||
ctx.collect_fn(f);
|
||||
}
|
||||
DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
|
||||
DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)),
|
||||
DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_signature(c)),
|
||||
DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)),
|
||||
DefWithBodyId::VariantId(v) => {
|
||||
ctx.return_ty = TyBuilder::builtin(
|
||||
match db.enum_data(v.lookup(db.upcast()).parent).variant_body_type() {
|
||||
match db.enum_signature(v.lookup(db.upcast()).parent).variant_body_type() {
|
||||
hir_def::layout::IntegerType::Pointer(signed) => match signed {
|
||||
true => BuiltinType::Int(BuiltinInt::Isize),
|
||||
false => BuiltinType::Uint(BuiltinUint::Usize),
|
||||
|
|
@ -124,16 +123,6 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
|
|||
},
|
||||
);
|
||||
}
|
||||
DefWithBodyId::InTypeConstId(c) => {
|
||||
// FIXME(const-generic-body): We should not get the return type in this way.
|
||||
ctx.return_ty = c
|
||||
.lookup(db.upcast())
|
||||
.expected_ty
|
||||
.box_any()
|
||||
.downcast::<InTypeConstIdMetadata>()
|
||||
.unwrap()
|
||||
.0;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.infer_body();
|
||||
|
|
@ -597,7 +586,8 @@ pub(crate) struct InferenceContext<'a> {
|
|||
/// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext
|
||||
/// and resolve the path via its methods. This will ensure proper error reporting.
|
||||
pub(crate) resolver: Resolver,
|
||||
generics: OnceCell<Option<Generics>>,
|
||||
generic_def: GenericDefId,
|
||||
generics: OnceCell<Generics>,
|
||||
table: unify::InferenceTable<'a>,
|
||||
/// The traits in scope, disregarding block modules. This is used for caching purposes.
|
||||
traits_in_scope: FxHashSet<TraitId>,
|
||||
|
|
@ -708,6 +698,12 @@ impl<'a> InferenceContext<'a> {
|
|||
return_coercion: None,
|
||||
db,
|
||||
owner,
|
||||
generic_def: match owner {
|
||||
DefWithBodyId::FunctionId(it) => it.into(),
|
||||
DefWithBodyId::StaticId(it) => it.into(),
|
||||
DefWithBodyId::ConstId(it) => it.into(),
|
||||
DefWithBodyId::VariantId(it) => it.lookup(db.upcast()).parent.into(),
|
||||
},
|
||||
body,
|
||||
traits_in_scope: resolver.traits_in_scope(db.upcast()),
|
||||
resolver,
|
||||
|
|
@ -724,14 +720,8 @@ impl<'a> InferenceContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn generics(&self) -> Option<&Generics> {
|
||||
self.generics
|
||||
.get_or_init(|| {
|
||||
self.resolver
|
||||
.generic_def()
|
||||
.map(|def| crate::generics::generics(self.db.upcast(), def))
|
||||
})
|
||||
.as_ref()
|
||||
pub(crate) fn generics(&self) -> &Generics {
|
||||
self.generics.get_or_init(|| crate::generics::generics(self.db.upcast(), self.generic_def))
|
||||
}
|
||||
|
||||
// FIXME: This function should be private in module. It is currently only used in the consteval, since we need
|
||||
|
|
@ -894,9 +884,9 @@ impl<'a> InferenceContext<'a> {
|
|||
result
|
||||
}
|
||||
|
||||
fn collect_const(&mut self, data: &ConstData) {
|
||||
fn collect_const(&mut self, data: &ConstSignature) {
|
||||
let return_ty =
|
||||
self.make_ty(data.type_ref, &data.types_map, InferenceTyDiagnosticSource::Signature);
|
||||
self.make_ty(data.type_ref, &data.store, InferenceTyDiagnosticSource::Signature);
|
||||
|
||||
// Constants might be defining usage sites of TAITs.
|
||||
self.make_tait_coercion_table(iter::once(&return_ty));
|
||||
|
|
@ -904,9 +894,9 @@ impl<'a> InferenceContext<'a> {
|
|||
self.return_ty = return_ty;
|
||||
}
|
||||
|
||||
fn collect_static(&mut self, data: &StaticData) {
|
||||
fn collect_static(&mut self, data: &StaticSignature) {
|
||||
let return_ty =
|
||||
self.make_ty(data.type_ref, &data.types_map, InferenceTyDiagnosticSource::Signature);
|
||||
self.make_ty(data.type_ref, &data.store, InferenceTyDiagnosticSource::Signature);
|
||||
|
||||
// Statics might be defining usage sites of TAITs.
|
||||
self.make_tait_coercion_table(iter::once(&return_ty));
|
||||
|
|
@ -915,13 +905,13 @@ impl<'a> InferenceContext<'a> {
|
|||
}
|
||||
|
||||
fn collect_fn(&mut self, func: FunctionId) {
|
||||
let data = self.db.function_data(func);
|
||||
let data = self.db.function_signature(func);
|
||||
let mut param_tys =
|
||||
self.with_ty_lowering(&data.types_map, InferenceTyDiagnosticSource::Signature, |ctx| {
|
||||
ctx.type_param_mode(ParamLoweringMode::Placeholder)
|
||||
.impl_trait_mode(ImplTraitLoweringMode::Param);
|
||||
self.with_ty_lowering(&data.store, InferenceTyDiagnosticSource::Signature, |ctx| {
|
||||
ctx.type_param_mode(ParamLoweringMode::Placeholder);
|
||||
data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>()
|
||||
});
|
||||
|
||||
// Check if function contains a va_list, if it does then we append it to the parameter types
|
||||
// that are collected from the function data
|
||||
if data.is_varargs() {
|
||||
|
|
@ -956,35 +946,43 @@ impl<'a> InferenceContext<'a> {
|
|||
tait_candidates.insert(ty);
|
||||
}
|
||||
}
|
||||
let return_ty = data.ret_type;
|
||||
|
||||
let return_ty =
|
||||
self.with_ty_lowering(&data.types_map, InferenceTyDiagnosticSource::Signature, |ctx| {
|
||||
ctx.type_param_mode(ParamLoweringMode::Placeholder)
|
||||
.impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
||||
.lower_ty(return_ty)
|
||||
});
|
||||
let return_ty = self.insert_type_vars(return_ty);
|
||||
|
||||
let return_ty = if let Some(rpits) = self.db.return_type_impl_traits(func) {
|
||||
// RPIT opaque types use substitution of their parent function.
|
||||
let fn_placeholders = TyBuilder::placeholder_subst(self.db, func);
|
||||
let mut mode = ImplTraitReplacingMode::ReturnPosition(FxHashSet::default());
|
||||
let result =
|
||||
self.insert_inference_vars_for_impl_trait(return_ty, fn_placeholders, &mut mode);
|
||||
if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
|
||||
tait_candidates.extend(taits);
|
||||
}
|
||||
let rpits = rpits.skip_binders();
|
||||
for (id, _) in rpits.impl_traits.iter() {
|
||||
if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) {
|
||||
never!("Missed RPIT in `insert_inference_vars_for_rpit`");
|
||||
e.insert(TyKind::Error.intern(Interner));
|
||||
let return_ty = match data.ret_type {
|
||||
Some(return_ty) => {
|
||||
let return_ty = self.with_ty_lowering(
|
||||
&data.store,
|
||||
InferenceTyDiagnosticSource::Signature,
|
||||
|ctx| {
|
||||
ctx.type_param_mode(ParamLoweringMode::Placeholder)
|
||||
.impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
||||
.lower_ty(return_ty)
|
||||
},
|
||||
);
|
||||
let return_ty = self.insert_type_vars(return_ty);
|
||||
if let Some(rpits) = self.db.return_type_impl_traits(func) {
|
||||
// RPIT opaque types use substitution of their parent function.
|
||||
let fn_placeholders = TyBuilder::placeholder_subst(self.db, func);
|
||||
let mut mode = ImplTraitReplacingMode::ReturnPosition(FxHashSet::default());
|
||||
let result = self.insert_inference_vars_for_impl_trait(
|
||||
return_ty,
|
||||
fn_placeholders,
|
||||
&mut mode,
|
||||
);
|
||||
if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
|
||||
tait_candidates.extend(taits);
|
||||
}
|
||||
let rpits = rpits.skip_binders();
|
||||
for (id, _) in rpits.impl_traits.iter() {
|
||||
if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) {
|
||||
never!("Missed RPIT in `insert_inference_vars_for_rpit`");
|
||||
e.insert(TyKind::Error.intern(Interner));
|
||||
}
|
||||
}
|
||||
result
|
||||
} else {
|
||||
return_ty
|
||||
}
|
||||
}
|
||||
result
|
||||
} else {
|
||||
return_ty
|
||||
None => self.result.standard_types.unit.clone(),
|
||||
};
|
||||
|
||||
self.return_ty = self.normalize_associated_types_in(return_ty);
|
||||
|
|
@ -1287,38 +1285,54 @@ impl<'a> InferenceContext<'a> {
|
|||
|
||||
fn with_ty_lowering<R>(
|
||||
&mut self,
|
||||
types_map: &TypesMap,
|
||||
store: &ExpressionStore,
|
||||
types_source: InferenceTyDiagnosticSource,
|
||||
f: impl FnOnce(&mut TyLoweringContext<'_>) -> R,
|
||||
) -> R {
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
types_map,
|
||||
self.owner.into(),
|
||||
store,
|
||||
&self.diagnostics,
|
||||
types_source,
|
||||
self.generic_def,
|
||||
);
|
||||
f(&mut ctx)
|
||||
}
|
||||
|
||||
fn with_body_ty_lowering<R>(&mut self, f: impl FnOnce(&mut TyLoweringContext<'_>) -> R) -> R {
|
||||
self.with_ty_lowering(&self.body.types, InferenceTyDiagnosticSource::Body, f)
|
||||
self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, f)
|
||||
}
|
||||
|
||||
fn make_ty(
|
||||
&mut self,
|
||||
type_ref: TypeRefId,
|
||||
types_map: &TypesMap,
|
||||
store: &ExpressionStore,
|
||||
type_source: InferenceTyDiagnosticSource,
|
||||
) -> Ty {
|
||||
let ty = self.with_ty_lowering(types_map, type_source, |ctx| ctx.lower_ty(type_ref));
|
||||
let ty = self.with_ty_lowering(store, type_source, |ctx| ctx.lower_ty(type_ref));
|
||||
let ty = self.insert_type_vars(ty);
|
||||
self.normalize_associated_types_in(ty)
|
||||
}
|
||||
|
||||
fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty {
|
||||
self.make_ty(type_ref, &self.body.types, InferenceTyDiagnosticSource::Body)
|
||||
self.make_ty(type_ref, self.body, InferenceTyDiagnosticSource::Body)
|
||||
}
|
||||
|
||||
fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty) -> Const {
|
||||
let const_ = self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, |ctx| {
|
||||
ctx.type_param_mode = ParamLoweringMode::Placeholder;
|
||||
ctx.lower_const(&const_ref, ty)
|
||||
});
|
||||
self.insert_type_vars(const_)
|
||||
}
|
||||
|
||||
fn make_path_as_body_const(&mut self, path: &Path, ty: Ty) -> Const {
|
||||
let const_ = self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, |ctx| {
|
||||
ctx.type_param_mode = ParamLoweringMode::Placeholder;
|
||||
ctx.lower_path_as_const(path, ty)
|
||||
});
|
||||
self.insert_type_vars(const_)
|
||||
}
|
||||
|
||||
fn err_ty(&self) -> Ty {
|
||||
|
|
@ -1326,7 +1340,7 @@ impl<'a> InferenceContext<'a> {
|
|||
}
|
||||
|
||||
fn make_body_lifetime(&mut self, lifetime_ref: &LifetimeRef) -> Lifetime {
|
||||
let lt = self.with_ty_lowering(TypesMap::EMPTY, InferenceTyDiagnosticSource::Body, |ctx| {
|
||||
let lt = self.with_ty_lowering(self.body, InferenceTyDiagnosticSource::Body, |ctx| {
|
||||
ctx.lower_lifetime(lifetime_ref)
|
||||
});
|
||||
self.insert_type_vars(lt)
|
||||
|
|
@ -1494,10 +1508,10 @@ impl<'a> InferenceContext<'a> {
|
|||
let mut ctx = TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
&self.body.types,
|
||||
self.owner.into(),
|
||||
&self.body.store,
|
||||
&self.diagnostics,
|
||||
InferenceTyDiagnosticSource::Body,
|
||||
self.generic_def,
|
||||
);
|
||||
let mut path_ctx = ctx.at_path(path, node);
|
||||
let (resolution, unresolved) = if value_ns {
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ fn pointer_kind(ty: &Ty, table: &mut InferenceTable<'_>) -> Result<Option<Pointe
|
|||
return Err(());
|
||||
};
|
||||
|
||||
let struct_data = table.db.variant_data(id.into());
|
||||
let struct_data = table.db.variant_fields(id.into());
|
||||
if let Some((last_field, _)) = struct_data.fields().iter().last() {
|
||||
let last_field_ty =
|
||||
table.db.field_types(id.into())[last_field].clone().substitute(Interner, subst);
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ use chalk_ir::{
|
|||
use either::Either;
|
||||
use hir_def::{
|
||||
DefWithBodyId, FieldId, HasModule, TupleFieldId, TupleId, VariantId,
|
||||
data::adt::VariantData,
|
||||
expr_store::path::Path,
|
||||
hir::{
|
||||
Array, AsmOperand, BinaryOp, BindingId, CaptureBy, ClosureKind, Expr, ExprId, ExprOrPatId,
|
||||
Pat, PatId, Statement, UnaryOp,
|
||||
},
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItem,
|
||||
path::Path,
|
||||
resolver::ValueNs,
|
||||
};
|
||||
use hir_def::{Lookup, type_ref::TypeRefId};
|
||||
|
|
@ -641,18 +641,20 @@ impl CapturedItem {
|
|||
match proj {
|
||||
ProjectionElem::Deref => {}
|
||||
ProjectionElem::Field(Either::Left(f)) => {
|
||||
match &*f.parent.variant_data(db.upcast()) {
|
||||
VariantData::Record { fields, .. } => {
|
||||
let variant_data = f.parent.variant_data(db.upcast());
|
||||
match variant_data.shape {
|
||||
FieldsShape::Record => {
|
||||
result.push('_');
|
||||
result.push_str(fields[f.local_id].name.as_str())
|
||||
result.push_str(variant_data.fields()[f.local_id].name.as_str())
|
||||
}
|
||||
VariantData::Tuple { fields, .. } => {
|
||||
let index = fields.iter().position(|it| it.0 == f.local_id);
|
||||
FieldsShape::Tuple => {
|
||||
let index =
|
||||
variant_data.fields().iter().position(|it| it.0 == f.local_id);
|
||||
if let Some(index) = index {
|
||||
format_to!(result, "_{index}");
|
||||
}
|
||||
}
|
||||
VariantData::Unit => {}
|
||||
FieldsShape::Unit => {}
|
||||
}
|
||||
}
|
||||
ProjectionElem::Field(Either::Right(f)) => format_to!(result, "_{}", f.index),
|
||||
|
|
@ -683,18 +685,22 @@ impl CapturedItem {
|
|||
ProjectionElem::Deref => {}
|
||||
ProjectionElem::Field(Either::Left(f)) => {
|
||||
let variant_data = f.parent.variant_data(db.upcast());
|
||||
match &*variant_data {
|
||||
VariantData::Record { fields, .. } => format_to!(
|
||||
match variant_data.shape {
|
||||
FieldsShape::Record => format_to!(
|
||||
result,
|
||||
".{}",
|
||||
fields[f.local_id].name.display(db.upcast(), edition)
|
||||
variant_data.fields()[f.local_id].name.display(db.upcast(), edition)
|
||||
),
|
||||
VariantData::Tuple { fields, .. } => format_to!(
|
||||
FieldsShape::Tuple => format_to!(
|
||||
result,
|
||||
".{}",
|
||||
fields.iter().position(|it| it.0 == f.local_id).unwrap_or_default()
|
||||
variant_data
|
||||
.fields()
|
||||
.iter()
|
||||
.position(|it| it.0 == f.local_id)
|
||||
.unwrap_or_default()
|
||||
),
|
||||
VariantData::Unit => {}
|
||||
FieldsShape::Unit => {}
|
||||
}
|
||||
}
|
||||
ProjectionElem::Field(Either::Right(f)) => {
|
||||
|
|
@ -741,16 +747,17 @@ impl CapturedItem {
|
|||
result = format!("({result})");
|
||||
}
|
||||
let variant_data = f.parent.variant_data(db.upcast());
|
||||
let field = match &*variant_data {
|
||||
VariantData::Record { fields, .. } => {
|
||||
fields[f.local_id].name.as_str().to_owned()
|
||||
let field = match variant_data.shape {
|
||||
FieldsShape::Record => {
|
||||
variant_data.fields()[f.local_id].name.as_str().to_owned()
|
||||
}
|
||||
VariantData::Tuple { fields, .. } => fields
|
||||
FieldsShape::Tuple => variant_data
|
||||
.fields()
|
||||
.iter()
|
||||
.position(|it| it.0 == f.local_id)
|
||||
.unwrap_or_default()
|
||||
.to_string(),
|
||||
VariantData::Unit => "[missing field]".to_owned(),
|
||||
FieldsShape::Unit => "[missing field]".to_owned(),
|
||||
};
|
||||
result = format!("{result}.{field}");
|
||||
field_need_paren = false;
|
||||
|
|
@ -852,10 +859,7 @@ impl CapturedItemWithoutTy {
|
|||
Ok(BoundVar::new(outer_binder, idx).to_ty(Interner))
|
||||
}
|
||||
}
|
||||
let Some(generics) = ctx.generics() else {
|
||||
return Binders::empty(Interner, ty);
|
||||
};
|
||||
let filler = &mut Filler { db: ctx.db, generics };
|
||||
let filler = &mut Filler { db: ctx.db, generics: ctx.generics() };
|
||||
let result = ty.clone().try_fold_with(filler, DebruijnIndex::INNERMOST).unwrap_or(ty);
|
||||
make_binders(ctx.db, filler.generics, result)
|
||||
}
|
||||
|
|
@ -876,7 +880,6 @@ impl InferenceContext<'_> {
|
|||
return None;
|
||||
}
|
||||
let hygiene = self.body.expr_or_pat_path_hygiene(id);
|
||||
|
||||
self.resolver.resolve_path_in_value_ns_fully(self.db.upcast(), path, hygiene).and_then(
|
||||
|result| match result {
|
||||
ValueNs::LocalBinding(binding) => {
|
||||
|
|
@ -1517,7 +1520,7 @@ impl InferenceContext<'_> {
|
|||
self.consume_place(place)
|
||||
}
|
||||
VariantId::StructId(s) => {
|
||||
let vd = &*self.db.variant_data(s.into());
|
||||
let vd = &*self.db.variant_fields(s.into());
|
||||
for field_pat in args.iter() {
|
||||
let arg = field_pat.pat;
|
||||
let Some(local_id) = vd.field(&field_pat.name) else {
|
||||
|
|
@ -1569,7 +1572,7 @@ impl InferenceContext<'_> {
|
|||
self.consume_place(place)
|
||||
}
|
||||
VariantId::StructId(s) => {
|
||||
let vd = &*self.db.variant_data(s.into());
|
||||
let vd = &*self.db.variant_fields(s.into());
|
||||
let (al, ar) =
|
||||
args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
|
||||
let fields = vd.fields().iter();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,10 @@ use std::cell::RefCell;
|
|||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use either::Either;
|
||||
use hir_def::{TypeOwnerId, hir::ExprOrPatId, path::Path, resolver::Resolver, type_ref::TypesMap};
|
||||
use hir_def::GenericDefId;
|
||||
use hir_def::expr_store::ExpressionStore;
|
||||
use hir_def::expr_store::path::Path;
|
||||
use hir_def::{hir::ExprOrPatId, resolver::Resolver};
|
||||
use la_arena::{Idx, RawIdx};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -58,12 +61,12 @@ impl<'a> InferenceTyLoweringContext<'a> {
|
|||
pub(super) fn new(
|
||||
db: &'a dyn HirDatabase,
|
||||
resolver: &'a Resolver,
|
||||
types_map: &'a TypesMap,
|
||||
owner: TypeOwnerId,
|
||||
store: &'a ExpressionStore,
|
||||
diagnostics: &'a Diagnostics,
|
||||
source: InferenceTyDiagnosticSource,
|
||||
generic_def: GenericDefId,
|
||||
) -> Self {
|
||||
Self { ctx: TyLoweringContext::new(db, resolver, types_map, owner), diagnostics, source }
|
||||
Self { ctx: TyLoweringContext::new(db, resolver, store, generic_def), diagnostics, source }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -9,12 +9,12 @@ use chalk_ir::{DebruijnIndex, Mutability, TyVariableKind, cast::Cast};
|
|||
use either::Either;
|
||||
use hir_def::{
|
||||
BlockId, FieldId, GenericDefId, GenericParamId, ItemContainerId, Lookup, TupleFieldId, TupleId,
|
||||
expr_store::path::{GenericArg, GenericArgs, Path},
|
||||
hir::{
|
||||
ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, Expr, ExprId, ExprOrPatId, LabelId,
|
||||
Literal, Pat, PatId, Statement, UnaryOp,
|
||||
},
|
||||
lang_item::{LangItem, LangItemTarget},
|
||||
path::{GenericArg, GenericArgs, Path},
|
||||
resolver::ValueNs,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
|
|
@ -36,9 +36,7 @@ use crate::{
|
|||
pat::contains_explicit_ref_binding,
|
||||
},
|
||||
lang_items::lang_items_for_bin_op,
|
||||
lower::{
|
||||
ParamLoweringMode, const_or_path_to_chalk, generic_arg_to_chalk, lower_to_chalk_mutability,
|
||||
},
|
||||
lower::{ParamLoweringMode, generic_arg_to_chalk, lower_to_chalk_mutability},
|
||||
mapping::{ToChalk, from_chalk},
|
||||
method_resolution::{self, VisibleFromModule},
|
||||
primitive::{self, UintTy},
|
||||
|
|
@ -347,8 +345,7 @@ impl InferenceContext<'_> {
|
|||
}
|
||||
Expr::Const(id) => {
|
||||
self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
|
||||
let loc = this.db.lookup_intern_anonymous_const(*id);
|
||||
this.infer_expr(loc.root, expected, ExprIsRead::Yes)
|
||||
this.infer_expr(*id, expected, ExprIsRead::Yes)
|
||||
})
|
||||
.1
|
||||
}
|
||||
|
|
@ -810,6 +807,7 @@ impl InferenceContext<'_> {
|
|||
.map_or((self.err_ty(), Vec::new()), |adj| {
|
||||
adj.apply(&mut self.table, base_ty)
|
||||
});
|
||||
|
||||
// mutability will be fixed up in `InferenceContext::infer_mut`;
|
||||
adj.push(Adjustment::borrow(
|
||||
Mutability::Not,
|
||||
|
|
@ -1566,12 +1564,12 @@ impl InferenceContext<'_> {
|
|||
});
|
||||
}
|
||||
&TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref parameters) => {
|
||||
let local_id = self.db.variant_data(s.into()).field(name)?;
|
||||
let local_id = self.db.variant_fields(s.into()).field(name)?;
|
||||
let field = FieldId { parent: s.into(), local_id };
|
||||
(field, parameters.clone())
|
||||
}
|
||||
&TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), ref parameters) => {
|
||||
let local_id = self.db.variant_data(u.into()).field(name)?;
|
||||
let local_id = self.db.variant_fields(u.into()).field(name)?;
|
||||
let field = FieldId { parent: u.into(), local_id };
|
||||
(field, parameters.clone())
|
||||
}
|
||||
|
|
@ -2102,20 +2100,10 @@ impl InferenceContext<'_> {
|
|||
kind_id,
|
||||
args.next().unwrap(), // `peek()` is `Some(_)`, so guaranteed no panic
|
||||
self,
|
||||
&self.body.types,
|
||||
&self.body.store,
|
||||
|this, type_ref| this.make_body_ty(type_ref),
|
||||
|this, c, ty| {
|
||||
const_or_path_to_chalk(
|
||||
this.db,
|
||||
&this.resolver,
|
||||
this.owner.into(),
|
||||
ty,
|
||||
c,
|
||||
ParamLoweringMode::Placeholder,
|
||||
|| this.generics(),
|
||||
DebruijnIndex::INNERMOST,
|
||||
)
|
||||
},
|
||||
|this, c, ty| this.make_body_const(*c, ty),
|
||||
|this, path, ty| this.make_path_as_body_const(path, ty),
|
||||
|this, lt_ref| this.make_body_lifetime(lt_ref),
|
||||
),
|
||||
};
|
||||
|
|
@ -2195,7 +2183,7 @@ impl InferenceContext<'_> {
|
|||
_ => return Default::default(),
|
||||
};
|
||||
|
||||
let data = self.db.function_data(func);
|
||||
let data = self.db.function_signature(func);
|
||||
let Some(legacy_const_generics_indices) = &data.legacy_const_generics_indices else {
|
||||
return Default::default();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -69,8 +69,7 @@ impl InferenceContext<'_> {
|
|||
}
|
||||
}
|
||||
Expr::Const(id) => {
|
||||
let loc = self.db.lookup_intern_anonymous_const(*id);
|
||||
self.infer_mut_expr(loc.root, Mutability::Not);
|
||||
self.infer_mut_expr(*id, Mutability::Not);
|
||||
}
|
||||
Expr::Let { pat, expr } => self.infer_mut_expr(*expr, self.pat_bound_mutability(*pat)),
|
||||
Expr::Block { id: _, statements, tail, label: _ }
|
||||
|
|
|
|||
|
|
@ -4,9 +4,8 @@ use std::iter::repeat_with;
|
|||
|
||||
use hir_def::{
|
||||
HasModule,
|
||||
expr_store::Body,
|
||||
expr_store::{Body, path::Path},
|
||||
hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, Literal, Pat, PatId},
|
||||
path::Path,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use stdx::TupleExt;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
use chalk_ir::cast::Cast;
|
||||
use hir_def::{
|
||||
AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup,
|
||||
path::{Path, PathSegment},
|
||||
expr_store::path::{Path, PathSegment},
|
||||
resolver::{ResolveValueResult, TypeNs, ValueNs},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
|
|
@ -159,10 +159,10 @@ impl InferenceContext<'_> {
|
|||
let mut ctx = TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
&self.body.types,
|
||||
self.owner.into(),
|
||||
self.body,
|
||||
&self.diagnostics,
|
||||
InferenceTyDiagnosticSource::Body,
|
||||
self.generic_def,
|
||||
);
|
||||
let mut path_ctx = if no_diagnostics {
|
||||
ctx.at_path_forget_diagnostics(path)
|
||||
|
|
@ -281,7 +281,7 @@ impl InferenceContext<'_> {
|
|||
self.db.trait_items(trait_).items.iter().map(|(_name, id)| *id).find_map(|item| {
|
||||
match item {
|
||||
AssocItemId::FunctionId(func) => {
|
||||
if segment.name == &self.db.function_data(func).name {
|
||||
if segment.name == &self.db.function_signature(func).name {
|
||||
Some(AssocItemId::FunctionId(func))
|
||||
} else {
|
||||
None
|
||||
|
|
@ -289,7 +289,7 @@ impl InferenceContext<'_> {
|
|||
}
|
||||
|
||||
AssocItemId::ConstId(konst) => {
|
||||
if self.db.const_data(konst).name.as_ref() == Some(segment.name) {
|
||||
if self.db.const_signature(konst).name.as_ref() == Some(segment.name) {
|
||||
Some(AssocItemId::ConstId(konst))
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -1001,7 +1001,7 @@ impl<'a> InferenceTable<'a> {
|
|||
// Must use a loop here and not recursion because otherwise users will conduct completely
|
||||
// artificial examples of structs that have themselves as the tail field and complain r-a crashes.
|
||||
while let Some((AdtId::StructId(id), subst)) = ty.as_adt() {
|
||||
let struct_data = self.db.variant_data(id.into());
|
||||
let struct_data = self.db.variant_fields(id.into());
|
||||
if let Some((last_field, _)) = struct_data.fields().iter().next_back() {
|
||||
let last_field_ty = self.db.field_types(id.into())[last_field]
|
||||
.clone()
|
||||
|
|
@ -1094,7 +1094,6 @@ mod resolve {
|
|||
.assert_ty_ref(Interner)
|
||||
.clone();
|
||||
}
|
||||
|
||||
if let Some(known_ty) = self.table.var_unification_table.probe_var(var) {
|
||||
// known_ty may contain other variables that are known by now
|
||||
self.var_stack.push(var);
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ impl UninhabitedFrom<'_> {
|
|||
variant: VariantId,
|
||||
subst: &Substitution,
|
||||
) -> ControlFlow<VisiblyUninhabited> {
|
||||
let variant_data = self.db.variant_data(variant);
|
||||
let variant_data = self.db.variant_fields(variant);
|
||||
let fields = variant_data.fields();
|
||||
if fields.is_empty() {
|
||||
return CONTINUE_OPAQUELY_INHABITED;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Functions to detect special lang items
|
||||
|
||||
use hir_def::{AdtId, data::adt::StructFlags, lang_item::LangItem};
|
||||
use hir_def::{AdtId, lang_item::LangItem, signatures::StructFlags};
|
||||
use hir_expand::name::Name;
|
||||
use intern::sym;
|
||||
|
||||
|
|
@ -8,13 +8,13 @@ use crate::db::HirDatabase;
|
|||
|
||||
pub fn is_box(db: &dyn HirDatabase, adt: AdtId) -> bool {
|
||||
let AdtId::StructId(id) = adt else { return false };
|
||||
db.struct_data(id).flags.contains(StructFlags::IS_BOX)
|
||||
db.struct_signature(id).flags.contains(StructFlags::IS_BOX)
|
||||
}
|
||||
|
||||
pub fn is_unsafe_cell(db: &dyn HirDatabase, adt: AdtId) -> bool {
|
||||
let AdtId::StructId(id) = adt else { return false };
|
||||
|
||||
db.struct_data(id).flags.contains(StructFlags::IS_UNSAFE_CELL)
|
||||
db.struct_signature(id).flags.contains(StructFlags::IS_UNSAFE_CELL)
|
||||
}
|
||||
|
||||
pub fn lang_items_for_bin_op(op: syntax::ast::BinaryOp) -> Option<(Name, LangItem)> {
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ pub fn layout_of_ty_query(
|
|||
let result = match kind {
|
||||
TyKind::Adt(AdtId(def), subst) => {
|
||||
if let hir_def::AdtId::StructId(s) = def {
|
||||
let data = db.struct_data(*s);
|
||||
let data = db.struct_signature(*s);
|
||||
let repr = data.repr.unwrap_or_default();
|
||||
if repr.simd() {
|
||||
return layout_of_simd_ty(db, *s, repr.packed(), subst, trait_env, &target);
|
||||
|
|
@ -378,7 +378,7 @@ pub(crate) fn layout_of_ty_recover(
|
|||
fn struct_tail_erasing_lifetimes(db: &dyn HirDatabase, pointee: Ty) -> Ty {
|
||||
match pointee.kind(Interner) {
|
||||
&TyKind::Adt(AdtId(hir_def::AdtId::StructId(i)), ref subst) => {
|
||||
let data = db.variant_data(i.into());
|
||||
let data = db.variant_fields(i.into());
|
||||
let mut it = data.fields().iter().rev();
|
||||
match it.next() {
|
||||
Some((f, _)) => {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ use std::{cmp, ops::Bound};
|
|||
|
||||
use hir_def::{
|
||||
AdtId, VariantId,
|
||||
data::adt::VariantData,
|
||||
layout::{Integer, ReprOptions, TargetDataLayout},
|
||||
signatures::VariantFields,
|
||||
};
|
||||
use intern::sym;
|
||||
use rustc_index::IndexVec;
|
||||
|
|
@ -34,7 +34,7 @@ pub fn layout_of_adt_query(
|
|||
};
|
||||
let dl = &*target;
|
||||
let cx = LayoutCx::new(dl);
|
||||
let handle_variant = |def: VariantId, var: &VariantData| {
|
||||
let handle_variant = |def: VariantId, var: &VariantFields| {
|
||||
var.fields()
|
||||
.iter()
|
||||
.map(|(fd, _)| db.layout_of_ty(field_ty(db, def, fd, &subst), trait_env.clone()))
|
||||
|
|
@ -42,15 +42,15 @@ pub fn layout_of_adt_query(
|
|||
};
|
||||
let (variants, repr) = match def {
|
||||
AdtId::StructId(s) => {
|
||||
let data = db.struct_data(s);
|
||||
let data = db.struct_signature(s);
|
||||
let mut r = SmallVec::<[_; 1]>::new();
|
||||
r.push(handle_variant(s.into(), &db.variant_data(s.into()))?);
|
||||
r.push(handle_variant(s.into(), &db.variant_fields(s.into()))?);
|
||||
(r, data.repr.unwrap_or_default())
|
||||
}
|
||||
AdtId::UnionId(id) => {
|
||||
let data = db.union_data(id);
|
||||
let data = db.union_signature(id);
|
||||
let mut r = SmallVec::new();
|
||||
r.push(handle_variant(id.into(), &db.variant_data(id.into()))?);
|
||||
r.push(handle_variant(id.into(), &db.variant_fields(id.into()))?);
|
||||
(r, data.repr.unwrap_or_default())
|
||||
}
|
||||
AdtId::EnumId(e) => {
|
||||
|
|
@ -58,9 +58,9 @@ pub fn layout_of_adt_query(
|
|||
let r = variants
|
||||
.variants
|
||||
.iter()
|
||||
.map(|&(v, _)| handle_variant(v.into(), &db.variant_data(v.into())))
|
||||
.map(|&(v, _)| handle_variant(v.into(), &db.variant_fields(v.into())))
|
||||
.collect::<Result<SmallVec<_>, _>>()?;
|
||||
(r, db.enum_data(e).repr.unwrap_or_default())
|
||||
(r, db.enum_signature(e).repr.unwrap_or_default())
|
||||
}
|
||||
};
|
||||
let variants = variants
|
||||
|
|
|
|||
|
|
@ -44,21 +44,26 @@ fn eval_goal(
|
|||
let adt_or_type_alias_id = scope.declarations().find_map(|x| match x {
|
||||
hir_def::ModuleDefId::AdtId(x) => {
|
||||
let name = match x {
|
||||
hir_def::AdtId::StructId(x) => {
|
||||
db.struct_data(x).name.display_no_db(file_id.edition()).to_smolstr()
|
||||
}
|
||||
hir_def::AdtId::StructId(x) => db
|
||||
.struct_signature(x)
|
||||
.name
|
||||
.display_no_db(file_id.edition())
|
||||
.to_smolstr(),
|
||||
hir_def::AdtId::UnionId(x) => {
|
||||
db.union_data(x).name.display_no_db(file_id.edition()).to_smolstr()
|
||||
db.union_signature(x).name.display_no_db(file_id.edition()).to_smolstr()
|
||||
}
|
||||
hir_def::AdtId::EnumId(x) => {
|
||||
db.enum_data(x).name.display_no_db(file_id.edition()).to_smolstr()
|
||||
db.enum_signature(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(file_id.edition()).to_smolstr();
|
||||
let name = db
|
||||
.type_alias_signature(x)
|
||||
.name
|
||||
.display_no_db(file_id.edition())
|
||||
.to_smolstr();
|
||||
(name == "Goal").then_some(Either::Right(x))
|
||||
}
|
||||
_ => None,
|
||||
|
|
@ -101,7 +106,8 @@ fn eval_expr(
|
|||
.declarations()
|
||||
.find_map(|x| match x {
|
||||
hir_def::ModuleDefId::FunctionId(x) => {
|
||||
let name = db.function_data(x).name.display_no_db(file_id.edition()).to_smolstr();
|
||||
let name =
|
||||
db.function_signature(x).name.display_no_db(file_id.edition()).to_smolstr();
|
||||
(name == "main").then_some(x)
|
||||
}
|
||||
_ => None,
|
||||
|
|
@ -512,10 +518,7 @@ fn niche_optimization() {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn const_eval() {
|
||||
size_and_align! {
|
||||
struct Goal([i32; 2 + 2]);
|
||||
}
|
||||
fn const_eval_simple() {
|
||||
size_and_align! {
|
||||
const X: usize = 5;
|
||||
struct Goal([i32; X]);
|
||||
|
|
@ -527,6 +530,15 @@ fn const_eval() {
|
|||
struct Ar<T>([T; foo::BAR]);
|
||||
struct Goal(Ar<Ar<i32>>);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// FIXME
|
||||
#[should_panic]
|
||||
fn const_eval_complex() {
|
||||
size_and_align! {
|
||||
struct Goal([i32; 2 + 2]);
|
||||
}
|
||||
size_and_align! {
|
||||
type Goal = [u8; 2 + 2];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1022,15 +1022,6 @@ pub fn known_const_to_ast(
|
|||
db: &dyn HirDatabase,
|
||||
display_target: DisplayTarget,
|
||||
) -> Option<ConstArg> {
|
||||
if let ConstValue::Concrete(c) = &konst.interned().value {
|
||||
match c.interned {
|
||||
ConstScalar::UnevaluatedConst(GeneralConstId::InTypeConstId(cid), _) => {
|
||||
return Some(cid.source(db.upcast()));
|
||||
}
|
||||
ConstScalar::Unknown => return None,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
Some(make::expr_const_value(konst.display(db, display_target).to_string().as_str()))
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,13 +1,10 @@
|
|||
//! This files contains the declaration of diagnostics kinds for ty and path lowering.
|
||||
|
||||
use either::Either;
|
||||
use hir_def::type_ref::TypeRefId;
|
||||
|
||||
type TypeSource = Either<TypeRefId, hir_def::type_ref::TypeSource>;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct TyLoweringDiagnostic {
|
||||
pub source: TypeSource,
|
||||
pub source: TypeRefId,
|
||||
pub kind: TyLoweringDiagnosticKind,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@ use chalk_ir::{BoundVar, cast::Cast, fold::Shift};
|
|||
use either::Either;
|
||||
use hir_def::{
|
||||
GenericDefId, GenericParamId, ItemContainerId, Lookup, TraitId,
|
||||
data::TraitFlags,
|
||||
expr_store::HygieneId,
|
||||
generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
|
||||
path::{GenericArg, GenericArgs, GenericArgsParentheses, Path, PathSegment, PathSegments},
|
||||
expr_store::{
|
||||
HygieneId,
|
||||
path::{GenericArg, GenericArgs, GenericArgsParentheses, Path, PathSegment, PathSegments},
|
||||
},
|
||||
resolver::{ResolveValueResult, TypeNs, ValueNs},
|
||||
type_ref::{TypeBound, TypeRef, TypesMap},
|
||||
signatures::TraitFlags,
|
||||
type_ref::TypeRef,
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use stdx::never;
|
||||
|
|
@ -23,9 +24,7 @@ use crate::{
|
|||
consteval::unknown_const_as_generic,
|
||||
error_lifetime,
|
||||
generics::generics,
|
||||
lower::{
|
||||
ImplTraitLoweringState, generic_arg_to_chalk, named_associated_type_shorthand_candidates,
|
||||
},
|
||||
lower::{generic_arg_to_chalk, named_associated_type_shorthand_candidates},
|
||||
to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
|
||||
utils::associated_type_by_name_including_super_traits,
|
||||
};
|
||||
|
|
@ -228,12 +227,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
|
|||
TyKind::Placeholder(to_placeholder_idx(self.ctx.db, param_id.into()))
|
||||
}
|
||||
ParamLoweringMode::Variable => {
|
||||
let idx = match self
|
||||
.ctx
|
||||
.generics()
|
||||
.expect("generics in scope")
|
||||
.type_or_const_param_idx(param_id.into())
|
||||
{
|
||||
let idx = match self.ctx.generics().type_or_const_param_idx(param_id.into()) {
|
||||
None => {
|
||||
never!("no matching generics");
|
||||
return (TyKind::Error.intern(Interner), None);
|
||||
|
|
@ -246,7 +240,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
|
|||
}
|
||||
.intern(Interner),
|
||||
TypeNs::SelfType(impl_id) => {
|
||||
let generics = self.ctx.generics().expect("impl should have generic param scope");
|
||||
let generics = self.ctx.generics();
|
||||
|
||||
match self.ctx.type_param_mode {
|
||||
ParamLoweringMode::Placeholder => {
|
||||
|
|
@ -480,21 +474,20 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
|
|||
}
|
||||
|
||||
fn select_associated_type(&mut self, res: Option<TypeNs>) -> Ty {
|
||||
let Some((generics, res)) = self.ctx.generics().zip(res) else {
|
||||
let Some(res) = res else {
|
||||
return TyKind::Error.intern(Interner);
|
||||
};
|
||||
let segment = self.current_or_prev_segment;
|
||||
let ty = named_associated_type_shorthand_candidates(
|
||||
self.ctx.db,
|
||||
generics.def(),
|
||||
self.ctx.def,
|
||||
res,
|
||||
Some(segment.name.clone()),
|
||||
move |name, t, associated_ty| {
|
||||
let generics = self.ctx.generics().unwrap();
|
||||
|
||||
if name != segment.name {
|
||||
return None;
|
||||
}
|
||||
let generics = self.ctx.generics();
|
||||
|
||||
let parent_subst = t.substitution.clone();
|
||||
let parent_subst = match self.ctx.type_param_mode {
|
||||
|
|
@ -612,8 +605,12 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
|
|||
self.current_or_prev_segment.args_and_bindings.is_some_and(|generics| {
|
||||
generics.parenthesized == GenericArgsParentheses::ReturnTypeNotation
|
||||
});
|
||||
let is_fn_trait =
|
||||
!self.ctx.db.trait_data(trait_).flags.contains(TraitFlags::RUSTC_PAREN_SUGAR);
|
||||
let is_fn_trait = !self
|
||||
.ctx
|
||||
.db
|
||||
.trait_signature(trait_)
|
||||
.flags
|
||||
.contains(TraitFlags::RUSTC_PAREN_SUGAR);
|
||||
is_rtn || is_fn_trait
|
||||
}
|
||||
_ => true,
|
||||
|
|
@ -719,9 +716,10 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
|
|||
id,
|
||||
arg,
|
||||
self.ctx,
|
||||
self.ctx.types_map,
|
||||
self.ctx.store,
|
||||
|ctx, type_ref| ctx.lower_ty(type_ref),
|
||||
|ctx, const_ref, ty| ctx.lower_const(const_ref, ty),
|
||||
|ctx, path, ty| ctx.lower_path_as_const(path, ty),
|
||||
|ctx, lifetime_ref| ctx.lower_lifetime(lifetime_ref),
|
||||
);
|
||||
substs.push(arg);
|
||||
|
|
@ -795,7 +793,6 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
|
|||
|
||||
pub(super) fn assoc_type_bindings_from_type_bound<'c>(
|
||||
mut self,
|
||||
bound: &'c TypeBound,
|
||||
trait_ref: TraitRef,
|
||||
) -> Option<impl Iterator<Item = QuantifiedWhereClause> + use<'a, 'b, 'c>> {
|
||||
self.current_or_prev_segment.args_and_bindings.map(|args_and_bindings| {
|
||||
|
|
@ -819,7 +816,8 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
|
|||
false, // this is not relevant
|
||||
Some(super_trait_ref.self_type_parameter(Interner)),
|
||||
);
|
||||
let self_params = generics(self.ctx.db.upcast(), associated_ty.into()).len_self();
|
||||
let generics = generics(self.ctx.db.upcast(), associated_ty.into());
|
||||
let self_params = generics.len_self();
|
||||
let substitution = Substitution::from_iter(
|
||||
Interner,
|
||||
substitution
|
||||
|
|
@ -835,7 +833,7 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
|
|||
binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
|
||||
);
|
||||
if let Some(type_ref) = binding.type_ref {
|
||||
match (&self.ctx.types_map[type_ref], self.ctx.impl_trait_mode.mode) {
|
||||
match (&self.ctx.store[type_ref], self.ctx.impl_trait_mode.mode) {
|
||||
(TypeRef::ImplTrait(_), ImplTraitLoweringMode::Disallowed) => (),
|
||||
(_, ImplTraitLoweringMode::Disallowed | ImplTraitLoweringMode::Opaque) => {
|
||||
let ty = self.ctx.lower_ty(type_ref);
|
||||
|
|
@ -844,72 +842,6 @@ impl<'a, 'b> PathLoweringContext<'a, 'b> {
|
|||
predicates
|
||||
.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
|
||||
}
|
||||
(_, ImplTraitLoweringMode::Param | ImplTraitLoweringMode::Variable) => {
|
||||
// Find the generic index for the target of our `bound`
|
||||
let target_param_idx =
|
||||
self.ctx.resolver.where_predicates_in_scope().find_map(
|
||||
|(p, (_, types_map))| match p {
|
||||
WherePredicate::TypeBound {
|
||||
target: WherePredicateTypeTarget::TypeOrConstParam(idx),
|
||||
bound: b,
|
||||
} if std::ptr::eq::<TypesMap>(
|
||||
self.ctx.types_map,
|
||||
types_map,
|
||||
) && bound == b =>
|
||||
{
|
||||
Some(idx)
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
);
|
||||
let ty = if let Some(target_param_idx) = target_param_idx {
|
||||
let mut counter = 0;
|
||||
let generics = self.ctx.generics().expect("generics in scope");
|
||||
for (idx, data) in generics.iter_self_type_or_consts() {
|
||||
// Count the number of `impl Trait` things that appear before
|
||||
// the target of our `bound`.
|
||||
// Our counter within `impl_trait_mode` should be that number
|
||||
// to properly lower each types within `type_ref`
|
||||
if data.type_param().is_some_and(|p| {
|
||||
p.provenance == TypeParamProvenance::ArgumentImplTrait
|
||||
}) {
|
||||
counter += 1;
|
||||
}
|
||||
if idx == *target_param_idx {
|
||||
break;
|
||||
}
|
||||
}
|
||||
let mut ext = TyLoweringContext::new_maybe_unowned(
|
||||
self.ctx.db,
|
||||
self.ctx.resolver,
|
||||
self.ctx.types_map,
|
||||
self.ctx.types_source_map,
|
||||
self.ctx.owner,
|
||||
)
|
||||
.with_type_param_mode(self.ctx.type_param_mode);
|
||||
match self.ctx.impl_trait_mode.mode {
|
||||
ImplTraitLoweringMode::Param => {
|
||||
ext.impl_trait_mode =
|
||||
ImplTraitLoweringState::param(counter);
|
||||
}
|
||||
ImplTraitLoweringMode::Variable => {
|
||||
ext.impl_trait_mode =
|
||||
ImplTraitLoweringState::variable(counter);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
let ty = ext.lower_ty(type_ref);
|
||||
self.ctx.diagnostics.extend(ext.diagnostics);
|
||||
ty
|
||||
} else {
|
||||
self.ctx.lower_ty(type_ref)
|
||||
};
|
||||
|
||||
let alias_eq =
|
||||
AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
|
||||
predicates
|
||||
.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
|
||||
}
|
||||
}
|
||||
}
|
||||
for bound in binding.bounds.iter() {
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use chalk_ir::{UniverseIndex, WithKind, cast::Cast};
|
|||
use hir_def::{
|
||||
AssocItemId, BlockId, ConstId, FunctionId, HasModule, ImplId, ItemContainerId, Lookup,
|
||||
ModuleId, TraitId,
|
||||
data::{TraitFlags, adt::StructFlags},
|
||||
nameres::{DefMap, assoc::ImplItems},
|
||||
signatures::{ConstFlags, EnumFlags, FnFlags, StructFlags, TraitFlags, TypeAliasFlags},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use intern::sym;
|
||||
|
|
@ -313,7 +313,7 @@ impl InherentImpls {
|
|||
fn collect_def_map(&mut self, db: &dyn HirDatabase, def_map: &DefMap) {
|
||||
for (_module_id, module_data) in def_map.modules() {
|
||||
for impl_id in module_data.scope.impls() {
|
||||
let data = db.impl_data(impl_id);
|
||||
let data = db.impl_signature(impl_id);
|
||||
if data.target_trait.is_some() {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -384,14 +384,17 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<Sma
|
|||
&TyKind::Adt(AdtId(def_id), _) => {
|
||||
let rustc_has_incoherent_inherent_impls = match def_id {
|
||||
hir_def::AdtId::StructId(id) => db
|
||||
.struct_data(id)
|
||||
.struct_signature(id)
|
||||
.flags
|
||||
.contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL),
|
||||
.contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
|
||||
hir_def::AdtId::UnionId(id) => db
|
||||
.union_data(id)
|
||||
.union_signature(id)
|
||||
.flags
|
||||
.contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL),
|
||||
hir_def::AdtId::EnumId(id) => db.enum_data(id).rustc_has_incoherent_inherent_impls,
|
||||
.contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
|
||||
hir_def::AdtId::EnumId(id) => db
|
||||
.enum_signature(id)
|
||||
.flags
|
||||
.contains(EnumFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
|
||||
};
|
||||
Some(if rustc_has_incoherent_inherent_impls {
|
||||
db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::Adt(def_id))
|
||||
|
|
@ -401,17 +404,23 @@ pub fn def_crates(db: &dyn HirDatabase, ty: &Ty, cur_crate: Crate) -> Option<Sma
|
|||
}
|
||||
&TyKind::Foreign(id) => {
|
||||
let alias = from_foreign_def_id(id);
|
||||
Some(if db.type_alias_data(alias).rustc_has_incoherent_inherent_impls() {
|
||||
db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::ForeignType(id))
|
||||
} else {
|
||||
smallvec![alias.module(db.upcast()).krate()]
|
||||
})
|
||||
Some(
|
||||
if db
|
||||
.type_alias_signature(alias)
|
||||
.flags
|
||||
.contains(TypeAliasFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
|
||||
{
|
||||
db.incoherent_inherent_impl_crates(cur_crate, TyFingerprint::ForeignType(id))
|
||||
} else {
|
||||
smallvec![alias.module(db.upcast()).krate()]
|
||||
},
|
||||
)
|
||||
}
|
||||
TyKind::Dyn(_) => {
|
||||
let trait_id = ty.dyn_trait()?;
|
||||
Some(
|
||||
if db
|
||||
.trait_data(trait_id)
|
||||
.trait_signature(trait_id)
|
||||
.flags
|
||||
.contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
|
||||
{
|
||||
|
|
@ -618,8 +627,8 @@ pub fn lookup_impl_const(
|
|||
let substitution = Substitution::from_iter(Interner, subs.iter(Interner));
|
||||
let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution };
|
||||
|
||||
let const_data = db.const_data(const_id);
|
||||
let name = match const_data.name.as_ref() {
|
||||
let const_signature = db.const_signature(const_id);
|
||||
let name = match const_signature.name.as_ref() {
|
||||
Some(name) => name,
|
||||
None => return (const_id, subs),
|
||||
};
|
||||
|
|
@ -691,7 +700,7 @@ pub(crate) fn lookup_impl_method_query(
|
|||
substitution: Substitution::from_iter(Interner, fn_subst.iter(Interner).skip(fn_params)),
|
||||
};
|
||||
|
||||
let name = &db.function_data(func).name;
|
||||
let name = &db.function_signature(func).name;
|
||||
let Some((impl_fn, impl_subst)) =
|
||||
lookup_impl_assoc_item_for_trait_ref(trait_ref, db, env, name).and_then(|assoc| {
|
||||
if let (AssocItemId::FunctionId(id), subst) = assoc { Some((id, subst)) } else { None }
|
||||
|
|
@ -822,17 +831,20 @@ fn is_inherent_impl_coherent(
|
|||
|
||||
&TyKind::Adt(AdtId(adt), _) => match adt {
|
||||
hir_def::AdtId::StructId(id) => db
|
||||
.struct_data(id)
|
||||
.struct_signature(id)
|
||||
.flags
|
||||
.contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL),
|
||||
.contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
|
||||
hir_def::AdtId::UnionId(id) => db
|
||||
.union_data(id)
|
||||
.union_signature(id)
|
||||
.flags
|
||||
.contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL),
|
||||
hir_def::AdtId::EnumId(it) => db.enum_data(it).rustc_has_incoherent_inherent_impls,
|
||||
.contains(StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
|
||||
hir_def::AdtId::EnumId(it) => db
|
||||
.enum_signature(it)
|
||||
.flags
|
||||
.contains(EnumFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
|
||||
},
|
||||
TyKind::Dyn(it) => it.principal_id().is_some_and(|trait_id| {
|
||||
db.trait_data(from_chalk_trait_id(trait_id))
|
||||
db.trait_signature(from_chalk_trait_id(trait_id))
|
||||
.flags
|
||||
.contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
|
||||
}),
|
||||
|
|
@ -843,11 +855,16 @@ fn is_inherent_impl_coherent(
|
|||
rustc_has_incoherent_inherent_impls
|
||||
&& !items.items.is_empty()
|
||||
&& items.items.iter().all(|&(_, assoc)| match assoc {
|
||||
AssocItemId::FunctionId(it) => db.function_data(it).rustc_allow_incoherent_impl(),
|
||||
AssocItemId::ConstId(it) => db.const_data(it).rustc_allow_incoherent_impl(),
|
||||
AssocItemId::TypeAliasId(it) => {
|
||||
db.type_alias_data(it).rustc_allow_incoherent_impl()
|
||||
AssocItemId::FunctionId(it) => {
|
||||
db.function_signature(it).flags.contains(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPLS)
|
||||
}
|
||||
AssocItemId::ConstId(it) => {
|
||||
db.const_signature(it).flags.contains(ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL)
|
||||
}
|
||||
AssocItemId::TypeAliasId(it) => db
|
||||
.type_alias_signature(it)
|
||||
.flags
|
||||
.contains(TypeAliasFlags::RUSTC_ALLOW_INCOHERENT_IMPLS),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -882,8 +899,8 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
|
|||
match ty.kind(Interner) {
|
||||
TyKind::Ref(_, _, referenced) => ty = referenced.clone(),
|
||||
&TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), ref subs) => {
|
||||
let struct_data = db.struct_data(s);
|
||||
if struct_data.flags.contains(StructFlags::IS_FUNDAMENTAL) {
|
||||
let struct_signature = db.struct_signature(s);
|
||||
if struct_signature.flags.contains(StructFlags::IS_FUNDAMENTAL) {
|
||||
let next = subs.type_parameters(Interner).next();
|
||||
match next {
|
||||
Some(it) => ty = it,
|
||||
|
|
@ -901,7 +918,7 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
|
|||
|
||||
// FIXME: param coverage
|
||||
// - No uncovered type parameters `P1..=Pn` may appear in `T0..Ti`` (excluding `Ti`)
|
||||
trait_ref.substitution.type_parameters(Interner).any(|ty| {
|
||||
let is_not_orphan = trait_ref.substitution.type_parameters(Interner).any(|ty| {
|
||||
match unwrap_fundamental(ty).kind(Interner) {
|
||||
&TyKind::Adt(AdtId(id), _) => is_local(id.module(db.upcast()).krate()),
|
||||
TyKind::Error => true,
|
||||
|
|
@ -910,7 +927,9 @@ pub fn check_orphan_rules(db: &dyn HirDatabase, impl_: ImplId) -> bool {
|
|||
}),
|
||||
_ => false,
|
||||
}
|
||||
})
|
||||
});
|
||||
#[allow(clippy::let_and_return)]
|
||||
is_not_orphan
|
||||
}
|
||||
|
||||
pub fn iterate_path_candidates(
|
||||
|
|
@ -1206,7 +1225,7 @@ fn iterate_trait_method_candidates(
|
|||
let TraitEnvironment { krate, block, .. } = *table.trait_env;
|
||||
|
||||
'traits: for &t in traits_in_scope {
|
||||
let data = db.trait_data(t);
|
||||
let data = db.trait_signature(t);
|
||||
|
||||
// Traits annotated with `#[rustc_skip_during_method_dispatch]` are skipped during
|
||||
// method resolution, if the receiver is an array, and we're compiling for editions before
|
||||
|
|
@ -1521,7 +1540,7 @@ fn is_valid_trait_method_candidate(
|
|||
let db = table.db;
|
||||
match item {
|
||||
AssocItemId::FunctionId(fn_id) => {
|
||||
let data = db.function_data(fn_id);
|
||||
let data = db.function_signature(fn_id);
|
||||
|
||||
check_that!(name.is_none_or(|n| n == &data.name));
|
||||
|
||||
|
|
@ -1552,7 +1571,7 @@ fn is_valid_trait_method_candidate(
|
|||
}
|
||||
AssocItemId::ConstId(c) => {
|
||||
check_that!(receiver_ty.is_none());
|
||||
check_that!(name.is_none_or(|n| db.const_data(c).name.as_ref() == Some(n)));
|
||||
check_that!(name.is_none_or(|n| db.const_signature(c).name.as_ref() == Some(n)));
|
||||
|
||||
IsValidCandidate::Yes
|
||||
}
|
||||
|
|
@ -1574,7 +1593,7 @@ fn is_valid_impl_fn_candidate(
|
|||
check_that!(name.is_none_or(|n| n == item_name));
|
||||
|
||||
let db = table.db;
|
||||
let data = db.function_data(fn_id);
|
||||
let data = db.function_signature(fn_id);
|
||||
|
||||
if let Some(from_module) = visible_from_module {
|
||||
if !db.function_visibility(fn_id).is_visible_from(db.upcast(), from_module) {
|
||||
|
|
|
|||
|
|
@ -9,11 +9,12 @@ use hir_def::{
|
|||
AdtId, DefWithBodyId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, StaticId,
|
||||
VariantId,
|
||||
builtin_type::BuiltinType,
|
||||
data::adt::{StructFlags, VariantData},
|
||||
expr_store::HygieneId,
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItem,
|
||||
layout::{TagEncoding, Variants},
|
||||
resolver::{HasResolver, TypeNs, ValueNs},
|
||||
signatures::{StaticFlags, StructFlags},
|
||||
};
|
||||
use hir_expand::{HirFileIdExt, InFile, mod_path::path, name::Name};
|
||||
use intern::sym;
|
||||
|
|
@ -368,7 +369,7 @@ impl MirEvalError {
|
|||
for (func, span, def) in stack.iter().take(30).rev() {
|
||||
match func {
|
||||
Either::Left(func) => {
|
||||
let function_name = db.function_data(*func);
|
||||
let function_name = db.function_signature(*func);
|
||||
writeln!(
|
||||
f,
|
||||
"In function {} ({:?})",
|
||||
|
|
@ -421,7 +422,7 @@ impl MirEvalError {
|
|||
)?;
|
||||
}
|
||||
MirEvalError::MirLowerError(func, err) => {
|
||||
let function_name = db.function_data(*func);
|
||||
let function_name = db.function_signature(*func);
|
||||
let self_ = match func.lookup(db.upcast()).container {
|
||||
ItemContainerId::ImplId(impl_id) => Some({
|
||||
let generics = crate::generics::generics(db.upcast(), impl_id.into());
|
||||
|
|
@ -432,7 +433,7 @@ impl MirEvalError {
|
|||
.to_string()
|
||||
}),
|
||||
ItemContainerId::TraitId(it) => Some(
|
||||
db.trait_data(it)
|
||||
db.trait_signature(it)
|
||||
.name
|
||||
.display(db.upcast(), display_target.edition)
|
||||
.to_string(),
|
||||
|
|
@ -1761,7 +1762,7 @@ impl Evaluator<'_> {
|
|||
AdtId::EnumId(_) => not_supported!("unsizing enums"),
|
||||
};
|
||||
let Some((last_field, _)) =
|
||||
self.db.variant_data(id.into()).fields().iter().next_back()
|
||||
self.db.variant_fields(id.into()).fields().iter().next_back()
|
||||
else {
|
||||
not_supported!("unsizing struct without field");
|
||||
};
|
||||
|
|
@ -2243,7 +2244,7 @@ impl Evaluator<'_> {
|
|||
}
|
||||
chalk_ir::TyKind::Adt(adt, subst) => match adt.0 {
|
||||
AdtId::StructId(s) => {
|
||||
let data = this.db.variant_data(s.into());
|
||||
let data = this.db.variant_fields(s.into());
|
||||
let layout = this.layout(ty)?;
|
||||
let field_types = this.db.field_types(s.into());
|
||||
for (f, _) in data.fields().iter() {
|
||||
|
|
@ -2272,7 +2273,7 @@ impl Evaluator<'_> {
|
|||
bytes,
|
||||
e,
|
||||
) {
|
||||
let data = &this.db.variant_data(v.into());
|
||||
let data = &this.db.variant_fields(v.into());
|
||||
let field_types = this.db.field_types(v.into());
|
||||
for (f, _) in data.fields().iter() {
|
||||
let offset =
|
||||
|
|
@ -2755,8 +2756,8 @@ impl Evaluator<'_> {
|
|||
if let Some(o) = self.static_locations.get(&st) {
|
||||
return Ok(*o);
|
||||
};
|
||||
let static_data = self.db.static_data(st);
|
||||
let result = if !static_data.is_extern() {
|
||||
let static_data = self.db.static_signature(st);
|
||||
let result = if !static_data.flags.contains(StaticFlags::IS_EXTERN) {
|
||||
let konst = self.db.const_eval_static(st).map_err(|e| {
|
||||
MirEvalError::ConstEvalError(static_data.name.as_str().to_owned(), Box::new(e))
|
||||
})?;
|
||||
|
|
@ -2843,16 +2844,16 @@ impl Evaluator<'_> {
|
|||
TyKind::Adt(id, subst) => {
|
||||
match id.0 {
|
||||
AdtId::StructId(s) => {
|
||||
let data = self.db.struct_data(s);
|
||||
let data = self.db.struct_signature(s);
|
||||
if data.flags.contains(StructFlags::IS_MANUALLY_DROP) {
|
||||
return Ok(());
|
||||
}
|
||||
let layout = self.layout_adt(id.0, subst.clone())?;
|
||||
match self.db.variant_data(s.into()).as_ref() {
|
||||
VariantData::Record { fields, .. }
|
||||
| VariantData::Tuple { fields, .. } => {
|
||||
let variant_fields = self.db.variant_fields(s.into());
|
||||
match variant_fields.shape {
|
||||
FieldsShape::Record | FieldsShape::Tuple => {
|
||||
let field_types = self.db.field_types(s.into());
|
||||
for (field, _) in fields.iter() {
|
||||
for (field, _) in variant_fields.fields().iter() {
|
||||
let offset = layout
|
||||
.fields
|
||||
.offset(u32::from(field.into_raw()) as usize)
|
||||
|
|
@ -2862,7 +2863,7 @@ impl Evaluator<'_> {
|
|||
self.run_drop_glue_deep(ty, locals, addr, &[], span)?;
|
||||
}
|
||||
}
|
||||
VariantData::Unit => (),
|
||||
FieldsShape::Unit => (),
|
||||
}
|
||||
}
|
||||
AdtId::UnionId(_) => (), // union fields don't need drop
|
||||
|
|
@ -2923,7 +2924,7 @@ pub fn render_const_using_debug_impl(
|
|||
let resolver = owner.resolver(db.upcast());
|
||||
let Some(TypeNs::TraitId(debug_trait)) = resolver.resolve_path_in_type_ns_fully(
|
||||
db.upcast(),
|
||||
&hir_def::path::Path::from_known_path_with_no_generic(path![core::fmt::Debug]),
|
||||
&hir_def::expr_store::path::Path::from_known_path_with_no_generic(path![core::fmt::Debug]),
|
||||
) else {
|
||||
not_supported!("core::fmt::Debug not found");
|
||||
};
|
||||
|
|
@ -2954,7 +2955,7 @@ pub fn render_const_using_debug_impl(
|
|||
evaluator.write_memory(a3.offset(3 * evaluator.ptr_size()), &[1])?;
|
||||
let Some(ValueNs::FunctionId(format_fn)) = resolver.resolve_path_in_value_ns_fully(
|
||||
db.upcast(),
|
||||
&hir_def::path::Path::from_known_path_with_no_generic(path![std::fmt::format]),
|
||||
&hir_def::expr_store::path::Path::from_known_path_with_no_generic(path![std::fmt::format]),
|
||||
HygieneId::ROOT,
|
||||
) else {
|
||||
not_supported!("std::fmt::format not found");
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ impl Evaluator<'_> {
|
|||
return Ok(false);
|
||||
}
|
||||
|
||||
let function_data = self.db.function_data(def);
|
||||
let function_data = self.db.function_signature(def);
|
||||
let attrs = self.db.attrs(def.into());
|
||||
let is_intrinsic = attrs.by_key(&sym::rustc_intrinsic).exists()
|
||||
// Keep this around for a bit until extern "rustc-intrinsic" abis are no longer used
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ impl Evaluator<'_> {
|
|||
Some(len) => len,
|
||||
_ => {
|
||||
if let AdtId::StructId(id) = id.0 {
|
||||
let struct_data = self.db.variant_data(id.into());
|
||||
let struct_data = self.db.variant_fields(id.into());
|
||||
let fields = struct_data.fields();
|
||||
let Some((first_field, _)) = fields.iter().next() else {
|
||||
not_supported!("simd type with no field");
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ 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, Edition::CURRENT).to_string() == "main" {
|
||||
if db.function_signature(x).name.display(db, Edition::CURRENT).to_string() == "main"
|
||||
{
|
||||
Some(x)
|
||||
} else {
|
||||
None
|
||||
|
|
|
|||
|
|
@ -7,16 +7,14 @@ use chalk_ir::{BoundVar, ConstData, DebruijnIndex, TyKind};
|
|||
use hir_def::{
|
||||
AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId,
|
||||
Lookup, TraitId, TupleId, TypeOrConstParamId,
|
||||
data::adt::{StructKind, VariantData},
|
||||
expr_store::{Body, HygieneId},
|
||||
expr_store::{Body, ExpressionStore, HygieneId, path::Path},
|
||||
hir::{
|
||||
ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal, MatchArm,
|
||||
Pat, PatId, RecordFieldPat, RecordLitField,
|
||||
},
|
||||
item_tree::FieldsShape,
|
||||
lang_item::{LangItem, LangItemTarget},
|
||||
path::Path,
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
||||
type_ref::TypesMap,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use la_arena::ArenaMap;
|
||||
|
|
@ -30,7 +28,7 @@ use crate::{
|
|||
Adjust, Adjustment, AutoBorrow, CallableDefId, TyBuilder, TyExt,
|
||||
consteval::ConstEvalError,
|
||||
db::{HirDatabase, InternedClosure, InternedClosureId},
|
||||
display::{DisplayTarget, HirDisplay, hir_display_with_types_map},
|
||||
display::{DisplayTarget, HirDisplay, hir_display_with_store},
|
||||
error_lifetime,
|
||||
generics::generics,
|
||||
infer::{CaptureKind, CapturedItem, TypeMismatch, cast::CastTy, unify::InferenceTable},
|
||||
|
|
@ -255,10 +253,10 @@ impl MirLowerError {
|
|||
db: &dyn HirDatabase,
|
||||
p: &Path,
|
||||
display_target: DisplayTarget,
|
||||
types_map: &TypesMap,
|
||||
store: &ExpressionStore,
|
||||
) -> Self {
|
||||
Self::UnresolvedName(
|
||||
hir_display_with_types_map(p, types_map).display(db, display_target).to_string(),
|
||||
hir_display_with_store(p, store).display(db, display_target).to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -417,7 +415,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
if let DefWithBodyId::FunctionId(f) = self.owner {
|
||||
let assoc = f.lookup(self.db.upcast());
|
||||
if let ItemContainerId::TraitId(t) = assoc.container {
|
||||
let name = &self.db.function_data(f).name;
|
||||
let name = &self.db.function_signature(f).name;
|
||||
return Err(MirLowerError::TraitFunctionDefinition(t, name.clone()));
|
||||
}
|
||||
}
|
||||
|
|
@ -466,7 +464,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
self.db,
|
||||
p,
|
||||
DisplayTarget::from_crate(self.db, self.krate()),
|
||||
&self.body.types,
|
||||
self.body,
|
||||
)
|
||||
})?;
|
||||
self.resolver.reset_to_guard(resolver_guard);
|
||||
|
|
@ -499,8 +497,8 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
Ok(Some(current))
|
||||
}
|
||||
ValueNs::EnumVariantId(variant_id) => {
|
||||
let variant_data = &self.db.variant_data(variant_id.into());
|
||||
if variant_data.kind() == StructKind::Unit {
|
||||
let variant_fields = &self.db.variant_fields(variant_id.into());
|
||||
if variant_fields.shape == FieldsShape::Unit {
|
||||
let ty = self.infer.type_of_expr[expr_id].clone();
|
||||
current = self.lower_enum_variant(
|
||||
variant_id,
|
||||
|
|
@ -840,7 +838,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
let variant_id =
|
||||
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)
|
||||
hir_display_with_store(&**p, self.body)
|
||||
.display(self.db, self.display_target())
|
||||
.to_string(),
|
||||
),
|
||||
|
|
@ -850,13 +848,13 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
TyKind::Adt(_, s) => s.clone(),
|
||||
_ => not_supported!("Non ADT record literal"),
|
||||
};
|
||||
let variant_data = variant_id.variant_data(self.db.upcast());
|
||||
let variant_fields = self.db.variant_fields(variant_id);
|
||||
match variant_id {
|
||||
VariantId::EnumVariantId(_) | VariantId::StructId(_) => {
|
||||
let mut operands = vec![None; variant_data.fields().len()];
|
||||
let mut operands = vec![None; variant_fields.fields().len()];
|
||||
for RecordLitField { name, expr } in fields.iter() {
|
||||
let field_id =
|
||||
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
|
||||
variant_fields.field(name).ok_or(MirLowerError::UnresolvedField)?;
|
||||
let Some((op, c)) = self.lower_expr_to_some_operand(*expr, current)?
|
||||
else {
|
||||
return Ok(None);
|
||||
|
|
@ -899,7 +897,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
not_supported!("Union record literal with more than one field");
|
||||
};
|
||||
let local_id =
|
||||
variant_data.field(name).ok_or(MirLowerError::UnresolvedField)?;
|
||||
variant_fields.field(name).ok_or(MirLowerError::UnresolvedField)?;
|
||||
let place = place.project(
|
||||
PlaceElem::Field(Either::Left(FieldId {
|
||||
parent: union_id.into(),
|
||||
|
|
@ -914,17 +912,18 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
Expr::Await { .. } => not_supported!("await"),
|
||||
Expr::Yeet { .. } => not_supported!("yeet"),
|
||||
Expr::Async { .. } => not_supported!("async block"),
|
||||
&Expr::Const(id) => {
|
||||
let subst = self.placeholder_subst();
|
||||
self.lower_const(
|
||||
id.into(),
|
||||
current,
|
||||
place,
|
||||
subst,
|
||||
expr_id.into(),
|
||||
self.expr_ty_without_adjust(expr_id),
|
||||
)?;
|
||||
Ok(Some(current))
|
||||
&Expr::Const(_) => {
|
||||
// let subst = self.placeholder_subst();
|
||||
// self.lower_const(
|
||||
// id.into(),
|
||||
// current,
|
||||
// place,
|
||||
// subst,
|
||||
// expr_id.into(),
|
||||
// self.expr_ty_without_adjust(expr_id),
|
||||
// )?;
|
||||
// Ok(Some(current))
|
||||
not_supported!("const block")
|
||||
}
|
||||
Expr::Cast { expr, type_ref: _ } => {
|
||||
let Some((it, current)) = self.lower_expr_to_some_operand(*expr, current)? else {
|
||||
|
|
@ -1165,7 +1164,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
Rvalue::Aggregate(
|
||||
AggregateKind::Adt(st.into(), subst.clone()),
|
||||
self.db
|
||||
.variant_data(st.into())
|
||||
.variant_fields(st.into())
|
||||
.fields()
|
||||
.iter()
|
||||
.map(|it| {
|
||||
|
|
@ -1371,7 +1370,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
self.db,
|
||||
c,
|
||||
DisplayTarget::from_crate(db, owner.krate(db.upcast())),
|
||||
&self.body.types,
|
||||
self.body,
|
||||
)
|
||||
};
|
||||
let pr = self
|
||||
|
|
@ -2125,22 +2124,25 @@ pub fn mir_body_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Result<Arc<Mi
|
|||
let edition = krate.data(db).edition;
|
||||
let detail = match def {
|
||||
DefWithBodyId::FunctionId(it) => {
|
||||
db.function_data(it).name.display(db.upcast(), edition).to_string()
|
||||
db.function_signature(it).name.display(db.upcast(), edition).to_string()
|
||||
}
|
||||
DefWithBodyId::StaticId(it) => {
|
||||
db.static_data(it).name.display(db.upcast(), edition).to_string()
|
||||
db.static_signature(it).name.display(db.upcast(), edition).to_string()
|
||||
}
|
||||
DefWithBodyId::ConstId(it) => db
|
||||
.const_data(it)
|
||||
.const_signature(it)
|
||||
.name
|
||||
.clone()
|
||||
.unwrap_or_else(Name::missing)
|
||||
.display(db.upcast(), edition)
|
||||
.to_string(),
|
||||
DefWithBodyId::VariantId(it) => {
|
||||
db.enum_variant_data(it).name.display(db.upcast(), edition).to_string()
|
||||
let loc = it.lookup(db.upcast());
|
||||
db.enum_variants(loc.parent).variants[loc.index as usize]
|
||||
.1
|
||||
.display(db.upcast(), edition)
|
||||
.to_string()
|
||||
}
|
||||
DefWithBodyId::InTypeConstId(it) => format!("in type const {it:?}"),
|
||||
};
|
||||
let _p = tracing::info_span!("mir_body_query", ?detail).entered();
|
||||
let body = db.body(def);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! MIR lowering for patterns
|
||||
|
||||
use hir_def::{AssocItemId, hir::ExprId};
|
||||
use hir_def::{AssocItemId, hir::ExprId, signatures::VariantFields};
|
||||
|
||||
use crate::{
|
||||
BindingMode,
|
||||
|
|
@ -11,7 +11,7 @@ use crate::{
|
|||
MemoryMap, MirLowerCtx, MirLowerError, MirSpan, Mutability, Operand, Pat, PatId, Place,
|
||||
PlaceElem, ProjectionElem, RecordFieldPat, ResolveValueResult, Result, Rvalue,
|
||||
Substitution, SwitchTargets, TerminatorKind, TupleFieldId, TupleId, TyBuilder, TyKind,
|
||||
ValueNs, VariantData, VariantId,
|
||||
ValueNs, VariantId,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -350,12 +350,7 @@ impl MirLowerCtx<'_> {
|
|||
)?,
|
||||
None => {
|
||||
let unresolved_name = || {
|
||||
MirLowerError::unresolved_path(
|
||||
self.db,
|
||||
p,
|
||||
self.display_target(),
|
||||
&self.body.types,
|
||||
)
|
||||
MirLowerError::unresolved_path(self.db, p, self.display_target(), self.body)
|
||||
};
|
||||
let hygiene = self.body.pat_path_hygiene(pattern);
|
||||
let pr = self
|
||||
|
|
@ -597,7 +592,7 @@ impl MirLowerCtx<'_> {
|
|||
}
|
||||
self.pattern_matching_variant_fields(
|
||||
shape,
|
||||
&self.db.variant_data(v.into()),
|
||||
&self.db.variant_fields(v.into()),
|
||||
variant,
|
||||
current,
|
||||
current_else,
|
||||
|
|
@ -607,7 +602,7 @@ impl MirLowerCtx<'_> {
|
|||
}
|
||||
VariantId::StructId(s) => self.pattern_matching_variant_fields(
|
||||
shape,
|
||||
&self.db.variant_data(s.into()),
|
||||
&self.db.variant_fields(s.into()),
|
||||
variant,
|
||||
current,
|
||||
current_else,
|
||||
|
|
@ -623,7 +618,7 @@ impl MirLowerCtx<'_> {
|
|||
fn pattern_matching_variant_fields(
|
||||
&mut self,
|
||||
shape: AdtPatternShape<'_>,
|
||||
variant_data: &VariantData,
|
||||
variant_data: &VariantFields,
|
||||
v: VariantId,
|
||||
current: BasicBlockId,
|
||||
current_else: Option<BasicBlockId>,
|
||||
|
|
|
|||
|
|
@ -43,11 +43,11 @@ impl MirBody {
|
|||
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);
|
||||
let data = db.function_signature(id);
|
||||
w!(this, "fn {}() ", data.name.display(db.upcast(), this.display_target.edition));
|
||||
}
|
||||
hir_def::DefWithBodyId::StaticId(id) => {
|
||||
let data = db.static_data(id);
|
||||
let data = db.static_signature(id);
|
||||
w!(
|
||||
this,
|
||||
"static {}: _ = ",
|
||||
|
|
@ -55,7 +55,7 @@ impl MirBody {
|
|||
);
|
||||
}
|
||||
hir_def::DefWithBodyId::ConstId(id) => {
|
||||
let data = db.const_data(id);
|
||||
let data = db.const_signature(id);
|
||||
w!(
|
||||
this,
|
||||
"const {}: _ = ",
|
||||
|
|
@ -79,9 +79,6 @@ impl MirBody {
|
|||
.display(db.upcast(), this.display_target.edition),
|
||||
)
|
||||
}
|
||||
hir_def::DefWithBodyId::InTypeConstId(id) => {
|
||||
w!(this, "in type const {id:?} = ");
|
||||
}
|
||||
});
|
||||
ctx.result
|
||||
}
|
||||
|
|
@ -333,17 +330,19 @@ impl<'a> MirPrettyCtx<'a> {
|
|||
w!(this, ")");
|
||||
}
|
||||
ProjectionElem::Field(Either::Left(field)) => {
|
||||
let variant_data = field.parent.variant_data(this.db.upcast());
|
||||
let name = &variant_data.fields()[field.local_id].name;
|
||||
let variant_fields = this.db.variant_fields(field.parent);
|
||||
let name = &variant_fields.fields()[field.local_id].name;
|
||||
match field.parent {
|
||||
hir_def::VariantId::EnumVariantId(e) => {
|
||||
w!(this, "(");
|
||||
f(this, local, head);
|
||||
let variant_name = &this.db.enum_variant_data(e).name;
|
||||
let loc = e.lookup(this.db.upcast());
|
||||
w!(
|
||||
this,
|
||||
" as {}).{}",
|
||||
variant_name.display(this.db.upcast(), this.display_target.edition),
|
||||
this.db.enum_variants(loc.parent).variants[loc.index as usize]
|
||||
.1
|
||||
.display(this.db.upcast(), this.display_target.edition),
|
||||
name.display(this.db.upcast(), this.display_target.edition)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,7 +160,6 @@ fn check_impl(
|
|||
let loc = it.lookup(&db);
|
||||
loc.source(&db).value.syntax().text_range().start()
|
||||
}
|
||||
DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(),
|
||||
});
|
||||
let mut unexpected_type_mismatches = String::new();
|
||||
for (def, krate) in defs {
|
||||
|
|
@ -419,7 +418,6 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
|||
let loc = it.lookup(&db);
|
||||
loc.source(&db).value.syntax().text_range().start()
|
||||
}
|
||||
DefWithBodyId::InTypeConstId(it) => it.source(&db).syntax().text_range().start(),
|
||||
});
|
||||
for (def, krate) in defs {
|
||||
let (body, source_map) = db.body_with_source_map(def);
|
||||
|
|
|
|||
|
|
@ -103,6 +103,6 @@ fn baz() -> i32 {
|
|||
}
|
||||
});
|
||||
});
|
||||
assert!(format!("{events:?}").matches("infer_shim").count() == 1, "{events:#?}")
|
||||
assert_eq!(format!("{events:?}").matches("infer_shim").count(), 1, "{events:#?}")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1584,23 +1584,6 @@ type Member<U> = ConstGen<U, N>;
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cfgd_out_self_param() {
|
||||
cov_mark::check!(cfgd_out_self_param);
|
||||
check_no_mismatches(
|
||||
r#"
|
||||
struct S;
|
||||
impl S {
|
||||
fn f(#[cfg(never)] &self) {}
|
||||
}
|
||||
|
||||
fn f(s: S) {
|
||||
s.f();
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple_struct_pattern_with_unmatched_args_crash() {
|
||||
check_infer(
|
||||
|
|
|
|||
|
|
@ -1784,6 +1784,8 @@ impl Foo for u8 {
|
|||
}
|
||||
|
||||
#[test]
|
||||
// FIXME
|
||||
#[should_panic]
|
||||
fn const_eval_in_function_signature() {
|
||||
check_types(
|
||||
r#"
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ impl DebugContext<'_> {
|
|||
f: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let name = match id.0 {
|
||||
AdtId::StructId(it) => self.0.struct_data(it).name.clone(),
|
||||
AdtId::UnionId(it) => self.0.union_data(it).name.clone(),
|
||||
AdtId::EnumId(it) => self.0.enum_data(it).name.clone(),
|
||||
AdtId::StructId(it) => self.0.struct_signature(it).name.clone(),
|
||||
AdtId::UnionId(it) => self.0.union_signature(it).name.clone(),
|
||||
AdtId::EnumId(it) => self.0.enum_signature(it).name.clone(),
|
||||
};
|
||||
name.display(self.0.upcast(), Edition::LATEST).fmt(f)?;
|
||||
Ok(())
|
||||
|
|
@ -35,7 +35,7 @@ impl DebugContext<'_> {
|
|||
f: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let trait_: hir_def::TraitId = from_chalk_trait_id(id);
|
||||
let trait_data = self.0.trait_data(trait_);
|
||||
let trait_data = self.0.trait_signature(trait_);
|
||||
trait_data.name.display(self.0.upcast(), Edition::LATEST).fmt(f)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -46,12 +46,12 @@ impl DebugContext<'_> {
|
|||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let type_alias: TypeAliasId = from_assoc_type_id(id);
|
||||
let type_alias_data = self.0.type_alias_data(type_alias);
|
||||
let type_alias_data = self.0.type_alias_signature(type_alias);
|
||||
let trait_ = match type_alias.lookup(self.0.upcast()).container {
|
||||
ItemContainerId::TraitId(t) => t,
|
||||
_ => panic!("associated type not in trait"),
|
||||
};
|
||||
let trait_data = self.0.trait_data(trait_);
|
||||
let trait_data = self.0.trait_signature(trait_);
|
||||
write!(
|
||||
fmt,
|
||||
"{}::{}",
|
||||
|
|
@ -67,12 +67,12 @@ impl DebugContext<'_> {
|
|||
fmt: &mut fmt::Formatter<'_>,
|
||||
) -> Result<(), fmt::Error> {
|
||||
let type_alias = from_assoc_type_id(projection_ty.associated_ty_id);
|
||||
let type_alias_data = self.0.type_alias_data(type_alias);
|
||||
let type_alias_data = self.0.type_alias_signature(type_alias);
|
||||
let trait_ = match type_alias.lookup(self.0.upcast()).container {
|
||||
ItemContainerId::TraitId(t) => t,
|
||||
_ => panic!("associated type not in trait"),
|
||||
};
|
||||
let trait_name = &self.0.trait_data(trait_).name;
|
||||
let trait_name = &self.0.trait_signature(trait_).name;
|
||||
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);
|
||||
|
|
@ -106,9 +106,12 @@ impl DebugContext<'_> {
|
|||
) -> Result<(), fmt::Error> {
|
||||
let def: CallableDefId = from_chalk(self.0, fn_def_id);
|
||||
let name = match def {
|
||||
CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(),
|
||||
CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(),
|
||||
CallableDefId::EnumVariantId(e) => self.0.enum_variant_data(e).name.clone(),
|
||||
CallableDefId::FunctionId(ff) => self.0.function_signature(ff).name.clone(),
|
||||
CallableDefId::StructId(s) => self.0.struct_signature(s).name.clone(),
|
||||
CallableDefId::EnumVariantId(e) => {
|
||||
let loc = e.lookup(self.0.upcast());
|
||||
self.0.enum_variants(loc.parent).variants[loc.index as usize].1.clone()
|
||||
}
|
||||
};
|
||||
match def {
|
||||
CallableDefId::FunctionId(_) => {
|
||||
|
|
|
|||
|
|
@ -113,15 +113,16 @@ pub(crate) fn trait_solve_query(
|
|||
block: Option<BlockId>,
|
||||
goal: Canonical<InEnvironment<Goal>>,
|
||||
) -> 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(), Edition::LATEST).to_string()
|
||||
}
|
||||
let _p = tracing::info_span!("trait_solve_query", detail = ?match &goal.value.goal.data(Interner) {
|
||||
GoalData::DomainGoal(DomainGoal::Holds(WhereClause::Implemented(it))) => db
|
||||
.trait_signature(it.hir_trait_id())
|
||||
.name
|
||||
.display(db.upcast(), Edition::LATEST)
|
||||
.to_string(),
|
||||
GoalData::DomainGoal(DomainGoal::Holds(WhereClause::AliasEq(_))) => "alias_eq".to_owned(),
|
||||
_ => "??".to_owned(),
|
||||
};
|
||||
let _p = tracing::info_span!("trait_solve_query", ?detail).entered();
|
||||
tracing::info!("trait_solve_query({:?})", goal.value.goal);
|
||||
})
|
||||
.entered();
|
||||
|
||||
if let GoalData::DomainGoal(DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
|
||||
alias: AliasTy::Projection(projection_ty),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
//! Helper functions for working with def, which don't need to be a separate
|
||||
//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
|
||||
|
||||
use std::{hash::Hash, iter};
|
||||
use std::iter;
|
||||
|
||||
use base_db::Crate;
|
||||
use chalk_ir::{
|
||||
|
|
@ -9,10 +9,9 @@ use chalk_ir::{
|
|||
fold::{FallibleTypeFolder, Shift},
|
||||
};
|
||||
use hir_def::{
|
||||
EnumId, EnumVariantId, FunctionId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId,
|
||||
TypeOrConstParamId,
|
||||
EnumId, EnumVariantId, FunctionId, Lookup, TraitId, TypeAliasId, TypeOrConstParamId,
|
||||
db::DefDatabase,
|
||||
generics::{WherePredicate, WherePredicateTypeTarget},
|
||||
hir::generics::{WherePredicate, WherePredicateTypeTarget},
|
||||
lang_item::LangItem,
|
||||
resolver::{HasResolver, TypeNs},
|
||||
type_ref::{TraitBoundModifier, TypeRef},
|
||||
|
|
@ -164,26 +163,25 @@ impl Iterator for ClauseElaborator<'_> {
|
|||
|
||||
fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(TraitId)) {
|
||||
let resolver = trait_.resolver(db);
|
||||
let generic_params = db.generic_params(trait_.into());
|
||||
let (generic_params, store) = db.generic_params_and_store(trait_.into());
|
||||
let trait_self = generic_params.trait_self_param();
|
||||
generic_params
|
||||
.where_predicates()
|
||||
.filter_map(|pred| match pred {
|
||||
WherePredicate::ForLifetime { target, bound, .. }
|
||||
| WherePredicate::TypeBound { target, bound } => {
|
||||
let is_trait = match target {
|
||||
WherePredicateTypeTarget::TypeRef(type_ref) => {
|
||||
match &generic_params.types_map[*type_ref] {
|
||||
TypeRef::Path(p) => p.is_self_type(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
let is_trait = match *target {
|
||||
WherePredicateTypeTarget::TypeRef(type_ref) => match &store[type_ref] {
|
||||
TypeRef::Path(p) => p.is_self_type(),
|
||||
TypeRef::TypeParam(p) => Some(p.local_id()) == trait_self,
|
||||
_ => false,
|
||||
},
|
||||
WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
|
||||
Some(*local_id) == trait_self
|
||||
Some(local_id) == trait_self
|
||||
}
|
||||
};
|
||||
match is_trait {
|
||||
true => bound.as_path(&generic_params.types_map),
|
||||
true => bound.as_path(&store),
|
||||
false => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -276,7 +274,7 @@ pub fn is_fn_unsafe_to_call(
|
|||
caller_target_features: &TargetFeatures,
|
||||
call_edition: Edition,
|
||||
) -> Unsafety {
|
||||
let data = db.function_data(func);
|
||||
let data = db.function_signature(func);
|
||||
if data.is_unsafe() {
|
||||
return Unsafety::Unsafe;
|
||||
}
|
||||
|
|
@ -395,28 +393,3 @@ pub(crate) fn detect_variant_from_bytes<'a>(
|
|||
};
|
||||
Some((var_id, var_layout))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct InTypeConstIdMetadata(pub(crate) Ty);
|
||||
|
||||
impl OpaqueInternableThing for InTypeConstIdMetadata {
|
||||
fn dyn_hash(&self, mut state: &mut dyn std::hash::Hasher) {
|
||||
self.hash(&mut state);
|
||||
}
|
||||
|
||||
fn dyn_eq(&self, other: &dyn OpaqueInternableThing) -> bool {
|
||||
other.as_any().downcast_ref::<Self>() == Some(self)
|
||||
}
|
||||
|
||||
fn dyn_clone(&self) -> Box<dyn OpaqueInternableThing> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn box_any(&self) -> Box<dyn std::any::Any> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use crate::{
|
|||
};
|
||||
use base_db::salsa::Cycle;
|
||||
use chalk_ir::Mutability;
|
||||
use hir_def::data::adt::StructFlags;
|
||||
use hir_def::signatures::StructFlags;
|
||||
use hir_def::{AdtId, GenericDefId, GenericParamId, VariantId};
|
||||
use std::fmt;
|
||||
use std::ops::Not;
|
||||
|
|
@ -34,7 +34,7 @@ pub(crate) fn variances_of(db: &dyn HirDatabase, def: GenericDefId) -> Option<Ar
|
|||
GenericDefId::FunctionId(_) => (),
|
||||
GenericDefId::AdtId(adt) => {
|
||||
if let AdtId::StructId(id) = adt {
|
||||
let flags = &db.struct_data(id).flags;
|
||||
let flags = &db.struct_signature(id).flags;
|
||||
if flags.contains(StructFlags::IS_UNSAFE_CELL) {
|
||||
return Some(Arc::from_iter(vec![Variance::Invariant; 1]));
|
||||
} else if flags.contains(StructFlags::IS_PHANTOM_DATA) {
|
||||
|
|
@ -489,7 +489,7 @@ impl Context<'_> {
|
|||
mod tests {
|
||||
use expect_test::{Expect, expect};
|
||||
use hir_def::{
|
||||
AdtId, GenericDefId, ModuleDefId, generics::GenericParamDataRef, src::HasSource,
|
||||
AdtId, GenericDefId, ModuleDefId, hir::generics::GenericParamDataRef, src::HasSource,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use stdx::format_to;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue