Normalize type alias in projected_ty
This commit is contained in:
parent
41b8b0b77d
commit
832eb0d94c
@ -3,9 +3,14 @@
|
|||||||
use std::{fmt::Display, iter};
|
use std::{fmt::Display, iter};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
consteval::usize_const, db::HirDatabase, display::HirDisplay, infer::PointerCast,
|
consteval::usize_const,
|
||||||
lang_items::is_box, mapping::ToChalk, CallableDefId, ClosureId, Const, ConstScalar,
|
db::HirDatabase,
|
||||||
InferenceResult, Interner, MemoryMap, Substitution, Ty, TyKind,
|
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 base_db::CrateId;
|
||||||
use chalk_ir::Mutability;
|
use chalk_ir::Mutability;
|
||||||
@ -34,6 +39,7 @@
|
|||||||
};
|
};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use stdx::{impl_from, never};
|
use stdx::{impl_from, never};
|
||||||
|
use triomphe::Arc;
|
||||||
|
|
||||||
use super::consteval::{intern_const_scalar, try_const_usize};
|
use super::consteval::{intern_const_scalar, try_const_usize};
|
||||||
|
|
||||||
@ -131,11 +137,19 @@ pub enum ProjectionElem<V, T> {
|
|||||||
impl<V, T> ProjectionElem<V, T> {
|
impl<V, T> ProjectionElem<V, T> {
|
||||||
pub fn projected_ty(
|
pub fn projected_ty(
|
||||||
&self,
|
&self,
|
||||||
base: Ty,
|
mut base: Ty,
|
||||||
db: &dyn HirDatabase,
|
db: &dyn HirDatabase,
|
||||||
closure_field: impl FnOnce(ClosureId, &Substitution, usize) -> Ty,
|
closure_field: impl FnOnce(ClosureId, &Substitution, usize) -> Ty,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
) -> Ty {
|
) -> 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 {
|
match self {
|
||||||
ProjectionElem::Deref => match &base.data(Interner).kind {
|
ProjectionElem::Deref => match &base.data(Interner).kind {
|
||||||
TyKind::Raw(_, inner) | TyKind::Ref(_, _, inner) => inner.clone(),
|
TyKind::Raw(_, inner) | TyKind::Ref(_, _, inner) => inner.clone(),
|
||||||
|
@ -1084,6 +1084,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]
|
#[test]
|
||||||
fn allow_unused_mut_for_identifiers_starting_with_underline() {
|
fn allow_unused_mut_for_identifiers_starting_with_underline() {
|
||||||
check_diagnostics(
|
check_diagnostics(
|
||||||
|
Loading…
Reference in New Issue
Block a user