aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/code_model.rs9
-rw-r--r--crates/hir_def/src/body/lower.rs17
-rw-r--r--crates/hir_def/src/builtin_type.rs132
-rw-r--r--crates/hir_def/src/expr.rs3
-rw-r--r--crates/hir_ty/src/display.rs16
-rw-r--r--crates/hir_ty/src/infer.rs6
-rw-r--r--crates/hir_ty/src/infer/expr.rs67
-rw-r--r--crates/hir_ty/src/infer/unify.rs26
-rw-r--r--crates/hir_ty/src/lib.rs45
-rw-r--r--crates/hir_ty/src/method_resolution.rs94
-rw-r--r--crates/hir_ty/src/op.rs24
-rw-r--r--crates/hir_ty/src/primitive.rs160
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs90
13 files changed, 270 insertions, 419 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index b3218833d..4109b2ea8 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -32,8 +32,8 @@ use hir_ty::{
32 method_resolution, 32 method_resolution,
33 traits::{FnTrait, Solution, SolutionVariables}, 33 traits::{FnTrait, Solution, SolutionVariables},
34 ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, 34 ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate,
35 InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty, 35 InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment,
36 TyDefId, TyKind, TypeCtor, 36 Ty, TyDefId, TyKind, TypeCtor,
37}; 37};
38use rustc_hash::FxHashSet; 38use rustc_hash::FxHashSet;
39use stdx::{format_to, impl_from}; 39use stdx::{format_to, impl_from};
@@ -1553,7 +1553,10 @@ impl Type {
1553 ) 1553 )
1554 } 1554 }
1555 pub fn is_bool(&self) -> bool { 1555 pub fn is_bool(&self) -> bool {
1556 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) 1556 matches!(
1557 self.ty.value,
1558 Ty::Apply(ApplicationTy { ctor: TypeCtor::Scalar(Scalar::Bool), .. })
1559 )
1557 } 1560 }
1558 1561
1559 pub fn is_mutable_reference(&self) -> bool { 1562 pub fn is_mutable_reference(&self) -> bool {
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index c18001e15..40beb2f7a 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -24,7 +24,7 @@ use test_utils::mark;
24use crate::{ 24use crate::{
25 adt::StructKind, 25 adt::StructKind,
26 body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, 26 body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax},
27 builtin_type::{BuiltinFloat, BuiltinInt}, 27 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
28 db::DefDatabase, 28 db::DefDatabase,
29 diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, 29 diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro},
30 expr::{ 30 expr::{
@@ -1065,11 +1065,16 @@ impl From<ast::LiteralKind> for Literal {
1065 fn from(ast_lit_kind: ast::LiteralKind) -> Self { 1065 fn from(ast_lit_kind: ast::LiteralKind) -> Self {
1066 match ast_lit_kind { 1066 match ast_lit_kind {
1067 LiteralKind::IntNumber(lit) => { 1067 LiteralKind::IntNumber(lit) => {
1068 if let Some(float_suffix) = lit.suffix().and_then(BuiltinFloat::from_suffix) { 1068 if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
1069 return Literal::Float(Default::default(), Some(float_suffix)); 1069 return Literal::Float(Default::default(), builtin);
1070 } else if let builtin @ Some(_) =
1071 lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it))
1072 {
1073 Literal::Int(Default::default(), builtin)
1074 } else {
1075 let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it));
1076 Literal::Uint(Default::default(), builtin)
1070 } 1077 }
1071 let ty = lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it));
1072 Literal::Int(Default::default(), ty)
1073 } 1078 }
1074 LiteralKind::FloatNumber(lit) => { 1079 LiteralKind::FloatNumber(lit) => {
1075 let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it)); 1080 let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it));
@@ -1077,7 +1082,7 @@ impl From<ast::LiteralKind> for Literal {
1077 } 1082 }
1078 LiteralKind::ByteString(_) => Literal::ByteString(Default::default()), 1083 LiteralKind::ByteString(_) => Literal::ByteString(Default::default()),
1079 LiteralKind::String(_) => Literal::String(Default::default()), 1084 LiteralKind::String(_) => Literal::String(Default::default()),
1080 LiteralKind::Byte => Literal::Int(Default::default(), Some(BuiltinInt::U8)), 1085 LiteralKind::Byte => Literal::Uint(Default::default(), Some(BuiltinUint::U8)),
1081 LiteralKind::Bool(val) => Literal::Bool(val), 1086 LiteralKind::Bool(val) => Literal::Bool(val),
1082 LiteralKind::Char => Literal::Char(Default::default()), 1087 LiteralKind::Char => Literal::Char(Default::default()),
1083 } 1088 }
diff --git a/crates/hir_def/src/builtin_type.rs b/crates/hir_def/src/builtin_type.rs
index 0f872b5c0..7cbaf30b8 100644
--- a/crates/hir_def/src/builtin_type.rs
+++ b/crates/hir_def/src/builtin_type.rs
@@ -6,38 +6,32 @@
6use std::fmt; 6use std::fmt;
7 7
8use hir_expand::name::{name, AsName, Name}; 8use hir_expand::name::{name, AsName, Name};
9 9/// Different signed int types.
10#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 10#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub enum Signedness { 11pub enum BuiltinInt {
12 Signed, 12 Isize,
13 Unsigned, 13 I8,
14} 14 I16,
15 15 I32,
16#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 16 I64,
17pub enum IntBitness { 17 I128,
18 Xsize,
19 X8,
20 X16,
21 X32,
22 X64,
23 X128,
24}
25
26#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
27pub enum FloatBitness {
28 X32,
29 X64,
30} 18}
31 19
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 20/// Different unsigned int types.
33pub struct BuiltinInt { 21#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
34 pub signedness: Signedness, 22pub enum BuiltinUint {
35 pub bitness: IntBitness, 23 Usize,
24 U8,
25 U16,
26 U32,
27 U64,
28 U128,
36} 29}
37 30
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 31#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
39pub struct BuiltinFloat { 32pub enum BuiltinFloat {
40 pub bitness: FloatBitness, 33 F32,
34 F64,
41} 35}
42 36
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -46,6 +40,7 @@ pub enum BuiltinType {
46 Bool, 40 Bool,
47 Str, 41 Str,
48 Int(BuiltinInt), 42 Int(BuiltinInt),
43 Uint(BuiltinUint),
49 Float(BuiltinFloat), 44 Float(BuiltinFloat),
50} 45}
51 46
@@ -56,19 +51,19 @@ impl BuiltinType {
56 (name![bool], BuiltinType::Bool), 51 (name![bool], BuiltinType::Bool),
57 (name![str], BuiltinType::Str), 52 (name![str], BuiltinType::Str),
58 53
59 (name![isize], BuiltinType::Int(BuiltinInt::ISIZE)), 54 (name![isize], BuiltinType::Int(BuiltinInt::Isize)),
60 (name![i8], BuiltinType::Int(BuiltinInt::I8)), 55 (name![i8], BuiltinType::Int(BuiltinInt::I8)),
61 (name![i16], BuiltinType::Int(BuiltinInt::I16)), 56 (name![i16], BuiltinType::Int(BuiltinInt::I16)),
62 (name![i32], BuiltinType::Int(BuiltinInt::I32)), 57 (name![i32], BuiltinType::Int(BuiltinInt::I32)),
63 (name![i64], BuiltinType::Int(BuiltinInt::I64)), 58 (name![i64], BuiltinType::Int(BuiltinInt::I64)),
64 (name![i128], BuiltinType::Int(BuiltinInt::I128)), 59 (name![i128], BuiltinType::Int(BuiltinInt::I128)),
65 60
66 (name![usize], BuiltinType::Int(BuiltinInt::USIZE)), 61 (name![usize], BuiltinType::Uint(BuiltinUint::Usize)),
67 (name![u8], BuiltinType::Int(BuiltinInt::U8)), 62 (name![u8], BuiltinType::Uint(BuiltinUint::U8)),
68 (name![u16], BuiltinType::Int(BuiltinInt::U16)), 63 (name![u16], BuiltinType::Uint(BuiltinUint::U16)),
69 (name![u32], BuiltinType::Int(BuiltinInt::U32)), 64 (name![u32], BuiltinType::Uint(BuiltinUint::U32)),
70 (name![u64], BuiltinType::Int(BuiltinInt::U64)), 65 (name![u64], BuiltinType::Uint(BuiltinUint::U64)),
71 (name![u128], BuiltinType::Int(BuiltinInt::U128)), 66 (name![u128], BuiltinType::Uint(BuiltinUint::U128)),
72 67
73 (name![f32], BuiltinType::Float(BuiltinFloat::F32)), 68 (name![f32], BuiltinType::Float(BuiltinFloat::F32)),
74 (name![f64], BuiltinType::Float(BuiltinFloat::F64)), 69 (name![f64], BuiltinType::Float(BuiltinFloat::F64)),
@@ -81,24 +76,25 @@ impl AsName for BuiltinType {
81 BuiltinType::Char => name![char], 76 BuiltinType::Char => name![char],
82 BuiltinType::Bool => name![bool], 77 BuiltinType::Bool => name![bool],
83 BuiltinType::Str => name![str], 78 BuiltinType::Str => name![str],
84 BuiltinType::Int(BuiltinInt { signedness, bitness }) => match (signedness, bitness) { 79 BuiltinType::Int(it) => match it {
85 (Signedness::Signed, IntBitness::Xsize) => name![isize], 80 BuiltinInt::Isize => name![isize],
86 (Signedness::Signed, IntBitness::X8) => name![i8], 81 BuiltinInt::I8 => name![i8],
87 (Signedness::Signed, IntBitness::X16) => name![i16], 82 BuiltinInt::I16 => name![i16],
88 (Signedness::Signed, IntBitness::X32) => name![i32], 83 BuiltinInt::I32 => name![i32],
89 (Signedness::Signed, IntBitness::X64) => name![i64], 84 BuiltinInt::I64 => name![i64],
90 (Signedness::Signed, IntBitness::X128) => name![i128], 85 BuiltinInt::I128 => name![i128],
91 86 },
92 (Signedness::Unsigned, IntBitness::Xsize) => name![usize], 87 BuiltinType::Uint(it) => match it {
93 (Signedness::Unsigned, IntBitness::X8) => name![u8], 88 BuiltinUint::Usize => name![usize],
94 (Signedness::Unsigned, IntBitness::X16) => name![u16], 89 BuiltinUint::U8 => name![u8],
95 (Signedness::Unsigned, IntBitness::X32) => name![u32], 90 BuiltinUint::U16 => name![u16],
96 (Signedness::Unsigned, IntBitness::X64) => name![u64], 91 BuiltinUint::U32 => name![u32],
97 (Signedness::Unsigned, IntBitness::X128) => name![u128], 92 BuiltinUint::U64 => name![u64],
93 BuiltinUint::U128 => name![u128],
98 }, 94 },
99 BuiltinType::Float(BuiltinFloat { bitness }) => match bitness { 95 BuiltinType::Float(it) => match it {
100 FloatBitness::X32 => name![f32], 96 BuiltinFloat::F32 => name![f32],
101 FloatBitness::X64 => name![f64], 97 BuiltinFloat::F64 => name![f64],
102 }, 98 },
103 } 99 }
104 } 100 }
@@ -113,31 +109,26 @@ impl fmt::Display for BuiltinType {
113 109
114#[rustfmt::skip] 110#[rustfmt::skip]
115impl BuiltinInt { 111impl BuiltinInt {
116 pub const ISIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::Xsize };
117 pub const I8 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X8 };
118 pub const I16 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X16 };
119 pub const I32 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X32 };
120 pub const I64 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X64 };
121 pub const I128 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X128 };
122
123 pub const USIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize };
124 pub const U8 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X8 };
125 pub const U16 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X16 };
126 pub const U32 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X32 };
127 pub const U64 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X64 };
128 pub const U128 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X128 };
129
130
131 pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> { 112 pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> {
132 let res = match suffix { 113 let res = match suffix {
133 "isize" => Self::ISIZE, 114 "isize" => Self::Isize,
134 "i8" => Self::I8, 115 "i8" => Self::I8,
135 "i16" => Self::I16, 116 "i16" => Self::I16,
136 "i32" => Self::I32, 117 "i32" => Self::I32,
137 "i64" => Self::I64, 118 "i64" => Self::I64,
138 "i128" => Self::I128, 119 "i128" => Self::I128,
139 120
140 "usize" => Self::USIZE, 121 _ => return None,
122 };
123 Some(res)
124 }
125}
126
127#[rustfmt::skip]
128impl BuiltinUint {
129 pub fn from_suffix(suffix: &str) -> Option<BuiltinUint> {
130 let res = match suffix {
131 "usize" => Self::Usize,
141 "u8" => Self::U8, 132 "u8" => Self::U8,
142 "u16" => Self::U16, 133 "u16" => Self::U16,
143 "u32" => Self::U32, 134 "u32" => Self::U32,
@@ -152,9 +143,6 @@ impl BuiltinInt {
152 143
153#[rustfmt::skip] 144#[rustfmt::skip]
154impl BuiltinFloat { 145impl BuiltinFloat {
155 pub const F32: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X32 };
156 pub const F64: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X64 };
157
158 pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> { 146 pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> {
159 let res = match suffix { 147 let res = match suffix {
160 "f32" => BuiltinFloat::F32, 148 "f32" => BuiltinFloat::F32,
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs
index 4d72eaeaf..24be93773 100644
--- a/crates/hir_def/src/expr.rs
+++ b/crates/hir_def/src/expr.rs
@@ -17,7 +17,7 @@ use la_arena::{Idx, RawIdx};
17use syntax::ast::RangeOp; 17use syntax::ast::RangeOp;
18 18
19use crate::{ 19use crate::{
20 builtin_type::{BuiltinFloat, BuiltinInt}, 20 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
21 path::{GenericArgs, Path}, 21 path::{GenericArgs, Path},
22 type_ref::{Mutability, Rawness, TypeRef}, 22 type_ref::{Mutability, Rawness, TypeRef},
23 BlockId, 23 BlockId,
@@ -43,6 +43,7 @@ pub enum Literal {
43 Char(char), 43 Char(char),
44 Bool(bool), 44 Bool(bool),
45 Int(u64, Option<BuiltinInt>), 45 Int(u64, Option<BuiltinInt>),
46 Uint(u64, Option<BuiltinUint>),
46 Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq 47 Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
47} 48}
48 49
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 271fcbfaf..b4801cb21 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -3,8 +3,9 @@
3use std::{borrow::Cow, fmt}; 3use std::{borrow::Cow, fmt};
4 4
5use crate::{ 5use crate::{
6 db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, 6 db::HirDatabase, primitive, utils::generics, ApplicationTy, CallableDefId, FnSig,
7 Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 7 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs,
8 TraitRef, Ty, TypeCtor,
8}; 9};
9use arrayvec::ArrayVec; 10use arrayvec::ArrayVec;
10use hir_def::{ 11use hir_def::{
@@ -241,10 +242,13 @@ impl HirDisplay for ApplicationTy {
241 } 242 }
242 243
243 match self.ctor { 244 match self.ctor {
244 TypeCtor::Bool => write!(f, "bool")?, 245 TypeCtor::Scalar(Scalar::Bool) => write!(f, "bool")?,
245 TypeCtor::Char => write!(f, "char")?, 246 TypeCtor::Scalar(Scalar::Char) => write!(f, "char")?,
246 TypeCtor::Int(t) => write!(f, "{}", t)?, 247 TypeCtor::Scalar(Scalar::Float(t)) => {
247 TypeCtor::Float(t) => write!(f, "{}", t)?, 248 write!(f, "{}", primitive::float_ty_to_string(t))?
249 }
250 TypeCtor::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?,
251 TypeCtor::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
248 TypeCtor::Str => write!(f, "str")?, 252 TypeCtor::Str => write!(f, "str")?,
249 TypeCtor::Slice => { 253 TypeCtor::Slice => {
250 let t = self.parameters.as_single(); 254 let t = self.parameters.as_single();
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 4b683c5a7..657f011d2 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -41,7 +41,7 @@ use super::{
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, Scalar,
45}; 45};
46 46
47pub(crate) use unify::unify; 47pub(crate) use unify::unify;
@@ -684,8 +684,8 @@ impl InferTy {
684 fn fallback_value(self) -> Ty { 684 fn fallback_value(self) -> Ty {
685 match self { 685 match self {
686 InferTy::TypeVar(..) => Ty::Unknown, 686 InferTy::TypeVar(..) => Ty::Unknown,
687 InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())), 687 InferTy::IntVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Int(IntTy::I32))),
688 InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())), 688 InferTy::FloatVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))),
689 InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), 689 InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never),
690 } 690 }
691 } 691 }
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index cb59a6937..3fec0e431 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -4,7 +4,6 @@ use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use hir_def::{ 6use hir_def::{
7 builtin_type::Signedness,
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 7 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 8 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 9 resolver::resolver_for_expr,
@@ -16,10 +15,11 @@ use test_utils::mark;
16 15
17use crate::{ 16use crate::{
18 autoderef, method_resolution, op, 17 autoderef, method_resolution, op,
18 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 19 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 20 utils::{generics, variant_data, Generics},
21 ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, 21 ApplicationTy, Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness,
22 Rawness, Substs, TraitRef, Ty, TypeCtor, 22 Scalar, Substs, TraitRef, Ty, TypeCtor,
23}; 23};
24 24
25use super::{ 25use super::{
@@ -120,7 +120,10 @@ impl<'a> InferenceContext<'a> {
120 Expr::Missing => Ty::Unknown, 120 Expr::Missing => Ty::Unknown,
121 Expr::If { condition, then_branch, else_branch } => { 121 Expr::If { condition, then_branch, else_branch } => {
122 // if let is desugared to match, so this is always simple if 122 // if let is desugared to match, so this is always simple if
123 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 123 self.infer_expr(
124 *condition,
125 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))),
126 );
124 127
125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 128 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
126 let mut both_arms_diverge = Diverges::Always; 129 let mut both_arms_diverge = Diverges::Always;
@@ -203,7 +206,10 @@ impl<'a> InferenceContext<'a> {
203 label: label.map(|label| self.body[label].name.clone()), 206 label: label.map(|label| self.body[label].name.clone()),
204 }); 207 });
205 // while let is desugared to a match loop, so this is always simple while 208 // while let is desugared to a match loop, so this is always simple while
206 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 209 self.infer_expr(
210 *condition,
211 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))),
212 );
207 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 213 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
208 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 214 let _ctxt = self.breakables.pop().expect("breakable stack broken");
209 // the body may not run, so it diverging doesn't mean we diverge 215 // the body may not run, so it diverging doesn't mean we diverge
@@ -321,7 +327,7 @@ impl<'a> InferenceContext<'a> {
321 if let Some(guard_expr) = arm.guard { 327 if let Some(guard_expr) = arm.guard {
322 self.infer_expr( 328 self.infer_expr(
323 guard_expr, 329 guard_expr,
324 &Expectation::has_type(Ty::simple(TypeCtor::Bool)), 330 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))),
325 ); 331 );
326 } 332 }
327 333
@@ -534,10 +540,13 @@ impl<'a> InferenceContext<'a> {
534 match &inner_ty { 540 match &inner_ty {
535 // Fast path for builtins 541 // Fast path for builtins
536 Ty::Apply(ApplicationTy { 542 Ty::Apply(ApplicationTy {
537 ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), 543 ctor: TypeCtor::Scalar(Scalar::Int(_)),
544 ..
545 })
546 | Ty::Apply(ApplicationTy {
547 ctor: TypeCtor::Scalar(Scalar::Float(_)),
538 .. 548 ..
539 }) 549 })
540 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. })
541 | Ty::Infer(InferTy::IntVar(..)) 550 | Ty::Infer(InferTy::IntVar(..))
542 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, 551 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
543 // Otherwise we resolve via the std::ops::Neg trait 552 // Otherwise we resolve via the std::ops::Neg trait
@@ -548,8 +557,18 @@ impl<'a> InferenceContext<'a> {
548 UnaryOp::Not => { 557 UnaryOp::Not => {
549 match &inner_ty { 558 match &inner_ty {
550 // Fast path for builtins 559 // Fast path for builtins
551 Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) 560 Ty::Apply(ApplicationTy {
552 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) 561 ctor: TypeCtor::Scalar(Scalar::Bool),
562 ..
563 })
564 | Ty::Apply(ApplicationTy {
565 ctor: TypeCtor::Scalar(Scalar::Int(_)),
566 ..
567 })
568 | Ty::Apply(ApplicationTy {
569 ctor: TypeCtor::Scalar(Scalar::Uint(_)),
570 ..
571 })
553 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 572 | Ty::Infer(InferTy::IntVar(..)) => inner_ty,
554 // Otherwise we resolve via the std::ops::Not trait 573 // Otherwise we resolve via the std::ops::Not trait
555 _ => self 574 _ => self
@@ -561,7 +580,9 @@ impl<'a> InferenceContext<'a> {
561 Expr::BinaryOp { lhs, rhs, op } => match op { 580 Expr::BinaryOp { lhs, rhs, op } => match op {
562 Some(op) => { 581 Some(op) => {
563 let lhs_expectation = match op { 582 let lhs_expectation = match op {
564 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), 583 BinaryOp::LogicOp(..) => {
584 Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool)))
585 }
565 _ => Expectation::none(), 586 _ => Expectation::none(),
566 }; 587 };
567 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 588 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -688,7 +709,9 @@ impl<'a> InferenceContext<'a> {
688 ); 709 );
689 self.infer_expr( 710 self.infer_expr(
690 *repeat, 711 *repeat,
691 &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), 712 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint(
713 UintTy::Usize,
714 )))),
692 ); 715 );
693 } 716 }
694 } 717 }
@@ -696,22 +719,32 @@ impl<'a> InferenceContext<'a> {
696 Ty::apply_one(TypeCtor::Array, elem_ty) 719 Ty::apply_one(TypeCtor::Array, elem_ty)
697 } 720 }
698 Expr::Literal(lit) => match lit { 721 Expr::Literal(lit) => match lit {
699 Literal::Bool(..) => Ty::simple(TypeCtor::Bool), 722 Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)),
700 Literal::String(..) => { 723 Literal::String(..) => {
701 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) 724 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str))
702 } 725 }
703 Literal::ByteString(..) => { 726 Literal::ByteString(..) => {
704 let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); 727 let byte_type = Ty::simple(TypeCtor::Scalar(Scalar::Uint(UintTy::U8)));
705 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 728 let array_type = Ty::apply_one(TypeCtor::Array, byte_type);
706 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 729 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type)
707 } 730 }
708 Literal::Char(..) => Ty::simple(TypeCtor::Char), 731 Literal::Char(..) => Ty::simple(TypeCtor::Scalar(Scalar::Char)),
709 Literal::Int(_v, ty) => match ty { 732 Literal::Int(_v, ty) => match ty {
710 Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), 733 Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Int(
734 primitive::int_ty_from_builtin(*int_ty),
735 ))),
736 None => self.table.new_integer_var(),
737 },
738 Literal::Uint(_v, ty) => match ty {
739 Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint(
740 primitive::uint_ty_from_builtin(*int_ty),
741 ))),
711 None => self.table.new_integer_var(), 742 None => self.table.new_integer_var(),
712 }, 743 },
713 Literal::Float(_v, ty) => match ty { 744 Literal::Float(_v, ty) => match ty {
714 Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), 745 Some(float_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Float(
746 primitive::float_ty_from_builtin(*float_ty),
747 ))),
715 None => self.table.new_float_var(), 748 None => self.table.new_float_var(),
716 }, 749 },
717 }, 750 },
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 76984242e..57eb8cede 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -8,8 +8,8 @@ use test_utils::mark;
8 8
9use super::{InferenceContext, Obligation}; 9use super::{InferenceContext, Obligation};
10use crate::{ 10use crate::{
11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Substs, Ty, 11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs,
12 TyKind, TypeCtor, TypeWalk, 12 Ty, TyKind, TypeCtor, TypeWalk,
13}; 13};
14 14
15impl<'a> InferenceContext<'a> { 15impl<'a> InferenceContext<'a> {
@@ -300,10 +300,24 @@ impl InferenceTable {
300 | (other, Ty::Infer(InferTy::TypeVar(tv))) 300 | (other, Ty::Infer(InferTy::TypeVar(tv)))
301 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) 301 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other)
302 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) 302 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv)))
303 | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) 303 | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_))))
304 | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) 304 | (other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_))), Ty::Infer(InferTy::IntVar(tv)))
305 | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) 305 | (
306 | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { 306 Ty::Infer(InferTy::IntVar(tv)),
307 other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))),
308 )
309 | (
310 other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))),
311 Ty::Infer(InferTy::IntVar(tv)),
312 )
313 | (
314 Ty::Infer(InferTy::FloatVar(tv)),
315 other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))),
316 )
317 | (
318 other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))),
319 Ty::Infer(InferTy::FloatVar(tv)),
320 ) => {
307 // the type var is unknown since we tried to resolve it 321 // the type var is unknown since we tried to resolve it
308 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); 322 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone()));
309 true 323 true
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 50d248674..676519594 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -38,7 +38,6 @@ use itertools::Itertools;
38use crate::{ 38use crate::{
39 db::HirDatabase, 39 db::HirDatabase,
40 display::HirDisplay, 40 display::HirDisplay,
41 primitive::{FloatTy, IntTy},
42 utils::{generics, make_mut_slice, Generics}, 41 utils::{generics, make_mut_slice, Generics},
43}; 42};
44 43
@@ -50,7 +49,7 @@ pub use lower::{
50}; 49};
51pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 50pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
52 51
53pub use chalk_ir::{BoundVar, DebruijnIndex}; 52pub use chalk_ir::{BoundVar, DebruijnIndex, Scalar};
54 53
55#[derive(Clone, PartialEq, Eq, Debug, Hash)] 54#[derive(Clone, PartialEq, Eq, Debug, Hash)]
56pub enum Lifetime { 55pub enum Lifetime {
@@ -63,18 +62,8 @@ pub enum Lifetime {
63/// tuples. 62/// tuples.
64#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 63#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
65pub enum TypeCtor { 64pub enum TypeCtor {
66 /// The primitive boolean type. Written as `bool`. 65 /// a scalar type like `bool` or `u32`
67 Bool, 66 Scalar(Scalar),
68
69 /// The primitive character type; holds a Unicode scalar value
70 /// (a non-surrogate code point). Written as `char`.
71 Char,
72
73 /// A primitive integer type. For example, `i32`.
74 Int(IntTy),
75
76 /// A primitive floating-point type. For example, `f64`.
77 Float(FloatTy),
78 67
79 /// Structures, enumerations and unions. 68 /// Structures, enumerations and unions.
80 Adt(AdtId), 69 Adt(AdtId),
@@ -152,10 +141,7 @@ pub enum TypeCtor {
152impl TypeCtor { 141impl TypeCtor {
153 pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize { 142 pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize {
154 match self { 143 match self {
155 TypeCtor::Bool 144 TypeCtor::Scalar(_)
156 | TypeCtor::Char
157 | TypeCtor::Int(_)
158 | TypeCtor::Float(_)
159 | TypeCtor::Str 145 | TypeCtor::Str
160 | TypeCtor::Never => 0, 146 | TypeCtor::Never => 0,
161 TypeCtor::Slice 147 TypeCtor::Slice
@@ -197,10 +183,7 @@ impl TypeCtor {
197 183
198 pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> { 184 pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> {
199 match self { 185 match self {
200 TypeCtor::Bool 186 TypeCtor::Scalar(_)
201 | TypeCtor::Char
202 | TypeCtor::Int(_)
203 | TypeCtor::Float(_)
204 | TypeCtor::Str 187 | TypeCtor::Str
205 | TypeCtor::Never 188 | TypeCtor::Never
206 | TypeCtor::Slice 189 | TypeCtor::Slice
@@ -232,10 +215,7 @@ impl TypeCtor {
232 215
233 pub fn as_generic_def(self) -> Option<GenericDefId> { 216 pub fn as_generic_def(self) -> Option<GenericDefId> {
234 match self { 217 match self {
235 TypeCtor::Bool 218 TypeCtor::Scalar(_)
236 | TypeCtor::Char
237 | TypeCtor::Int(_)
238 | TypeCtor::Float(_)
239 | TypeCtor::Str 219 | TypeCtor::Str
240 | TypeCtor::Never 220 | TypeCtor::Never
241 | TypeCtor::Slice 221 | TypeCtor::Slice
@@ -741,11 +721,16 @@ impl Ty {
741 } 721 }
742 pub fn builtin(builtin: BuiltinType) -> Self { 722 pub fn builtin(builtin: BuiltinType) -> Self {
743 Ty::simple(match builtin { 723 Ty::simple(match builtin {
744 BuiltinType::Char => TypeCtor::Char, 724 BuiltinType::Char => TypeCtor::Scalar(Scalar::Char),
745 BuiltinType::Bool => TypeCtor::Bool, 725 BuiltinType::Bool => TypeCtor::Scalar(Scalar::Bool),
746 BuiltinType::Str => TypeCtor::Str, 726 BuiltinType::Str => TypeCtor::Str,
747 BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), 727 BuiltinType::Int(t) => TypeCtor::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))),
748 BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), 728 BuiltinType::Uint(t) => {
729 TypeCtor::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t)))
730 }
731 BuiltinType::Float(t) => {
732 TypeCtor::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t)))
733 }
749 }) 734 })
750 } 735 }
751 736
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index b3d1fe9a4..66d8de959 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -7,11 +7,8 @@ use std::{iter, sync::Arc};
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use hir_def::{ 9use hir_def::{
10 builtin_type::{IntBitness, Signedness}, 10 lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId,
11 lang_item::LangItemTarget, 11 GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId,
12 type_ref::Mutability,
13 AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId,
14 TraitId,
15}; 12};
16use hir_expand::name::Name; 13use hir_expand::name::Name;
17use rustc_hash::{FxHashMap, FxHashSet}; 14use rustc_hash::{FxHashMap, FxHashSet};
@@ -19,10 +16,10 @@ use rustc_hash::{FxHashMap, FxHashSet};
19use crate::{ 16use crate::{
20 autoderef, 17 autoderef,
21 db::HirDatabase, 18 db::HirDatabase,
22 primitive::{FloatBitness, FloatTy, IntTy}, 19 primitive::{self, FloatTy, IntTy, UintTy},
23 utils::all_super_traits, 20 utils::all_super_traits,
24 ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Substs, TraitEnvironment, TraitRef, Ty, 21 ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Scalar, Substs, TraitEnvironment,
25 TyKind, TypeCtor, TypeWalk, 22 TraitRef, Ty, TyKind, TypeCtor, TypeWalk,
26}; 23};
27 24
28/// This is used as a key for indexing impls. 25/// This is used as a key for indexing impls.
@@ -46,59 +43,23 @@ impl TyFingerprint {
46} 43}
47 44
48pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ 45pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
49 TyFingerprint::Apply(TypeCtor::Int(IntTy { 46 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I8))),
50 signedness: Signedness::Unsigned, 47 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I16))),
51 bitness: IntBitness::X8, 48 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I32))),
52 })), 49 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I64))),
53 TyFingerprint::Apply(TypeCtor::Int(IntTy { 50 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I128))),
54 signedness: Signedness::Unsigned, 51 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::Isize))),
55 bitness: IntBitness::X16, 52 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))),
56 })), 53 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U16))),
57 TyFingerprint::Apply(TypeCtor::Int(IntTy { 54 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U32))),
58 signedness: Signedness::Unsigned, 55 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U64))),
59 bitness: IntBitness::X32, 56 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U128))),
60 })), 57 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::Usize))),
61 TyFingerprint::Apply(TypeCtor::Int(IntTy {
62 signedness: Signedness::Unsigned,
63 bitness: IntBitness::X64,
64 })),
65 TyFingerprint::Apply(TypeCtor::Int(IntTy {
66 signedness: Signedness::Unsigned,
67 bitness: IntBitness::X128,
68 })),
69 TyFingerprint::Apply(TypeCtor::Int(IntTy {
70 signedness: Signedness::Unsigned,
71 bitness: IntBitness::Xsize,
72 })),
73 TyFingerprint::Apply(TypeCtor::Int(IntTy {
74 signedness: Signedness::Signed,
75 bitness: IntBitness::X8,
76 })),
77 TyFingerprint::Apply(TypeCtor::Int(IntTy {
78 signedness: Signedness::Signed,
79 bitness: IntBitness::X16,
80 })),
81 TyFingerprint::Apply(TypeCtor::Int(IntTy {
82 signedness: Signedness::Signed,
83 bitness: IntBitness::X32,
84 })),
85 TyFingerprint::Apply(TypeCtor::Int(IntTy {
86 signedness: Signedness::Signed,
87 bitness: IntBitness::X64,
88 })),
89 TyFingerprint::Apply(TypeCtor::Int(IntTy {
90 signedness: Signedness::Signed,
91 bitness: IntBitness::X128,
92 })),
93 TyFingerprint::Apply(TypeCtor::Int(IntTy {
94 signedness: Signedness::Signed,
95 bitness: IntBitness::Xsize,
96 })),
97]; 58];
98 59
99pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ 60pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
100 TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })), 61 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F32))),
101 TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })), 62 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))),
102]; 63];
103 64
104/// Trait impls defined or available in some crate. 65/// Trait impls defined or available in some crate.
@@ -257,14 +218,19 @@ impl Ty {
257 TypeCtor::ForeignType(type_alias_id) => { 218 TypeCtor::ForeignType(type_alias_id) => {
258 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); 219 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast()));
259 } 220 }
260 TypeCtor::Bool => lang_item_crate!("bool"), 221 TypeCtor::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
261 TypeCtor::Char => lang_item_crate!("char"), 222 TypeCtor::Scalar(Scalar::Char) => lang_item_crate!("char"),
262 TypeCtor::Float(f) => match f.bitness { 223 TypeCtor::Scalar(Scalar::Float(f)) => match f {
263 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 224 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
264 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), 225 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
265 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), 226 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
266 }, 227 },
267 TypeCtor::Int(i) => lang_item_crate!(i.ty_to_string()), 228 TypeCtor::Scalar(Scalar::Int(t)) => {
229 lang_item_crate!(primitive::int_ty_to_string(t))
230 }
231 TypeCtor::Scalar(Scalar::Uint(t)) => {
232 lang_item_crate!(primitive::uint_ty_to_string(t))
233 }
268 TypeCtor::Str => lang_item_crate!("str_alloc", "str"), 234 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
269 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"), 235 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
270 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"), 236 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
index 0870874fc..a4999c51d 100644
--- a/crates/hir_ty/src/op.rs
+++ b/crates/hir_ty/src/op.rs
@@ -2,15 +2,17 @@
2use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; 2use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
3 3
4use super::{InferTy, Ty, TypeCtor}; 4use super::{InferTy, Ty, TypeCtor};
5use crate::ApplicationTy; 5use crate::{ApplicationTy, Scalar};
6 6
7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { 7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
8 match op { 8 match op {
9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool), 9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)),
10 BinaryOp::Assignment { .. } => Ty::unit(), 10 BinaryOp::Assignment { .. } => Ty::unit(),
11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { 11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty {
12 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 12 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
13 TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, 13 TypeCtor::Scalar(Scalar::Int(_))
14 | TypeCtor::Scalar(Scalar::Uint(_))
15 | TypeCtor::Scalar(Scalar::Float(_)) => lhs_ty,
14 _ => Ty::Unknown, 16 _ => Ty::Unknown,
15 }, 17 },
16 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 18 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
@@ -18,7 +20,9 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
18 }, 20 },
19 BinaryOp::ArithOp(_) => match rhs_ty { 21 BinaryOp::ArithOp(_) => match rhs_ty {
20 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 22 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
21 TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty, 23 TypeCtor::Scalar(Scalar::Int(_))
24 | TypeCtor::Scalar(Scalar::Uint(_))
25 | TypeCtor::Scalar(Scalar::Float(_)) => rhs_ty,
22 _ => Ty::Unknown, 26 _ => Ty::Unknown,
23 }, 27 },
24 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, 28 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty,
@@ -29,15 +33,11 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
29 33
30pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { 34pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
31 match op { 35 match op {
32 BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool), 36 BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)),
33 BinaryOp::Assignment { op: None } => lhs_ty, 37 BinaryOp::Assignment { op: None } => lhs_ty,
34 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { 38 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty {
35 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 39 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
36 TypeCtor::Int(..) 40 TypeCtor::Scalar(_) | TypeCtor::Str => lhs_ty,
37 | TypeCtor::Float(..)
38 | TypeCtor::Str
39 | TypeCtor::Char
40 | TypeCtor::Bool => lhs_ty,
41 _ => Ty::Unknown, 41 _ => Ty::Unknown,
42 }, 42 },
43 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 43 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
@@ -48,7 +48,9 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
48 | BinaryOp::Assignment { op: Some(_) } 48 | BinaryOp::Assignment { op: Some(_) }
49 | BinaryOp::ArithOp(_) => match lhs_ty { 49 | BinaryOp::ArithOp(_) => match lhs_ty {
50 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 50 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
51 TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, 51 TypeCtor::Scalar(Scalar::Int(_))
52 | TypeCtor::Scalar(Scalar::Uint(_))
53 | TypeCtor::Scalar(Scalar::Float(_)) => lhs_ty,
52 _ => Ty::Unknown, 54 _ => Ty::Unknown,
53 }, 55 },
54 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 56 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
diff --git a/crates/hir_ty/src/primitive.rs b/crates/hir_ty/src/primitive.rs
index 37966b709..2449addfb 100644
--- a/crates/hir_ty/src/primitive.rs
+++ b/crates/hir_ty/src/primitive.rs
@@ -3,137 +3,63 @@
3//! * during type inference, they can be uncertain (ie, `let x = 92;`) 3//! * during type inference, they can be uncertain (ie, `let x = 92;`)
4//! * they don't belong to any particular crate. 4//! * they don't belong to any particular crate.
5 5
6use std::fmt; 6pub use chalk_ir::{FloatTy, IntTy, UintTy};
7 7pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint};
8pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; 8
9 9pub fn int_ty_to_string(ty: IntTy) -> &'static str {
10#[derive(Copy, Clone, Eq, PartialEq, Hash)] 10 match ty {
11pub struct IntTy { 11 IntTy::Isize => "isize",
12 pub signedness: Signedness, 12 IntTy::I8 => "i8",
13 pub bitness: IntBitness, 13 IntTy::I16 => "i16",
14} 14 IntTy::I32 => "i32",
15 15 IntTy::I64 => "i64",
16impl fmt::Debug for IntTy { 16 IntTy::I128 => "i128",
17 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18 fmt::Display::fmt(self, f)
19 }
20}
21
22impl fmt::Display for IntTy {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 write!(f, "{}", self.ty_to_string())
25 }
26}
27
28impl IntTy {
29 pub fn isize() -> IntTy {
30 IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize }
31 }
32
33 pub fn i8() -> IntTy {
34 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 }
35 }
36
37 pub fn i16() -> IntTy {
38 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 }
39 }
40
41 pub fn i32() -> IntTy {
42 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 }
43 }
44
45 pub fn i64() -> IntTy {
46 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 }
47 }
48
49 pub fn i128() -> IntTy {
50 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 }
51 } 17 }
52
53 pub fn usize() -> IntTy {
54 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize }
55 }
56
57 pub fn u8() -> IntTy {
58 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 }
59 }
60
61 pub fn u16() -> IntTy {
62 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 }
63 }
64
65 pub fn u32() -> IntTy {
66 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 }
67 }
68
69 pub fn u64() -> IntTy {
70 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 }
71 }
72
73 pub fn u128() -> IntTy {
74 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 }
75 }
76
77 pub fn ty_to_string(self) -> &'static str {
78 match (self.signedness, self.bitness) {
79 (Signedness::Signed, IntBitness::Xsize) => "isize",
80 (Signedness::Signed, IntBitness::X8) => "i8",
81 (Signedness::Signed, IntBitness::X16) => "i16",
82 (Signedness::Signed, IntBitness::X32) => "i32",
83 (Signedness::Signed, IntBitness::X64) => "i64",
84 (Signedness::Signed, IntBitness::X128) => "i128",
85 (Signedness::Unsigned, IntBitness::Xsize) => "usize",
86 (Signedness::Unsigned, IntBitness::X8) => "u8",
87 (Signedness::Unsigned, IntBitness::X16) => "u16",
88 (Signedness::Unsigned, IntBitness::X32) => "u32",
89 (Signedness::Unsigned, IntBitness::X64) => "u64",
90 (Signedness::Unsigned, IntBitness::X128) => "u128",
91 }
92 }
93}
94
95#[derive(Copy, Clone, PartialEq, Eq, Hash)]
96pub struct FloatTy {
97 pub bitness: FloatBitness,
98} 18}
99 19
100impl fmt::Debug for FloatTy { 20pub fn uint_ty_to_string(ty: UintTy) -> &'static str {
101 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 21 match ty {
102 fmt::Display::fmt(self, f) 22 UintTy::Usize => "usize",
23 UintTy::U8 => "u8",
24 UintTy::U16 => "u16",
25 UintTy::U32 => "u32",
26 UintTy::U64 => "u64",
27 UintTy::U128 => "u128",
103 } 28 }
104} 29}
105 30
106impl fmt::Display for FloatTy { 31pub fn float_ty_to_string(ty: FloatTy) -> &'static str {
107 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 32 match ty {
108 write!(f, "{}", self.ty_to_string()) 33 FloatTy::F32 => "f32",
34 FloatTy::F64 => "f64",
109 } 35 }
110} 36}
111 37
112impl FloatTy { 38pub(super) fn int_ty_from_builtin(t: BuiltinInt) -> IntTy {
113 pub fn f32() -> FloatTy { 39 match t {
114 FloatTy { bitness: FloatBitness::X32 } 40 BuiltinInt::Isize => IntTy::Isize,
115 } 41 BuiltinInt::I8 => IntTy::I8,
116 42 BuiltinInt::I16 => IntTy::I16,
117 pub fn f64() -> FloatTy { 43 BuiltinInt::I32 => IntTy::I32,
118 FloatTy { bitness: FloatBitness::X64 } 44 BuiltinInt::I64 => IntTy::I64,
119 } 45 BuiltinInt::I128 => IntTy::I128,
120
121 pub fn ty_to_string(self) -> &'static str {
122 match self.bitness {
123 FloatBitness::X32 => "f32",
124 FloatBitness::X64 => "f64",
125 }
126 } 46 }
127} 47}
128 48
129impl From<BuiltinInt> for IntTy { 49pub(super) fn uint_ty_from_builtin(t: BuiltinUint) -> UintTy {
130 fn from(t: BuiltinInt) -> Self { 50 match t {
131 IntTy { signedness: t.signedness, bitness: t.bitness } 51 BuiltinUint::Usize => UintTy::Usize,
52 BuiltinUint::U8 => UintTy::U8,
53 BuiltinUint::U16 => UintTy::U16,
54 BuiltinUint::U32 => UintTy::U32,
55 BuiltinUint::U64 => UintTy::U64,
56 BuiltinUint::U128 => UintTy::U128,
132 } 57 }
133} 58}
134 59
135impl From<BuiltinFloat> for FloatTy { 60pub(super) fn float_ty_from_builtin(t: BuiltinFloat) -> FloatTy {
136 fn from(t: BuiltinFloat) -> Self { 61 match t {
137 FloatTy { bitness: t.bitness } 62 BuiltinFloat::F32 => FloatTy::F32,
63 BuiltinFloat::F64 => FloatTy::F64,
138 } 64 }
139} 65}
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 8700d664e..5a3cb7906 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -4,7 +4,7 @@
4//! conversions. 4//! conversions.
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar, 7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex,
8 UniverseIndex, 8 UniverseIndex,
9}; 9};
10use chalk_solve::rust_ir; 10use chalk_solve::rust_ir;
@@ -14,10 +14,11 @@ use hir_def::{type_ref::Mutability, AssocContainerId, GenericDefId, Lookup, Type
14 14
15use crate::{ 15use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, 17 primitive::UintTy,
18 traits::{Canonical, Obligation}, 18 traits::{Canonical, Obligation},
19 ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, 19 ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId,
20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor, 20 ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind,
21 TypeCtor,
21}; 22};
22 23
23use super::interner::*; 24use super::interner::*;
@@ -63,19 +64,7 @@ impl ToChalk for Ty {
63 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) 64 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
64 } 65 }
65 66
66 TypeCtor::Bool => chalk_ir::TyKind::Scalar(Scalar::Bool).intern(&Interner), 67 TypeCtor::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner),
67 TypeCtor::Char => chalk_ir::TyKind::Scalar(Scalar::Char).intern(&Interner),
68 TypeCtor::Int(int_ty) => {
69 chalk_ir::TyKind::Scalar(int_ty_to_chalk(int_ty)).intern(&Interner)
70 }
71 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
72 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
73 .intern(&Interner)
74 }
75 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
76 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
77 .intern(&Interner)
78 }
79 68
80 TypeCtor::Tuple { cardinality } => { 69 TypeCtor::Tuple { cardinality } => {
81 let substitution = apply_ty.parameters.to_chalk(db); 70 let substitution = apply_ty.parameters.to_chalk(db);
@@ -219,22 +208,7 @@ impl ToChalk for Ty {
219 apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst) 208 apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst)
220 } 209 }
221 210
222 chalk_ir::TyKind::Scalar(Scalar::Bool) => Ty::simple(TypeCtor::Bool), 211 chalk_ir::TyKind::Scalar(scalar) => Ty::simple(TypeCtor::Scalar(scalar)),
223 chalk_ir::TyKind::Scalar(Scalar::Char) => Ty::simple(TypeCtor::Char),
224 chalk_ir::TyKind::Scalar(Scalar::Int(int_ty)) => Ty::simple(TypeCtor::Int(IntTy {
225 signedness: Signedness::Signed,
226 bitness: bitness_from_chalk_int(int_ty),
227 })),
228 chalk_ir::TyKind::Scalar(Scalar::Uint(uint_ty)) => Ty::simple(TypeCtor::Int(IntTy {
229 signedness: Signedness::Unsigned,
230 bitness: bitness_from_chalk_uint(uint_ty),
231 })),
232 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
233 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }))
234 }
235 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
236 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }))
237 }
238 chalk_ir::TyKind::Tuple(cardinality, subst) => { 212 chalk_ir::TyKind::Tuple(cardinality, subst) => {
239 apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst) 213 apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst)
240 } 214 }
@@ -292,8 +266,7 @@ fn ref_to_chalk(
292/// fake constant here, because Chalks built-in logic may expect it to be there. 266/// fake constant here, because Chalks built-in logic may expect it to be there.
293fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { 267fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
294 let arg = subst[0].clone().to_chalk(db); 268 let arg = subst[0].clone().to_chalk(db);
295 let usize_ty = 269 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
296 chalk_ir::TyKind::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner);
297 let const_ = chalk_ir::ConstData { 270 let const_ = chalk_ir::ConstData {
298 ty: usize_ty, 271 ty: usize_ty,
299 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), 272 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
@@ -364,55 +337,6 @@ impl ToChalk for OpaqueTyId {
364 } 337 }
365} 338}
366 339
367fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness {
368 use chalk_ir::UintTy;
369
370 match uint_ty {
371 UintTy::Usize => IntBitness::Xsize,
372 UintTy::U8 => IntBitness::X8,
373 UintTy::U16 => IntBitness::X16,
374 UintTy::U32 => IntBitness::X32,
375 UintTy::U64 => IntBitness::X64,
376 UintTy::U128 => IntBitness::X128,
377 }
378}
379
380fn bitness_from_chalk_int(int_ty: chalk_ir::IntTy) -> IntBitness {
381 use chalk_ir::IntTy;
382
383 match int_ty {
384 IntTy::Isize => IntBitness::Xsize,
385 IntTy::I8 => IntBitness::X8,
386 IntTy::I16 => IntBitness::X16,
387 IntTy::I32 => IntBitness::X32,
388 IntTy::I64 => IntBitness::X64,
389 IntTy::I128 => IntBitness::X128,
390 }
391}
392
393fn int_ty_to_chalk(int_ty: IntTy) -> Scalar {
394 use chalk_ir::{IntTy, UintTy};
395
396 match int_ty.signedness {
397 Signedness::Signed => Scalar::Int(match int_ty.bitness {
398 IntBitness::Xsize => IntTy::Isize,
399 IntBitness::X8 => IntTy::I8,
400 IntBitness::X16 => IntTy::I16,
401 IntBitness::X32 => IntTy::I32,
402 IntBitness::X64 => IntTy::I64,
403 IntBitness::X128 => IntTy::I128,
404 }),
405 Signedness::Unsigned => Scalar::Uint(match int_ty.bitness {
406 IntBitness::Xsize => UintTy::Usize,
407 IntBitness::X8 => UintTy::U8,
408 IntBitness::X16 => UintTy::U16,
409 IntBitness::X32 => UintTy::U32,
410 IntBitness::X64 => UintTy::U64,
411 IntBitness::X128 => UintTy::U128,
412 }),
413 }
414}
415
416impl ToChalk for Mutability { 340impl ToChalk for Mutability {
417 type Chalk = chalk_ir::Mutability; 341 type Chalk = chalk_ir::Mutability;
418 fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk { 342 fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk {