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.
This commit is contained in:
commit
021604431c
@ -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),
|
||||
};
|
||||
|
@ -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
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
@ -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: "",
|
||||
|
@ -63,6 +63,7 @@ pub mod marker {
|
||||
#[lang = "sized"]
|
||||
#[fundamental]
|
||||
#[rustc_specialization_trait]
|
||||
#[rustc_coinductive]
|
||||
pub trait Sized {}
|
||||
// endregion:sized
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user