rust-lang/rust#119820 is a breaking change. A crater run found 17 regressed crates.
calling Ramhorns::get
https://docs.rs/ramhorns/0.14.0/ramhorns/struct.Ramhorns.html#method.get relies on inference guidance by dropping a candidate due to the leak check
This can be minimized to
trait Trait<T> {}
impl<T> Trait<T> for T {}
impl<T> Trait<T> for &T {}
fn get<S>(_: &S)
where
for<'a> &'a u32: Trait<S>,
{}
fn render(template: &Box<u32>) {
get(template);
// `for<'a> &'a u32: Trait<?S>` previously discarded the first impl
// as it causes a placeholder error. This inferred `?S` to `u32`,
// causing coercion to add a necessary auto-deref step here.
}
FIXED IN maciejhirsz/ramhorns#69. NICE
Caused by multiple impls with one getting dropped due to the leak check.
struct SmtParser<R> {
input: R,
}
pub trait IdentParser<Ident, Type, Input>: Copy {
// ..
}
impl<'a, Br> IdentParser<&'a str, &'a str, &'a mut SmtParser<Br>> for () {
// ..
}
impl<'a, Br> IdentParser<String, String, &'a mut SmtParser<Br>> for () {
// ..
}
impl<R> SmtParser<R> {
fn get_model<Ident, Type, Parser>(&mut self, parser: Parser)
where
Parser: for<'a> IdentParser<Ident, Type, &'a mut Self>,
{}
}
fn foo<R>(mut p: SmtParser<R>) {
p.get_model(()); // impl for `&'a str` causes a leak check failure
}
FIXED IN kino-mc/rsmt2#43
https://github.com/launchbadge/sqlx some derives of sqlx::Type
- https://github.com/OliverFlecke/budget-api
- https://github.com/alvarotolentino/docmanager-rust
- https://github.com/cost-management/cost-management-api
- https://github.com/robertohuertasm/yt-api-rest-actix-web
- https://github.com/vorrarit/test-rust
- https://crates.io/crates/etwin_forum_store/0.12.3
- https://crates.io/crates/etwin_services/0.12.3
- https://github.com/foxford/dispatcher
Higher ranked lifetime error when deriving sqlx::Type
, e.g.
use sqlx::Type;
#[derive(Type)]
struct Position {
id: i64,
}
This expands into
struct Position {
id: i64,
}
impl Encode<'_, Postgres> for Position
where
i64: for<'q> Encode<'q, Postgres>,
i64: Type<Postgres>,
{
fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull {
let mut encoder = PgRecordEncoder::new(buf);
encoder.encode(&self.id);
encoder.finish();
IsNull::No
}
fn size_hint(&self) -> usize {
1usize * (4 + 4) + <i64 as Encode<Postgres>>::size_hint(&self.id)
}
}
impl<'r> Decode<'r, Postgres> for Position
where
i64: Decode<'r, Postgres>,
i64: Type<Postgres>,
{
fn decode(value: PgValueRef<'r>) -> Result<Self, Box<dyn Error + 'static + Send + Sync>> {
let mut decoder = PgRecordDecoder::new(value)?;
let id = decoder.try_decode::<i64>()?;
// ERROR: this requires `for<'r> i64: Decode<'r, Postgres>`
Ok(Position { id })
}
}
impl Type<Postgres> for Position {
fn type_info() -> PgTypeInfo {
PgTypeInfo::with_name("Position")
}
}
Replacing the higher ranked bound in https://github.com/launchbadge/sqlx/blob/84d576004c93a32133688426eacb50434bb5c5f0/sqlx-postgres/src/types/record.rs#L97 should fix this and compiles. Similarly, why does Encode
require i64: for<'q> Encode<'q, Postgres>
instead of i64: Encode<'param, Postgres>
?
ALREADY FIXED ON MASTER
// from the `tracing-subscriber` crate
trait MakeWriter<'a> {}
impl<'a, F: Fn() -> W> MakeWriter<'a> for F {}
fn new_formatting_layer<F: for<'a> MakeWriter<'a>>(_: F) {}
fn get_subsriber<'a, F: MakeWriter<'a> + Fn() -> W>(f: F) {
new_formatting_layer(f)
// Non-HR bound, HR goal.
}
FIXED IN renato145/docker_queue#1
We get a universe error when using the param_env
candidate but are able to successfully use the impl candidate. Without the leak check both candidates may apply and we prefer the param_env
candidate in winnowing.
trait Trait {}
impl<T: Trait> Trait for &T {}
impl Trait for u32 {}
fn hr_bound<T>()
where
for<'a> &'a T: Trait,
{}
fn foo<T>()
where
T: Trait,
for<'a> &'a &'a T: Trait,
{
hr_bound::<&T>();
// We get a universe error when using the `param_env` candidate
// but are able to successfully use the impl candidate. Without
// the leak check both candidates may apply and we prefer the
// `param_env` candidate in winnowing.
}
fn main() {}
FIXED IN lycantropos/rene#5
Generated code by a derive, something like the following:
use serde::{de::DeserializeOwned, Deserialize, Deserializer};
struct NeedsOwned(bool);
impl<'de> Deserialize<'de> for NeedsOwned
where
bool: DeserializeOwned,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Ok(NeedsOwned(<bool as Deserialize>::deserialize(deserializer)?))
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
bool: Deserialize<'de>,
D: Deserializer<'de>,
{
// requires `bool: DeserializeOwned` which requires `for<'de> bool: Deserialize<'de>`
match <NeedsOwned as ::serde::Deserialize>::deserialize(deserializer) {
Ok(value) => Ok(value.0),
Err(e) => Err(e),
}
}
FIXED IN jmeggitt/serde_flat_path#1
Failure in a branch of rocket
https://github.com/jebrosen/Rocket/tree/tracing-rebase-202103
A trivial where-bound uses the same bound variable in both the self-type and as a trait argument, while impl uses separate lifetimes.
This means that trying to apply the where-bound for F: for<'a> FormatFields<'a>
results in a higher ranked region error while applying the impl succeeds.
trait FormatFields<'a> {}
struct FmtContext<'a, S> {
whatever: &'a S,
}
impl<'a, 'b, S> FormatFields<'a> for FmtContext<'b, S> {}
fn requires_hr<F: for<'a> FormatFields<'a>>(_: &F) {}
fn format_event<S>(x: &FmtContext<'_, S>)
where
for<'a> FmtContext<'a, S>: FormatFields<'a>,
{
requires_hr(x)
}
fn main() {}
WON'T FIX, REQUIRES ADJUSTING AN UNMAINTAINED BRANCH OF ROCKET