diff options
| author | hkalbasi <hamidrezakalbasi@protonmail.com> | 2023-07-17 01:16:26 +0330 |
|---|---|---|
| committer | hkalbasi <hamidrezakalbasi@protonmail.com> | 2023-07-17 01:16:26 +0330 |
| commit | 832eb0d94c54e9d983e4f2df2ce9b78e6edd30f6 (patch) | |
| tree | 30712fff458713d681f7ff90209d2021f2eb534b | |
| parent | 41b8b0b77d5f30ff63aa3c2fdf87e643ca9481e5 (diff) | |
| download | rust-832eb0d94c54e9d983e4f2df2ce9b78e6edd30f6.tar.gz rust-832eb0d94c54e9d983e4f2df2ce9b78e6edd30f6.zip | |
Normalize type alias in projected_ty
| -rw-r--r-- | crates/hir-ty/src/mir.rs | 22 | ||||
| -rw-r--r-- | crates/ide-diagnostics/src/handlers/mutability_errors.rs | 27 |
2 files changed, 45 insertions, 4 deletions
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs index dc846fc3947..da5b496e141 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 935f12a3969..e0c3bedce46 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#" |
