mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-28 20:16:58 +03:00
Merge #11957
11957: fix panic on GAT r=flodiebold a=skyzh Signed-off-by: Alex Chi <iskyzh@gmail.com> 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 <iskyzh@gmail.com>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user