From d026479ba6084d00b900fed3c5c06363d605e68e Mon Sep 17 00:00:00 2001 From: Ryo Yoshida Date: Sat, 24 Jun 2023 21:53:50 +0900 Subject: [PATCH] Support `#[rustc_coinductive]` --- crates/hir-ty/src/chalk_db.rs | 8 +++++-- crates/hir-ty/src/tests/traits.rs | 32 ++++++++++++++++++++++++++ crates/ide/src/inlay_hints/chaining.rs | 12 +++++----- crates/test-utils/src/minicore.rs | 1 + 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 5dd8e2719a23..fb8c9a9a1c43 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 97ae732a9046..764e77950f5e 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) { "#, ); } + +#[test] +fn rustc_coinductive() { + // Taken from rust-lang/rust#108033 with modification. + check_types( + r#" +#[rustc_coinductive] +trait Trait { type Assoc; } + +impl Trait for (T, U) +where + (U, T): Trait, + (): ConstrainToU32, +{ + type Assoc = i32; +} + +trait ConstrainToU32 {} +impl ConstrainToU32 for () {} + +fn impls_trait() -> R +where + (T, U): Trait, +{ 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 774383d50d61..8ac62bee7b09 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 0d6e4b98d8ca..041675d7d83d 100644 --- a/crates/test-utils/src/minicore.rs +++ b/crates/test-utils/src/minicore.rs @@ -62,6 +62,7 @@ pub mod marker { #[lang = "sized"] #[fundamental] #[rustc_specialization_trait] + #[rustc_coinductive] pub trait Sized {} // endregion:sized