diff options
| author | Shoyu Vanilla <modulo641@gmail.com> | 2024-08-14 09:37:20 +0900 |
|---|---|---|
| committer | Shoyu Vanilla <modulo641@gmail.com> | 2024-08-14 23:17:48 +0900 |
| commit | 81b68b2078e480673e89496807238b97ab033722 (patch) | |
| tree | 660f8d142abe49dba4505308bc4979f8475558c5 | |
| parent | f96e296927cc0c6e9dd611edb943f6349001eca5 (diff) | |
| download | rust-81b68b2078e480673e89496807238b97ab033722.tar.gz rust-81b68b2078e480673e89496807238b97ab033722.zip | |
fix: Panic while canonicalizing erroneous projection type
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir-ty/src/infer.rs | 3 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs | 21 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir-ty/src/traits.rs | 14 |
3 files changed, 35 insertions, 3 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index 45d423d03c0..5a7deab3a44 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -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, }; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs index 28198386120..26e9243e738 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs @@ -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} + "#]], + ); +} diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs index c46382a0ea8..00791c51491 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/traits.rs @@ -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) |
