mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-12 05:08:52 +00:00
Describe variance resolution approach differences to rustc
This commit is contained in:
parent
bb921fbe94
commit
2d299ab8a4
1 changed files with 27 additions and 36 deletions
|
@ -2,6 +2,16 @@
|
||||||
//! chapter for more info.
|
//! chapter for more info.
|
||||||
//!
|
//!
|
||||||
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/variance.html
|
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/variance.html
|
||||||
|
//!
|
||||||
|
//! The implementation here differs from rustc. Rustc does a crate wide fixpoint resolution
|
||||||
|
//! as the algorithm for determining variance is a fixpoint computation with potential cycles that
|
||||||
|
//! need to be resolved. rust-analyzer does not want a crate-wide analysis though as that would hurt
|
||||||
|
//! incrementality too much and as such our query is based on a per item basis.
|
||||||
|
//!
|
||||||
|
//! This does unfortunately run into the issue that we can run into query cycles which salsa
|
||||||
|
//! currently does not allow to be resolved via a fixpoint computation. This will likely be resolved
|
||||||
|
//! by the next salsa version. If not, we will likely have to adapt and go with the rustc approach
|
||||||
|
//! while installing firewall per item queries to prevent invalidation issues.
|
||||||
|
|
||||||
use crate::db::HirDatabase;
|
use crate::db::HirDatabase;
|
||||||
use crate::generics::{generics, Generics};
|
use crate::generics::{generics, Generics};
|
||||||
|
@ -371,19 +381,6 @@ impl Context<'_> {
|
||||||
if args.is_empty() {
|
if args.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if def_id == self.generics.def() {
|
|
||||||
// HACK: Workaround for the trivial cycle salsa case (see
|
|
||||||
// recursive_one_bivariant_more_non_bivariant_params test)
|
|
||||||
for k in args {
|
|
||||||
match k.data(Interner) {
|
|
||||||
GenericArgData::Lifetime(lt) => {
|
|
||||||
self.add_constraints_from_region(lt, Variance::Bivariant)
|
|
||||||
}
|
|
||||||
GenericArgData::Ty(ty) => self.add_constraints_from_ty(ty, Variance::Bivariant),
|
|
||||||
GenericArgData::Const(val) => self.add_constraints_from_const(val, variance),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let Some(variances) = self.db.variances_of(def_id) else {
|
let Some(variances) = self.db.variances_of(def_id) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -400,7 +397,6 @@ impl Context<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds constraints appropriate for a const expression `val`
|
/// Adds constraints appropriate for a const expression `val`
|
||||||
/// in a context with ambient variance `variance`
|
/// in a context with ambient variance `variance`
|
||||||
|
@ -956,22 +952,17 @@ struct S3<T>(S<T, T>);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn recursive_one_bivariant_more_non_bivariant_params() {
|
fn prove_fixedpoint() {
|
||||||
// FIXME: This is wrong, this should be `BivariantPartialIndirect[T: bivariant, U: covariant]` (likewise for Wrapper)
|
// FIXME: This is wrong, this should be `FixedPoint[T: covariant, U: covariant, V: covariant]`
|
||||||
// This is a limitation of current salsa where a cycle may only set a fallback value to the
|
// This is a limitation of current salsa where a cycle may only set a fallback value to the
|
||||||
// query result which is not what we want! We want to treat the cycle call as fallback
|
// query result, but we need to solve a fixpoint here. The new salsa will have this
|
||||||
// without setting the query result to the fallback.
|
// fortunately.
|
||||||
// `BivariantPartial` works as we workaround for the trivial case of being self-referential
|
|
||||||
check(
|
check(
|
||||||
r#"
|
r#"
|
||||||
struct BivariantPartial<T, U>(*const BivariantPartial<T, U>, U);
|
struct FixedPoint<T, U, V>(&'static FixedPoint<(), T, U>, V);
|
||||||
struct Wrapper<T, U>(BivariantPartialIndirect<T, U>);
|
|
||||||
struct BivariantPartialIndirect<T, U>(*const Wrapper<T, U>, U);
|
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
BivariantPartial[T: bivariant, U: covariant]
|
FixedPoint[T: bivariant, U: bivariant, V: bivariant]
|
||||||
Wrapper[T: bivariant, U: bivariant]
|
|
||||||
BivariantPartialIndirect[T: bivariant, U: bivariant]
|
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue