mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 21:54:42 +00:00
fix: Panic while canonicalizing erroneous projection type
This commit is contained in:
parent
78c2bdce86
commit
e6d8970e07
3 changed files with 35 additions and 3 deletions
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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}
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue