diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 00b0dc08252..fc1a74641cc 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -14,7 +14,7 @@ use hir_def::{ per_ns::PerNs, resolver::{HasResolver, Resolver}, src::HasSource as _, - type_ref::{Mutability, TypeRef}, + type_ref::TypeRef, AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, @@ -32,8 +32,8 @@ use hir_ty::{ method_resolution, traits::{FnTrait, Solution, SolutionVariables}, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, - InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, - Ty, TyDefId, TyVariableKind, + InEnvironment, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, + TraitEnvironment, Ty, TyDefId, TyVariableKind, }; use rustc_hash::FxHashSet; use stdx::{format_to, impl_from}; @@ -836,7 +836,7 @@ pub enum Access { impl From for Access { fn from(mutability: Mutability) -> Access { match mutability { - Mutability::Shared => Access::Shared, + Mutability::Not => Access::Shared, Mutability::Mut => Access::Exclusive, } } @@ -865,7 +865,10 @@ impl SelfParam { .params .first() .map(|param| match *param { - TypeRef::Reference(.., mutability) => mutability.into(), + TypeRef::Reference(.., mutability) => match mutability { + hir_def::type_ref::Mutability::Shared => Access::Shared, + hir_def::type_ref::Mutability::Mut => Access::Exclusive, + }, _ => Access::Owned, }) .unwrap_or(Access::Owned) diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index f3a4333cb74..d4a8b48e655 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -8,6 +8,7 @@ use crate::{ TraitRef, Ty, }; use arrayvec::ArrayVec; +use chalk_ir::Mutability; use hir_def::{ db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, AssocContainerId, HasModule, Lookup, ModuleId, TraitId, @@ -291,9 +292,23 @@ impl HirDisplay for Ty { t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); if matches!(self, Ty::Raw(..)) { - write!(f, "*{}", m.as_keyword_for_ptr())?; + write!( + f, + "*{}", + match m { + Mutability::Not => "const ", + Mutability::Mut => "mut ", + } + )?; } else { - write!(f, "&{}", m.as_keyword_for_ref())?; + write!( + f, + "&{}", + match m { + Mutability::Not => "", + Mutability::Mut => "mut ", + } + )?; } let datas; diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 18a4f5e8af7..4d771a91e8d 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -18,6 +18,7 @@ use std::mem; use std::ops::Index; use std::sync::Arc; +use chalk_ir::Mutability; use hir_def::{ body::Body, data::{ConstData, FunctionData, StaticData}, @@ -25,7 +26,7 @@ use hir_def::{ lang_item::LangItemTarget, path::{path, Path}, resolver::{HasResolver, Resolver, TypeNs}, - type_ref::{Mutability, TypeRef}, + type_ref::TypeRef, AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId, TypeAliasId, VariantId, }; @@ -87,7 +88,7 @@ impl BindingMode { fn convert(annotation: BindingAnnotation) -> BindingMode { match annotation { BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, - BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared), + BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not), BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut), } } diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index c33d8c61e4a..cf0a3add49d 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs @@ -4,8 +4,8 @@ //! //! See: https://doc.rust-lang.org/nomicon/coercions.html -use chalk_ir::TyVariableKind; -use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; +use chalk_ir::{Mutability, TyVariableKind}; +use hir_def::lang_item::LangItemTarget; use test_utils::mark; use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; @@ -73,20 +73,20 @@ impl<'a> InferenceContext<'a> { match (&mut from_ty, to_ty) { // `*mut T` -> `*const T` // `&mut T` -> `&T` - (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Shared, ..)) - | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Shared, ..)) => { + (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..)) + | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => { *m1 = *m2; } // `&T` -> `*const T` // `&mut T` -> `*mut T`/`*const T` - (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Shared, ..)) + (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..)) | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { from_ty = Ty::Raw(m2, substs.clone()); } // Illegal mutability conversion - (Ty::Raw(Mutability::Shared, ..), Ty::Raw(Mutability::Mut, ..)) - | (Ty::Ref(Mutability::Shared, ..), Ty::Ref(Mutability::Mut, ..)) => return false, + (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..)) + | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false, // `{function_type}` -> `fn()` (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 7852b3d23b1..cf1f1038a9b 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -3,7 +3,7 @@ use std::iter::{repeat, repeat_with}; use std::{mem, sync::Arc}; -use chalk_ir::TyVariableKind; +use chalk_ir::{Mutability, TyVariableKind}; use hir_def::{ expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, path::{GenericArg, GenericArgs}, @@ -15,12 +15,14 @@ use syntax::ast::RangeOp; use test_utils::mark; use crate::{ - autoderef, method_resolution, op, + autoderef, + lower::lower_to_chalk_mutability, + method_resolution, op, primitive::{self, UintTy}, traits::{FnTrait, InEnvironment}, utils::{generics, variant_data, Generics}, - Binders, CallableDefId, FnPointer, FnSig, Mutability, Obligation, OpaqueTyId, Rawness, Scalar, - Substs, TraitRef, Ty, + Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, Substs, + TraitRef, Ty, }; use super::{ @@ -462,10 +464,11 @@ impl<'a> InferenceContext<'a> { cast_ty } Expr::Ref { expr, rawness, mutability } => { + let mutability = lower_to_chalk_mutability(*mutability); let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = &expected.ty.as_reference_or_ptr() { - if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { + if *exp_mutability == Mutability::Mut && mutability == Mutability::Not { // FIXME: throw type error - expected mut reference but found shared ref, // which cannot be coerced } @@ -479,8 +482,8 @@ impl<'a> InferenceContext<'a> { }; let inner_ty = self.infer_expr_inner(*expr, &expectation); match rawness { - Rawness::RawPtr => Ty::Raw(*mutability, Substs::single(inner_ty)), - Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)), + Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), + Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), } } Expr::Box { expr } => { @@ -684,11 +687,11 @@ impl<'a> InferenceContext<'a> { } Expr::Literal(lit) => match lit { Literal::Bool(..) => Ty::Scalar(Scalar::Bool), - Literal::String(..) => Ty::Ref(Mutability::Shared, Substs::single(Ty::Str)), + Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), Literal::ByteString(..) => { let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); let array_type = Ty::Array(Substs::single(byte_type)); - Ty::Ref(Mutability::Shared, Substs::single(array_type)) + Ty::Ref(Mutability::Not, Substs::single(array_type)) } Literal::Char(..) => Ty::Scalar(Scalar::Char), Literal::Int(_v, ty) => match ty { diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index a318e47f3ba..eb099311ca7 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs @@ -3,17 +3,17 @@ use std::iter::repeat; use std::sync::Arc; +use chalk_ir::Mutability; use hir_def::{ expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, path::Path, - type_ref::Mutability, FieldId, }; use hir_expand::name::Name; use test_utils::mark; use super::{BindingMode, Expectation, InferenceContext}; -use crate::{utils::variant_data, Substs, Ty}; +use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty}; impl<'a> InferenceContext<'a> { fn infer_tuple_struct_pat( @@ -103,7 +103,7 @@ impl<'a> InferenceContext<'a> { expected = inner; default_bm = match default_bm { BindingMode::Move => BindingMode::Ref(mutability), - BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), + BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not), BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability), } } @@ -152,9 +152,10 @@ impl<'a> InferenceContext<'a> { } } Pat::Ref { pat, mutability } => { + let mutability = lower_to_chalk_mutability(*mutability); let expectation = match expected.as_reference() { Some((inner_ty, exp_mut)) => { - if *mutability != exp_mut { + if mutability != exp_mut { // FIXME: emit type error? } inner_ty @@ -162,7 +163,7 @@ impl<'a> InferenceContext<'a> { _ => &Ty::Unknown, }; let subty = self.infer_pat(*pat, expectation, default_bm); - Ty::Ref(*mutability, Substs::single(subty)) + Ty::Ref(mutability, Substs::single(subty)) } Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( p.as_ref(), diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 9bcaf6fa72b..c2a20c480d0 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -27,11 +27,9 @@ use std::{iter, mem, ops::Deref, sync::Arc}; use base_db::salsa; use hir_def::{ - builtin_type::BuiltinType, - expr::ExprId, - type_ref::{Mutability, Rawness}, - AdtId, AssocContainerId, DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId, - Lookup, TraitId, TypeAliasId, TypeParamId, + builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AdtId, AssocContainerId, + DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, + TypeAliasId, TypeParamId, }; use itertools::Itertools; @@ -49,7 +47,7 @@ pub use lower::{ }; pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; -pub use chalk_ir::{BoundVar, DebruijnIndex, Scalar, TyVariableKind}; +pub use chalk_ir::{BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind}; #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum Lifetime { diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index ca06c9fe2d3..1b5843d48a0 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -8,6 +8,7 @@ use std::{iter, sync::Arc}; use base_db::CrateId; +use chalk_ir::Mutability; use hir_def::{ adt::StructKind, builtin_type::BuiltinType, @@ -157,7 +158,7 @@ impl Ty { } TypeRef::RawPtr(inner, mutability) => { let inner_ty = Ty::from_hir(ctx, inner); - Ty::Raw(*mutability, Substs::single(inner_ty)) + Ty::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) } TypeRef::Array(inner) => { let inner_ty = Ty::from_hir(ctx, inner); @@ -169,7 +170,7 @@ impl Ty { } TypeRef::Reference(inner, _, mutability) => { let inner_ty = Ty::from_hir(ctx, inner); - Ty::Ref(*mutability, Substs::single(inner_ty)) + Ty::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) } TypeRef::Placeholder => Ty::Unknown, TypeRef::Fn(params, is_varargs) => { @@ -1259,3 +1260,10 @@ pub(crate) fn return_type_impl_traits( Some(Arc::new(Binders::new(num_binders, return_type_impl_traits))) } } + +pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability { + match m { + hir_def::type_ref::Mutability::Shared => Mutability::Not, + hir_def::type_ref::Mutability::Mut => Mutability::Mut, + } +} diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index dd5109d4eec..f301a84777e 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -6,9 +6,10 @@ use std::{iter, sync::Arc}; use arrayvec::ArrayVec; use base_db::CrateId; +use chalk_ir::Mutability; use hir_def::{ - lang_item::LangItemTarget, type_ref::Mutability, AdtId, AssocContainerId, AssocItemId, - FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, TypeAliasId, + lang_item::LangItemTarget, AdtId, AssocContainerId, AssocItemId, FunctionId, GenericDefId, + HasModule, ImplId, Lookup, ModuleId, TraitId, TypeAliasId, }; use hir_expand::name::Name; use rustc_hash::{FxHashMap, FxHashSet}; @@ -251,7 +252,7 @@ impl Ty { } Ty::Str => lang_item_crate!("str_alloc", "str"), Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"), - Ty::Raw(Mutability::Shared, _) => lang_item_crate!("const_ptr"), + Ty::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), Ty::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), Ty::Dyn(_) => { return self.dyn_trait().and_then(|trait_| { @@ -429,7 +430,7 @@ fn iterate_method_candidates_with_autoref( } let refed = Canonical { kinds: deref_chain[0].kinds.clone(), - value: Ty::Ref(Mutability::Shared, Substs::single(deref_chain[0].value.clone())), + value: Ty::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())), }; if iterate_method_candidates_by_receiver( &refed, diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 6e6055d809f..db1760e6c56 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -10,7 +10,7 @@ use chalk_ir::{ use chalk_solve::rust_ir; use base_db::salsa::InternKey; -use hir_def::{type_ref::Mutability, AssocContainerId, GenericDefId, Lookup, TypeAliasId}; +use hir_def::{AssocContainerId, GenericDefId, Lookup, TypeAliasId}; use crate::{ db::HirDatabase, @@ -65,7 +65,7 @@ impl ToChalk for Ty { } Ty::Raw(mutability, substs) => { let ty = substs[0].clone().to_chalk(db); - chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) + chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner) } Ty::Slice(substs) => { chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner) @@ -198,11 +198,11 @@ impl ToChalk for Ty { Ty::Tuple(cardinality, from_chalk(db, subst)) } chalk_ir::TyKind::Raw(mutability, ty) => { - Ty::Raw(from_chalk(db, mutability), Substs::single(from_chalk(db, ty))) + Ty::Raw(mutability, Substs::single(from_chalk(db, ty))) } chalk_ir::TyKind::Slice(ty) => Ty::Slice(Substs::single(from_chalk(db, ty))), chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { - Ty::Ref(from_chalk(db, mutability), Substs::single(from_chalk(db, ty))) + Ty::Ref(mutability, Substs::single(from_chalk(db, ty))) } chalk_ir::TyKind::Str => Ty::Str, chalk_ir::TyKind::Never => Ty::Never, @@ -230,12 +230,12 @@ impl ToChalk for Ty { /// fake lifetime here, because Chalks built-in logic may expect it to be there. fn ref_to_chalk( db: &dyn HirDatabase, - mutability: Mutability, + mutability: chalk_ir::Mutability, subst: Substs, ) -> chalk_ir::Ty { let arg = subst[0].clone().to_chalk(db); let lifetime = LifetimeData::Static.intern(&Interner); - chalk_ir::TyKind::Ref(mutability.to_chalk(db), lifetime, arg).intern(&Interner) + chalk_ir::TyKind::Ref(mutability, lifetime, arg).intern(&Interner) } /// We currently don't model constants, but Chalk does. So, we have to insert a @@ -313,22 +313,6 @@ impl ToChalk for OpaqueTyId { } } -impl ToChalk for Mutability { - type Chalk = chalk_ir::Mutability; - fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk { - match self { - Mutability::Shared => chalk_ir::Mutability::Not, - Mutability::Mut => chalk_ir::Mutability::Mut, - } - } - fn from_chalk(_db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { - match chalk { - chalk_ir::Mutability::Mut => Mutability::Mut, - chalk_ir::Mutability::Not => Mutability::Shared, - } - } -} - impl ToChalk for hir_def::ImplId { type Chalk = ImplId;