Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/lib.rs')
-rw-r--r--crates/hir-ty/src/lib.rs86
1 files changed, 59 insertions, 27 deletions
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index fdacc1d899..41c381220c 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -2,6 +2,8 @@
//! information and various assists.
#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
+// It's useful to refer to code that is private in doc comments.
+#![allow(rustdoc::private_intra_doc_links)]
// FIXME: We used to import `rustc_*` deps from `rustc_private` with `feature = "in-rust-tree" but
// temporarily switched to crates.io versions due to hardships that working on them from rustc
@@ -23,6 +25,7 @@ extern crate ra_ap_rustc_next_trait_solver as rustc_next_trait_solver;
extern crate self as hir_ty;
+pub mod builtin_derive;
mod infer;
mod inhabitedness;
mod lower;
@@ -47,6 +50,7 @@ pub mod method_resolution;
pub mod mir;
pub mod primitive;
pub mod traits;
+pub mod upvars;
#[cfg(test)]
mod test_db;
@@ -59,15 +63,15 @@ use hir_def::{CallableDefId, TypeOrConstParamId, type_ref::Rawness};
use hir_expand::name::Name;
use indexmap::{IndexMap, map::Entry};
use intern::{Symbol, sym};
+use macros::GenericTypeVisitable;
use mir::{MirEvalError, VTableMap};
use rustc_hash::{FxBuildHasher, FxHashMap, FxHashSet};
use rustc_type_ir::{
BoundVarIndexKind, TypeSuperVisitable, TypeVisitableExt, UpcastFrom,
- inherent::{IntoKind, SliceLike, Ty as _},
+ inherent::{IntoKind, Ty as _},
};
use syntax::ast::{ConstArg, make};
use traits::FnTrait;
-use triomphe::Arc;
use crate::{
db::HirDatabase,
@@ -75,8 +79,8 @@ use crate::{
infer::unify::InferenceTable,
next_solver::{
AliasTy, Binder, BoundConst, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, Canonical,
- CanonicalVarKind, CanonicalVars, Const, ConstKind, DbInterner, FnSig, PolyFnSig, Predicate,
- Region, RegionKind, TraitRef, Ty, TyKind, Tys, abi,
+ CanonicalVarKind, CanonicalVars, Const, ConstKind, DbInterner, FnSig, GenericArgs,
+ PolyFnSig, Predicate, Region, RegionKind, TraitRef, Ty, TyKind, Tys, abi,
},
};
@@ -86,16 +90,15 @@ pub use infer::{
InferenceTyDiagnosticSource, OverloadedDeref, PointerCast,
cast::CastError,
closure::analysis::{CaptureKind, CapturedItem},
- could_coerce, could_unify, could_unify_deeply,
+ could_coerce, could_unify, could_unify_deeply, infer_query_with_inspect,
};
pub use lower::{
- LifetimeElisionKind, TyDefId, TyLoweringContext, ValueTyDefId,
+ GenericPredicates, ImplTraits, LifetimeElisionKind, TyDefId, TyLoweringContext, ValueTyDefId,
associated_type_shorthand_candidates, diagnostics::*,
};
-pub use method_resolution::check_orphan_rules;
pub use next_solver::interner::{attach_db, attach_db_allow_change, with_attached_db};
pub use target_feature::TargetFeatures;
-pub use traits::TraitEnvironment;
+pub use traits::{ParamEnvAndCrate, check_orphan_rules};
pub use utils::{
TargetFeatureIsSafeInTarget, Unsafety, all_super_traits, direct_super_traits,
is_fn_unsafe_to_call, target_feature_is_safe_in_target,
@@ -104,7 +107,7 @@ pub use utils::{
/// A constant can have reference to other things. Memory map job is holding
/// the necessary bits of memory of the const eval session to keep the constant
/// meaningful.
-#[derive(Debug, Default, Clone, PartialEq, Eq)]
+#[derive(Debug, Default, Clone, PartialEq, Eq, GenericTypeVisitable)]
pub enum MemoryMap<'db> {
#[default]
Empty,
@@ -112,7 +115,7 @@ pub enum MemoryMap<'db> {
Complex(Box<ComplexMemoryMap<'db>>),
}
-#[derive(Debug, Default, Clone, PartialEq, Eq)]
+#[derive(Debug, Default, Clone, PartialEq, Eq, GenericTypeVisitable)]
pub struct ComplexMemoryMap<'db> {
memory: IndexMap<usize, Box<[u8]>, FxBuildHasher>,
vtable: VTableMap<'db>,
@@ -134,7 +137,7 @@ impl ComplexMemoryMap<'_> {
}
impl<'db> MemoryMap<'db> {
- pub fn vtable_ty(&self, id: usize) -> Result<Ty<'db>, MirEvalError<'db>> {
+ pub fn vtable_ty(&self, id: usize) -> Result<Ty<'db>, MirEvalError> {
match self {
MemoryMap::Empty | MemoryMap::Simple(_) => Err(MirEvalError::InvalidVTableId(id)),
MemoryMap::Complex(cm) => cm.vtable.ty(id),
@@ -150,8 +153,8 @@ impl<'db> MemoryMap<'db> {
/// allocator function as `f` and it will return a mapping of old addresses to new addresses.
fn transform_addresses(
&self,
- mut f: impl FnMut(&[u8], usize) -> Result<usize, MirEvalError<'db>>,
- ) -> Result<FxHashMap<usize, usize>, MirEvalError<'db>> {
+ mut f: impl FnMut(&[u8], usize) -> Result<usize, MirEvalError>,
+ ) -> Result<FxHashMap<usize, usize>, MirEvalError> {
let mut transform = |(addr, val): (&usize, &[u8])| {
let addr = *addr;
let align = if addr == 0 { 64 } else { (addr - (addr & (addr - 1))).min(64) };
@@ -333,9 +336,9 @@ impl FnAbi {
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
-pub enum ImplTraitId<'db> {
- ReturnTypeImplTrait(hir_def::FunctionId, next_solver::ImplTraitIdx<'db>),
- TypeAliasImplTrait(hir_def::TypeAliasId, next_solver::ImplTraitIdx<'db>),
+pub enum ImplTraitId {
+ ReturnTypeImplTrait(hir_def::FunctionId, next_solver::ImplTraitIdx),
+ TypeAliasImplTrait(hir_def::TypeAliasId, next_solver::ImplTraitIdx),
}
/// 'Canonicalizes' the `t` by replacing any errors with new variables. Also
@@ -468,34 +471,34 @@ where
Canonical {
value,
max_universe: rustc_type_ir::UniverseIndex::ZERO,
- variables: CanonicalVars::new_from_iter(interner, error_replacer.vars),
+ variables: CanonicalVars::new_from_slice(&error_replacer.vars),
}
}
/// To be used from `hir` only.
pub fn callable_sig_from_fn_trait<'db>(
self_ty: Ty<'db>,
- trait_env: Arc<TraitEnvironment<'db>>,
+ trait_env: ParamEnvAndCrate<'db>,
db: &'db dyn HirDatabase,
) -> Option<(FnTrait, PolyFnSig<'db>)> {
- let krate = trait_env.krate;
- let fn_once_trait = FnTrait::FnOnce.get_id(db, krate)?;
+ let mut table = InferenceTable::new(db, trait_env.param_env, trait_env.krate, None);
+ let lang_items = table.interner().lang_items();
+
+ let fn_once_trait = FnTrait::FnOnce.get_id(lang_items)?;
let output_assoc_type = fn_once_trait
.trait_items(db)
.associated_type_by_name(&Name::new_symbol_root(sym::Output))?;
- let mut table = InferenceTable::new(db, trait_env.clone(), None);
-
// Register two obligations:
// - Self: FnOnce<?args_ty>
// - <Self as FnOnce<?args_ty>>::Output == ?ret_ty
let args_ty = table.next_ty_var();
- let args = [self_ty, args_ty];
- let trait_ref = TraitRef::new(table.interner(), fn_once_trait.into(), args);
+ let args = GenericArgs::new_from_slice(&[self_ty.into(), args_ty.into()]);
+ let trait_ref = TraitRef::new_from_args(table.interner(), fn_once_trait.into(), args);
let projection = Ty::new_alias(
table.interner(),
rustc_type_ir::AliasTyKind::Projection,
- AliasTy::new(table.interner(), output_assoc_type.into(), args),
+ AliasTy::new_from_args(table.interner(), output_assoc_type.into(), args),
);
let pred = Predicate::upcast_from(trait_ref, table.interner());
@@ -503,8 +506,8 @@ pub fn callable_sig_from_fn_trait<'db>(
table.register_obligation(pred);
let return_ty = table.normalize_alias_ty(projection);
for fn_x in [FnTrait::Fn, FnTrait::FnMut, FnTrait::FnOnce] {
- let fn_x_trait = fn_x.get_id(db, krate)?;
- let trait_ref = TraitRef::new(table.interner(), fn_x_trait.into(), args);
+ let fn_x_trait = fn_x.get_id(lang_items)?;
+ let trait_ref = TraitRef::new_from_args(table.interner(), fn_x_trait.into(), args);
if !table
.try_obligation(Predicate::upcast_from(trait_ref, table.interner()))
.no_solution()
@@ -570,6 +573,35 @@ where
Vec::from_iter(collector.params)
}
+struct TypeInferenceVarCollector<'db> {
+ type_inference_vars: Vec<Ty<'db>>,
+}
+
+impl<'db> rustc_type_ir::TypeVisitor<DbInterner<'db>> for TypeInferenceVarCollector<'db> {
+ type Result = ();
+
+ fn visit_ty(&mut self, ty: Ty<'db>) -> Self::Result {
+ use crate::rustc_type_ir::Flags;
+ if ty.is_ty_var() {
+ self.type_inference_vars.push(ty);
+ } else if ty.flags().intersects(rustc_type_ir::TypeFlags::HAS_TY_INFER) {
+ ty.super_visit_with(self);
+ } else {
+ // Fast path: don't visit inner types (e.g. generic arguments) when `flags` indicate
+ // that there are no placeholders.
+ }
+ }
+}
+
+pub fn collect_type_inference_vars<'db, T>(value: &T) -> Vec<Ty<'db>>
+where
+ T: ?Sized + rustc_type_ir::TypeVisitable<DbInterner<'db>>,
+{
+ let mut collector = TypeInferenceVarCollector { type_inference_vars: vec![] };
+ value.visit_with(&mut collector);
+ collector.type_inference_vars
+}
+
pub fn known_const_to_ast<'db>(
konst: Const<'db>,
db: &'db dyn HirDatabase,