Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #15125 - lowr:patch/rustc_coinductive, r=Veykril
internal: support `#[rustc_coinductive]` rust-lang/rust#100386 changed the trait solver so that `Sized` is treated as coinductive trait, just like auto traits. This is now controlled by the perma-unstable `#[rustc_coinductive]` attribute (rust-lang/rust#108033), which this PR adds support for. In practice, I don't think this matters much if at all. Currently we don't give chalk enough information so chalk cannot precisely (dis)prove `Sized` bounds.
bors 2023-06-28
parent 891331c · parent d026479 · commit 0216044
-rw-r--r--crates/hir-ty/src/chalk_db.rs8
-rw-r--r--crates/hir-ty/src/tests/traits.rs32
-rw-r--r--crates/ide/src/inlay_hints/chaining.rs12
-rw-r--r--crates/test-utils/src/minicore.rs1
4 files changed, 45 insertions, 8 deletions
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs
index 5dd8e2719a..fb8c9a9a1c 100644
--- a/crates/hir-ty/src/chalk_db.rs
+++ b/crates/hir-ty/src/chalk_db.rs
@@ -550,6 +550,10 @@ pub(crate) fn trait_datum_query(
debug!("trait_datum {:?}", trait_id);
let trait_ = from_chalk_trait_id(trait_id);
let trait_data = db.trait_data(trait_);
+
+ let coinductive =
+ trait_data.is_auto || db.attrs(trait_.into()).by_key("rustc_coinductive").exists();
+
debug!("trait {:?} = {:?}", trait_id, trait_data.name);
let generic_params = generics(db.upcast(), trait_.into());
let bound_vars = generic_params.bound_vars_subst(db, DebruijnIndex::INNERMOST);
@@ -557,7 +561,7 @@ pub(crate) fn trait_datum_query(
auto: trait_data.is_auto,
upstream: trait_.lookup(db.upcast()).container.krate() != krate,
non_enumerable: true,
- coinductive: false, // only relevant for Chalk testing
+ coinductive,
// FIXME: set these flags correctly
marker: false,
fundamental: false,
@@ -637,7 +641,7 @@ pub(crate) fn struct_datum_query(
fundamental: false,
phantom_data: false,
};
- // FIXME provide enum variants properly (for auto traits)
+ // FIXME provide enum variants properly (for auto traits and `Sized`)
let variant = rust_ir::AdtVariantDatum {
fields: Vec::new(), // FIXME add fields (only relevant for auto traits),
};
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 97ae732a90..764e77950f 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -4410,3 +4410,35 @@ fn test(v: S<i32>) {
"#,
);
}
+
+#[test]
+fn rustc_coinductive() {
+ // Taken from rust-lang/rust#108033 with modification.
+ check_types(
+ r#"
+#[rustc_coinductive]
+trait Trait { type Assoc; }
+
+impl<T, U> Trait for (T, U)
+where
+ (U, T): Trait,
+ (): ConstrainToU32<T>,
+{
+ type Assoc = i32;
+}
+
+trait ConstrainToU32<T> {}
+impl ConstrainToU32<u32> for () {}
+
+fn impls_trait<T, U, R>() -> R
+where
+ (T, U): Trait<Assoc = R>,
+{ loop {} }
+
+fn main() {
+ let _ = impls_trait::<_, _, _>();
+ //^ i32
+}
+"#,
+ );
+}
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index 774383d50d..8ac62bee7b 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -474,7 +474,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9288..9296,
+ range: 9313..9321,
},
),
tooltip: "",
@@ -487,7 +487,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9320..9324,
+ range: 9345..9349,
},
),
tooltip: "",
@@ -511,7 +511,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9288..9296,
+ range: 9313..9321,
},
),
tooltip: "",
@@ -524,7 +524,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9320..9324,
+ range: 9345..9349,
},
),
tooltip: "",
@@ -548,7 +548,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9288..9296,
+ range: 9313..9321,
},
),
tooltip: "",
@@ -561,7 +561,7 @@ fn main() {
file_id: FileId(
1,
),
- range: 9320..9324,
+ range: 9345..9349,
},
),
tooltip: "",
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index d7201f996d..200bb0e8a5 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -63,6 +63,7 @@ pub mod marker {
#[lang = "sized"]
#[fundamental]
#[rustc_specialization_trait]
+ #[rustc_coinductive]
pub trait Sized {}
// endregion:sized