mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 07:04:22 +00:00
Merge #2410
2410: Introduce hir_ty r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
36dca8de93
12 changed files with 331 additions and 247 deletions
23
Cargo.lock
generated
23
Cargo.lock
generated
|
@ -995,6 +995,7 @@ dependencies = [
|
|||
"ra_db 0.1.0",
|
||||
"ra_hir_def 0.1.0",
|
||||
"ra_hir_expand 0.1.0",
|
||||
"ra_hir_ty 0.1.0",
|
||||
"ra_mbe 0.1.0",
|
||||
"ra_prof 0.1.0",
|
||||
"ra_syntax 0.1.0",
|
||||
|
@ -1036,6 +1037,28 @@ dependencies = [
|
|||
"ra_tt 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ra_hir_ty"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
|
||||
"chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
|
||||
"chalk-solve 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)",
|
||||
"ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ra_arena 0.1.0",
|
||||
"ra_db 0.1.0",
|
||||
"ra_hir_def 0.1.0",
|
||||
"ra_hir_expand 0.1.0",
|
||||
"ra_prof 0.1.0",
|
||||
"ra_syntax 0.1.0",
|
||||
"rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"test_utils 0.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ra_ide_api"
|
||||
version = "0.1.0"
|
||||
|
|
|
@ -23,6 +23,7 @@ mbe = { path = "../ra_mbe", package = "ra_mbe" }
|
|||
tt = { path = "../ra_tt", package = "ra_tt" }
|
||||
hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
|
||||
hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
|
||||
hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
|
||||
test_utils = { path = "../test_utils" }
|
||||
ra_prof = { path = "../ra_prof" }
|
||||
|
||||
|
|
|
@ -997,6 +997,15 @@ pub struct ImplBlock {
|
|||
}
|
||||
|
||||
impl ImplBlock {
|
||||
pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> {
|
||||
let impls = db.impls_in_crate(krate.crate_id);
|
||||
impls.all_impls().map(Self::from).collect()
|
||||
}
|
||||
pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> {
|
||||
let impls = db.impls_in_crate(krate.crate_id);
|
||||
impls.lookup_impl_blocks_for_trait(trait_).map(Self::from).collect()
|
||||
}
|
||||
|
||||
pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> {
|
||||
db.impl_data(self.id).target_trait.clone()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use ra_arena::map::ArenaMap;
|
||||
use ra_db::salsa;
|
||||
use ra_db::{salsa, CrateId};
|
||||
|
||||
use crate::{
|
||||
ty::{
|
||||
|
@ -60,7 +60,7 @@ pub trait HirDatabase: DefDatabase {
|
|||
fn generic_defaults(&self, def: GenericDefId) -> Substs;
|
||||
|
||||
#[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
|
||||
fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
|
||||
fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>;
|
||||
|
||||
#[salsa::invoke(crate::ty::traits::impls_for_trait_query)]
|
||||
fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>;
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::iter;
|
|||
use std::sync::Arc;
|
||||
|
||||
use hir_def::{
|
||||
builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType},
|
||||
builtin_type::BuiltinType,
|
||||
generics::WherePredicate,
|
||||
path::{GenericArg, PathSegment},
|
||||
resolver::{HasResolver, Resolver, TypeNs},
|
||||
|
@ -27,7 +27,7 @@ use super::{
|
|||
use crate::{
|
||||
db::HirDatabase,
|
||||
ty::{
|
||||
primitive::{FloatTy, IntTy, Uncertain},
|
||||
primitive::{FloatTy, IntTy},
|
||||
Adt,
|
||||
},
|
||||
util::make_mut_slice,
|
||||
|
@ -679,36 +679,6 @@ fn type_for_builtin(def: BuiltinType) -> Ty {
|
|||
})
|
||||
}
|
||||
|
||||
impl From<BuiltinInt> for IntTy {
|
||||
fn from(t: BuiltinInt) -> Self {
|
||||
IntTy { signedness: t.signedness, bitness: t.bitness }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BuiltinFloat> for FloatTy {
|
||||
fn from(t: BuiltinFloat) -> Self {
|
||||
FloatTy { bitness: t.bitness }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<BuiltinInt>> for Uncertain<IntTy> {
|
||||
fn from(t: Option<BuiltinInt>) -> Self {
|
||||
match t {
|
||||
None => Uncertain::Unknown,
|
||||
Some(t) => Uncertain::Known(t.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
|
||||
fn from(t: Option<BuiltinFloat>) -> Self {
|
||||
match t {
|
||||
None => Uncertain::Unknown,
|
||||
Some(t) => Uncertain::Known(t.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig {
|
||||
let struct_data = db.struct_data(def.into());
|
||||
let fields = struct_data.variant_data.fields();
|
||||
|
|
|
@ -5,14 +5,19 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule};
|
||||
use hir_def::{
|
||||
lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef,
|
||||
HasModule, ImplId, TraitId,
|
||||
};
|
||||
use ra_db::CrateId;
|
||||
use ra_prof::profile;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
ty::primitive::{FloatBitness, Uncertain},
|
||||
ty::{Ty, TypeCtor},
|
||||
AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait,
|
||||
AssocItem, Crate, Function, Mutability, Name, Trait,
|
||||
};
|
||||
|
||||
use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef};
|
||||
|
@ -37,53 +42,57 @@ impl TyFingerprint {
|
|||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct CrateImplBlocks {
|
||||
impls: FxHashMap<TyFingerprint, Vec<ImplBlock>>,
|
||||
impls_by_trait: FxHashMap<Trait, Vec<ImplBlock>>,
|
||||
impls: FxHashMap<TyFingerprint, Vec<ImplId>>,
|
||||
impls_by_trait: FxHashMap<TraitId, Vec<ImplId>>,
|
||||
}
|
||||
|
||||
impl CrateImplBlocks {
|
||||
pub(crate) fn impls_in_crate_query(
|
||||
db: &impl HirDatabase,
|
||||
krate: Crate,
|
||||
krate: CrateId,
|
||||
) -> Arc<CrateImplBlocks> {
|
||||
let mut crate_impl_blocks =
|
||||
let _p = profile("impls_in_crate_query");
|
||||
let mut res =
|
||||
CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() };
|
||||
if let Some(module) = krate.root_module(db) {
|
||||
crate_impl_blocks.collect_recursive(db, module);
|
||||
}
|
||||
Arc::new(crate_impl_blocks)
|
||||
}
|
||||
pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + '_ {
|
||||
let fingerprint = TyFingerprint::for_impl(ty);
|
||||
fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied()
|
||||
}
|
||||
|
||||
pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplBlock> + '_ {
|
||||
self.impls_by_trait.get(&tr).into_iter().flatten().copied()
|
||||
}
|
||||
let crate_def_map = db.crate_def_map(krate);
|
||||
for (_module_id, module_data) in crate_def_map.modules.iter() {
|
||||
for &impl_id in module_data.impls.iter() {
|
||||
let impl_data = db.impl_data(impl_id);
|
||||
let resolver = impl_id.resolver(db);
|
||||
|
||||
pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a {
|
||||
self.impls.values().chain(self.impls_by_trait.values()).flatten().copied()
|
||||
}
|
||||
let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) };
|
||||
|
||||
fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) {
|
||||
for impl_block in module.impl_blocks(db) {
|
||||
let target_ty = impl_block.target_ty(db);
|
||||
|
||||
if impl_block.target_trait(db).is_some() {
|
||||
if let Some(tr) = impl_block.target_trait_ref(db) {
|
||||
self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block);
|
||||
}
|
||||
} else {
|
||||
if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
|
||||
self.impls.entry(target_ty_fp).or_default().push(impl_block);
|
||||
match &impl_data.target_trait {
|
||||
Some(trait_ref) => {
|
||||
if let Some(tr) =
|
||||
TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty))
|
||||
{
|
||||
res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) {
|
||||
res.impls.entry(target_ty_fp).or_default().push(impl_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for child in module.children(db) {
|
||||
self.collect_recursive(db, child);
|
||||
}
|
||||
Arc::new(res)
|
||||
}
|
||||
pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplId> + '_ {
|
||||
let fingerprint = TyFingerprint::for_impl(ty);
|
||||
fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied()
|
||||
}
|
||||
|
||||
pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplId> + '_ {
|
||||
self.impls_by_trait.get(&tr.id).into_iter().flatten().copied()
|
||||
}
|
||||
|
||||
pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplId> + 'a {
|
||||
self.impls.values().chain(self.impls_by_trait.values()).flatten().copied()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,14 +288,14 @@ fn iterate_inherent_methods<T>(
|
|||
mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
|
||||
) -> Option<T> {
|
||||
for krate in def_crates(db, krate, &ty.value)? {
|
||||
let impls = db.impls_in_crate(krate);
|
||||
let impls = db.impls_in_crate(krate.crate_id);
|
||||
|
||||
for impl_block in impls.lookup_impl_blocks(&ty.value) {
|
||||
for item in impl_block.items(db) {
|
||||
for &item in db.impl_data(impl_block).items.iter() {
|
||||
if !is_valid_candidate(db, name, mode, item) {
|
||||
continue;
|
||||
}
|
||||
if let Some(result) = callback(&ty.value, item) {
|
||||
if let Some(result) = callback(&ty.value, item.into()) {
|
||||
return Some(result);
|
||||
}
|
||||
}
|
||||
|
@ -299,17 +308,17 @@ fn is_valid_candidate(
|
|||
db: &impl HirDatabase,
|
||||
name: Option<&Name>,
|
||||
mode: LookupMode,
|
||||
item: AssocItem,
|
||||
item: AssocItemId,
|
||||
) -> bool {
|
||||
match item {
|
||||
AssocItem::Function(m) => {
|
||||
let data = db.function_data(m.id);
|
||||
name.map_or(true, |name| data.name == *name)
|
||||
AssocItemId::FunctionId(m) => {
|
||||
let data = db.function_data(m);
|
||||
name.map_or(true, |name| &data.name == name)
|
||||
&& (data.has_self_param || mode == LookupMode::Path)
|
||||
}
|
||||
AssocItem::Const(c) => {
|
||||
name.map_or(true, |name| Some(name) == c.name(db).as_ref())
|
||||
&& (mode == LookupMode::Path)
|
||||
AssocItemId::ConstId(c) => {
|
||||
let data = db.const_data(c);
|
||||
name.map_or(true, |name| data.name.as_ref() == Some(name)) && (mode == LookupMode::Path)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
@ -344,11 +353,11 @@ impl Ty {
|
|||
mut callback: impl FnMut(AssocItem) -> Option<T>,
|
||||
) -> Option<T> {
|
||||
for krate in def_crates(db, krate, &self)? {
|
||||
let impls = db.impls_in_crate(krate);
|
||||
let impls = db.impls_in_crate(krate.crate_id);
|
||||
|
||||
for impl_block in impls.lookup_impl_blocks(&self) {
|
||||
for item in impl_block.items(db) {
|
||||
if let Some(result) = callback(item) {
|
||||
for &item in db.impl_data(impl_block).items.iter() {
|
||||
if let Some(result) = callback(item.into()) {
|
||||
return Some(result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,160 +1,3 @@
|
|||
//! FIXME: write short doc here
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub use hir_def::builtin_type::{FloatBitness, IntBitness, Signedness};
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
|
||||
pub enum Uncertain<T> {
|
||||
Unknown,
|
||||
Known(T),
|
||||
}
|
||||
|
||||
impl From<IntTy> for Uncertain<IntTy> {
|
||||
fn from(ty: IntTy) -> Self {
|
||||
Uncertain::Known(ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Uncertain<IntTy> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Uncertain::Unknown => write!(f, "{{integer}}"),
|
||||
Uncertain::Known(ty) => write!(f, "{}", ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FloatTy> for Uncertain<FloatTy> {
|
||||
fn from(ty: FloatTy) -> Self {
|
||||
Uncertain::Known(ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Uncertain<FloatTy> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Uncertain::Unknown => write!(f, "{{float}}"),
|
||||
Uncertain::Known(ty) => write!(f, "{}", ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct IntTy {
|
||||
pub signedness: Signedness,
|
||||
pub bitness: IntBitness,
|
||||
}
|
||||
|
||||
impl fmt::Debug for IntTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for IntTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.ty_to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntTy {
|
||||
pub fn isize() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize }
|
||||
}
|
||||
|
||||
pub fn i8() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 }
|
||||
}
|
||||
|
||||
pub fn i16() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 }
|
||||
}
|
||||
|
||||
pub fn i32() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 }
|
||||
}
|
||||
|
||||
pub fn i64() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 }
|
||||
}
|
||||
|
||||
pub fn i128() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 }
|
||||
}
|
||||
|
||||
pub fn usize() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize }
|
||||
}
|
||||
|
||||
pub fn u8() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 }
|
||||
}
|
||||
|
||||
pub fn u16() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 }
|
||||
}
|
||||
|
||||
pub fn u32() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 }
|
||||
}
|
||||
|
||||
pub fn u64() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 }
|
||||
}
|
||||
|
||||
pub fn u128() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 }
|
||||
}
|
||||
|
||||
pub(crate) fn ty_to_string(self) -> &'static str {
|
||||
match (self.signedness, self.bitness) {
|
||||
(Signedness::Signed, IntBitness::Xsize) => "isize",
|
||||
(Signedness::Signed, IntBitness::X8) => "i8",
|
||||
(Signedness::Signed, IntBitness::X16) => "i16",
|
||||
(Signedness::Signed, IntBitness::X32) => "i32",
|
||||
(Signedness::Signed, IntBitness::X64) => "i64",
|
||||
(Signedness::Signed, IntBitness::X128) => "i128",
|
||||
(Signedness::Unsigned, IntBitness::Xsize) => "usize",
|
||||
(Signedness::Unsigned, IntBitness::X8) => "u8",
|
||||
(Signedness::Unsigned, IntBitness::X16) => "u16",
|
||||
(Signedness::Unsigned, IntBitness::X32) => "u32",
|
||||
(Signedness::Unsigned, IntBitness::X64) => "u64",
|
||||
(Signedness::Unsigned, IntBitness::X128) => "u128",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct FloatTy {
|
||||
pub bitness: FloatBitness,
|
||||
}
|
||||
|
||||
impl fmt::Debug for FloatTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FloatTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.ty_to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl FloatTy {
|
||||
pub fn f32() -> FloatTy {
|
||||
FloatTy { bitness: FloatBitness::X32 }
|
||||
}
|
||||
|
||||
pub fn f64() -> FloatTy {
|
||||
FloatTy { bitness: FloatBitness::X64 }
|
||||
}
|
||||
|
||||
pub(crate) fn ty_to_string(self) -> &'static str {
|
||||
match self.bitness {
|
||||
FloatBitness::X32 => "f32",
|
||||
FloatBitness::X64 => "f64",
|
||||
}
|
||||
}
|
||||
}
|
||||
pub use hir_ty::primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain};
|
||||
|
|
|
@ -88,8 +88,8 @@ pub(crate) fn impls_for_trait_query(
|
|||
for dep in krate.dependencies(db) {
|
||||
impls.extend(db.impls_for_trait(dep.krate, trait_).iter());
|
||||
}
|
||||
let crate_impl_blocks = db.impls_in_crate(krate);
|
||||
impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_));
|
||||
let crate_impl_blocks = db.impls_in_crate(krate.crate_id);
|
||||
impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from));
|
||||
impls.into_iter().collect()
|
||||
}
|
||||
|
||||
|
|
32
crates/ra_hir_ty/Cargo.toml
Normal file
32
crates/ra_hir_ty/Cargo.toml
Normal file
|
@ -0,0 +1,32 @@
|
|||
[package]
|
||||
edition = "2018"
|
||||
name = "ra_hir_ty"
|
||||
version = "0.1.0"
|
||||
authors = ["rust-analyzer developers"]
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.5"
|
||||
rustc-hash = "1.0"
|
||||
parking_lot = "0.9.0"
|
||||
ena = "0.13"
|
||||
|
||||
ra_syntax = { path = "../ra_syntax" }
|
||||
ra_arena = { path = "../ra_arena" }
|
||||
ra_db = { path = "../ra_db" }
|
||||
hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
|
||||
hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
|
||||
test_utils = { path = "../test_utils" }
|
||||
ra_prof = { path = "../ra_prof" }
|
||||
|
||||
# https://github.com/rust-lang/chalk/pull/294
|
||||
chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" }
|
||||
chalk-rust-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" }
|
||||
chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" }
|
||||
|
||||
lalrpop-intern = "0.15.1"
|
||||
|
||||
[dev-dependencies]
|
||||
insta = "0.12.0"
|
4
crates/ra_hir_ty/src/lib.rs
Normal file
4
crates/ra_hir_ty/src/lib.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
//! Work in Progress: everything related to types, type inference and trait
|
||||
//! solving.
|
||||
|
||||
pub mod primitive;
|
193
crates/ra_hir_ty/src/primitive.rs
Normal file
193
crates/ra_hir_ty/src/primitive.rs
Normal file
|
@ -0,0 +1,193 @@
|
|||
//! Defines primitive types, which have a couple of peculiarities:
|
||||
//!
|
||||
//! * during type inference, they can be uncertain (ie, `let x = 92;`)
|
||||
//! * they don't belong to any particular crate.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness};
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
|
||||
pub enum Uncertain<T> {
|
||||
Unknown,
|
||||
Known(T),
|
||||
}
|
||||
|
||||
impl From<IntTy> for Uncertain<IntTy> {
|
||||
fn from(ty: IntTy) -> Self {
|
||||
Uncertain::Known(ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Uncertain<IntTy> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Uncertain::Unknown => write!(f, "{{integer}}"),
|
||||
Uncertain::Known(ty) => write!(f, "{}", ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FloatTy> for Uncertain<FloatTy> {
|
||||
fn from(ty: FloatTy) -> Self {
|
||||
Uncertain::Known(ty)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Uncertain<FloatTy> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Uncertain::Unknown => write!(f, "{{float}}"),
|
||||
Uncertain::Known(ty) => write!(f, "{}", ty),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct IntTy {
|
||||
pub signedness: Signedness,
|
||||
pub bitness: IntBitness,
|
||||
}
|
||||
|
||||
impl fmt::Debug for IntTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for IntTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.ty_to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntTy {
|
||||
pub fn isize() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize }
|
||||
}
|
||||
|
||||
pub fn i8() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 }
|
||||
}
|
||||
|
||||
pub fn i16() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 }
|
||||
}
|
||||
|
||||
pub fn i32() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 }
|
||||
}
|
||||
|
||||
pub fn i64() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 }
|
||||
}
|
||||
|
||||
pub fn i128() -> IntTy {
|
||||
IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 }
|
||||
}
|
||||
|
||||
pub fn usize() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize }
|
||||
}
|
||||
|
||||
pub fn u8() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 }
|
||||
}
|
||||
|
||||
pub fn u16() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 }
|
||||
}
|
||||
|
||||
pub fn u32() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 }
|
||||
}
|
||||
|
||||
pub fn u64() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 }
|
||||
}
|
||||
|
||||
pub fn u128() -> IntTy {
|
||||
IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 }
|
||||
}
|
||||
|
||||
pub fn ty_to_string(self) -> &'static str {
|
||||
match (self.signedness, self.bitness) {
|
||||
(Signedness::Signed, IntBitness::Xsize) => "isize",
|
||||
(Signedness::Signed, IntBitness::X8) => "i8",
|
||||
(Signedness::Signed, IntBitness::X16) => "i16",
|
||||
(Signedness::Signed, IntBitness::X32) => "i32",
|
||||
(Signedness::Signed, IntBitness::X64) => "i64",
|
||||
(Signedness::Signed, IntBitness::X128) => "i128",
|
||||
(Signedness::Unsigned, IntBitness::Xsize) => "usize",
|
||||
(Signedness::Unsigned, IntBitness::X8) => "u8",
|
||||
(Signedness::Unsigned, IntBitness::X16) => "u16",
|
||||
(Signedness::Unsigned, IntBitness::X32) => "u32",
|
||||
(Signedness::Unsigned, IntBitness::X64) => "u64",
|
||||
(Signedness::Unsigned, IntBitness::X128) => "u128",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct FloatTy {
|
||||
pub bitness: FloatBitness,
|
||||
}
|
||||
|
||||
impl fmt::Debug for FloatTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for FloatTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.ty_to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl FloatTy {
|
||||
pub fn f32() -> FloatTy {
|
||||
FloatTy { bitness: FloatBitness::X32 }
|
||||
}
|
||||
|
||||
pub fn f64() -> FloatTy {
|
||||
FloatTy { bitness: FloatBitness::X64 }
|
||||
}
|
||||
|
||||
pub fn ty_to_string(self) -> &'static str {
|
||||
match self.bitness {
|
||||
FloatBitness::X32 => "f32",
|
||||
FloatBitness::X64 => "f64",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BuiltinInt> for IntTy {
|
||||
fn from(t: BuiltinInt) -> Self {
|
||||
IntTy { signedness: t.signedness, bitness: t.bitness }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BuiltinFloat> for FloatTy {
|
||||
fn from(t: BuiltinFloat) -> Self {
|
||||
FloatTy { bitness: t.bitness }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<BuiltinInt>> for Uncertain<IntTy> {
|
||||
fn from(t: Option<BuiltinInt>) -> Self {
|
||||
match t {
|
||||
None => Uncertain::Unknown,
|
||||
Some(t) => Uncertain::Known(t.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> {
|
||||
fn from(t: Option<BuiltinFloat>) -> Self {
|
||||
match t {
|
||||
None => Uncertain::Unknown,
|
||||
Some(t) => Uncertain::Known(t.into()),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
//! FIXME: write short doc here
|
||||
|
||||
use hir::{db::HirDatabase, ApplicationTy, FromSource, Ty, TypeCtor};
|
||||
use hir::{ApplicationTy, FromSource, ImplBlock, Ty, TypeCtor};
|
||||
use ra_db::SourceDatabase;
|
||||
use ra_syntax::{algo::find_node_at_offset, ast, AstNode};
|
||||
|
||||
|
@ -56,11 +56,11 @@ fn impls_for_def(
|
|||
};
|
||||
|
||||
let krate = module.krate();
|
||||
let impls = db.impls_in_crate(krate);
|
||||
let impls = ImplBlock::all_in_crate(db, krate);
|
||||
|
||||
Some(
|
||||
impls
|
||||
.all_impls()
|
||||
.into_iter()
|
||||
.filter(|impl_block| is_equal_for_find_impls(&ty, &impl_block.target_ty(db)))
|
||||
.map(|imp| imp.to_nav(db))
|
||||
.collect(),
|
||||
|
@ -77,9 +77,9 @@ fn impls_for_trait(
|
|||
let tr = hir::Trait::from_source(db, src)?;
|
||||
|
||||
let krate = module.krate();
|
||||
let impls = db.impls_in_crate(krate);
|
||||
let impls = ImplBlock::for_trait(db, krate, tr);
|
||||
|
||||
Some(impls.lookup_impl_blocks_for_trait(tr).map(|imp| imp.to_nav(db)).collect())
|
||||
Some(impls.into_iter().map(|imp| imp.to_nav(db)).collect())
|
||||
}
|
||||
|
||||
fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool {
|
||||
|
|
Loading…
Reference in a new issue