Unnamed repository; edit this file 'description' to name the repository.
Merge #11957
11957: fix panic on GAT r=flodiebold a=skyzh Signed-off-by: Alex Chi <[email protected]> This is still a workaround on GAT panic, and didn't solve the full problem. But at least we won't panic now. False positive is better than panicking and letting VSCode constantly pop out the warning 🤣 This PR is simple -- only apply the https://github.com/rust-analyzer/rust-analyzer/pull/11878 fix on const generics. For normal GATs, just follow the previous approach. This PR fixes https://github.com/rust-analyzer/rust-analyzer/issues/11939, I've added it as a test case. This PR didn't fully fix / https://github.com/rust-analyzer/rust-analyzer/issues/11923. But at least it won't panic now -- will only give a type mismatch error. Not sure if it fixes / https://github.com/rust-analyzer/rust-analyzer/issues/11921, I'll test it later. cc `@flodiebold` for review, thanks! Co-authored-by: Alex Chi <[email protected]>
bors[bot] 2022-04-11
parent 24cf957 · parent 51d6671 · commit b1c9a6b
-rw-r--r--crates/hir_ty/src/tests/regression.rs22
-rw-r--r--crates/hir_ty/src/utils.rs23
2 files changed, 37 insertions, 8 deletions
diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs
index a02ec6f85c..c3c934c468 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -1471,7 +1471,7 @@ fn regression_11688_3() {
}
#[test]
-fn gat_crash() {
+fn gat_crash_1() {
cov_mark::check!(ignore_gats);
check_no_mismatches(
r#"
@@ -1490,6 +1490,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);
check_no_mismatches(
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index 0ffd428cff..bdb7677f5d 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -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 }
}