mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 21:25:25 +00:00 
			
		
		
		
	Switch TraitRef in hir::TraitRef to next solver
This commit is contained in:
		
							parent
							
								
									7f0ec8b69f
								
							
						
					
					
						commit
						e979349978
					
				
					 4 changed files with 288 additions and 41 deletions
				
			
		| 
						 | 
				
			
			@ -11,8 +11,8 @@ use base_db::Crate;
 | 
			
		|||
use chalk_ir::{BoundVar, Safety, TyKind};
 | 
			
		||||
use either::Either;
 | 
			
		||||
use hir_def::{
 | 
			
		||||
    GenericDefId, HasModule, ImportPathConfig, LocalFieldId, Lookup, ModuleDefId, ModuleId,
 | 
			
		||||
    TraitId,
 | 
			
		||||
    GeneralConstId, GenericDefId, HasModule, ImportPathConfig, LocalFieldId, Lookup, ModuleDefId,
 | 
			
		||||
    ModuleId, TraitId,
 | 
			
		||||
    db::DefDatabase,
 | 
			
		||||
    expr_store::{ExpressionStore, path::Path},
 | 
			
		||||
    find_path::{self, PrefixKind},
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ use rustc_apfloat::{
 | 
			
		|||
};
 | 
			
		||||
use rustc_hash::FxHashSet;
 | 
			
		||||
use rustc_type_ir::{
 | 
			
		||||
    AliasTyKind,
 | 
			
		||||
    AliasTyKind, RegionKind,
 | 
			
		||||
    inherent::{AdtDef, IntoKind, SliceLike},
 | 
			
		||||
};
 | 
			
		||||
use smallvec::SmallVec;
 | 
			
		||||
| 
						 | 
				
			
			@ -61,8 +61,9 @@ use crate::{
 | 
			
		|||
    next_solver::{
 | 
			
		||||
        BoundExistentialPredicate, Ctor, DbInterner, GenericArgs, SolverDefId,
 | 
			
		||||
        mapping::{
 | 
			
		||||
            ChalkToNextSolver, convert_args_for_result, convert_const_for_result,
 | 
			
		||||
            convert_region_for_result, convert_ty_for_result,
 | 
			
		||||
            ChalkToNextSolver, bound_var_to_lifetime_idx, bound_var_to_type_or_const_param_idx,
 | 
			
		||||
            convert_args_for_result, convert_const_for_result, convert_region_for_result,
 | 
			
		||||
            convert_ty_for_result,
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    primitive, to_assoc_type_id,
 | 
			
		||||
| 
						 | 
				
			
			@ -715,28 +716,56 @@ impl HirDisplay for GenericArg {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'db> HirDisplay for crate::next_solver::GenericArg<'db> {
 | 
			
		||||
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
 | 
			
		||||
        match self.kind() {
 | 
			
		||||
            rustc_type_ir::GenericArgKind::Type(ty) => ty.hir_fmt(f),
 | 
			
		||||
            rustc_type_ir::GenericArgKind::Lifetime(lt) => lt.hir_fmt(f),
 | 
			
		||||
            rustc_type_ir::GenericArgKind::Const(c) => c.hir_fmt(f),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl HirDisplay for Const {
 | 
			
		||||
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
 | 
			
		||||
        let data = self.interned();
 | 
			
		||||
        match &data.value {
 | 
			
		||||
            ConstValue::BoundVar(idx) => idx.hir_fmt(f),
 | 
			
		||||
            ConstValue::InferenceVar(..) => write!(f, "#c#"),
 | 
			
		||||
            ConstValue::Placeholder(idx) => {
 | 
			
		||||
                let id = from_placeholder_idx(f.db, *idx);
 | 
			
		||||
        let c = self.to_nextsolver(DbInterner::new_with(f.db, None, None));
 | 
			
		||||
        c.hir_fmt(f)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'db> HirDisplay for crate::next_solver::Const<'db> {
 | 
			
		||||
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
 | 
			
		||||
        match self.kind() {
 | 
			
		||||
            rustc_type_ir::ConstKind::Bound(db, bound_const) => {
 | 
			
		||||
                write!(f, "?{}.{}", db.as_u32(), bound_const.as_u32())
 | 
			
		||||
            }
 | 
			
		||||
            rustc_type_ir::ConstKind::Infer(..) => write!(f, "#c#"),
 | 
			
		||||
            rustc_type_ir::ConstKind::Placeholder(idx) => {
 | 
			
		||||
                let id = bound_var_to_type_or_const_param_idx(f.db, idx.bound);
 | 
			
		||||
                let generics = generics(f.db, id.parent);
 | 
			
		||||
                let param_data = &generics[id.local_id];
 | 
			
		||||
                write!(f, "{}", param_data.name().unwrap().display(f.db, f.edition()))?;
 | 
			
		||||
                Ok(())
 | 
			
		||||
            }
 | 
			
		||||
            ConstValue::Concrete(c) => match &c.interned {
 | 
			
		||||
                ConstScalar::Bytes(b, m) => render_const_scalar(f, b, m, &data.ty),
 | 
			
		||||
                ConstScalar::UnevaluatedConst(c, parameters) => {
 | 
			
		||||
                    write!(f, "{}", c.name(f.db))?;
 | 
			
		||||
                    hir_fmt_generics(f, parameters.as_slice(Interner), c.generic_def(f.db), None)?;
 | 
			
		||||
                    Ok(())
 | 
			
		||||
                }
 | 
			
		||||
                ConstScalar::Unknown => f.write_char('_'),
 | 
			
		||||
            },
 | 
			
		||||
            rustc_type_ir::ConstKind::Value(const_bytes) => render_const_scalar_ns(
 | 
			
		||||
                f,
 | 
			
		||||
                &const_bytes.value.inner().0,
 | 
			
		||||
                &const_bytes.value.inner().1,
 | 
			
		||||
                const_bytes.ty,
 | 
			
		||||
            ),
 | 
			
		||||
            rustc_type_ir::ConstKind::Unevaluated(unev) => {
 | 
			
		||||
                let c = match unev.def {
 | 
			
		||||
                    SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
 | 
			
		||||
                    SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
 | 
			
		||||
                    _ => unreachable!(),
 | 
			
		||||
                };
 | 
			
		||||
                write!(f, "{}", c.name(f.db))?;
 | 
			
		||||
                hir_fmt_generics_ns(f, unev.args.as_slice(), c.generic_def(f.db), None)?;
 | 
			
		||||
                Ok(())
 | 
			
		||||
            }
 | 
			
		||||
            rustc_type_ir::ConstKind::Error(..) => f.write_char('_'),
 | 
			
		||||
            rustc_type_ir::ConstKind::Expr(..) => write!(f, "<const-expr>"),
 | 
			
		||||
            rustc_type_ir::ConstKind::Param(_) => write!(f, "<param>"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1748,6 +1777,27 @@ fn hir_fmt_generics(
 | 
			
		|||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn hir_fmt_generics_ns<'db>(
 | 
			
		||||
    f: &mut HirFormatter<'_>,
 | 
			
		||||
    parameters: &[crate::next_solver::GenericArg<'db>],
 | 
			
		||||
    generic_def: Option<hir_def::GenericDefId>,
 | 
			
		||||
    self_: Option<crate::next_solver::Ty<'db>>,
 | 
			
		||||
) -> Result<(), HirDisplayError> {
 | 
			
		||||
    if parameters.is_empty() {
 | 
			
		||||
        return Ok(());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let parameters_to_write = generic_args_sans_defaults_ns(f, generic_def, parameters);
 | 
			
		||||
 | 
			
		||||
    if !parameters_to_write.is_empty() {
 | 
			
		||||
        write!(f, "<")?;
 | 
			
		||||
        hir_fmt_generic_arguments_ns(f, parameters_to_write, self_)?;
 | 
			
		||||
        write!(f, ">")?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn generic_args_sans_defaults<'ga>(
 | 
			
		||||
    f: &mut HirFormatter<'_>,
 | 
			
		||||
    generic_def: Option<hir_def::GenericDefId>,
 | 
			
		||||
| 
						 | 
				
			
			@ -1803,6 +1853,87 @@ fn generic_args_sans_defaults<'ga>(
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn hir_fmt_generic_args<'db>(
 | 
			
		||||
    f: &mut HirFormatter<'_>,
 | 
			
		||||
    parameters: &[crate::next_solver::GenericArg<'db>],
 | 
			
		||||
    generic_def: Option<hir_def::GenericDefId>,
 | 
			
		||||
    self_: Option<crate::next_solver::Ty<'db>>,
 | 
			
		||||
) -> Result<(), HirDisplayError> {
 | 
			
		||||
    if parameters.is_empty() {
 | 
			
		||||
        return Ok(());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let parameters_to_write = generic_args_sans_defaults_ns(f, generic_def, parameters);
 | 
			
		||||
 | 
			
		||||
    if !parameters_to_write.is_empty() {
 | 
			
		||||
        write!(f, "<")?;
 | 
			
		||||
        hir_fmt_generic_arguments_ns(f, parameters_to_write, self_)?;
 | 
			
		||||
        write!(f, ">")?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn generic_args_sans_defaults_ns<'ga, 'db>(
 | 
			
		||||
    f: &mut HirFormatter<'_>,
 | 
			
		||||
    generic_def: Option<hir_def::GenericDefId>,
 | 
			
		||||
    parameters: &'ga [crate::next_solver::GenericArg<'db>],
 | 
			
		||||
) -> &'ga [crate::next_solver::GenericArg<'db>] {
 | 
			
		||||
    let interner = DbInterner::new_with(f.db, Some(f.krate()), None);
 | 
			
		||||
    if f.display_kind.is_source_code() || f.omit_verbose_types() {
 | 
			
		||||
        match generic_def
 | 
			
		||||
            .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
 | 
			
		||||
            .filter(|it| !it.is_empty())
 | 
			
		||||
        {
 | 
			
		||||
            None => parameters,
 | 
			
		||||
            Some(default_parameters) => {
 | 
			
		||||
                let should_show = |arg: &crate::next_solver::GenericArg<'db>, i: usize| {
 | 
			
		||||
                    let is_err = |arg: &crate::next_solver::GenericArg<'db>| match arg.kind() {
 | 
			
		||||
                        rustc_type_ir::GenericArgKind::Lifetime(it) => {
 | 
			
		||||
                            matches!(it.kind(), RegionKind::ReError(..))
 | 
			
		||||
                        }
 | 
			
		||||
                        rustc_type_ir::GenericArgKind::Type(it) => {
 | 
			
		||||
                            matches!(it.kind(), rustc_type_ir::TyKind::Error(..))
 | 
			
		||||
                        }
 | 
			
		||||
                        rustc_type_ir::GenericArgKind::Const(it) => {
 | 
			
		||||
                            matches!(it.kind(), rustc_type_ir::ConstKind::Error(..),)
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                    // if the arg is error like, render it to inform the user
 | 
			
		||||
                    if is_err(arg) {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    // otherwise, if the arg is equal to the param default, hide it (unless the
 | 
			
		||||
                    // default is an error which can happen for the trait Self type)
 | 
			
		||||
                    match default_parameters.get(i) {
 | 
			
		||||
                        None => true,
 | 
			
		||||
                        Some(default_parameter) => {
 | 
			
		||||
                            // !is_err(default_parameter.skip_binders())
 | 
			
		||||
                            // &&
 | 
			
		||||
                            arg != &default_parameter
 | 
			
		||||
                                .clone()
 | 
			
		||||
                                .substitute(
 | 
			
		||||
                                    Interner,
 | 
			
		||||
                                    &convert_args_for_result(interner, ¶meters[..i]),
 | 
			
		||||
                                )
 | 
			
		||||
                                .to_nextsolver(interner)
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
                let mut default_from = 0;
 | 
			
		||||
                for (i, parameter) in parameters.iter().enumerate() {
 | 
			
		||||
                    if should_show(parameter, i) {
 | 
			
		||||
                        default_from = i + 1;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                ¶meters[0..default_from]
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        parameters
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn hir_fmt_generic_arguments(
 | 
			
		||||
    f: &mut HirFormatter<'_>,
 | 
			
		||||
    parameters: &[GenericArg],
 | 
			
		||||
| 
						 | 
				
			
			@ -1827,6 +1958,30 @@ fn hir_fmt_generic_arguments(
 | 
			
		|||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn hir_fmt_generic_arguments_ns<'db>(
 | 
			
		||||
    f: &mut HirFormatter<'_>,
 | 
			
		||||
    parameters: &[crate::next_solver::GenericArg<'db>],
 | 
			
		||||
    self_: Option<crate::next_solver::Ty<'db>>,
 | 
			
		||||
) -> Result<(), HirDisplayError> {
 | 
			
		||||
    let mut first = true;
 | 
			
		||||
    let lifetime_offset = parameters.iter().position(|arg| arg.region().is_some());
 | 
			
		||||
 | 
			
		||||
    let (ty_or_const, lifetimes) = match lifetime_offset {
 | 
			
		||||
        Some(offset) => parameters.split_at(offset),
 | 
			
		||||
        None => (parameters, &[][..]),
 | 
			
		||||
    };
 | 
			
		||||
    for generic_arg in lifetimes.iter().chain(ty_or_const) {
 | 
			
		||||
        if !mem::take(&mut first) {
 | 
			
		||||
            write!(f, ", ")?;
 | 
			
		||||
        }
 | 
			
		||||
        match self_ {
 | 
			
		||||
            self_ @ Some(_) if generic_arg.ty() == self_ => write!(f, "Self")?,
 | 
			
		||||
            _ => generic_arg.hir_fmt(f)?,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl HirDisplay for CallableSig {
 | 
			
		||||
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
 | 
			
		||||
        let CallableSig { params_and_return: _, is_varargs, safety, abi: _ } = *self;
 | 
			
		||||
| 
						 | 
				
			
			@ -2067,6 +2222,20 @@ impl HirDisplay for TraitRef {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'db> HirDisplay for crate::next_solver::TraitRef<'db> {
 | 
			
		||||
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
 | 
			
		||||
        let trait_ = match self.def_id {
 | 
			
		||||
            SolverDefId::TraitId(id) => id,
 | 
			
		||||
            _ => unreachable!(),
 | 
			
		||||
        };
 | 
			
		||||
        f.start_location_link(trait_.into());
 | 
			
		||||
        write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?;
 | 
			
		||||
        f.end_location_link();
 | 
			
		||||
        let substs = self.args.as_slice();
 | 
			
		||||
        hir_fmt_generic_args(f, &substs[1..], None, substs[0].ty())
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl HirDisplay for WhereClause {
 | 
			
		||||
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
 | 
			
		||||
        if f.should_truncate() {
 | 
			
		||||
| 
						 | 
				
			
			@ -2147,6 +2316,35 @@ impl HirDisplay for LifetimeData {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'db> HirDisplay for crate::next_solver::Region<'db> {
 | 
			
		||||
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
 | 
			
		||||
        match self.kind() {
 | 
			
		||||
            rustc_type_ir::RegionKind::RePlaceholder(idx) => {
 | 
			
		||||
                let id = bound_var_to_lifetime_idx(f.db, idx.bound.var);
 | 
			
		||||
                let generics = generics(f.db, id.parent);
 | 
			
		||||
                let param_data = &generics[id.local_id];
 | 
			
		||||
                write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
 | 
			
		||||
                Ok(())
 | 
			
		||||
            }
 | 
			
		||||
            rustc_type_ir::RegionKind::ReBound(db, idx) => {
 | 
			
		||||
                write!(f, "?{}.{}", db.as_u32(), idx.var.as_u32())
 | 
			
		||||
            }
 | 
			
		||||
            rustc_type_ir::RegionKind::ReVar(_) => write!(f, "_"),
 | 
			
		||||
            rustc_type_ir::RegionKind::ReStatic => write!(f, "'static"),
 | 
			
		||||
            rustc_type_ir::RegionKind::ReError(..) => {
 | 
			
		||||
                if cfg!(test) {
 | 
			
		||||
                    write!(f, "'?")
 | 
			
		||||
                } else {
 | 
			
		||||
                    write!(f, "'_")
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            rustc_type_ir::RegionKind::ReErased => write!(f, "'<erased>"),
 | 
			
		||||
            rustc_type_ir::RegionKind::ReEarlyParam(_) => write!(f, "<param>"),
 | 
			
		||||
            rustc_type_ir::RegionKind::ReLateParam(_) => write!(f, "<late-param>"),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl HirDisplay for DomainGoal {
 | 
			
		||||
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
 | 
			
		||||
        match self {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,29 @@ impl<'db> std::fmt::Debug for GenericArg<'db> {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'db> GenericArg<'db> {
 | 
			
		||||
    pub fn ty(self) -> Option<Ty<'db>> {
 | 
			
		||||
        match self.kind() {
 | 
			
		||||
            GenericArgKind::Type(ty) => Some(ty),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn expect_ty(self) -> Ty<'db> {
 | 
			
		||||
        match self.kind() {
 | 
			
		||||
            GenericArgKind::Type(ty) => ty,
 | 
			
		||||
            _ => panic!("Expected ty, got {:?}", self),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn region(self) -> Option<Region<'db>> {
 | 
			
		||||
        match self.kind() {
 | 
			
		||||
            GenericArgKind::Lifetime(r) => Some(r),
 | 
			
		||||
            _ => None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'db> From<Term<'db>> for GenericArg<'db> {
 | 
			
		||||
    fn from(value: Term<'db>) -> Self {
 | 
			
		||||
        match value {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,13 +18,14 @@ use rustc_type_ir::{
 | 
			
		|||
    shift_vars,
 | 
			
		||||
    solve::Goal,
 | 
			
		||||
};
 | 
			
		||||
use salsa::plumbing::AsId;
 | 
			
		||||
use salsa::plumbing::FromId;
 | 
			
		||||
use salsa::{Id, plumbing::AsId};
 | 
			
		||||
 | 
			
		||||
use crate::{
 | 
			
		||||
    ConcreteConst, ConstScalar, ImplTraitId, Interner, MemoryMap,
 | 
			
		||||
    db::{
 | 
			
		||||
        HirDatabase, InternedClosureId, InternedCoroutineId, InternedOpaqueTyId,
 | 
			
		||||
        InternedTypeOrConstParamId,
 | 
			
		||||
        HirDatabase, InternedClosureId, InternedCoroutineId, InternedLifetimeParamId,
 | 
			
		||||
        InternedOpaqueTyId, InternedTypeOrConstParamId,
 | 
			
		||||
    },
 | 
			
		||||
    from_assoc_type_id, from_chalk_trait_id,
 | 
			
		||||
    mapping::ToChalk,
 | 
			
		||||
| 
						 | 
				
			
			@ -55,6 +56,24 @@ pub fn to_placeholder_idx<T: Clone + std::fmt::Debug>(
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn bound_var_to_type_or_const_param_idx(
 | 
			
		||||
    db: &dyn HirDatabase,
 | 
			
		||||
    var: rustc_type_ir::BoundVar,
 | 
			
		||||
) -> TypeOrConstParamId {
 | 
			
		||||
    // SAFETY: We cannot really encapsulate this unfortunately, so just hope this is sound.
 | 
			
		||||
    let interned_id = InternedTypeOrConstParamId::from_id(unsafe { Id::from_index(var.as_u32()) });
 | 
			
		||||
    interned_id.loc(db)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn bound_var_to_lifetime_idx(
 | 
			
		||||
    db: &dyn HirDatabase,
 | 
			
		||||
    var: rustc_type_ir::BoundVar,
 | 
			
		||||
) -> LifetimeParamId {
 | 
			
		||||
    // SAFETY: We cannot really encapsulate this unfortunately, so just hope this is sound.
 | 
			
		||||
    let interned_id = InternedLifetimeParamId::from_id(unsafe { Id::from_index(var.as_u32()) });
 | 
			
		||||
    interned_id.loc(db)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn convert_binder_to_early_binder<'db, T: rustc_type_ir::TypeFoldable<DbInterner<'db>>>(
 | 
			
		||||
    interner: DbInterner<'db>,
 | 
			
		||||
    binder: rustc_type_ir::Binder<DbInterner<'db>, T>,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ pub use crate::{
 | 
			
		|||
        VisibleTraits,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
use rustc_type_ir::inherent::IntoKind;
 | 
			
		||||
use rustc_type_ir::inherent::{IntoKind, SliceLike};
 | 
			
		||||
 | 
			
		||||
// Be careful with these re-exports.
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			@ -4513,14 +4513,20 @@ impl Impl {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn trait_(self, db: &dyn HirDatabase) -> Option<Trait> {
 | 
			
		||||
        let trait_ref = db.impl_trait(self.id)?;
 | 
			
		||||
        let id = trait_ref.skip_binders().hir_trait_id();
 | 
			
		||||
        let trait_ref = db.impl_trait_ns(self.id)?;
 | 
			
		||||
        let id = trait_ref.skip_binder().def_id;
 | 
			
		||||
        let id = match id {
 | 
			
		||||
            SolverDefId::TraitId(id) => id,
 | 
			
		||||
            _ => unreachable!(),
 | 
			
		||||
        };
 | 
			
		||||
        Some(Trait { id })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn trait_ref(self, db: &dyn HirDatabase) -> Option<TraitRef<'_>> {
 | 
			
		||||
        let interner = DbInterner::new_with(db, None, None);
 | 
			
		||||
        let substs = TyBuilder::placeholder_subst(db, self.id);
 | 
			
		||||
        let trait_ref = db.impl_trait(self.id)?.substitute(Interner, &substs);
 | 
			
		||||
        let trait_ref =
 | 
			
		||||
            db.impl_trait(self.id)?.substitute(Interner, &substs).to_nextsolver(interner);
 | 
			
		||||
        let resolver = self.id.resolver(db);
 | 
			
		||||
        Some(TraitRef::new_with_resolver(db, &resolver, trait_ref))
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -4589,7 +4595,7 @@ impl Impl {
 | 
			
		|||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
 | 
			
		||||
pub struct TraitRef<'db> {
 | 
			
		||||
    env: Arc<TraitEnvironment>,
 | 
			
		||||
    trait_ref: hir_ty::TraitRef,
 | 
			
		||||
    trait_ref: hir_ty::next_solver::TraitRef<'db>,
 | 
			
		||||
    _pd: PhantomCovariantLifetime<'db>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4597,7 +4603,7 @@ impl<'db> TraitRef<'db> {
 | 
			
		|||
    pub(crate) fn new_with_resolver(
 | 
			
		||||
        db: &'db dyn HirDatabase,
 | 
			
		||||
        resolver: &Resolver<'_>,
 | 
			
		||||
        trait_ref: hir_ty::TraitRef,
 | 
			
		||||
        trait_ref: hir_ty::next_solver::TraitRef<'db>,
 | 
			
		||||
    ) -> Self {
 | 
			
		||||
        let env = resolver
 | 
			
		||||
            .generic_def()
 | 
			
		||||
| 
						 | 
				
			
			@ -4606,25 +4612,26 @@ impl<'db> TraitRef<'db> {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn trait_(&self) -> Trait {
 | 
			
		||||
        let id = self.trait_ref.hir_trait_id();
 | 
			
		||||
        let id = match self.trait_ref.def_id {
 | 
			
		||||
            SolverDefId::TraitId(id) => id,
 | 
			
		||||
            _ => unreachable!(),
 | 
			
		||||
        };
 | 
			
		||||
        Trait { id }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn self_ty(&self) -> Type<'_> {
 | 
			
		||||
        let ty = self.trait_ref.self_type_parameter(Interner);
 | 
			
		||||
        Type { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() }
 | 
			
		||||
    pub fn self_ty(&self) -> TypeNs<'_> {
 | 
			
		||||
        let ty = self.trait_ref.self_ty();
 | 
			
		||||
        TypeNs { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the
 | 
			
		||||
    /// first argument is the `Self` type.
 | 
			
		||||
    pub fn get_type_argument(&self, idx: usize) -> Option<Type<'db>> {
 | 
			
		||||
        self.trait_ref
 | 
			
		||||
            .substitution
 | 
			
		||||
            .as_slice(Interner)
 | 
			
		||||
            .get(idx)
 | 
			
		||||
            .and_then(|arg| arg.ty(Interner))
 | 
			
		||||
            .cloned()
 | 
			
		||||
            .map(|ty| Type { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() })
 | 
			
		||||
    pub fn get_type_argument(&self, idx: usize) -> Option<TypeNs<'db>> {
 | 
			
		||||
        self.trait_ref.args.as_slice().get(idx).and_then(|arg| arg.ty()).map(|ty| TypeNs {
 | 
			
		||||
            env: self.env.clone(),
 | 
			
		||||
            ty,
 | 
			
		||||
            _pd: PhantomCovariantLifetime::new(),
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue