]> git.lizzy.rs Git - rust.git/commitdiff
fix panic on GAT
authorAlex Chi <iskyzh@gmail.com>
Mon, 11 Apr 2022 05:44:01 +0000 (13:44 +0800)
committerAlex Chi <iskyzh@gmail.com>
Mon, 11 Apr 2022 05:52:02 +0000 (13:52 +0800)
Signed-off-by: Alex Chi <iskyzh@gmail.com>
crates/hir_ty/src/tests/regression.rs
crates/hir_ty/src/utils.rs

index a02ec6f85c6f6c865fd659300afaf2b5f59ae256..c3c934c4680c1546abeabde089792d753c6dd7ed 100644 (file)
@@ -1471,7 +1471,7 @@ fn dynamic_programming() {
 }
 
 #[test]
-fn gat_crash() {
+fn gat_crash_1() {
     cov_mark::check!(ignore_gats);
     check_no_mismatches(
         r#"
@@ -1489,6 +1489,26 @@ fn test<T: Crash>() {
     );
 }
 
+#[test]
+fn gat_crash_2() {
+    check_no_mismatches(
+        r#"
+pub struct InlineStorage {}
+
+pub struct InlineStorageHandle<T: ?Sized> {}
+
+pub unsafe trait Storage {
+    type Handle<T: ?Sized>;
+    fn create<T: ?Sized>() -> Self::Handle<T>;
+}
+
+unsafe impl Storage for InlineStorage {
+    type Handle<T: ?Sized> = InlineStorageHandle<T>;
+}
+"#,
+    );
+}
+
 #[test]
 fn cfgd_out_self_param() {
     cov_mark::check!(cfgd_out_self_param);
index 0ffd428cff108fe199742f0d438e456c00274f25..bdb7677f5d7863e1e7b67067a5d702d89a3db663 100644 (file)
@@ -176,13 +176,22 @@ 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 };
+        let params = db.generic_params(def);
+        if params
+            .type_or_consts
+            .iter()
+            .any(|(_, x)| matches!(x, TypeOrConstParamData::ConstParamData(_)))
+        {
+            // XXX: treat const generic associated types as not existing to avoid crashes (#11769)
+            //
+            // 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 };
+        } else {
+            return Generics { def, params, parent_generics };
+        }
     }
     Generics { def, params: db.generic_params(def), parent_generics }
 }