fix: Panic while canonicalizing erroneous projection type

This commit is contained in:
Shoyu Vanilla 2024-08-14 09:37:20 +09:00
parent 78c2bdce86
commit e6d8970e07
3 changed files with 35 additions and 3 deletions

View file

@ -1436,7 +1436,8 @@ impl<'a> InferenceContext<'a> {
let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
let ty = match ty.kind(Interner) {
TyKind::Alias(AliasTy::Projection(proj_ty)) => {
self.db.normalize_projection(proj_ty.clone(), self.table.trait_env.clone())
let ty = self.table.normalize_projection_ty(proj_ty.clone());
self.table.resolve_ty_shallow(&ty)
}
_ => ty,
};

View file

@ -2141,3 +2141,24 @@ fn test() {
}"#,
);
}
#[test]
fn issue_17866() {
check_infer(
r#"
trait T {
type A;
}
type Foo = <S as T>::A;
fn main() {
Foo {};
}
"#,
expect![[r#"
60..75 '{ Foo {}; }': ()
66..72 'Foo {}': {unknown}
"#]],
);
}

View file

@ -14,13 +14,13 @@ use hir_def::{
};
use hir_expand::name::Name;
use intern::sym;
use stdx::panic_context;
use stdx::{never, panic_context};
use triomphe::Arc;
use crate::{
db::HirDatabase, infer::unify::InferenceTable, utils::UnevaluatedConstEvaluatorFolder, AliasEq,
AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment, Interner, ProjectionTy,
ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, WhereClause,
ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, TypeFlags, WhereClause,
};
/// This controls how much 'time' we give the Chalk solver before giving up.
@ -90,6 +90,16 @@ pub(crate) fn normalize_projection_query(
projection: ProjectionTy,
env: Arc<TraitEnvironment>,
) -> Ty {
if projection.substitution.iter(Interner).any(|arg| {
arg.ty(Interner)
.is_some_and(|ty| ty.data(Interner).flags.intersects(TypeFlags::HAS_TY_INFER))
}) {
never!(
"Invoking `normalize_projection_query` with a projection type containing inference var"
);
return TyKind::Error.intern(Interner);
}
let mut table = InferenceTable::new(db, env);
let ty = table.normalize_projection_ty(projection);
table.resolve_completely(ty)