-
Notifications
You must be signed in to change notification settings - Fork 13.4k
coherence: fix is_knowable logic #46192
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
a583d9e
to
b2302bb
Compare
b2302bb
to
5360699
Compare
@bors try |
⌛ Trying commit 5360699 with merge faf75254806fa54615158a9058c5a50b81dc8006... |
@bors r- retry |
⌛ Trying commit 5360699 with merge 999ab8e65bc12abb057c3e7ba58a538ae3ab7c57... |
@bors untry |
@bors retry |
⌛ Trying commit 5360699 with merge 0bac3d526df71b0959316897d8d8b8d1baf6b4f1... |
@bors try retry |
coherence: fix is_knowable logic A trait-ref that passes the orphan-check rules can still be implemented in a crate downstream from our crate (for example, `LocalType for LocalTrait<_>` might be matched by a `LocalType for LocalTrait<TypeFromDownstreamCrate>`), and this should be known by the `is_knowable` logic. Trait selection had a hackfix for this, but it's an hacky fix that does not handle all cases. This patch removes it. cc #43355. FIXME: make this a soft error. I suppose we'll crater first. r? @nikomatsakis Needs a crater run
☀️ Test successful - status-travis |
Crater run started. |
c4ca8e3
to
11f22ab
Compare
☔ The latest upstream changes (presumably #46430) made this pull request unmergeable. Please resolve the merge conflicts. |
Hi @arielb1 (crater requester), @nikomatsakis (reviewer)! Crater results are at: http://cargobomb-reports.s3.amazonaws.com/pr-46192/index.html. 'Blacklisted' crates (spurious failures etc) can be found here. If you see any spurious failures not on the list, please make a PR against that file. (interested observers: Crater is a tool for testing the impact of changes on the crates.io ecosystem. You can find out more at the repo if you're curious) |
Regressions: crossbeam-epoch-0.1.0 & bow-1.0.3 (yay I broke Servo, but this is no longer a dependency)
This is a problem because any joker can write this (on nightly, but some variants are probably possible using #![feature(optin_builtin_traits)]
pub struct Foo;
pub auto trait Xyz {}
impl !Xyz for Foo {}
impl !Xyz for Box<Foo> {}
impl<T: Xyz> From<T> for Box<Foo> {
fn from(_: T) -> Self { Box::new(Foo) }
}
fn main() {
let _foo = <Box<Foo>>::from(());
} Which would cause a coherence conflict on linking for the trait-ref I think the only fix is to not use glib v0.1.3
This causes a conflict because downstream crates can implement The crate author had actually encountered some other coherence problems with this approach, and removed this in a new version of their crate: gtk-rs/glib@b36de4e#diff-dd26c2766e65aca43e4228e64ebd0cf8 I don't see any crates depending on ocl v0.15.0rusqlite v0.10.3rusqlcipher v0.14.6This is basically the same issue as impl<'a, E> From<E> for EventArray where E: Into<Event>
impl<'a, E> From<&'a E> for EventArray where E: Into<Event> + Clone
This is still an issue in the newest crate version, probably need to talk with the crate authors
lru-disk-cache v0.1.0 (aka sccache)
This is a conflict because coherence can't see that This can be fixed by the crate author by breaking the associated type to a type parameter: use std::borrow::Borrow;
/// A trait for measuring the size of a cache entry.
///
/// If you implement this trait, you should use `usize` as the `Measure` type, otherwise you will
/// also have to implement [`CountableMeter`][countablemeter].
///
/// [countablemeter]: trait.Meter.html
pub trait Meter<K, V> {
/// The type used to store measurements.
type Measure: Default + Copy;
/// Calculate the size of `key` and `value`.
fn measure<Q: ?Sized>(&self, key: &Q, value: &V) -> Self::Measure
where K: Borrow<Q>;
}
/// Size limit based on a simple count of cache items.
pub struct Count;
impl<K, V> Meter<K, V> for Count {
/// Don't store anything, the measurement can be derived from the map.
type Measure = ();
/// Don't actually count anything either.
fn measure<Q: ?Sized>(&self, _: &Q, _: &V) -> ()
where K: Borrow<Q>
{}
}
/// A trait to allow the default `Count` measurement to not store an
/// extraneous counter.
pub trait CountableMeter<K, V>: Meter<K, V> {
/// Add `amount` to `current` and return the sum.
fn add(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure;
/// Subtract `amount` from `current` and return the difference.
fn sub(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure;
/// Return `current` as a `usize` if possible, otherwise return `None`.
///
/// If this method returns `None` the cache will use the number of cache entries as
/// its size.
fn size(&self, current: Self::Measure) -> Option<usize>;
}
/// `Count` is all no-ops, the number of entries in the map is the size.
impl<K, V, T: Meter<K, V>> CountableMeter<K, V> for T
where T: CountableMeterWithMeasure<K, V, <T as Meter<K, V>>::Measure>
{
fn add(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure {
CountableMeterWithMeasure::add(self, current, amount)
}
fn sub(&self, current: Self::Measure, amount: Self::Measure) -> Self::Measure {
CountableMeterWithMeasure::sub(self, current, amount)
}
fn size(&self, current: Self::Measure) -> Option<usize> {
CountableMeterWithMeasure::size(self, current)
}
}
pub trait CountableMeterWithMeasure<K, V, M> {
/// Add `amount` to `current` and return the sum.
fn add(&self, current: M, amount: M) -> M;
/// Subtract `amount` from `current` and return the difference.
fn sub(&self, current: M, amount: M) -> M;
/// Return `current` as a `usize` if possible, otherwise return `None`.
///
/// If this method returns `None` the cache will use the number of cache entries as
/// its size.
fn size(&self, current: M) -> Option<usize>;
}
/// For any other `Meter` with `Measure=usize`, just do the simple math.
impl<K, V, T> CountableMeterWithMeasure<K, V, usize> for T {
fn add(&self, current: usize, amount: usize) -> usize {
current + amount
}
fn sub(&self, current: usize, amount: usize) -> usize {
current - amount
}
fn size(&self, current: usize) -> Option<usize> { Some(current) }
}
impl<K, V> CountableMeterWithMeasure<K, V, ()> for Count {
fn add(&self, current: (), amount: ()) {}
fn sub(&self, current: (), amount: ()) {}
fn size(&self, current: ()) -> Option<usize> { None }
}
fn main() {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few documentation nits.
src/librustc/traits/coherence.rs
Outdated
/// impl<T> IntoIterator for Vec<T> | ||
/// impl<T: Iterator> IntoIterator for T | ||
/// ``` | ||
/// We need to be able to prove that `Option<$0>: !Iterator` for every type $0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: s/Option/Vec/, right?
} | ||
|
||
/// Check whether a trait-ref is potentially implementable by a crate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wonderful.
@arielb1 this only issues warnings presently, right? Seems like we ought to land it, no? r=me, if you agree. |
Yea this only issues warnings. I'll land this. |
Patch as suggested by @arielb1: rust-lang/rust#46192 (comment)
I pushed a fix to lru-disk-cache in sccache, thanks for providing working code! |
@bors r=nikomatsakis |
📌 Commit 11f22ab has been approved by |
11f22ab
to
425c2c3
Compare
@bors r=nikomatsakis |
📌 Commit 425c2c3 has been approved by |
coherence: fix is_knowable logic A trait-ref that passes the orphan-check rules can still be implemented in a crate downstream from our crate (for example, `LocalType for LocalTrait<_>` might be matched by a `LocalType for LocalTrait<TypeFromDownstreamCrate>`), and this should be known by the `is_knowable` logic. Trait selection had a hackfix for this, but it's an hacky fix that does not handle all cases. This patch removes it. fixes #43355. r? @nikomatsakis Needs a crater run
💔 Test failed - status-travis |
coherence: fix is_knowable logic A trait-ref that passes the orphan-check rules can still be implemented in a crate downstream from our crate (for example, `LocalType for LocalTrait<_>` might be matched by a `LocalType for LocalTrait<TypeFromDownstreamCrate>`), and this should be known by the `is_knowable` logic. Trait selection had a hackfix for this, but it's an hacky fix that does not handle all cases. This patch removes it. fixes #43355. r? @nikomatsakis Needs a crater run
☀️ Test successful - status-appveyor, status-travis |
Patch as suggested by @arielb1: rust-lang/rust#46192 (comment)
A trait-ref that passes the orphan-check rules can still be implemented in a crate downstream from our crate (for example,
LocalType for LocalTrait<_>
might be matched by aLocalType for LocalTrait<TypeFromDownstreamCrate>
), and this should be known by theis_knowable
logic.Trait selection had a hackfix for this, but it's an hacky fix that does not handle all cases. This patch removes it.
fixes #43355.
r? @nikomatsakis
Needs a crater run