mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 22:54:58 +00:00
Merge pull request #18074 from ChayimFriedman2/typeref-source-map
internal: Build source map for `hir_def::TypeRef`s
This commit is contained in:
commit
80e9d014be
46 changed files with 2511 additions and 929 deletions
|
@ -615,8 +615,9 @@ pub(crate) fn associated_ty_data_query(
|
|||
let type_alias_data = db.type_alias_data(type_alias);
|
||||
let generic_params = generics(db.upcast(), type_alias.into());
|
||||
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
|
||||
let ctx = crate::TyLoweringContext::new(db, &resolver, type_alias.into())
|
||||
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
|
||||
let ctx =
|
||||
crate::TyLoweringContext::new(db, &resolver, &type_alias_data.types_map, type_alias.into())
|
||||
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
|
||||
|
||||
let trait_subst = TyBuilder::subst_for_def(db, trait_, None)
|
||||
.fill_with_bound_vars(crate::DebruijnIndex::INNERMOST, generic_params.len_self())
|
||||
|
|
|
@ -309,7 +309,7 @@ impl<'a> DeclValidator<'a> {
|
|||
/// Check incorrect names for struct fields.
|
||||
fn validate_struct_fields(&mut self, struct_id: StructId) {
|
||||
let data = self.db.struct_data(struct_id);
|
||||
let VariantData::Record(fields) = data.variant_data.as_ref() else {
|
||||
let VariantData::Record { fields, .. } = data.variant_data.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let edition = self.edition(struct_id);
|
||||
|
@ -469,7 +469,7 @@ 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.enum_variant_data(variant_id);
|
||||
let VariantData::Record(fields) = variant_data.variant_data.as_ref() else {
|
||||
let VariantData::Record { fields, .. } = variant_data.variant_data.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let edition = self.edition(variant_id);
|
||||
|
|
|
@ -341,7 +341,7 @@ impl HirDisplay for Pat {
|
|||
};
|
||||
|
||||
let variant_data = variant.variant_data(f.db.upcast());
|
||||
if let VariantData::Record(rec_fields) = &*variant_data {
|
||||
if let VariantData::Record { fields: rec_fields, .. } = &*variant_data {
|
||||
write!(f, " {{ ")?;
|
||||
|
||||
let mut printed = 0;
|
||||
|
|
|
@ -19,7 +19,9 @@ use hir_def::{
|
|||
lang_item::{LangItem, LangItemTarget},
|
||||
nameres::DefMap,
|
||||
path::{Path, PathKind},
|
||||
type_ref::{TraitBoundModifier, TypeBound, TypeRef, UseArgRef},
|
||||
type_ref::{
|
||||
TraitBoundModifier, TypeBound, TypeRef, TypeRefId, TypesMap, TypesSourceMap, UseArgRef,
|
||||
},
|
||||
visibility::Visibility,
|
||||
GenericDefId, HasModule, ImportPathConfig, ItemContainerId, LocalFieldId, Lookup, ModuleDefId,
|
||||
ModuleId, TraitId,
|
||||
|
@ -806,7 +808,7 @@ fn render_variant_after_name(
|
|||
memory_map: &MemoryMap,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match data {
|
||||
VariantData::Record(fields) | VariantData::Tuple(fields) => {
|
||||
VariantData::Record { fields, .. } | VariantData::Tuple { fields, .. } => {
|
||||
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);
|
||||
|
@ -817,7 +819,7 @@ fn render_variant_after_name(
|
|||
render_const_scalar(f, &b[offset..offset + size], memory_map, &ty)
|
||||
};
|
||||
let mut it = fields.iter();
|
||||
if matches!(data, VariantData::Record(_)) {
|
||||
if matches!(data, VariantData::Record { .. }) {
|
||||
write!(f, " {{")?;
|
||||
if let Some((id, data)) = it.next() {
|
||||
write!(f, " {}: ", data.name.display(f.db.upcast(), f.edition()))?;
|
||||
|
@ -1897,100 +1899,150 @@ pub fn write_visibility(
|
|||
}
|
||||
}
|
||||
|
||||
impl HirDisplay for TypeRef {
|
||||
pub trait HirDisplayWithTypesMap {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
) -> Result<(), HirDisplayError>;
|
||||
}
|
||||
|
||||
impl<T: ?Sized + HirDisplayWithTypesMap> HirDisplayWithTypesMap for &'_ T {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
T::hir_fmt(&**self, f, types_map)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hir_display_with_types_map<'a, T: HirDisplayWithTypesMap + 'a>(
|
||||
value: T,
|
||||
types_map: &'a TypesMap,
|
||||
) -> impl HirDisplay + 'a {
|
||||
TypesMapAdapter(value, types_map)
|
||||
}
|
||||
|
||||
struct TypesMapAdapter<'a, T>(T, &'a TypesMap);
|
||||
|
||||
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<T: HirDisplayWithTypesMap> HirDisplay for TypesMapAdapter<'_, T> {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||
match self {
|
||||
T::hir_fmt(&self.0, f, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl HirDisplayWithTypesMap for TypeRefId {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match &types_map[*self] {
|
||||
TypeRef::Never => write!(f, "!")?,
|
||||
TypeRef::Placeholder => write!(f, "_")?,
|
||||
TypeRef::Tuple(elems) => {
|
||||
write!(f, "(")?;
|
||||
f.write_joined(elems, ", ")?;
|
||||
f.write_joined(elems.iter().map(TypesMapAdapter::wrap(types_map)), ", ")?;
|
||||
if elems.len() == 1 {
|
||||
write!(f, ",")?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
}
|
||||
TypeRef::Path(path) => path.hir_fmt(f)?,
|
||||
TypeRef::Path(path) => path.hir_fmt(f, types_map)?,
|
||||
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)?;
|
||||
inner.hir_fmt(f, types_map)?;
|
||||
}
|
||||
TypeRef::Reference(inner, lifetime, mutability) => {
|
||||
let mutability = match mutability {
|
||||
TypeRef::Reference(ref_) => {
|
||||
let mutability = match ref_.mutability {
|
||||
hir_def::type_ref::Mutability::Shared => "",
|
||||
hir_def::type_ref::Mutability::Mut => "mut ",
|
||||
};
|
||||
write!(f, "&")?;
|
||||
if let Some(lifetime) = lifetime {
|
||||
if let Some(lifetime) = &ref_.lifetime {
|
||||
write!(f, "{} ", lifetime.name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
write!(f, "{mutability}")?;
|
||||
inner.hir_fmt(f)?;
|
||||
ref_.ty.hir_fmt(f, types_map)?;
|
||||
}
|
||||
TypeRef::Array(inner, len) => {
|
||||
TypeRef::Array(array) => {
|
||||
write!(f, "[")?;
|
||||
inner.hir_fmt(f)?;
|
||||
write!(f, "; {}]", len.display(f.db.upcast(), f.edition()))?;
|
||||
array.ty.hir_fmt(f, types_map)?;
|
||||
write!(f, "; {}]", array.len.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
TypeRef::Slice(inner) => {
|
||||
write!(f, "[")?;
|
||||
inner.hir_fmt(f)?;
|
||||
inner.hir_fmt(f, types_map)?;
|
||||
write!(f, "]")?;
|
||||
}
|
||||
&TypeRef::Fn(ref parameters, is_varargs, is_unsafe, ref abi) => {
|
||||
if is_unsafe {
|
||||
TypeRef::Fn(fn_) => {
|
||||
if fn_.is_unsafe() {
|
||||
write!(f, "unsafe ")?;
|
||||
}
|
||||
if let Some(abi) = abi {
|
||||
if let Some(abi) = fn_.abi() {
|
||||
f.write_str("extern \"")?;
|
||||
f.write_str(abi.as_str())?;
|
||||
f.write_str("\" ")?;
|
||||
}
|
||||
write!(f, "fn(")?;
|
||||
if let Some(((_, return_type), function_parameters)) = parameters.split_last() {
|
||||
if let Some(((_, return_type), function_parameters)) = fn_.params().split_last() {
|
||||
for index in 0..function_parameters.len() {
|
||||
let (param_name, param_type) = &function_parameters[index];
|
||||
if let Some(name) = param_name {
|
||||
write!(f, "{}: ", name.display(f.db.upcast(), f.edition()))?;
|
||||
}
|
||||
|
||||
param_type.hir_fmt(f)?;
|
||||
param_type.hir_fmt(f, types_map)?;
|
||||
|
||||
if index != function_parameters.len() - 1 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
}
|
||||
if is_varargs {
|
||||
write!(f, "{}...", if parameters.len() == 1 { "" } else { ", " })?;
|
||||
if fn_.is_varargs() {
|
||||
write!(f, "{}...", if fn_.params().len() == 1 { "" } else { ", " })?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
match &return_type {
|
||||
match &types_map[*return_type] {
|
||||
TypeRef::Tuple(tup) if tup.is_empty() => {}
|
||||
_ => {
|
||||
write!(f, " -> ")?;
|
||||
return_type.hir_fmt(f)?;
|
||||
return_type.hir_fmt(f, types_map)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
TypeRef::ImplTrait(bounds) => {
|
||||
write!(f, "impl ")?;
|
||||
f.write_joined(bounds, " + ")?;
|
||||
f.write_joined(bounds.iter().map(TypesMapAdapter::wrap(types_map)), " + ")?;
|
||||
}
|
||||
TypeRef::DynTrait(bounds) => {
|
||||
write!(f, "dyn ")?;
|
||||
f.write_joined(bounds, " + ")?;
|
||||
f.write_joined(bounds.iter().map(TypesMapAdapter::wrap(types_map)), " + ")?;
|
||||
}
|
||||
TypeRef::Macro(macro_call) => {
|
||||
let ctx = hir_def::lower::LowerCtx::new(f.db.upcast(), macro_call.file_id);
|
||||
let (mut types_map, mut types_source_map) =
|
||||
(TypesMap::default(), TypesSourceMap::default());
|
||||
let 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(&ctx, path) {
|
||||
Some(path) => path.hir_fmt(f)?,
|
||||
Some(path) => path.hir_fmt(f, &types_map)?,
|
||||
None => write!(f, "{{macro}}")?,
|
||||
},
|
||||
None => write!(f, "{{macro}}")?,
|
||||
|
@ -2003,15 +2055,19 @@ impl HirDisplay for TypeRef {
|
|||
}
|
||||
}
|
||||
|
||||
impl HirDisplay for TypeBound {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||
impl HirDisplayWithTypesMap for TypeBound {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match self {
|
||||
TypeBound::Path(path, modifier) => {
|
||||
match modifier {
|
||||
TraitBoundModifier::None => (),
|
||||
TraitBoundModifier::Maybe => write!(f, "?")?,
|
||||
}
|
||||
path.hir_fmt(f)
|
||||
path.hir_fmt(f, types_map)
|
||||
}
|
||||
TypeBound::Lifetime(lifetime) => {
|
||||
write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
|
||||
|
@ -2023,7 +2079,7 @@ impl HirDisplay for TypeBound {
|
|||
"for<{}> ",
|
||||
lifetimes.iter().map(|it| it.display(f.db.upcast(), edition)).format(", ")
|
||||
)?;
|
||||
path.hir_fmt(f)
|
||||
path.hir_fmt(f, types_map)
|
||||
}
|
||||
TypeBound::Use(args) => {
|
||||
let edition = f.edition();
|
||||
|
@ -2043,12 +2099,16 @@ impl HirDisplay for TypeBound {
|
|||
}
|
||||
}
|
||||
|
||||
impl HirDisplay for Path {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||
impl HirDisplayWithTypesMap for Path {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match (self.type_anchor(), self.kind()) {
|
||||
(Some(anchor), _) => {
|
||||
write!(f, "<")?;
|
||||
anchor.hir_fmt(f)?;
|
||||
anchor.hir_fmt(f, types_map)?;
|
||||
write!(f, ">")?;
|
||||
}
|
||||
(_, PathKind::Plain) => {}
|
||||
|
@ -2091,7 +2151,7 @@ impl HirDisplay for Path {
|
|||
});
|
||||
if let Some(ty) = trait_self_ty {
|
||||
write!(f, "<")?;
|
||||
ty.hir_fmt(f)?;
|
||||
ty.hir_fmt(f, types_map)?;
|
||||
write!(f, " as ")?;
|
||||
// Now format the path of the trait...
|
||||
}
|
||||
|
@ -2107,21 +2167,26 @@ impl HirDisplay for Path {
|
|||
if generic_args.desugared_from_fn {
|
||||
// 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 `,`.
|
||||
if let hir_def::path::GenericArg::Type(TypeRef::Tuple(v)) =
|
||||
&generic_args.args[0]
|
||||
{
|
||||
let tuple = match generic_args.args[0] {
|
||||
hir_def::path::GenericArg::Type(ty) => match &types_map[ty] {
|
||||
TypeRef::Tuple(it) => Some(it),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
if let Some(v) = tuple {
|
||||
if v.len() == 1 {
|
||||
write!(f, "(")?;
|
||||
v[0].hir_fmt(f)?;
|
||||
v[0].hir_fmt(f, types_map)?;
|
||||
write!(f, ")")?;
|
||||
} else {
|
||||
generic_args.args[0].hir_fmt(f)?;
|
||||
generic_args.args[0].hir_fmt(f, types_map)?;
|
||||
}
|
||||
}
|
||||
if let Some(ret) = &generic_args.bindings[0].type_ref {
|
||||
if !matches!(ret, TypeRef::Tuple(v) if v.is_empty()) {
|
||||
if let Some(ret) = generic_args.bindings[0].type_ref {
|
||||
if !matches!(&types_map[ret], TypeRef::Tuple(v) if v.is_empty()) {
|
||||
write!(f, " -> ")?;
|
||||
ret.hir_fmt(f)?;
|
||||
ret.hir_fmt(f, types_map)?;
|
||||
}
|
||||
}
|
||||
return Ok(());
|
||||
|
@ -2136,7 +2201,7 @@ impl HirDisplay for Path {
|
|||
} else {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
arg.hir_fmt(f)?;
|
||||
arg.hir_fmt(f, types_map)?;
|
||||
}
|
||||
for binding in generic_args.bindings.iter() {
|
||||
if first {
|
||||
|
@ -2149,11 +2214,14 @@ impl HirDisplay for Path {
|
|||
match &binding.type_ref {
|
||||
Some(ty) => {
|
||||
write!(f, " = ")?;
|
||||
ty.hir_fmt(f)?
|
||||
ty.hir_fmt(f, types_map)?
|
||||
}
|
||||
None => {
|
||||
write!(f, ": ")?;
|
||||
f.write_joined(binding.bounds.iter(), " + ")?;
|
||||
f.write_joined(
|
||||
binding.bounds.iter().map(TypesMapAdapter::wrap(types_map)),
|
||||
" + ",
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2175,10 +2243,14 @@ impl HirDisplay for Path {
|
|||
}
|
||||
}
|
||||
|
||||
impl HirDisplay for hir_def::path::GenericArg {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
|
||||
impl HirDisplayWithTypesMap for hir_def::path::GenericArg {
|
||||
fn hir_fmt(
|
||||
&self,
|
||||
f: &mut HirFormatter<'_>,
|
||||
types_map: &TypesMap,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match self {
|
||||
hir_def::path::GenericArg::Type(ty) => ty.hir_fmt(f),
|
||||
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()))
|
||||
}
|
||||
|
|
|
@ -16,12 +16,13 @@ use hir_def::{
|
|||
GenericParamDataRef, GenericParams, LifetimeParamData, TypeOrConstParamData,
|
||||
TypeParamProvenance,
|
||||
},
|
||||
type_ref::TypesMap,
|
||||
ConstParamId, GenericDefId, GenericParamId, ItemContainerId, LifetimeParamId,
|
||||
LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
|
||||
};
|
||||
use intern::Interned;
|
||||
use itertools::chain;
|
||||
use stdx::TupleExt;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{db::HirDatabase, lt_to_placeholder_idx, to_placeholder_idx, Interner, Substitution};
|
||||
|
||||
|
@ -34,7 +35,7 @@ pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
|
|||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct Generics {
|
||||
def: GenericDefId,
|
||||
params: Interned<GenericParams>,
|
||||
params: Arc<GenericParams>,
|
||||
parent_generics: Option<Box<Generics>>,
|
||||
has_trait_self_param: bool,
|
||||
}
|
||||
|
@ -85,6 +86,18 @@ impl Generics {
|
|||
self.iter_self().chain(self.iter_parent())
|
||||
}
|
||||
|
||||
pub(crate) fn iter_with_types_map(
|
||||
&self,
|
||||
) -> impl Iterator<Item = ((GenericParamId, GenericParamDataRef<'_>), &TypesMap)> + '_ {
|
||||
self.iter_self().zip(std::iter::repeat(&self.params.types_map)).chain(
|
||||
self.iter_parent().zip(
|
||||
self.parent_generics()
|
||||
.into_iter()
|
||||
.flat_map(|it| std::iter::repeat(&it.params.types_map)),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/// Iterate over the params without parent params.
|
||||
pub(crate) fn iter_self(
|
||||
&self,
|
||||
|
|
|
@ -41,7 +41,7 @@ use hir_def::{
|
|||
layout::Integer,
|
||||
path::{ModPath, Path},
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
|
||||
type_ref::{LifetimeRef, TypeRef},
|
||||
type_ref::{LifetimeRef, TypeRefId, TypesMap},
|
||||
AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ImplId, ItemContainerId, Lookup,
|
||||
TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId,
|
||||
};
|
||||
|
@ -858,7 +858,7 @@ impl<'a> InferenceContext<'a> {
|
|||
}
|
||||
|
||||
fn collect_const(&mut self, data: &ConstData) {
|
||||
let return_ty = self.make_ty(&data.type_ref);
|
||||
let return_ty = self.make_ty(data.type_ref, &data.types_map);
|
||||
|
||||
// Constants might be defining usage sites of TAITs.
|
||||
self.make_tait_coercion_table(iter::once(&return_ty));
|
||||
|
@ -867,7 +867,7 @@ impl<'a> InferenceContext<'a> {
|
|||
}
|
||||
|
||||
fn collect_static(&mut self, data: &StaticData) {
|
||||
let return_ty = self.make_ty(&data.type_ref);
|
||||
let return_ty = self.make_ty(data.type_ref, &data.types_map);
|
||||
|
||||
// Statics might be defining usage sites of TAITs.
|
||||
self.make_tait_coercion_table(iter::once(&return_ty));
|
||||
|
@ -877,11 +877,11 @@ impl<'a> InferenceContext<'a> {
|
|||
|
||||
fn collect_fn(&mut self, func: FunctionId) {
|
||||
let data = self.db.function_data(func);
|
||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into())
|
||||
.with_type_param_mode(ParamLoweringMode::Placeholder)
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Param);
|
||||
let mut param_tys =
|
||||
data.params.iter().map(|type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
|
||||
let mut param_tys = self.with_ty_lowering(&data.types_map, |ctx| {
|
||||
ctx.type_param_mode(ParamLoweringMode::Placeholder)
|
||||
.impl_trait_mode(ImplTraitLoweringMode::Param);
|
||||
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() {
|
||||
|
@ -916,12 +916,13 @@ impl<'a> InferenceContext<'a> {
|
|||
tait_candidates.insert(ty);
|
||||
}
|
||||
}
|
||||
let return_ty = &*data.ret_type;
|
||||
let return_ty = data.ret_type;
|
||||
|
||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into())
|
||||
.with_type_param_mode(ParamLoweringMode::Placeholder)
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
|
||||
let return_ty = ctx.lower_ty(return_ty);
|
||||
let return_ty = self.with_ty_lowering(&data.types_map, |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) {
|
||||
|
@ -1225,20 +1226,43 @@ impl<'a> InferenceContext<'a> {
|
|||
self.result.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
|
||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||
let ty = ctx.lower_ty(type_ref);
|
||||
fn with_ty_lowering<R>(
|
||||
&self,
|
||||
types_map: &TypesMap,
|
||||
f: impl FnOnce(&mut crate::lower::TyLoweringContext<'_>) -> R,
|
||||
) -> R {
|
||||
let mut ctx = crate::lower::TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
types_map,
|
||||
self.owner.into(),
|
||||
);
|
||||
f(&mut ctx)
|
||||
}
|
||||
|
||||
fn with_body_ty_lowering<R>(
|
||||
&self,
|
||||
f: impl FnOnce(&mut crate::lower::TyLoweringContext<'_>) -> R,
|
||||
) -> R {
|
||||
self.with_ty_lowering(&self.body.types, f)
|
||||
}
|
||||
|
||||
fn make_ty(&mut self, type_ref: TypeRefId, types_map: &TypesMap) -> Ty {
|
||||
let ty = self.with_ty_lowering(types_map, |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)
|
||||
}
|
||||
|
||||
fn err_ty(&self) -> Ty {
|
||||
self.result.standard_types.unknown.clone()
|
||||
}
|
||||
|
||||
fn make_lifetime(&mut self, lifetime_ref: &LifetimeRef) -> Lifetime {
|
||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||
let lt = ctx.lower_lifetime(lifetime_ref);
|
||||
let lt = self.with_ty_lowering(TypesMap::EMPTY, |ctx| ctx.lower_lifetime(lifetime_ref));
|
||||
self.insert_type_vars(lt)
|
||||
}
|
||||
|
||||
|
@ -1396,7 +1420,12 @@ impl<'a> InferenceContext<'a> {
|
|||
Some(path) => path,
|
||||
None => return (self.err_ty(), None),
|
||||
};
|
||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||
let ctx = crate::lower::TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
&self.body.types,
|
||||
self.owner.into(),
|
||||
);
|
||||
let (resolution, unresolved) = if value_ns {
|
||||
match self.resolver.resolve_path_in_value_ns(self.db.upcast(), path, HygieneId::ROOT) {
|
||||
Some(ResolveValueResult::ValueNs(value, _)) => match value {
|
||||
|
|
|
@ -283,11 +283,11 @@ impl CapturedItem {
|
|||
ProjectionElem::Deref => {}
|
||||
ProjectionElem::Field(Either::Left(f)) => {
|
||||
match &*f.parent.variant_data(db.upcast()) {
|
||||
VariantData::Record(fields) => {
|
||||
VariantData::Record { fields, .. } => {
|
||||
result.push('_');
|
||||
result.push_str(fields[f.local_id].name.as_str())
|
||||
}
|
||||
VariantData::Tuple(fields) => {
|
||||
VariantData::Tuple { fields, .. } => {
|
||||
let index = fields.iter().position(|it| it.0 == f.local_id);
|
||||
if let Some(index) = index {
|
||||
format_to!(result, "_{index}");
|
||||
|
@ -325,12 +325,12 @@ impl CapturedItem {
|
|||
ProjectionElem::Field(Either::Left(f)) => {
|
||||
let variant_data = f.parent.variant_data(db.upcast());
|
||||
match &*variant_data {
|
||||
VariantData::Record(fields) => format_to!(
|
||||
VariantData::Record { fields, .. } => format_to!(
|
||||
result,
|
||||
".{}",
|
||||
fields[f.local_id].name.display(db.upcast(), edition)
|
||||
),
|
||||
VariantData::Tuple(fields) => format_to!(
|
||||
VariantData::Tuple { fields, .. } => format_to!(
|
||||
result,
|
||||
".{}",
|
||||
fields.iter().position(|it| it.0 == f.local_id).unwrap_or_default()
|
||||
|
@ -383,8 +383,10 @@ impl CapturedItem {
|
|||
}
|
||||
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(),
|
||||
VariantData::Tuple(fields) => fields
|
||||
VariantData::Record { fields, .. } => {
|
||||
fields[f.local_id].name.as_str().to_owned()
|
||||
}
|
||||
VariantData::Tuple { fields, .. } => fields
|
||||
.iter()
|
||||
.position(|it| it.0 == f.local_id)
|
||||
.unwrap_or_default()
|
||||
|
|
|
@ -198,7 +198,7 @@ impl InferenceContext<'_> {
|
|||
match &self.body[expr] {
|
||||
// Lang item paths cannot currently be local variables or statics.
|
||||
Expr::Path(Path::LangItem(_, _)) => false,
|
||||
Expr::Path(Path::Normal { type_anchor: Some(_), .. }) => false,
|
||||
Expr::Path(Path::Normal(path)) => path.type_anchor().is_none(),
|
||||
Expr::Path(path) => self
|
||||
.resolver
|
||||
.resolve_path_in_value_ns_fully(
|
||||
|
@ -382,7 +382,7 @@ impl InferenceContext<'_> {
|
|||
// collect explicitly written argument types
|
||||
for arg_type in arg_types.iter() {
|
||||
let arg_ty = match arg_type {
|
||||
Some(type_ref) => self.make_ty(type_ref),
|
||||
Some(type_ref) => self.make_body_ty(*type_ref),
|
||||
None => self.table.new_type_var(),
|
||||
};
|
||||
sig_tys.push(arg_ty);
|
||||
|
@ -390,7 +390,7 @@ impl InferenceContext<'_> {
|
|||
|
||||
// add return type
|
||||
let ret_ty = match ret_type {
|
||||
Some(type_ref) => self.make_ty(type_ref),
|
||||
Some(type_ref) => self.make_body_ty(*type_ref),
|
||||
None => self.table.new_type_var(),
|
||||
};
|
||||
if let ClosureKind::Async = closure_kind {
|
||||
|
@ -786,7 +786,7 @@ impl InferenceContext<'_> {
|
|||
self.resolve_associated_type(inner_ty, self.resolve_future_future_output())
|
||||
}
|
||||
Expr::Cast { expr, type_ref } => {
|
||||
let cast_ty = self.make_ty(type_ref);
|
||||
let cast_ty = self.make_body_ty(*type_ref);
|
||||
let expr_ty = self.infer_expr(
|
||||
*expr,
|
||||
&Expectation::Castable(cast_ty.clone()),
|
||||
|
@ -1214,7 +1214,7 @@ impl InferenceContext<'_> {
|
|||
let ty = match self.infer_path(path, id) {
|
||||
Some(ty) => ty,
|
||||
None => {
|
||||
if matches!(path, Path::Normal { mod_path, .. } if mod_path.is_ident() || mod_path.is_self())
|
||||
if path.mod_path().is_some_and(|mod_path| mod_path.is_ident() || mod_path.is_self())
|
||||
{
|
||||
self.push_diagnostic(InferenceDiagnostic::UnresolvedIdent { id });
|
||||
}
|
||||
|
@ -1598,7 +1598,7 @@ impl InferenceContext<'_> {
|
|||
Statement::Let { pat, type_ref, initializer, else_branch } => {
|
||||
let decl_ty = type_ref
|
||||
.as_ref()
|
||||
.map(|tr| this.make_ty(tr))
|
||||
.map(|&tr| this.make_body_ty(tr))
|
||||
.unwrap_or_else(|| this.table.new_type_var());
|
||||
|
||||
let ty = if let Some(expr) = initializer {
|
||||
|
@ -2141,7 +2141,8 @@ impl InferenceContext<'_> {
|
|||
kind_id,
|
||||
args.next().unwrap(), // `peek()` is `Some(_)`, so guaranteed no panic
|
||||
self,
|
||||
|this, type_ref| this.make_ty(type_ref),
|
||||
&self.body.types,
|
||||
|this, type_ref| this.make_body_ty(type_ref),
|
||||
|this, c, ty| {
|
||||
const_or_path_to_chalk(
|
||||
this.db,
|
||||
|
|
|
@ -94,8 +94,7 @@ impl InferenceContext<'_> {
|
|||
return Some(ValuePathResolution::NonGeneric(ty));
|
||||
};
|
||||
|
||||
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||
let substs = ctx.substs_from_path(path, value_def, true);
|
||||
let substs = self.with_body_ty_lowering(|ctx| ctx.substs_from_path(path, value_def, true));
|
||||
let substs = substs.as_slice(Interner);
|
||||
|
||||
if let ValueNs::EnumVariantId(_) = value {
|
||||
|
@ -152,8 +151,12 @@ impl InferenceContext<'_> {
|
|||
let last = path.segments().last()?;
|
||||
|
||||
// Don't use `self.make_ty()` here as we need `orig_ns`.
|
||||
let ctx =
|
||||
crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
|
||||
let ctx = crate::lower::TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
&self.body.types,
|
||||
self.owner.into(),
|
||||
);
|
||||
let (ty, orig_ns) = ctx.lower_ty_ext(type_ref);
|
||||
let ty = self.table.insert_type_vars(ty);
|
||||
let ty = self.table.normalize_associated_types_in(ty);
|
||||
|
@ -219,7 +222,7 @@ impl InferenceContext<'_> {
|
|||
|
||||
let _d;
|
||||
let (resolved_segment, remaining_segments) = match path {
|
||||
Path::Normal { .. } => {
|
||||
Path::Normal { .. } | Path::BarePath(_) => {
|
||||
assert!(remaining_index < path.segments().len());
|
||||
(
|
||||
path.segments().get(remaining_index - 1).unwrap(),
|
||||
|
@ -243,17 +246,10 @@ impl InferenceContext<'_> {
|
|||
(TypeNs::TraitId(trait_), true) => {
|
||||
let segment =
|
||||
remaining_segments.last().expect("there should be at least one segment here");
|
||||
let ctx = crate::lower::TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
self.owner.into(),
|
||||
);
|
||||
let trait_ref = ctx.lower_trait_ref_from_resolved_path(
|
||||
trait_,
|
||||
resolved_segment,
|
||||
self.table.new_type_var(),
|
||||
);
|
||||
|
||||
let self_ty = self.table.new_type_var();
|
||||
let trait_ref = self.with_body_ty_lowering(|ctx| {
|
||||
ctx.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty)
|
||||
});
|
||||
self.resolve_trait_assoc_item(trait_ref, segment, id)
|
||||
}
|
||||
(def, _) => {
|
||||
|
@ -263,17 +259,14 @@ impl InferenceContext<'_> {
|
|||
// as Iterator>::Item::default`)
|
||||
let remaining_segments_for_ty =
|
||||
remaining_segments.take(remaining_segments.len() - 1);
|
||||
let ctx = crate::lower::TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
self.owner.into(),
|
||||
);
|
||||
let (ty, _) = ctx.lower_partly_resolved_path(
|
||||
def,
|
||||
resolved_segment,
|
||||
remaining_segments_for_ty,
|
||||
true,
|
||||
);
|
||||
let (ty, _) = self.with_body_ty_lowering(|ctx| {
|
||||
ctx.lower_partly_resolved_path(
|
||||
def,
|
||||
resolved_segment,
|
||||
remaining_segments_for_ty,
|
||||
true,
|
||||
)
|
||||
});
|
||||
if ty.is_unknown() {
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ use hir_def::{
|
|||
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
|
||||
type_ref::{
|
||||
ConstRef, LifetimeRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
|
||||
TypeRefId, TypesMap, TypesSourceMap,
|
||||
},
|
||||
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
|
||||
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, ItemContainerId,
|
||||
|
@ -41,7 +42,6 @@ use hir_def::{
|
|||
TypeOwnerId, UnionId, VariantId,
|
||||
};
|
||||
use hir_expand::{name::Name, ExpandResult};
|
||||
use intern::Interned;
|
||||
use la_arena::{Arena, ArenaMap};
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_pattern_analysis::Captures;
|
||||
|
@ -122,6 +122,11 @@ pub struct TyLoweringContext<'a> {
|
|||
pub db: &'a dyn HirDatabase,
|
||||
resolver: &'a Resolver,
|
||||
generics: OnceCell<Option<Generics>>,
|
||||
types_map: &'a TypesMap,
|
||||
/// If this is set, that means we're in a context of a freshly expanded macro, and that means
|
||||
/// we should not use `TypeRefId` in diagnostics because the caller won't have the `TypesMap`,
|
||||
/// instead we need to put `TypeSource` from the source map.
|
||||
types_source_map: Option<&'a TypesSourceMap>,
|
||||
in_binders: DebruijnIndex,
|
||||
// FIXME: Should not be an `Option` but `Resolver` currently does not return owners in all cases
|
||||
// where expected
|
||||
|
@ -138,13 +143,20 @@ pub struct TyLoweringContext<'a> {
|
|||
}
|
||||
|
||||
impl<'a> TyLoweringContext<'a> {
|
||||
pub fn new(db: &'a dyn HirDatabase, resolver: &'a Resolver, owner: TypeOwnerId) -> Self {
|
||||
Self::new_maybe_unowned(db, resolver, Some(owner))
|
||||
pub fn new(
|
||||
db: &'a dyn HirDatabase,
|
||||
resolver: &'a Resolver,
|
||||
types_map: &'a TypesMap,
|
||||
owner: TypeOwnerId,
|
||||
) -> Self {
|
||||
Self::new_maybe_unowned(db, resolver, types_map, None, Some(owner))
|
||||
}
|
||||
|
||||
pub fn new_maybe_unowned(
|
||||
db: &'a dyn HirDatabase,
|
||||
resolver: &'a Resolver,
|
||||
types_map: &'a TypesMap,
|
||||
types_source_map: Option<&'a TypesSourceMap>,
|
||||
owner: Option<TypeOwnerId>,
|
||||
) -> Self {
|
||||
let impl_trait_mode = ImplTraitLoweringState::Disallowed;
|
||||
|
@ -154,6 +166,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
db,
|
||||
resolver,
|
||||
generics: OnceCell::new(),
|
||||
types_map,
|
||||
types_source_map,
|
||||
owner,
|
||||
in_binders,
|
||||
impl_trait_mode,
|
||||
|
@ -201,6 +215,16 @@ impl<'a> TyLoweringContext<'a> {
|
|||
pub fn with_type_param_mode(self, type_param_mode: ParamLoweringMode) -> Self {
|
||||
Self { type_param_mode, ..self }
|
||||
}
|
||||
|
||||
pub fn impl_trait_mode(&mut self, impl_trait_mode: ImplTraitLoweringMode) -> &mut Self {
|
||||
self.impl_trait_mode = ImplTraitLoweringState::new(impl_trait_mode);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn type_param_mode(&mut self, type_param_mode: ParamLoweringMode) -> &mut Self {
|
||||
self.type_param_mode = type_param_mode;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
|
@ -230,7 +254,7 @@ pub enum ParamLoweringMode {
|
|||
}
|
||||
|
||||
impl<'a> TyLoweringContext<'a> {
|
||||
pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
|
||||
pub fn lower_ty(&self, type_ref: TypeRefId) -> Ty {
|
||||
self.lower_ty_ext(type_ref).0
|
||||
}
|
||||
|
||||
|
@ -254,12 +278,13 @@ impl<'a> TyLoweringContext<'a> {
|
|||
.as_ref()
|
||||
}
|
||||
|
||||
pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
|
||||
pub fn lower_ty_ext(&self, type_ref_id: TypeRefId) -> (Ty, Option<TypeNs>) {
|
||||
let mut res = None;
|
||||
let type_ref = &self.types_map[type_ref_id];
|
||||
let ty = match type_ref {
|
||||
TypeRef::Never => TyKind::Never.intern(Interner),
|
||||
TypeRef::Tuple(inner) => {
|
||||
let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
|
||||
let inner_tys = inner.iter().map(|&tr| self.lower_ty(tr));
|
||||
TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
|
||||
.intern(Interner)
|
||||
}
|
||||
|
@ -268,38 +293,43 @@ impl<'a> TyLoweringContext<'a> {
|
|||
res = res_;
|
||||
ty
|
||||
}
|
||||
TypeRef::RawPtr(inner, mutability) => {
|
||||
&TypeRef::RawPtr(inner, mutability) => {
|
||||
let inner_ty = self.lower_ty(inner);
|
||||
TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(Interner)
|
||||
TyKind::Raw(lower_to_chalk_mutability(mutability), inner_ty).intern(Interner)
|
||||
}
|
||||
TypeRef::Array(inner, len) => {
|
||||
let inner_ty = self.lower_ty(inner);
|
||||
let const_len = self.lower_const(len, TyBuilder::usize());
|
||||
TypeRef::Array(array) => {
|
||||
let inner_ty = self.lower_ty(array.ty);
|
||||
let const_len = self.lower_const(&array.len, TyBuilder::usize());
|
||||
TyKind::Array(inner_ty, const_len).intern(Interner)
|
||||
}
|
||||
TypeRef::Slice(inner) => {
|
||||
&TypeRef::Slice(inner) => {
|
||||
let inner_ty = self.lower_ty(inner);
|
||||
TyKind::Slice(inner_ty).intern(Interner)
|
||||
}
|
||||
TypeRef::Reference(inner, lifetime, mutability) => {
|
||||
let inner_ty = self.lower_ty(inner);
|
||||
TypeRef::Reference(ref_) => {
|
||||
let inner_ty = self.lower_ty(ref_.ty);
|
||||
// FIXME: It should infer the eldided lifetimes instead of stubbing with static
|
||||
let lifetime =
|
||||
lifetime.as_ref().map_or_else(error_lifetime, |lr| self.lower_lifetime(lr));
|
||||
TyKind::Ref(lower_to_chalk_mutability(*mutability), lifetime, inner_ty)
|
||||
let lifetime = ref_
|
||||
.lifetime
|
||||
.as_ref()
|
||||
.map_or_else(error_lifetime, |lr| self.lower_lifetime(lr));
|
||||
TyKind::Ref(lower_to_chalk_mutability(ref_.mutability), lifetime, inner_ty)
|
||||
.intern(Interner)
|
||||
}
|
||||
TypeRef::Placeholder => TyKind::Error.intern(Interner),
|
||||
&TypeRef::Fn(ref params, variadic, is_unsafe, ref abi) => {
|
||||
TypeRef::Fn(fn_) => {
|
||||
let substs = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||
Substitution::from_iter(Interner, params.iter().map(|(_, tr)| ctx.lower_ty(tr)))
|
||||
Substitution::from_iter(
|
||||
Interner,
|
||||
fn_.params().iter().map(|&(_, tr)| ctx.lower_ty(tr)),
|
||||
)
|
||||
});
|
||||
TyKind::Function(FnPointer {
|
||||
num_binders: 0, // FIXME lower `for<'a> fn()` correctly
|
||||
sig: FnSig {
|
||||
abi: abi.as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
|
||||
safety: if is_unsafe { Safety::Unsafe } else { Safety::Safe },
|
||||
variadic,
|
||||
abi: fn_.abi().as_ref().map_or(FnAbi::Rust, FnAbi::from_symbol),
|
||||
safety: if fn_.is_unsafe() { Safety::Unsafe } else { Safety::Safe },
|
||||
variadic: fn_.is_varargs(),
|
||||
},
|
||||
substitution: FnSubst(substs),
|
||||
})
|
||||
|
@ -351,8 +381,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
ImplTraitLoweringState::Param(counter) => {
|
||||
let idx = counter.get();
|
||||
// Count the number of `impl Trait` things that appear within our bounds.
|
||||
// Since t hose have been emitted as implicit type args already.
|
||||
counter.set(idx + count_impl_traits(type_ref) as u16);
|
||||
// Since those have been emitted as implicit type args already.
|
||||
counter.set(idx + self.count_impl_traits(type_ref_id) as u16);
|
||||
let kind = self
|
||||
.generics()
|
||||
.expect("param impl trait lowering must be in a generic def")
|
||||
|
@ -376,7 +406,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
let idx = counter.get();
|
||||
// Count the number of `impl Trait` things that appear within our bounds.
|
||||
// Since t hose have been emitted as implicit type args already.
|
||||
counter.set(idx + count_impl_traits(type_ref) as u16);
|
||||
counter.set(idx + self.count_impl_traits(type_ref_id) as u16);
|
||||
let kind = self
|
||||
.generics()
|
||||
.expect("variable impl trait lowering must be in a generic def")
|
||||
|
@ -432,12 +462,40 @@ impl<'a> TyLoweringContext<'a> {
|
|||
match expander.enter_expand::<ast::Type>(self.db.upcast(), macro_call, resolver)
|
||||
{
|
||||
Ok(ExpandResult { value: Some((mark, expanded)), .. }) => {
|
||||
let ctx = expander.ctx(self.db.upcast());
|
||||
let (mut types_map, mut types_source_map) =
|
||||
(TypesMap::default(), TypesSourceMap::default());
|
||||
|
||||
let ctx = expander.ctx(
|
||||
self.db.upcast(),
|
||||
&mut types_map,
|
||||
&mut types_source_map,
|
||||
);
|
||||
// FIXME: Report syntax errors in expansion here
|
||||
let type_ref = TypeRef::from_ast(&ctx, expanded.tree());
|
||||
|
||||
drop(expander);
|
||||
let ty = self.lower_ty(&type_ref);
|
||||
|
||||
// FIXME: That may be better served by mutating `self` then restoring, but this requires
|
||||
// making it `&mut self`.
|
||||
let inner_ctx = TyLoweringContext {
|
||||
db: self.db,
|
||||
resolver: self.resolver,
|
||||
generics: self.generics.clone(),
|
||||
types_map: &types_map,
|
||||
types_source_map: Some(&types_source_map),
|
||||
in_binders: self.in_binders,
|
||||
owner: self.owner,
|
||||
type_param_mode: self.type_param_mode,
|
||||
impl_trait_mode: self.impl_trait_mode.take(),
|
||||
expander: RefCell::new(self.expander.take()),
|
||||
unsized_types: RefCell::new(self.unsized_types.take()),
|
||||
};
|
||||
|
||||
let ty = inner_ctx.lower_ty(type_ref);
|
||||
|
||||
self.impl_trait_mode.swap(&inner_ctx.impl_trait_mode);
|
||||
*self.expander.borrow_mut() = inner_ctx.expander.into_inner();
|
||||
*self.unsized_types.borrow_mut() = inner_ctx.unsized_types.into_inner();
|
||||
|
||||
self.expander.borrow_mut().as_mut().unwrap().exit(mark);
|
||||
Some(ty)
|
||||
|
@ -463,7 +521,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
/// This is only for `generic_predicates_for_param`, where we can't just
|
||||
/// lower the self types of the predicates since that could lead to cycles.
|
||||
/// So we just check here if the `type_ref` resolves to a generic param, and which.
|
||||
fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeOrConstParamId> {
|
||||
fn lower_ty_only_param(&self, type_ref: TypeRefId) -> Option<TypeOrConstParamId> {
|
||||
let type_ref = &self.types_map[type_ref];
|
||||
let path = match type_ref {
|
||||
TypeRef::Path(path) => path,
|
||||
_ => return None,
|
||||
|
@ -663,7 +722,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
|
||||
// trait object type without dyn
|
||||
let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
|
||||
let ty = self.lower_dyn_trait(&[Interned::new(bound)]);
|
||||
let ty = self.lower_dyn_trait(&[bound]);
|
||||
return (ty, None);
|
||||
}
|
||||
|
||||
|
@ -864,7 +923,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
assert!(matches!(id, GenericParamId::TypeParamId(_)));
|
||||
had_explicit_args = true;
|
||||
if let GenericArg::Type(ty) = &args[0] {
|
||||
substs.push(self.lower_ty(ty).cast(Interner));
|
||||
substs.push(self.lower_ty(*ty).cast(Interner));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -901,6 +960,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
id,
|
||||
arg,
|
||||
&mut (),
|
||||
self.types_map,
|
||||
|_, type_ref| self.lower_ty(type_ref),
|
||||
|_, const_ref, ty| self.lower_const(const_ref, ty),
|
||||
|_, lifetime_ref| self.lower_lifetime(lifetime_ref),
|
||||
|
@ -998,7 +1058,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
WherePredicate::ForLifetime { target, bound, .. }
|
||||
| WherePredicate::TypeBound { target, bound } => {
|
||||
let self_ty = match target {
|
||||
WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
|
||||
WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(*type_ref),
|
||||
&WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
|
||||
let param_id = hir_def::TypeOrConstParamId { parent: def, local_id };
|
||||
match self.type_param_mode {
|
||||
|
@ -1029,12 +1089,12 @@ impl<'a> TyLoweringContext<'a> {
|
|||
|
||||
pub(crate) fn lower_type_bound(
|
||||
&'a self,
|
||||
bound: &'a Interned<TypeBound>,
|
||||
bound: &'a TypeBound,
|
||||
self_ty: Ty,
|
||||
ignore_bindings: bool,
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
|
||||
let mut trait_ref = None;
|
||||
let clause = match bound.as_ref() {
|
||||
let clause = match bound {
|
||||
TypeBound::Path(path, TraitBoundModifier::None) => {
|
||||
trait_ref = self.lower_trait_ref_from_path(path, self_ty);
|
||||
trait_ref.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
|
||||
|
@ -1079,10 +1139,10 @@ impl<'a> TyLoweringContext<'a> {
|
|||
|
||||
fn assoc_type_bindings_from_type_bound(
|
||||
&'a self,
|
||||
bound: &'a Interned<TypeBound>,
|
||||
bound: &'a TypeBound,
|
||||
trait_ref: TraitRef,
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
|
||||
let last_segment = match bound.as_ref() {
|
||||
let last_segment = match bound {
|
||||
TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
|
||||
path.segments().last()
|
||||
}
|
||||
|
@ -1111,7 +1171,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
// this point (`super_trait_ref.substitution`).
|
||||
let substitution = self.substs_from_path_segment(
|
||||
// FIXME: This is hack. We shouldn't really build `PathSegment` directly.
|
||||
PathSegment { name: &binding.name, args_and_bindings: binding.args.as_deref() },
|
||||
PathSegment { name: &binding.name, args_and_bindings: binding.args.as_ref() },
|
||||
Some(associated_ty.into()),
|
||||
false, // this is not relevant
|
||||
Some(super_trait_ref.self_type_parameter(Interner)),
|
||||
|
@ -1131,8 +1191,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
let mut predicates: SmallVec<[_; 1]> = SmallVec::with_capacity(
|
||||
binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
|
||||
);
|
||||
if let Some(type_ref) = &binding.type_ref {
|
||||
match (type_ref, &self.impl_trait_mode) {
|
||||
if let Some(type_ref) = binding.type_ref {
|
||||
match (&self.types_map[type_ref], &self.impl_trait_mode) {
|
||||
(TypeRef::ImplTrait(_), ImplTraitLoweringState::Disallowed) => (),
|
||||
(
|
||||
_,
|
||||
|
@ -1179,6 +1239,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
let mut ext = TyLoweringContext::new_maybe_unowned(
|
||||
self.db,
|
||||
self.resolver,
|
||||
self.types_map,
|
||||
self.types_source_map,
|
||||
self.owner,
|
||||
)
|
||||
.with_type_param_mode(self.type_param_mode);
|
||||
|
@ -1216,7 +1278,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
|
||||
fn lower_dyn_trait(&self, bounds: &[TypeBound]) -> Ty {
|
||||
let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
|
||||
// INVARIANT: The principal trait bound, if present, must come first. Others may be in any
|
||||
// order but should be in the same order for the same set but possibly different order of
|
||||
|
@ -1314,7 +1376,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_impl_trait(&self, bounds: &[Interned<TypeBound>], krate: CrateId) -> ImplTrait {
|
||||
fn lower_impl_trait(&self, bounds: &[TypeBound], krate: CrateId) -> ImplTrait {
|
||||
cov_mark::hit!(lower_rpit);
|
||||
let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
|
||||
let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||
|
@ -1366,6 +1428,17 @@ impl<'a> TyLoweringContext<'a> {
|
|||
None => error_lifetime(),
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This does not handle macros!
|
||||
fn count_impl_traits(&self, type_ref: TypeRefId) -> usize {
|
||||
let mut count = 0;
|
||||
TypeRef::walk(type_ref, self.types_map, &mut |type_ref| {
|
||||
if matches!(type_ref, TypeRef::ImplTrait(_)) {
|
||||
count += 1;
|
||||
}
|
||||
});
|
||||
count
|
||||
}
|
||||
}
|
||||
|
||||
/// Build the signature of a callable item (function, struct or enum variant).
|
||||
|
@ -1386,17 +1459,6 @@ pub fn associated_type_shorthand_candidates<R>(
|
|||
named_associated_type_shorthand_candidates(db, def, res, None, |name, _, id| cb(name, id))
|
||||
}
|
||||
|
||||
// FIXME: This does not handle macros!
|
||||
fn count_impl_traits(type_ref: &TypeRef) -> usize {
|
||||
let mut count = 0;
|
||||
type_ref.walk(&mut |type_ref| {
|
||||
if matches!(type_ref, TypeRef::ImplTrait(_)) {
|
||||
count += 1;
|
||||
}
|
||||
});
|
||||
count
|
||||
}
|
||||
|
||||
fn named_associated_type_shorthand_candidates<R>(
|
||||
db: &dyn HirDatabase,
|
||||
// If the type parameter is defined in an impl and we're in a method, there
|
||||
|
@ -1500,10 +1562,10 @@ pub(crate) fn field_types_query(
|
|||
};
|
||||
let generics = generics(db.upcast(), def);
|
||||
let mut res = ArenaMap::default();
|
||||
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||
let ctx = TyLoweringContext::new(db, &resolver, var_data.types_map(), def.into())
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
for (field_id, field_data) in var_data.fields().iter() {
|
||||
res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(&field_data.type_ref)));
|
||||
res.insert(field_id, make_binders(db, &generics, ctx.lower_ty(field_data.type_ref)));
|
||||
}
|
||||
Arc::new(res)
|
||||
}
|
||||
|
@ -1523,38 +1585,38 @@ pub(crate) fn generic_predicates_for_param_query(
|
|||
assoc_name: Option<Name>,
|
||||
) -> GenericPredicates {
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx = if let GenericDefId::FunctionId(_) = def {
|
||||
TyLoweringContext::new(db, &resolver, def.into())
|
||||
let mut ctx = if let GenericDefId::FunctionId(_) = def {
|
||||
TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Variable)
|
||||
.with_type_param_mode(ParamLoweringMode::Variable)
|
||||
} else {
|
||||
TyLoweringContext::new(db, &resolver, def.into())
|
||||
TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
|
||||
.with_type_param_mode(ParamLoweringMode::Variable)
|
||||
};
|
||||
let generics = generics(db.upcast(), def);
|
||||
|
||||
// we have to filter out all other predicates *first*, before attempting to lower them
|
||||
let predicate = |(pred, &def): &(&_, _)| match pred {
|
||||
let predicate = |pred: &_, def: &_, ctx: &TyLoweringContext<'_>| match pred {
|
||||
WherePredicate::ForLifetime { target, bound, .. }
|
||||
| WherePredicate::TypeBound { target, bound, .. } => {
|
||||
let invalid_target = match target {
|
||||
WherePredicateTypeTarget::TypeRef(type_ref) => {
|
||||
ctx.lower_ty_only_param(type_ref) != Some(param_id)
|
||||
ctx.lower_ty_only_param(*type_ref) != Some(param_id)
|
||||
}
|
||||
&WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
|
||||
let target_id = TypeOrConstParamId { parent: def, local_id };
|
||||
let target_id = TypeOrConstParamId { parent: *def, local_id };
|
||||
target_id != param_id
|
||||
}
|
||||
};
|
||||
if invalid_target {
|
||||
// If this is filtered out without lowering, `?Sized` is not gathered into `ctx.unsized_types`
|
||||
if let TypeBound::Path(_, TraitBoundModifier::Maybe) = &**bound {
|
||||
ctx.lower_where_predicate(pred, &def, true).for_each(drop);
|
||||
if let TypeBound::Path(_, TraitBoundModifier::Maybe) = bound {
|
||||
ctx.lower_where_predicate(pred, def, true).for_each(drop);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
match &**bound {
|
||||
match bound {
|
||||
TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
|
||||
// Only lower the bound if the trait could possibly define the associated
|
||||
// type we're looking for.
|
||||
|
@ -1577,13 +1639,15 @@ pub(crate) fn generic_predicates_for_param_query(
|
|||
}
|
||||
WherePredicate::Lifetime { .. } => false,
|
||||
};
|
||||
let mut predicates: Vec<_> = resolver
|
||||
.where_predicates_in_scope()
|
||||
.filter(predicate)
|
||||
.flat_map(|(pred, def)| {
|
||||
ctx.lower_where_predicate(pred, def, true).map(|p| make_binders(db, &generics, p))
|
||||
})
|
||||
.collect();
|
||||
let mut predicates = Vec::new();
|
||||
for (params, def) in resolver.all_generic_params() {
|
||||
ctx.types_map = ¶ms.types_map;
|
||||
predicates.extend(
|
||||
params.where_predicates().filter(|pred| predicate(pred, def, &ctx)).flat_map(|pred| {
|
||||
ctx.lower_where_predicate(pred, def, true).map(|p| make_binders(db, &generics, p))
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
|
||||
if !subst.is_empty(Interner) {
|
||||
|
@ -1630,23 +1694,27 @@ pub(crate) fn trait_environment_query(
|
|||
def: GenericDefId,
|
||||
) -> Arc<TraitEnvironment> {
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx = if let GenericDefId::FunctionId(_) = def {
|
||||
TyLoweringContext::new(db, &resolver, def.into())
|
||||
let mut ctx = if let GenericDefId::FunctionId(_) = def {
|
||||
TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Param)
|
||||
.with_type_param_mode(ParamLoweringMode::Placeholder)
|
||||
} else {
|
||||
TyLoweringContext::new(db, &resolver, def.into())
|
||||
TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
|
||||
.with_type_param_mode(ParamLoweringMode::Placeholder)
|
||||
};
|
||||
let mut traits_in_scope = Vec::new();
|
||||
let mut clauses = Vec::new();
|
||||
for (pred, def) in resolver.where_predicates_in_scope() {
|
||||
for pred in ctx.lower_where_predicate(pred, def, false) {
|
||||
if let WhereClause::Implemented(tr) = &pred.skip_binders() {
|
||||
traits_in_scope.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
|
||||
for (params, def) in resolver.all_generic_params() {
|
||||
ctx.types_map = ¶ms.types_map;
|
||||
for pred in params.where_predicates() {
|
||||
for pred in ctx.lower_where_predicate(pred, def, false) {
|
||||
if let WhereClause::Implemented(tr) = pred.skip_binders() {
|
||||
traits_in_scope
|
||||
.push((tr.self_type_parameter(Interner).clone(), tr.hir_trait_id()));
|
||||
}
|
||||
let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
|
||||
clauses.push(program_clause.into_from_env_clause(Interner));
|
||||
}
|
||||
let program_clause: chalk_ir::ProgramClause<Interner> = pred.cast(Interner);
|
||||
clauses.push(program_clause.into_from_env_clause(Interner));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1725,18 +1793,20 @@ where
|
|||
}
|
||||
_ => (ImplTraitLoweringMode::Disallowed, ParamLoweringMode::Variable),
|
||||
};
|
||||
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||
let mut ctx = TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
|
||||
.with_impl_trait_mode(impl_trait_lowering)
|
||||
.with_type_param_mode(param_lowering);
|
||||
let generics = generics(db.upcast(), def);
|
||||
|
||||
let mut predicates = resolver
|
||||
.where_predicates_in_scope()
|
||||
.filter(|(pred, def)| filter(pred, def))
|
||||
.flat_map(|(pred, def)| {
|
||||
ctx.lower_where_predicate(pred, def, false).map(|p| make_binders(db, &generics, p))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let mut predicates = Vec::new();
|
||||
for (params, def) in resolver.all_generic_params() {
|
||||
ctx.types_map = ¶ms.types_map;
|
||||
predicates.extend(params.where_predicates().filter(|pred| filter(pred, def)).flat_map(
|
||||
|pred| {
|
||||
ctx.lower_where_predicate(pred, def, false).map(|p| make_binders(db, &generics, p))
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
if generics.len() > 0 {
|
||||
let subst = generics.bound_vars_subst(db, DebruijnIndex::INNERMOST);
|
||||
|
@ -1812,18 +1882,19 @@ pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) ->
|
|||
let resolver = def.resolver(db.upcast());
|
||||
let parent_start_idx = generic_params.len_self();
|
||||
|
||||
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||
let mut ctx = TyLoweringContext::new(db, &resolver, TypesMap::EMPTY, def.into())
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Disallowed)
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
GenericDefaults(Some(Arc::from_iter(generic_params.iter().enumerate().map(
|
||||
|(idx, (id, p))| {
|
||||
GenericDefaults(Some(Arc::from_iter(generic_params.iter_with_types_map().enumerate().map(
|
||||
|(idx, ((id, p), types_map))| {
|
||||
ctx.types_map = types_map;
|
||||
match p {
|
||||
GenericParamDataRef::TypeParamData(p) => {
|
||||
let ty = p.default.as_ref().map_or(TyKind::Error.intern(Interner), |ty| {
|
||||
// Each default can only refer to previous parameters.
|
||||
// Type variable default referring to parameter coming
|
||||
// after it is forbidden (FIXME: report diagnostic)
|
||||
fallback_bound_vars(ctx.lower_ty(ty), idx, parent_start_idx)
|
||||
fallback_bound_vars(ctx.lower_ty(*ty), idx, parent_start_idx)
|
||||
});
|
||||
crate::make_binders(db, &generic_params, ty.cast(Interner))
|
||||
}
|
||||
|
@ -1835,7 +1906,7 @@ pub(crate) fn generic_defaults_query(db: &dyn HirDatabase, def: GenericDefId) ->
|
|||
let mut val = p.default.as_ref().map_or_else(
|
||||
|| unknown_const_as_generic(db.const_param_ty(id)),
|
||||
|c| {
|
||||
let c = ctx.lower_const(c, ctx.lower_ty(&p.ty));
|
||||
let c = ctx.lower_const(c, ctx.lower_ty(p.ty));
|
||||
c.cast(Interner)
|
||||
},
|
||||
);
|
||||
|
@ -1875,14 +1946,14 @@ pub(crate) fn generic_defaults_recover(
|
|||
fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
|
||||
let data = db.function_data(def);
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx_params = TyLoweringContext::new(db, &resolver, def.into())
|
||||
let ctx_params = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Variable)
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let params = data.params.iter().map(|tr| ctx_params.lower_ty(tr));
|
||||
let ctx_ret = TyLoweringContext::new(db, &resolver, def.into())
|
||||
let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr));
|
||||
let ctx_ret = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let ret = ctx_ret.lower_ty(&data.ret_type);
|
||||
let ret = ctx_ret.lower_ty(data.ret_type);
|
||||
let generics = generics(db.upcast(), def.into());
|
||||
let sig = CallableSig::from_params_and_return(
|
||||
params,
|
||||
|
@ -1911,28 +1982,33 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
|
|||
let data = db.const_data(def);
|
||||
let generics = generics(db.upcast(), def.into());
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||
let ctx = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
|
||||
make_binders(db, &generics, ctx.lower_ty(&data.type_ref))
|
||||
make_binders(db, &generics, ctx.lower_ty(data.type_ref))
|
||||
}
|
||||
|
||||
/// Build the declared type of a static.
|
||||
fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
|
||||
let data = db.static_data(def);
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, def.into());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, &data.types_map, def.into());
|
||||
|
||||
Binders::empty(Interner, ctx.lower_ty(&data.type_ref))
|
||||
Binders::empty(Interner, ctx.lower_ty(data.type_ref))
|
||||
}
|
||||
|
||||
fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
|
||||
let struct_data = db.struct_data(def);
|
||||
let fields = struct_data.variant_data.fields();
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, AdtId::from(def).into())
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref));
|
||||
let ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
struct_data.variant_data.types_map(),
|
||||
AdtId::from(def).into(),
|
||||
)
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let params = fields.iter().map(|(_, field)| ctx.lower_ty(field.type_ref));
|
||||
let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
|
||||
Binders::new(
|
||||
binders,
|
||||
|
@ -1962,9 +2038,14 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
|
|||
let var_data = db.enum_variant_data(def);
|
||||
let fields = var_data.variant_data.fields();
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, DefWithBodyId::VariantId(def).into())
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref));
|
||||
let ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
var_data.variant_data.types_map(),
|
||||
DefWithBodyId::VariantId(def).into(),
|
||||
)
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let params = fields.iter().map(|(_, field)| ctx.lower_ty(field.type_ref));
|
||||
let (ret, binders) =
|
||||
type_for_adt(db, def.lookup(db.upcast()).parent.into()).into_value_and_skipped_binders();
|
||||
Binders::new(
|
||||
|
@ -2005,15 +2086,17 @@ fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
|
|||
fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
|
||||
let generics = generics(db.upcast(), t.into());
|
||||
let resolver = t.resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, t.into())
|
||||
let type_alias_data = db.type_alias_data(t);
|
||||
let ctx = TyLoweringContext::new(db, &resolver, &type_alias_data.types_map, t.into())
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let type_alias_data = db.type_alias_data(t);
|
||||
let inner = if type_alias_data.is_extern {
|
||||
TyKind::Foreign(crate::to_foreign_def_id(t)).intern(Interner)
|
||||
} else {
|
||||
let type_ref = &type_alias_data.type_ref;
|
||||
ctx.lower_ty(type_ref.as_deref().unwrap_or(&TypeRef::Error))
|
||||
type_alias_data
|
||||
.type_ref
|
||||
.map(|type_ref| ctx.lower_ty(type_ref))
|
||||
.unwrap_or_else(|| TyKind::Error.intern(Interner))
|
||||
};
|
||||
make_binders(db, &generics, inner)
|
||||
}
|
||||
|
@ -2086,9 +2169,9 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
|
|||
let impl_data = db.impl_data(impl_id);
|
||||
let resolver = impl_id.resolver(db.upcast());
|
||||
let generics = generics(db.upcast(), impl_id.into());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
|
||||
let ctx = TyLoweringContext::new(db, &resolver, &impl_data.types_map, impl_id.into())
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
make_binders(db, &generics, ctx.lower_ty(&impl_data.self_ty))
|
||||
make_binders(db, &generics, ctx.lower_ty(impl_data.self_ty))
|
||||
}
|
||||
|
||||
// returns None if def is a type arg
|
||||
|
@ -2096,13 +2179,13 @@ pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> T
|
|||
let parent_data = db.generic_params(def.parent());
|
||||
let data = &parent_data[def.local_id()];
|
||||
let resolver = def.parent().resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, def.parent().into());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, &parent_data.types_map, def.parent().into());
|
||||
match data {
|
||||
TypeOrConstParamData::TypeParamData(_) => {
|
||||
never!();
|
||||
Ty::new(Interner, TyKind::Error)
|
||||
}
|
||||
TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(&d.ty),
|
||||
TypeOrConstParamData::ConstParamData(d) => ctx.lower_ty(d.ty),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2118,7 +2201,7 @@ pub(crate) fn impl_self_ty_recover(
|
|||
pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
|
||||
let impl_data = db.impl_data(impl_id);
|
||||
let resolver = impl_id.resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, impl_id.into())
|
||||
let ctx = TyLoweringContext::new(db, &resolver, &impl_data.types_map, impl_id.into())
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
|
||||
let target_trait = impl_data.target_trait.as_ref()?;
|
||||
|
@ -2132,10 +2215,10 @@ pub(crate) fn return_type_impl_traits(
|
|||
// FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
|
||||
let data = db.function_data(def);
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx_ret = TyLoweringContext::new(db, &resolver, def.into())
|
||||
let ctx_ret = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let _ret = ctx_ret.lower_ty(&data.ret_type);
|
||||
let _ret = ctx_ret.lower_ty(data.ret_type);
|
||||
let generics = generics(db.upcast(), def.into());
|
||||
let return_type_impl_traits = ImplTraits {
|
||||
impl_traits: match ctx_ret.impl_trait_mode {
|
||||
|
@ -2156,10 +2239,10 @@ pub(crate) fn type_alias_impl_traits(
|
|||
) -> Option<Arc<Binders<ImplTraits>>> {
|
||||
let data = db.type_alias_data(def);
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(db, &resolver, def.into())
|
||||
let ctx = TyLoweringContext::new(db, &resolver, &data.types_map, def.into())
|
||||
.with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
|
||||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
if let Some(type_ref) = &data.type_ref {
|
||||
if let Some(type_ref) = data.type_ref {
|
||||
let _ty = ctx.lower_ty(type_ref);
|
||||
}
|
||||
let type_alias_impl_traits = ImplTraits {
|
||||
|
@ -2191,7 +2274,8 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
|
|||
kind_id: GenericParamId,
|
||||
arg: &'a GenericArg,
|
||||
this: &mut T,
|
||||
for_type: impl FnOnce(&mut T, &TypeRef) -> Ty + 'a,
|
||||
types_map: &TypesMap,
|
||||
for_type: impl FnOnce(&mut T, TypeRefId) -> Ty + 'a,
|
||||
for_const: impl FnOnce(&mut T, &ConstRef, Ty) -> Const + 'a,
|
||||
for_lifetime: impl FnOnce(&mut T, &LifetimeRef) -> Lifetime + 'a,
|
||||
) -> crate::GenericArg {
|
||||
|
@ -2204,7 +2288,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
|
|||
GenericParamId::LifetimeParamId(_) => ParamKind::Lifetime,
|
||||
};
|
||||
match (arg, kind) {
|
||||
(GenericArg::Type(type_ref), ParamKind::Type) => for_type(this, type_ref).cast(Interner),
|
||||
(GenericArg::Type(type_ref), ParamKind::Type) => for_type(this, *type_ref).cast(Interner),
|
||||
(GenericArg::Const(c), ParamKind::Const(c_ty)) => for_const(this, c, c_ty).cast(Interner),
|
||||
(GenericArg::Lifetime(lifetime_ref), ParamKind::Lifetime) => {
|
||||
for_lifetime(this, lifetime_ref).cast(Interner)
|
||||
|
@ -2215,7 +2299,7 @@ pub(crate) fn generic_arg_to_chalk<'a, T>(
|
|||
// We want to recover simple idents, which parser detects them
|
||||
// as types. Maybe here is not the best place to do it, but
|
||||
// it works.
|
||||
if let TypeRef::Path(p) = t {
|
||||
if let TypeRef::Path(p) = &types_map[*t] {
|
||||
if let Some(p) = p.mod_path() {
|
||||
if p.kind == PathKind::Plain {
|
||||
if let [n] = p.segments() {
|
||||
|
|
|
@ -2849,7 +2849,8 @@ impl Evaluator<'_> {
|
|||
}
|
||||
let layout = self.layout_adt(id.0, subst.clone())?;
|
||||
match data.variant_data.as_ref() {
|
||||
VariantData::Record(fields) | VariantData::Tuple(fields) => {
|
||||
VariantData::Record { fields, .. }
|
||||
| VariantData::Tuple { fields, .. } => {
|
||||
let field_types = self.db.field_types(s.into());
|
||||
for (field, _) in fields.iter() {
|
||||
let offset = layout
|
||||
|
|
|
@ -14,6 +14,7 @@ use hir_def::{
|
|||
lang_item::{LangItem, LangItemTarget},
|
||||
path::Path,
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
||||
type_ref::TypesMap,
|
||||
AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, HasModule, ItemContainerId, LocalFieldId,
|
||||
Lookup, TraitId, TupleId, TypeOrConstParamId,
|
||||
};
|
||||
|
@ -28,7 +29,7 @@ use triomphe::Arc;
|
|||
use crate::{
|
||||
consteval::ConstEvalError,
|
||||
db::{HirDatabase, InternedClosure},
|
||||
display::HirDisplay,
|
||||
display::{hir_display_with_types_map, HirDisplay},
|
||||
error_lifetime,
|
||||
generics::generics,
|
||||
infer::{cast::CastTy, unify::InferenceTable, CaptureKind, CapturedItem, TypeMismatch},
|
||||
|
@ -247,8 +248,15 @@ impl From<LayoutError> for MirLowerError {
|
|||
}
|
||||
|
||||
impl MirLowerError {
|
||||
fn unresolved_path(db: &dyn HirDatabase, p: &Path, edition: Edition) -> Self {
|
||||
Self::UnresolvedName(p.display(db, edition).to_string())
|
||||
fn unresolved_path(
|
||||
db: &dyn HirDatabase,
|
||||
p: &Path,
|
||||
edition: Edition,
|
||||
types_map: &TypesMap,
|
||||
) -> Self {
|
||||
Self::UnresolvedName(
|
||||
hir_display_with_types_map(p, types_map).display(db, edition).to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,7 +459,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
.resolver
|
||||
.resolve_path_in_value_ns_fully(self.db.upcast(), p, hygiene)
|
||||
.ok_or_else(|| {
|
||||
MirLowerError::unresolved_path(self.db, p, self.edition())
|
||||
MirLowerError::unresolved_path(
|
||||
self.db,
|
||||
p,
|
||||
self.edition(),
|
||||
&self.body.types,
|
||||
)
|
||||
})?;
|
||||
self.resolver.reset_to_guard(resolver_guard);
|
||||
result
|
||||
|
@ -824,7 +837,9 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
let variant_id =
|
||||
self.infer.variant_resolution_for_expr(expr_id).ok_or_else(|| match path {
|
||||
Some(p) => MirLowerError::UnresolvedName(
|
||||
p.display(self.db, self.edition()).to_string(),
|
||||
hir_display_with_types_map(&**p, &self.body.types)
|
||||
.display(self.db, self.edition())
|
||||
.to_string(),
|
||||
),
|
||||
None => MirLowerError::RecordLiteralWithoutPath,
|
||||
})?;
|
||||
|
@ -1359,10 +1374,10 @@ impl<'ctx> MirLowerCtx<'ctx> {
|
|||
};
|
||||
let edition = self.edition();
|
||||
let unresolved_name =
|
||||
|| MirLowerError::unresolved_path(self.db, c.as_ref(), edition);
|
||||
|| MirLowerError::unresolved_path(self.db, c, edition, &self.body.types);
|
||||
let pr = self
|
||||
.resolver
|
||||
.resolve_path_in_value_ns(self.db.upcast(), c.as_ref(), HygieneId::ROOT)
|
||||
.resolve_path_in_value_ns(self.db.upcast(), c, HygieneId::ROOT)
|
||||
.ok_or_else(unresolved_name)?;
|
||||
match pr {
|
||||
ResolveValueResult::ValueNs(v, _) => {
|
||||
|
|
|
@ -349,8 +349,9 @@ impl MirLowerCtx<'_> {
|
|||
mode,
|
||||
)?,
|
||||
None => {
|
||||
let unresolved_name =
|
||||
|| MirLowerError::unresolved_path(self.db, p, self.edition());
|
||||
let unresolved_name = || {
|
||||
MirLowerError::unresolved_path(self.db, p, self.edition(), &self.body.types)
|
||||
};
|
||||
let hygiene = self.body.pat_path_hygiene(pattern);
|
||||
let pr = self
|
||||
.resolver
|
||||
|
|
|
@ -163,10 +163,12 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(Tra
|
|||
WherePredicate::ForLifetime { target, bound, .. }
|
||||
| WherePredicate::TypeBound { target, bound } => {
|
||||
let is_trait = match target {
|
||||
WherePredicateTypeTarget::TypeRef(type_ref) => match &**type_ref {
|
||||
TypeRef::Path(p) => p.is_self_type(),
|
||||
_ => false,
|
||||
},
|
||||
WherePredicateTypeTarget::TypeRef(type_ref) => {
|
||||
match &generic_params.types_map[*type_ref] {
|
||||
TypeRef::Path(p) => p.is_self_type(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
|
||||
Some(*local_id) == trait_self
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue