about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Diebold <flodiebold@gmail.com>2022-04-02 13:04:04 +0200
committerFlorian Diebold <flodiebold@gmail.com>2022-04-02 13:14:42 +0200
commit019f48673ac7342b40161cebd9eadeacb4649458 (patch)
treee92a90a62c2376bc95761d9636852b0e8d792b42
parent63c4d6b20dd9445bea135473a6bf203644cfdd65 (diff)
downloadrust-019f48673ac7342b40161cebd9eadeacb4649458.tar.gz
rust-019f48673ac7342b40161cebd9eadeacb4649458.zip
fix: Paper over GAT panic
TIL that Chalk expects the arguments to a generic associated type to
come *before* the ones for the parent trait, not *after* as we have been
doing with all other nested generics. Fixing this requires a larger
refactoring, so for now this just papers over the problem by completely
ignoring parameters of associated types.

Fixes #11769.
-rw-r--r--crates/hir_ty/src/tests/regression.rs19
-rw-r--r--crates/hir_ty/src/utils.rs9
2 files changed, 28 insertions, 0 deletions
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index 2809b1e912a..65eb2da5afc 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -1497,3 +1497,22 @@ fn regression_11688_3() {
         "#,
     );
 }
+
+#[test]
+fn gat_crash() {
+    cov_mark::check!(ignore_gats);
+    check_no_mismatches(
+        r#"
+trait ATrait {}
+
+trait Crash {
+    type Member<const N: usize>: ATrait;
+    fn new<const N: usize>() -> Self::Member<N>;
+}
+
+fn test<T: Crash>() {
+    T::new();
+}
+"#,
+    );
+}
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 343e89eb9bb..c4a11c86d4a 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -175,6 +175,15 @@ pub(super) fn associated_type_by_name_including_super_traits(
 
 pub(crate) fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
     let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
+    if parent_generics.is_some() && matches!(def, GenericDefId::TypeAliasId(_)) {
+        // XXX: treat generic associated types as not existing to avoid crashes (#)
+        //
+        // Chalk expects the inner associated type's parameters to come
+        // *before*, not after the trait's generics as we've always done it.
+        // Adapting to this requires a larger refactoring
+        cov_mark::hit!(ignore_gats);
+        return Generics { def, params: Interned::new(Default::default()), parent_generics };
+    }
     Generics { def, params: db.generic_params(def), parent_generics }
 }