Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/mir.rs22
-rw-r--r--crates/ide-diagnostics/src/handlers/mutability_errors.rs27
2 files changed, 45 insertions, 4 deletions
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs
index dc846fc394..da5b496e14 100644
--- a/crates/hir-ty/src/mir.rs
+++ b/crates/hir-ty/src/mir.rs
@@ -3,9 +3,14 @@
use std::{fmt::Display, iter};
use crate::{
- consteval::usize_const, db::HirDatabase, display::HirDisplay, infer::PointerCast,
- lang_items::is_box, mapping::ToChalk, CallableDefId, ClosureId, Const, ConstScalar,
- InferenceResult, Interner, MemoryMap, Substitution, Ty, TyKind,
+ consteval::usize_const,
+ db::HirDatabase,
+ display::HirDisplay,
+ infer::{normalize, PointerCast},
+ lang_items::is_box,
+ mapping::ToChalk,
+ CallableDefId, ClosureId, Const, ConstScalar, InferenceResult, Interner, MemoryMap,
+ Substitution, TraitEnvironment, Ty, TyKind,
};
use base_db::CrateId;
use chalk_ir::Mutability;
@@ -34,6 +39,7 @@ pub use monomorphization::{
};
use smallvec::{smallvec, SmallVec};
use stdx::{impl_from, never};
+use triomphe::Arc;
use super::consteval::{intern_const_scalar, try_const_usize};
@@ -131,11 +137,19 @@ pub enum ProjectionElem<V, T> {
impl<V, T> ProjectionElem<V, T> {
pub fn projected_ty(
&self,
- base: Ty,
+ mut base: Ty,
db: &dyn HirDatabase,
closure_field: impl FnOnce(ClosureId, &Substitution, usize) -> Ty,
krate: CrateId,
) -> Ty {
+ if matches!(base.data(Interner).kind, TyKind::Alias(_) | TyKind::AssociatedType(..)) {
+ base = normalize(
+ db,
+ // FIXME: we should get this from caller
+ Arc::new(TraitEnvironment::empty(krate)),
+ base,
+ );
+ }
match self {
ProjectionElem::Deref => match &base.data(Interner).kind {
TyKind::Raw(_, inner) | TyKind::Ref(_, _, inner) => inner.clone(),
diff --git a/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
index 935f12a396..e0c3bedce4 100644
--- a/crates/ide-diagnostics/src/handlers/mutability_errors.rs
+++ b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
@@ -1085,6 +1085,33 @@ fn f() {
}
#[test]
+ fn regression_15143() {
+ check_diagnostics(
+ r#"
+ trait Tr {
+ type Ty;
+ }
+
+ struct A;
+
+ impl Tr for A {
+ type Ty = (u32, i64);
+ }
+
+ struct B<T: Tr> {
+ f: <T as Tr>::Ty,
+ }
+
+ fn main(b: B<A>) {
+ let f = b.f.0;
+ f = 5;
+ //^^^^^ 💡 error: cannot mutate immutable variable `f`
+ }
+ "#,
+ );
+ }
+
+ #[test]
fn allow_unused_mut_for_identifiers_starting_with_underline() {
check_diagnostics(
r#"