Skip to content

Commit 81b68b2

Browse files
committed
fix: Panic while canonicalizing erroneous projection type
1 parent f96e296 commit 81b68b2

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

src/tools/rust-analyzer/crates/hir-ty/src/infer.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1436,7 +1436,8 @@ impl<'a> InferenceContext<'a> {
14361436
let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
14371437
let ty = match ty.kind(Interner) {
14381438
TyKind::Alias(AliasTy::Projection(proj_ty)) => {
1439-
self.db.normalize_projection(proj_ty.clone(), self.table.trait_env.clone())
1439+
let ty = self.table.normalize_projection_ty(proj_ty.clone());
1440+
self.table.resolve_ty_shallow(&ty)
14401441
}
14411442
_ => ty,
14421443
};

src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,3 +2141,24 @@ fn test() {
21412141
}"#,
21422142
);
21432143
}
2144+
2145+
#[test]
2146+
fn issue_17866() {
2147+
check_infer(
2148+
r#"
2149+
trait T {
2150+
type A;
2151+
}
2152+
2153+
type Foo = <S as T>::A;
2154+
2155+
fn main() {
2156+
Foo {};
2157+
}
2158+
"#,
2159+
expect![[r#"
2160+
60..75 '{ Foo {}; }': ()
2161+
66..72 'Foo {}': {unknown}
2162+
"#]],
2163+
);
2164+
}

src/tools/rust-analyzer/crates/hir-ty/src/traits.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ use hir_def::{
1414
};
1515
use hir_expand::name::Name;
1616
use intern::sym;
17-
use stdx::panic_context;
17+
use stdx::{never, panic_context};
1818
use triomphe::Arc;
1919

2020
use crate::{
2121
db::HirDatabase, infer::unify::InferenceTable, utils::UnevaluatedConstEvaluatorFolder, AliasEq,
2222
AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment, Interner, ProjectionTy,
23-
ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, WhereClause,
23+
ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, TypeFlags, WhereClause,
2424
};
2525

2626
/// This controls how much 'time' we give the Chalk solver before giving up.
@@ -90,6 +90,16 @@ pub(crate) fn normalize_projection_query(
9090
projection: ProjectionTy,
9191
env: Arc<TraitEnvironment>,
9292
) -> Ty {
93+
if projection.substitution.iter(Interner).any(|arg| {
94+
arg.ty(Interner)
95+
.is_some_and(|ty| ty.data(Interner).flags.intersects(TypeFlags::HAS_TY_INFER))
96+
}) {
97+
never!(
98+
"Invoking `normalize_projection_query` with a projection type containing inference var"
99+
);
100+
return TyKind::Error.intern(Interner);
101+
}
102+
93103
let mut table = InferenceTable::new(db, env);
94104
let ty = table.normalize_projection_ty(projection);
95105
table.resolve_completely(ty)

0 commit comments

Comments
 (0)