mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Avoid interior mutability in TyLoweringContext
This requires some serious code juggling.
This commit is contained in:
parent
cd206f5c9b
commit
4317927231
4 changed files with 202 additions and 225 deletions
|
@ -615,7 +615,7 @@ 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 =
|
||||
let mut ctx =
|
||||
crate::TyLoweringContext::new(db, &resolver, &type_alias_data.types_map, type_alias.into())
|
||||
.with_type_param_mode(crate::lower::ParamLoweringMode::Variable);
|
||||
|
||||
|
@ -627,14 +627,16 @@ pub(crate) fn associated_ty_data_query(
|
|||
.build();
|
||||
let self_ty = TyKind::Alias(AliasTy::Projection(pro_ty)).intern(Interner);
|
||||
|
||||
let mut bounds: Vec<_> = type_alias_data
|
||||
.bounds
|
||||
.iter()
|
||||
.flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone(), false))
|
||||
.filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty))
|
||||
.collect();
|
||||
let mut bounds = Vec::new();
|
||||
for bound in &type_alias_data.bounds {
|
||||
ctx.lower_type_bound(bound, self_ty.clone(), false).for_each(|pred| {
|
||||
if let Some(pred) = generic_predicate_to_inline_bound(db, &pred, &self_ty) {
|
||||
bounds.push(pred);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if !ctx.unsized_types.borrow().contains(&self_ty) {
|
||||
if !ctx.unsized_types.contains(&self_ty) {
|
||||
let sized_trait = db
|
||||
.lang_item(resolver.krate(), LangItem::Sized)
|
||||
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
|
||||
|
|
|
@ -1420,7 +1420,7 @@ impl<'a> InferenceContext<'a> {
|
|||
Some(path) => path,
|
||||
None => return (self.err_ty(), None),
|
||||
};
|
||||
let ctx = crate::lower::TyLoweringContext::new(
|
||||
let mut ctx = crate::lower::TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
&self.body.types,
|
||||
|
|
|
@ -151,7 +151,7 @@ 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(
|
||||
let mut ctx = crate::lower::TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
&self.body.types,
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
//!
|
||||
//! This usually involves resolving names, collecting generic arguments etc.
|
||||
use std::{
|
||||
cell::{Cell, OnceCell, RefCell, RefMut},
|
||||
iter,
|
||||
cell::OnceCell,
|
||||
iter, mem,
|
||||
ops::{self, Not as _},
|
||||
};
|
||||
|
||||
|
@ -72,47 +72,32 @@ use crate::{
|
|||
TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ImplTraitLoweringState {
|
||||
#[derive(Debug, Default)]
|
||||
struct ImplTraitLoweringState {
|
||||
/// When turning `impl Trait` into opaque types, we have to collect the
|
||||
/// bounds at the same time to get the IDs correct (without becoming too
|
||||
/// complicated). I don't like using interior mutability (as for the
|
||||
/// counter), but I've tried and failed to make the lifetimes work for
|
||||
/// passing around a `&mut TyLoweringContext`. The core problem is that
|
||||
/// we're grouping the mutable data (the counter and this field) together
|
||||
/// with the immutable context (the references to the DB and resolver).
|
||||
/// Splitting this up would be a possible fix.
|
||||
Opaque(RefCell<Arena<ImplTrait>>),
|
||||
Param(Cell<u16>),
|
||||
Variable(Cell<u16>),
|
||||
Disallowed,
|
||||
/// complicated).
|
||||
mode: ImplTraitLoweringMode,
|
||||
// This is structured as a struct with fields and not as an enum because it helps with the borrow checker.
|
||||
opaque_type_data: Arena<ImplTrait>,
|
||||
param_and_variable_counter: u16,
|
||||
}
|
||||
impl ImplTraitLoweringState {
|
||||
fn new(impl_trait_mode: ImplTraitLoweringMode) -> ImplTraitLoweringState {
|
||||
match impl_trait_mode {
|
||||
ImplTraitLoweringMode::Opaque => Self::Opaque(RefCell::new(Arena::new())),
|
||||
ImplTraitLoweringMode::Param => Self::Param(Cell::new(0)),
|
||||
ImplTraitLoweringMode::Variable => Self::Variable(Cell::new(0)),
|
||||
ImplTraitLoweringMode::Disallowed => Self::Disallowed,
|
||||
fn new(mode: ImplTraitLoweringMode) -> ImplTraitLoweringState {
|
||||
Self { mode, opaque_type_data: Arena::new(), param_and_variable_counter: 0 }
|
||||
}
|
||||
fn param(counter: u16) -> Self {
|
||||
Self {
|
||||
mode: ImplTraitLoweringMode::Param,
|
||||
opaque_type_data: Arena::new(),
|
||||
param_and_variable_counter: counter,
|
||||
}
|
||||
}
|
||||
|
||||
fn take(&self) -> Self {
|
||||
match self {
|
||||
Self::Opaque(x) => Self::Opaque(RefCell::new(x.take())),
|
||||
Self::Param(x) => Self::Param(Cell::new(x.get())),
|
||||
Self::Variable(x) => Self::Variable(Cell::new(x.get())),
|
||||
Self::Disallowed => Self::Disallowed,
|
||||
}
|
||||
}
|
||||
|
||||
fn swap(&self, impl_trait_mode: &Self) {
|
||||
match (self, impl_trait_mode) {
|
||||
(Self::Opaque(x), Self::Opaque(y)) => x.swap(y),
|
||||
(Self::Param(x), Self::Param(y)) => x.swap(y),
|
||||
(Self::Variable(x), Self::Variable(y)) => x.swap(y),
|
||||
(Self::Disallowed, Self::Disallowed) => (),
|
||||
_ => panic!("mismatched lowering mode"),
|
||||
fn variable(counter: u16) -> Self {
|
||||
Self {
|
||||
mode: ImplTraitLoweringMode::Variable,
|
||||
opaque_type_data: Arena::new(),
|
||||
param_and_variable_counter: counter,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -137,9 +122,9 @@ pub struct TyLoweringContext<'a> {
|
|||
/// possible currently, so this should be fine for now.
|
||||
pub type_param_mode: ParamLoweringMode,
|
||||
impl_trait_mode: ImplTraitLoweringState,
|
||||
expander: RefCell<Option<Expander>>,
|
||||
expander: Option<Expander>,
|
||||
/// Tracks types with explicit `?Sized` bounds.
|
||||
pub(crate) unsized_types: RefCell<FxHashSet<Ty>>,
|
||||
pub(crate) unsized_types: FxHashSet<Ty>,
|
||||
}
|
||||
|
||||
impl<'a> TyLoweringContext<'a> {
|
||||
|
@ -159,7 +144,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
types_source_map: Option<&'a TypesSourceMap>,
|
||||
owner: Option<TypeOwnerId>,
|
||||
) -> Self {
|
||||
let impl_trait_mode = ImplTraitLoweringState::Disallowed;
|
||||
let impl_trait_mode = ImplTraitLoweringState::new(ImplTraitLoweringMode::Disallowed);
|
||||
let type_param_mode = ParamLoweringMode::Placeholder;
|
||||
let in_binders = DebruijnIndex::INNERMOST;
|
||||
Self {
|
||||
|
@ -172,38 +157,26 @@ impl<'a> TyLoweringContext<'a> {
|
|||
in_binders,
|
||||
impl_trait_mode,
|
||||
type_param_mode,
|
||||
expander: RefCell::new(None),
|
||||
unsized_types: RefCell::default(),
|
||||
expander: None,
|
||||
unsized_types: FxHashSet::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_debruijn<T>(
|
||||
&self,
|
||||
&mut self,
|
||||
debruijn: DebruijnIndex,
|
||||
f: impl FnOnce(&TyLoweringContext<'_>) -> T,
|
||||
f: impl FnOnce(&mut TyLoweringContext<'_>) -> T,
|
||||
) -> T {
|
||||
let impl_trait_mode = self.impl_trait_mode.take();
|
||||
let expander = self.expander.take();
|
||||
let unsized_types = self.unsized_types.take();
|
||||
let new_ctx = Self {
|
||||
in_binders: debruijn,
|
||||
impl_trait_mode,
|
||||
expander: RefCell::new(expander),
|
||||
unsized_types: RefCell::new(unsized_types),
|
||||
generics: self.generics.clone(),
|
||||
..*self
|
||||
};
|
||||
let result = f(&new_ctx);
|
||||
self.impl_trait_mode.swap(&new_ctx.impl_trait_mode);
|
||||
self.expander.replace(new_ctx.expander.into_inner());
|
||||
self.unsized_types.replace(new_ctx.unsized_types.into_inner());
|
||||
let old_debruijn = mem::replace(&mut self.in_binders, debruijn);
|
||||
let result = f(self);
|
||||
self.in_binders = old_debruijn;
|
||||
result
|
||||
}
|
||||
|
||||
pub fn with_shifted_in<T>(
|
||||
&self,
|
||||
&mut self,
|
||||
debruijn: DebruijnIndex,
|
||||
f: impl FnOnce(&TyLoweringContext<'_>) -> T,
|
||||
f: impl FnOnce(&mut TyLoweringContext<'_>) -> T,
|
||||
) -> T {
|
||||
self.with_debruijn(self.in_binders.shifted_in_from(debruijn), f)
|
||||
}
|
||||
|
@ -227,7 +200,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub enum ImplTraitLoweringMode {
|
||||
/// `impl Trait` gets lowered into an opaque type that doesn't unify with
|
||||
/// anything except itself. This is used in places where values flow 'out',
|
||||
|
@ -244,6 +217,7 @@ pub enum ImplTraitLoweringMode {
|
|||
/// currently checking.
|
||||
Variable,
|
||||
/// `impl Trait` is disallowed and will be an error.
|
||||
#[default]
|
||||
Disallowed,
|
||||
}
|
||||
|
||||
|
@ -254,12 +228,13 @@ pub enum ParamLoweringMode {
|
|||
}
|
||||
|
||||
impl<'a> TyLoweringContext<'a> {
|
||||
pub fn lower_ty(&self, type_ref: TypeRefId) -> Ty {
|
||||
pub fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty {
|
||||
self.lower_ty_ext(type_ref).0
|
||||
}
|
||||
|
||||
pub fn lower_const(&self, const_ref: &ConstRef, const_type: Ty) -> Const {
|
||||
pub fn lower_const(&mut self, const_ref: &ConstRef, const_type: Ty) -> Const {
|
||||
let Some(owner) = self.owner else { return unknown_const(const_type) };
|
||||
let debruijn = self.in_binders;
|
||||
const_or_path_to_chalk(
|
||||
self.db,
|
||||
self.resolver,
|
||||
|
@ -268,7 +243,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
const_ref,
|
||||
self.type_param_mode,
|
||||
|| self.generics(),
|
||||
self.in_binders,
|
||||
debruijn,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -278,7 +253,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
.as_ref()
|
||||
}
|
||||
|
||||
pub fn lower_ty_ext(&self, type_ref_id: TypeRefId) -> (Ty, Option<TypeNs>) {
|
||||
pub fn lower_ty_ext(&mut 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 {
|
||||
|
@ -337,8 +312,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
|
||||
TypeRef::ImplTrait(bounds) => {
|
||||
match &self.impl_trait_mode {
|
||||
ImplTraitLoweringState::Opaque(opaque_type_data) => {
|
||||
match self.impl_trait_mode.mode {
|
||||
ImplTraitLoweringMode::Opaque => {
|
||||
let origin = match self.resolver.generic_def() {
|
||||
Some(GenericDefId::FunctionId(it)) => Either::Left(it),
|
||||
Some(GenericDefId::TypeAliasId(it)) => Either::Right(it),
|
||||
|
@ -350,7 +325,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
// this dance is to make sure the data is in the right
|
||||
// place even if we encounter more opaque types while
|
||||
// lowering the bounds
|
||||
let idx = opaque_type_data.borrow_mut().alloc(ImplTrait {
|
||||
let idx = self.impl_trait_mode.opaque_type_data.alloc(ImplTrait {
|
||||
bounds: crate::make_single_type_binders(Vec::default()),
|
||||
});
|
||||
// We don't want to lower the bounds inside the binders
|
||||
|
@ -366,7 +341,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
.with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
|
||||
ctx.lower_impl_trait(bounds, self.resolver.krate())
|
||||
});
|
||||
opaque_type_data.borrow_mut()[idx] = actual_opaque_type_data;
|
||||
self.impl_trait_mode.opaque_type_data[idx] = actual_opaque_type_data;
|
||||
|
||||
let impl_trait_id = origin.either(
|
||||
|f| ImplTraitId::ReturnTypeImplTrait(f, idx),
|
||||
|
@ -378,11 +353,13 @@ impl<'a> TyLoweringContext<'a> {
|
|||
let parameters = generics.bound_vars_subst(self.db, self.in_binders);
|
||||
TyKind::OpaqueType(opaque_ty_id, parameters).intern(Interner)
|
||||
}
|
||||
ImplTraitLoweringState::Param(counter) => {
|
||||
let idx = counter.get();
|
||||
ImplTraitLoweringMode::Param => {
|
||||
let idx = self.impl_trait_mode.param_and_variable_counter;
|
||||
// Count the number of `impl Trait` things that appear within our bounds.
|
||||
// Since those have been emitted as implicit type args already.
|
||||
counter.set(idx + self.count_impl_traits(type_ref_id) as u16);
|
||||
self.impl_trait_mode.param_and_variable_counter =
|
||||
idx + self.count_impl_traits(type_ref_id) as u16;
|
||||
let db = self.db;
|
||||
let kind = self
|
||||
.generics()
|
||||
.expect("param impl trait lowering must be in a generic def")
|
||||
|
@ -398,15 +375,17 @@ impl<'a> TyLoweringContext<'a> {
|
|||
})
|
||||
.nth(idx as usize)
|
||||
.map_or(TyKind::Error, |id| {
|
||||
TyKind::Placeholder(to_placeholder_idx(self.db, id.into()))
|
||||
TyKind::Placeholder(to_placeholder_idx(db, id.into()))
|
||||
});
|
||||
kind.intern(Interner)
|
||||
}
|
||||
ImplTraitLoweringState::Variable(counter) => {
|
||||
let idx = counter.get();
|
||||
ImplTraitLoweringMode::Variable => {
|
||||
let idx = self.impl_trait_mode.param_and_variable_counter;
|
||||
// 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 + self.count_impl_traits(type_ref_id) as u16);
|
||||
self.impl_trait_mode.param_and_variable_counter =
|
||||
idx + self.count_impl_traits(type_ref_id) as u16;
|
||||
let debruijn = self.in_binders;
|
||||
let kind = self
|
||||
.generics()
|
||||
.expect("variable impl trait lowering must be in a generic def")
|
||||
|
@ -423,33 +402,31 @@ impl<'a> TyLoweringContext<'a> {
|
|||
})
|
||||
.nth(idx as usize)
|
||||
.map_or(TyKind::Error, |id| {
|
||||
TyKind::BoundVar(BoundVar { debruijn: self.in_binders, index: id })
|
||||
TyKind::BoundVar(BoundVar { debruijn, index: id })
|
||||
});
|
||||
kind.intern(Interner)
|
||||
}
|
||||
ImplTraitLoweringState::Disallowed => {
|
||||
ImplTraitLoweringMode::Disallowed => {
|
||||
// FIXME: report error
|
||||
TyKind::Error.intern(Interner)
|
||||
}
|
||||
}
|
||||
}
|
||||
TypeRef::Macro(macro_call) => {
|
||||
let (mut expander, recursion_start) = {
|
||||
match RefMut::filter_map(self.expander.borrow_mut(), Option::as_mut) {
|
||||
let (expander, recursion_start) = {
|
||||
match &mut self.expander {
|
||||
// There already is an expander here, this means we are already recursing
|
||||
Ok(expander) => (expander, false),
|
||||
Some(expander) => (expander, false),
|
||||
// No expander was created yet, so we are at the start of the expansion recursion
|
||||
// and therefore have to create an expander.
|
||||
Err(expander) => (
|
||||
RefMut::map(expander, |it| {
|
||||
it.insert(Expander::new(
|
||||
None => {
|
||||
let expander = self.expander.insert(Expander::new(
|
||||
self.db.upcast(),
|
||||
macro_call.file_id,
|
||||
self.resolver.module(),
|
||||
))
|
||||
}),
|
||||
true,
|
||||
),
|
||||
));
|
||||
(expander, true)
|
||||
}
|
||||
}
|
||||
};
|
||||
let ty = {
|
||||
|
@ -473,11 +450,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
// FIXME: Report syntax errors in expansion here
|
||||
let type_ref = TypeRef::from_ast(&mut ctx, expanded.tree());
|
||||
|
||||
drop(expander);
|
||||
|
||||
// FIXME: That may be better served by mutating `self` then restoring, but this requires
|
||||
// making it `&mut self`.
|
||||
let inner_ctx = TyLoweringContext {
|
||||
// Can't mutate `self`, must create a new instance, because of the lifetimes.
|
||||
let mut inner_ctx = TyLoweringContext {
|
||||
db: self.db,
|
||||
resolver: self.resolver,
|
||||
generics: self.generics.clone(),
|
||||
|
@ -486,30 +460,27 @@ impl<'a> TyLoweringContext<'a> {
|
|||
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()),
|
||||
impl_trait_mode: mem::take(&mut self.impl_trait_mode),
|
||||
expander: self.expander.take(),
|
||||
unsized_types: mem::take(&mut self.unsized_types),
|
||||
};
|
||||
|
||||
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.impl_trait_mode = inner_ctx.impl_trait_mode;
|
||||
self.expander = inner_ctx.expander;
|
||||
self.unsized_types = inner_ctx.unsized_types;
|
||||
|
||||
self.expander.borrow_mut().as_mut().unwrap().exit(mark);
|
||||
self.expander.as_mut().unwrap().exit(mark);
|
||||
Some(ty)
|
||||
}
|
||||
_ => {
|
||||
drop(expander);
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
|
||||
// drop the expander, resetting it to pre-recursion state
|
||||
if recursion_start {
|
||||
*self.expander.borrow_mut() = None;
|
||||
self.expander = None;
|
||||
}
|
||||
ty.unwrap_or_else(|| TyKind::Error.intern(Interner))
|
||||
}
|
||||
|
@ -544,7 +515,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
|
||||
pub(crate) fn lower_ty_relative_path(
|
||||
&self,
|
||||
&mut self,
|
||||
ty: Ty,
|
||||
// We need the original resolution to lower `Self::AssocTy` correctly
|
||||
res: Option<TypeNs>,
|
||||
|
@ -565,7 +536,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
|
||||
pub(crate) fn lower_partly_resolved_path(
|
||||
&self,
|
||||
&mut self,
|
||||
resolution: TypeNs,
|
||||
resolved_segment: PathSegment<'_>,
|
||||
remaining_segments: PathSegments<'_>,
|
||||
|
@ -706,7 +677,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
|
||||
}
|
||||
|
||||
pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
|
||||
pub(crate) fn lower_path(&mut self, path: &Path) -> (Ty, Option<TypeNs>) {
|
||||
// Resolve the path (in type namespace)
|
||||
if let Some(type_ref) = path.type_anchor() {
|
||||
let (ty, res) = self.lower_ty_ext(type_ref);
|
||||
|
@ -736,7 +707,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
|
||||
}
|
||||
|
||||
fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
|
||||
fn select_associated_type(&mut self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
|
||||
let Some((generics, res)) = self.generics().zip(res) else {
|
||||
return TyKind::Error.intern(Interner);
|
||||
};
|
||||
|
@ -746,6 +717,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
res,
|
||||
Some(segment.name.clone()),
|
||||
move |name, t, associated_ty| {
|
||||
let generics = self.generics().unwrap();
|
||||
|
||||
if name != segment.name {
|
||||
return None;
|
||||
}
|
||||
|
@ -797,7 +770,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
|
||||
fn lower_path_inner(
|
||||
&self,
|
||||
&mut self,
|
||||
segment: PathSegment<'_>,
|
||||
typeable: TyDefId,
|
||||
infer_args: bool,
|
||||
|
@ -814,7 +787,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
/// Collect generic arguments from a path into a `Substs`. See also
|
||||
/// `create_substs_for_ast_path` and `def_to_ty` in rustc.
|
||||
pub(super) fn substs_from_path(
|
||||
&self,
|
||||
&mut self,
|
||||
path: &Path,
|
||||
// Note that we don't call `db.value_type(resolved)` here,
|
||||
// `ValueTyDefId` is just a convenient way to pass generics and
|
||||
|
@ -855,7 +828,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
|
||||
pub(super) fn substs_from_path_segment(
|
||||
&self,
|
||||
&mut self,
|
||||
segment: PathSegment<'_>,
|
||||
def: Option<GenericDefId>,
|
||||
infer_args: bool,
|
||||
|
@ -870,7 +843,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
|
||||
fn substs_from_args_and_bindings(
|
||||
&self,
|
||||
&mut self,
|
||||
args_and_bindings: Option<&GenericArgs>,
|
||||
def: Option<GenericDefId>,
|
||||
infer_args: bool,
|
||||
|
@ -959,11 +932,11 @@ impl<'a> TyLoweringContext<'a> {
|
|||
self.db,
|
||||
id,
|
||||
arg,
|
||||
&mut (),
|
||||
self,
|
||||
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),
|
||||
|this, type_ref| this.lower_ty(type_ref),
|
||||
|this, const_ref, ty| this.lower_const(const_ref, ty),
|
||||
|this, lifetime_ref| this.lower_lifetime(lifetime_ref),
|
||||
);
|
||||
substs.push(arg);
|
||||
}
|
||||
|
@ -1016,7 +989,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
|
||||
pub(crate) fn lower_trait_ref_from_resolved_path(
|
||||
&self,
|
||||
&mut self,
|
||||
resolved: TraitId,
|
||||
segment: PathSegment<'_>,
|
||||
explicit_self_ty: Ty,
|
||||
|
@ -1025,7 +998,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
|
||||
}
|
||||
|
||||
fn lower_trait_ref_from_path(&self, path: &Path, explicit_self_ty: Ty) -> Option<TraitRef> {
|
||||
fn lower_trait_ref_from_path(&mut self, path: &Path, explicit_self_ty: Ty) -> Option<TraitRef> {
|
||||
let resolved = match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path)? {
|
||||
// FIXME(trait_alias): We need to handle trait alias here.
|
||||
TypeNs::TraitId(tr) => tr,
|
||||
|
@ -1035,12 +1008,16 @@ impl<'a> TyLoweringContext<'a> {
|
|||
Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
|
||||
}
|
||||
|
||||
fn lower_trait_ref(&self, trait_ref: &HirTraitRef, explicit_self_ty: Ty) -> Option<TraitRef> {
|
||||
fn lower_trait_ref(
|
||||
&mut self,
|
||||
trait_ref: &HirTraitRef,
|
||||
explicit_self_ty: Ty,
|
||||
) -> Option<TraitRef> {
|
||||
self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
|
||||
}
|
||||
|
||||
fn trait_ref_substs_from_path(
|
||||
&self,
|
||||
&mut self,
|
||||
segment: PathSegment<'_>,
|
||||
resolved: TraitId,
|
||||
explicit_self_ty: Ty,
|
||||
|
@ -1049,11 +1026,11 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
|
||||
pub(crate) fn lower_where_predicate<'b>(
|
||||
&'b self,
|
||||
&'b mut self,
|
||||
where_predicate: &'b WherePredicate,
|
||||
&def: &GenericDefId,
|
||||
ignore_bindings: bool,
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + 'b {
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + use<'a, 'b> {
|
||||
match where_predicate {
|
||||
WherePredicate::ForLifetime { target, bound, .. }
|
||||
| WherePredicate::TypeBound { target, bound } => {
|
||||
|
@ -1087,12 +1064,12 @@ impl<'a> TyLoweringContext<'a> {
|
|||
.into_iter()
|
||||
}
|
||||
|
||||
pub(crate) fn lower_type_bound(
|
||||
&'a self,
|
||||
bound: &'a TypeBound,
|
||||
pub(crate) fn lower_type_bound<'b>(
|
||||
&'b mut self,
|
||||
bound: &'b TypeBound,
|
||||
self_ty: Ty,
|
||||
ignore_bindings: bool,
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + use<'b, 'a> {
|
||||
let mut trait_ref = None;
|
||||
let clause = match bound {
|
||||
TypeBound::Path(path, TraitBoundModifier::None) => {
|
||||
|
@ -1111,7 +1088,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
.lower_trait_ref_from_path(path, self_ty.clone())
|
||||
.map(|trait_ref| trait_ref.hir_trait_id());
|
||||
if trait_id == sized_trait {
|
||||
self.unsized_types.borrow_mut().insert(self_ty);
|
||||
self.unsized_types.insert(self_ty);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -1131,17 +1108,18 @@ impl<'a> TyLoweringContext<'a> {
|
|||
};
|
||||
clause.into_iter().chain(
|
||||
trait_ref
|
||||
.into_iter()
|
||||
.filter(move |_| !ignore_bindings)
|
||||
.flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
|
||||
.map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr))
|
||||
.into_iter()
|
||||
.flatten(),
|
||||
)
|
||||
}
|
||||
|
||||
fn assoc_type_bindings_from_type_bound(
|
||||
&'a self,
|
||||
bound: &'a TypeBound,
|
||||
fn assoc_type_bindings_from_type_bound<'b>(
|
||||
&'b mut self,
|
||||
bound: &'b TypeBound,
|
||||
trait_ref: TraitRef,
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + 'a {
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + use<'b, 'a> {
|
||||
let last_segment = match bound {
|
||||
TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
|
||||
path.segments().last()
|
||||
|
@ -1192,22 +1170,16 @@ impl<'a> TyLoweringContext<'a> {
|
|||
binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
|
||||
);
|
||||
if let Some(type_ref) = binding.type_ref {
|
||||
match (&self.types_map[type_ref], &self.impl_trait_mode) {
|
||||
(TypeRef::ImplTrait(_), ImplTraitLoweringState::Disallowed) => (),
|
||||
(
|
||||
_,
|
||||
ImplTraitLoweringState::Disallowed | ImplTraitLoweringState::Opaque(_),
|
||||
) => {
|
||||
match (&self.types_map[type_ref], self.impl_trait_mode.mode) {
|
||||
(TypeRef::ImplTrait(_), ImplTraitLoweringMode::Disallowed) => (),
|
||||
(_, ImplTraitLoweringMode::Disallowed | ImplTraitLoweringMode::Opaque) => {
|
||||
let ty = self.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)));
|
||||
}
|
||||
(
|
||||
_,
|
||||
ImplTraitLoweringState::Param(_) | ImplTraitLoweringState::Variable(_),
|
||||
) => {
|
||||
(_, ImplTraitLoweringMode::Param | ImplTraitLoweringMode::Variable) => {
|
||||
// Find the generic index for the target of our `bound`
|
||||
let target_param_idx = self
|
||||
.resolver
|
||||
|
@ -1244,14 +1216,14 @@ impl<'a> TyLoweringContext<'a> {
|
|||
self.owner,
|
||||
)
|
||||
.with_type_param_mode(self.type_param_mode);
|
||||
match &self.impl_trait_mode {
|
||||
ImplTraitLoweringState::Param(_) => {
|
||||
match self.impl_trait_mode.mode {
|
||||
ImplTraitLoweringMode::Param => {
|
||||
ext.impl_trait_mode =
|
||||
ImplTraitLoweringState::Param(Cell::new(counter));
|
||||
ImplTraitLoweringState::param(counter);
|
||||
}
|
||||
ImplTraitLoweringState::Variable(_) => {
|
||||
ImplTraitLoweringMode::Variable => {
|
||||
ext.impl_trait_mode =
|
||||
ImplTraitLoweringState::Variable(Cell::new(counter));
|
||||
ImplTraitLoweringState::variable(counter);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -1278,7 +1250,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
fn lower_dyn_trait(&self, bounds: &[TypeBound]) -> Ty {
|
||||
fn lower_dyn_trait(&mut 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
|
||||
|
@ -1287,22 +1259,26 @@ impl<'a> TyLoweringContext<'a> {
|
|||
// These invariants are utilized by `TyExt::dyn_trait()` and chalk.
|
||||
let mut lifetime = None;
|
||||
let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||
let mut bounds: Vec<_> = bounds
|
||||
.iter()
|
||||
.flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
|
||||
.filter(|b| match b.skip_binders() {
|
||||
let mut lowered_bounds = Vec::new();
|
||||
for b in bounds {
|
||||
ctx.lower_type_bound(b, self_ty.clone(), false).for_each(|b| {
|
||||
let filter = match b.skip_binders() {
|
||||
WhereClause::Implemented(_) | WhereClause::AliasEq(_) => true,
|
||||
WhereClause::LifetimeOutlives(_) => false,
|
||||
WhereClause::TypeOutlives(t) => {
|
||||
lifetime = Some(t.lifetime.clone());
|
||||
false
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
};
|
||||
if filter {
|
||||
lowered_bounds.push(b);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let mut multiple_regular_traits = false;
|
||||
let mut multiple_same_projection = false;
|
||||
bounds.sort_unstable_by(|lhs, rhs| {
|
||||
lowered_bounds.sort_unstable_by(|lhs, rhs| {
|
||||
use std::cmp::Ordering;
|
||||
match (lhs.skip_binders(), rhs.skip_binders()) {
|
||||
(WhereClause::Implemented(lhs), WhereClause::Implemented(rhs)) => {
|
||||
|
@ -1344,13 +1320,13 @@ impl<'a> TyLoweringContext<'a> {
|
|||
return None;
|
||||
}
|
||||
|
||||
bounds.first().and_then(|b| b.trait_id())?;
|
||||
lowered_bounds.first().and_then(|b| b.trait_id())?;
|
||||
|
||||
// As multiple occurrences of the same auto traits *are* permitted, we deduplicate the
|
||||
// bounds. We shouldn't have repeated elements besides auto traits at this point.
|
||||
bounds.dedup();
|
||||
lowered_bounds.dedup();
|
||||
|
||||
Some(QuantifiedWhereClauses::from_iter(Interner, bounds))
|
||||
Some(QuantifiedWhereClauses::from_iter(Interner, lowered_bounds))
|
||||
});
|
||||
|
||||
if let Some(bounds) = bounds {
|
||||
|
@ -1376,16 +1352,16 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn lower_impl_trait(&self, bounds: &[TypeBound], krate: CrateId) -> ImplTrait {
|
||||
fn lower_impl_trait(&mut 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| {
|
||||
let mut predicates: Vec<_> = bounds
|
||||
.iter()
|
||||
.flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
|
||||
.collect();
|
||||
let mut predicates = Vec::new();
|
||||
for b in bounds {
|
||||
predicates.extend(ctx.lower_type_bound(b, self_ty.clone(), false));
|
||||
}
|
||||
|
||||
if !ctx.unsized_types.borrow().contains(&self_ty) {
|
||||
if !ctx.unsized_types.contains(&self_ty) {
|
||||
let sized_trait = ctx
|
||||
.db
|
||||
.lang_item(krate, LangItem::Sized)
|
||||
|
@ -1562,7 +1538,7 @@ pub(crate) fn field_types_query(
|
|||
};
|
||||
let generics = generics(db.upcast(), def);
|
||||
let mut res = ArenaMap::default();
|
||||
let ctx = TyLoweringContext::new(db, &resolver, var_data.types_map(), def.into())
|
||||
let mut 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)));
|
||||
|
@ -1596,7 +1572,7 @@ pub(crate) fn generic_predicates_for_param_query(
|
|||
let generics = generics(db.upcast(), def);
|
||||
|
||||
// we have to filter out all other predicates *first*, before attempting to lower them
|
||||
let predicate = |pred: &_, def: &_, ctx: &TyLoweringContext<'_>| match pred {
|
||||
let predicate = |pred: &_, def: &_, ctx: &mut TyLoweringContext<'_>| match pred {
|
||||
WherePredicate::ForLifetime { target, bound, .. }
|
||||
| WherePredicate::TypeBound { target, bound, .. } => {
|
||||
let invalid_target = match target {
|
||||
|
@ -1642,16 +1618,19 @@ pub(crate) fn generic_predicates_for_param_query(
|
|||
let mut predicates = Vec::new();
|
||||
for (params, def) in resolver.all_generic_params() {
|
||||
ctx.types_map = ¶ms.types_map;
|
||||
for pred in params.where_predicates() {
|
||||
if predicate(pred, def, &mut ctx) {
|
||||
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))
|
||||
}),
|
||||
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) {
|
||||
let explicitly_unsized_tys = ctx.unsized_types.into_inner();
|
||||
let explicitly_unsized_tys = ctx.unsized_types;
|
||||
if let Some(implicitly_sized_predicates) = implicitly_sized_clauses(
|
||||
db,
|
||||
param_id.parent,
|
||||
|
@ -1731,7 +1710,7 @@ pub(crate) fn trait_environment_query(
|
|||
|
||||
let subst = generics(db.upcast(), def).placeholder_subst(db);
|
||||
if !subst.is_empty(Interner) {
|
||||
let explicitly_unsized_tys = ctx.unsized_types.into_inner();
|
||||
let explicitly_unsized_tys = ctx.unsized_types;
|
||||
if let Some(implicitly_sized_clauses) =
|
||||
implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
|
||||
{
|
||||
|
@ -1801,16 +1780,19 @@ where
|
|||
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))
|
||||
},
|
||||
));
|
||||
for pred in params.where_predicates() {
|
||||
if filter(pred, def) {
|
||||
predicates.extend(
|
||||
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);
|
||||
let explicitly_unsized_tys = ctx.unsized_types.into_inner();
|
||||
let explicitly_unsized_tys = ctx.unsized_types;
|
||||
if let Some(implicitly_sized_predicates) =
|
||||
implicitly_sized_clauses(db, def, &explicitly_unsized_tys, &subst, &resolver)
|
||||
{
|
||||
|
@ -1906,7 +1888,8 @@ 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 param_ty = ctx.lower_ty(p.ty);
|
||||
let c = ctx.lower_const(c, param_ty);
|
||||
c.cast(Interner)
|
||||
},
|
||||
);
|
||||
|
@ -1946,11 +1929,11 @@ 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, &data.types_map, def.into())
|
||||
let mut 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, &data.types_map, def.into())
|
||||
let mut 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);
|
||||
|
@ -1982,7 +1965,7 @@ 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, &data.types_map, def.into())
|
||||
let mut 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))
|
||||
|
@ -1992,7 +1975,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
|
|||
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, &data.types_map, def.into());
|
||||
let mut ctx = TyLoweringContext::new(db, &resolver, &data.types_map, def.into());
|
||||
|
||||
Binders::empty(Interner, ctx.lower_ty(data.type_ref))
|
||||
}
|
||||
|
@ -2001,7 +1984,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
|
|||
let struct_data = db.struct_data(def);
|
||||
let fields = struct_data.variant_data.fields();
|
||||
let resolver = def.resolver(db.upcast());
|
||||
let ctx = TyLoweringContext::new(
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
struct_data.variant_data.types_map(),
|
||||
|
@ -2038,7 +2021,7 @@ 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(
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
var_data.variant_data.types_map(),
|
||||
|
@ -2087,7 +2070,7 @@ 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 type_alias_data = db.type_alias_data(t);
|
||||
let ctx = TyLoweringContext::new(db, &resolver, &type_alias_data.types_map, t.into())
|
||||
let mut 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 inner = if type_alias_data.is_extern {
|
||||
|
@ -2169,7 +2152,7 @@ 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_data.types_map, impl_id.into())
|
||||
let mut 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))
|
||||
}
|
||||
|
@ -2179,7 +2162,8 @@ 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, &parent_data.types_map, def.parent().into());
|
||||
let mut ctx =
|
||||
TyLoweringContext::new(db, &resolver, &parent_data.types_map, def.parent().into());
|
||||
match data {
|
||||
TypeOrConstParamData::TypeParamData(_) => {
|
||||
never!();
|
||||
|
@ -2201,7 +2185,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_data.types_map, impl_id.into())
|
||||
let mut 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()?;
|
||||
|
@ -2215,17 +2199,13 @@ 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, &data.types_map, def.into())
|
||||
let mut 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 generics = generics(db.upcast(), def.into());
|
||||
let return_type_impl_traits = ImplTraits {
|
||||
impl_traits: match ctx_ret.impl_trait_mode {
|
||||
ImplTraitLoweringState::Opaque(x) => x.into_inner(),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
};
|
||||
let return_type_impl_traits =
|
||||
ImplTraits { impl_traits: ctx_ret.impl_trait_mode.opaque_type_data };
|
||||
if return_type_impl_traits.impl_traits.is_empty() {
|
||||
None
|
||||
} else {
|
||||
|
@ -2239,18 +2219,13 @@ 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, &data.types_map, def.into())
|
||||
let mut 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 {
|
||||
let _ty = ctx.lower_ty(type_ref);
|
||||
}
|
||||
let type_alias_impl_traits = ImplTraits {
|
||||
impl_traits: match ctx.impl_trait_mode {
|
||||
ImplTraitLoweringState::Opaque(x) => x.into_inner(),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
};
|
||||
let type_alias_impl_traits = ImplTraits { impl_traits: ctx.impl_trait_mode.opaque_type_data };
|
||||
if type_alias_impl_traits.impl_traits.is_empty() {
|
||||
None
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue