1
Fork 0

Perform coherence checking per impl.

This commit is contained in:
Camille GILLOT 2021-05-09 20:53:13 +02:00
parent 21e9336fe8
commit 0ff8c65d6f
18 changed files with 258 additions and 291 deletions

View file

@ -906,9 +906,10 @@ rustc_queries! {
/// Checks whether all impls in the crate pass the overlap check, returning /// Checks whether all impls in the crate pass the overlap check, returning
/// which impls fail it. If all impls are correct, the returned slice is empty. /// which impls fail it. If all impls are correct, the returned slice is empty.
query orphan_check_crate(_: ()) -> &'tcx [LocalDefId] { query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
desc { desc { |tcx|
"checking whether the immpl in the this crate follow the orphan rules", "checking whether impl `{}` follows the orphan rules",
tcx.def_path_str(key.to_def_id()),
} }
} }

View file

@ -452,7 +452,7 @@ fn report_conflicting_impls(
match used_to_be_allowed { match used_to_be_allowed {
None => { None => {
let reported = if overlap.with_impl.is_local() let reported = if overlap.with_impl.is_local()
|| !tcx.orphan_check_crate(()).contains(&impl_def_id) || tcx.orphan_check_impl(impl_def_id).is_ok()
{ {
let err = struct_span_err!(tcx.sess, impl_span, E0119, ""); let err = struct_span_err!(tcx.sess, impl_span, E0119, "");
Some(decorate( Some(decorate(

View file

@ -146,7 +146,7 @@ pub fn provide(providers: &mut Providers) {
use self::builtin::coerce_unsized_info; use self::builtin::coerce_unsized_info;
use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls}; use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls};
use self::inherent_impls_overlap::crate_inherent_impls_overlap_check; use self::inherent_impls_overlap::crate_inherent_impls_overlap_check;
use self::orphan::orphan_check_crate; use self::orphan::orphan_check_impl;
*providers = Providers { *providers = Providers {
coherent_trait, coherent_trait,
@ -155,7 +155,7 @@ pub fn provide(providers: &mut Providers) {
inherent_impls, inherent_impls,
crate_inherent_impls_overlap_check, crate_inherent_impls_overlap_check,
coerce_unsized_info, coerce_unsized_info,
orphan_check_crate, orphan_check_impl,
..*providers ..*providers
}; };
} }
@ -171,23 +171,14 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
check_impl(tcx, impl_def_id, trait_ref); check_impl(tcx, impl_def_id, trait_ref);
check_object_overlap(tcx, impl_def_id, trait_ref); check_object_overlap(tcx, impl_def_id, trait_ref);
tcx.sess.time("unsafety_checking", || unsafety::check_item(tcx, impl_def_id));
tcx.sess.time("orphan_checking", || tcx.ensure().orphan_check_impl(impl_def_id));
} }
builtin::check_trait(tcx, def_id); builtin::check_trait(tcx, def_id);
} }
pub fn check_coherence(tcx: TyCtxt<'_>) {
tcx.sess.time("unsafety_checking", || unsafety::check(tcx));
tcx.ensure().orphan_check_crate(());
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
tcx.ensure().coherent_trait(trait_def_id);
}
// these queries are executed for side-effects (error reporting):
tcx.ensure().crate_inherent_impls(());
tcx.ensure().crate_inherent_impls_overlap_check(());
}
/// Checks whether an impl overlaps with the automatic `impl Trait for dyn Trait`. /// Checks whether an impl overlaps with the automatic `impl Trait for dyn Trait`.
fn check_object_overlap<'tcx>( fn check_object_overlap<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,

View file

@ -18,26 +18,29 @@ use rustc_span::Span;
use rustc_trait_selection::traits; use rustc_trait_selection::traits;
use std::ops::ControlFlow; use std::ops::ControlFlow;
pub(super) fn orphan_check_crate(tcx: TyCtxt<'_>, (): ()) -> &[LocalDefId] { #[instrument(skip(tcx), level = "debug")]
let mut errors = Vec::new(); pub(crate) fn orphan_check_impl(
for (&trait_def_id, impls_of_trait) in tcx.all_local_trait_impls(()) { tcx: TyCtxt<'_>,
for &impl_of_trait in impls_of_trait { impl_def_id: LocalDefId,
match orphan_check_impl(tcx, impl_of_trait) { ) -> Result<(), ErrorGuaranteed> {
Ok(()) => {} let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
Err(_) => errors.push(impl_of_trait), if trait_ref.references_error() {
} return Ok(());
}
if tcx.trait_is_auto(trait_def_id) {
lint_auto_trait_impls(tcx, trait_def_id, impls_of_trait);
}
} }
tcx.arena.alloc_slice(&errors)
let ret = do_orphan_check_impl(tcx, trait_ref, impl_def_id);
if tcx.trait_is_auto(trait_ref.def_id) {
lint_auto_trait_impls(tcx, trait_ref, impl_def_id);
}
ret
} }
#[instrument(skip(tcx), level = "debug")] fn do_orphan_check_impl<'tcx>(
fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { tcx: TyCtxt<'tcx>,
let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); trait_ref: ty::TraitRef<'tcx>,
def_id: LocalDefId,
) -> Result<(), ErrorGuaranteed> {
let trait_def_id = trait_ref.def_id; let trait_def_id = trait_ref.def_id;
let item = tcx.hir().item(hir::ItemId { def_id }); let item = tcx.hir().item(hir::ItemId { def_id });
@ -329,89 +332,82 @@ fn emit_orphan_check_error<'tcx>(
/// Lint impls of auto traits if they are likely to have /// Lint impls of auto traits if they are likely to have
/// unsound or surprising effects on auto impls. /// unsound or surprising effects on auto impls.
fn lint_auto_trait_impls(tcx: TyCtxt<'_>, trait_def_id: DefId, impls: &[LocalDefId]) { fn lint_auto_trait_impls<'tcx>(
let mut non_covering_impls = Vec::new(); tcx: TyCtxt<'tcx>,
for &impl_def_id in impls { trait_ref: ty::TraitRef<'tcx>,
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); impl_def_id: LocalDefId,
if trait_ref.references_error() { ) {
return; if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
} return;
if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
return;
}
assert_eq!(trait_ref.substs.len(), 1);
let self_ty = trait_ref.self_ty();
let (self_type_did, substs) = match self_ty.kind() {
ty::Adt(def, substs) => (def.did(), substs),
_ => {
// FIXME: should also lint for stuff like `&i32` but
// considering that auto traits are unstable, that
// isn't too important for now as this only affects
// crates using `nightly`, and std.
continue;
}
};
// Impls which completely cover a given root type are fine as they
// disable auto impls entirely. So only lint if the substs
// are not a permutation of the identity substs.
match tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) {
Ok(()) => {} // ok
Err(arg) => {
// Ideally:
//
// - compute the requirements for the auto impl candidate
// - check whether these are implied by the non covering impls
// - if not, emit the lint
//
// What we do here is a bit simpler:
//
// - badly check if an auto impl candidate definitely does not apply
// for the given simplified type
// - if so, do not lint
if fast_reject_auto_impl(tcx, trait_def_id, self_ty) {
// ok
} else {
non_covering_impls.push((impl_def_id, self_type_did, arg));
}
}
}
} }
for &(impl_def_id, self_type_did, arg) in &non_covering_impls { assert_eq!(trait_ref.substs.len(), 1);
tcx.struct_span_lint_hir( let self_ty = trait_ref.self_ty();
lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS, let (self_type_did, substs) = match self_ty.kind() {
tcx.hir().local_def_id_to_hir_id(impl_def_id), ty::Adt(def, substs) => (def.did(), substs),
tcx.def_span(impl_def_id), _ => {
|err| { // FIXME: should also lint for stuff like `&i32` but
let item_span = tcx.def_span(self_type_did); // considering that auto traits are unstable, that
let self_descr = tcx.def_kind(self_type_did).descr(self_type_did); // isn't too important for now as this only affects
let mut err = err.build(&format!( // crates using `nightly`, and std.
"cross-crate traits with a default impl, like `{}`, \ return;
}
};
// Impls which completely cover a given root type are fine as they
// disable auto impls entirely. So only lint if the substs
// are not a permutation of the identity substs.
let Err(arg) = tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) else {
// ok
return;
};
// Ideally:
//
// - compute the requirements for the auto impl candidate
// - check whether these are implied by the non covering impls
// - if not, emit the lint
//
// What we do here is a bit simpler:
//
// - badly check if an auto impl candidate definitely does not apply
// for the given simplified type
// - if so, do not lint
if fast_reject_auto_impl(tcx, trait_ref.def_id, self_ty) {
// ok
return;
}
tcx.struct_span_lint_hir(
lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS,
tcx.hir().local_def_id_to_hir_id(impl_def_id),
tcx.def_span(impl_def_id),
|err| {
let item_span = tcx.def_span(self_type_did);
let self_descr = tcx.def_kind(self_type_did).descr(self_type_did);
let mut err = err.build(&format!(
"cross-crate traits with a default impl, like `{}`, \
should not be specialized", should not be specialized",
tcx.def_path_str(trait_def_id), tcx.def_path_str(trait_ref.def_id),
)); ));
match arg { match arg {
ty::util::NotUniqueParam::DuplicateParam(arg) => { ty::util::NotUniqueParam::DuplicateParam(arg) => {
err.note(&format!("`{}` is mentioned multiple times", arg)); err.note(&format!("`{}` is mentioned multiple times", arg));
}
ty::util::NotUniqueParam::NotParam(arg) => {
err.note(&format!("`{}` is not a generic parameter", arg));
}
} }
err.span_note( ty::util::NotUniqueParam::NotParam(arg) => {
item_span, err.note(&format!("`{}` is not a generic parameter", arg));
&format!( }
"try using the same sequence of generic parameters as the {} definition", }
self_descr, err.span_note(
), item_span,
); &format!(
err.emit(); "try using the same sequence of generic parameters as the {} definition",
}, self_descr,
); ),
} );
err.emit();
},
);
} }
fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty: Ty<'tcx>) -> bool { fn fast_reject_auto_impl<'tcx>(tcx: TyCtxt<'tcx>, trait_def_id: DefId, self_ty: Ty<'tcx>) -> bool {

View file

@ -6,37 +6,18 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::Unsafety; use rustc_hir::Unsafety;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::LocalDefId;
pub fn check(tcx: TyCtxt<'_>) { pub(super) fn check_item(tcx: TyCtxt<'_>, def_id: LocalDefId) {
for id in tcx.hir().items() { debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Impl));
if matches!(tcx.def_kind(id.def_id), DefKind::Impl) { let item = tcx.hir().expect_item(def_id);
let item = tcx.hir().item(id); let hir::ItemKind::Impl(ref impl_) = item.kind else { bug!() };
if let hir::ItemKind::Impl(ref impl_) = item.kind {
check_unsafety_coherence(
tcx,
item,
Some(&impl_.generics),
impl_.unsafety,
impl_.polarity,
);
}
}
}
}
fn check_unsafety_coherence<'tcx>(
tcx: TyCtxt<'tcx>,
item: &hir::Item<'_>,
impl_generics: Option<&hir::Generics<'_>>,
unsafety: hir::Unsafety,
polarity: hir::ImplPolarity,
) {
if let Some(trait_ref) = tcx.impl_trait_ref(item.def_id) { if let Some(trait_ref) = tcx.impl_trait_ref(item.def_id) {
let trait_def = tcx.trait_def(trait_ref.def_id); let trait_def = tcx.trait_def(trait_ref.def_id);
let unsafe_attr = impl_generics.and_then(|generics| { let unsafe_attr =
generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle") impl_.generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
}); match (trait_def.unsafety, unsafe_attr, impl_.unsafety, impl_.polarity) {
match (trait_def.unsafety, unsafe_attr, unsafety, polarity) {
(Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => { (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {
struct_span_err!( struct_span_err!(
tcx.sess, tcx.sess,

View file

@ -513,7 +513,15 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
})?; })?;
tcx.sess.track_errors(|| { tcx.sess.track_errors(|| {
tcx.sess.time("coherence_checking", || coherence::check_coherence(tcx)); tcx.sess.time("coherence_checking", || {
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
tcx.ensure().coherent_trait(trait_def_id);
}
// these queries are executed for side-effects (error reporting):
tcx.ensure().crate_inherent_impls(());
tcx.ensure().crate_inherent_impls_overlap_check(());
});
})?; })?;
if tcx.features().rustc_attrs { if tcx.features().rustc_attrs {

View file

@ -1,3 +1,15 @@
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
|
LL | impl !Marker1 for dyn Object + Marker2 { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:17:1
|
LL | impl !Marker2 for dyn Object + Marker2 { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:23:1 --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:23:1
| |
@ -21,18 +33,6 @@ error[E0321]: cross-crate traits with a default impl, like `Send`, can only be i
LL | impl !Send for dyn Object + Marker2 {} LL | impl !Send for dyn Object + Marker2 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
|
LL | impl !Marker1 for dyn Object + Marker2 { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:17:1
|
LL | impl !Marker2 for dyn Object + Marker2 { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
error: aborting due to 5 previous errors error: aborting due to 5 previous errors
Some errors have detailed explanations: E0117, E0321, E0371. Some errors have detailed explanations: E0117, E0321, E0371.

View file

@ -1,3 +1,15 @@
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1
|
LL | impl Marker1 for dyn Object + Marker2 { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:17:1
|
LL | impl Marker2 for dyn Object + Marker2 { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:23:1 --> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:23:1
| |
@ -21,18 +33,6 @@ error[E0321]: cross-crate traits with a default impl, like `Send`, can only be i
LL | unsafe impl Send for dyn Object + Marker2 {} LL | unsafe impl Send for dyn Object + Marker2 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait with a default impl for non-struct/enum type
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:15:1
|
LL | impl Marker1 for dyn Object + Marker2 { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
--> $DIR/coherence-impl-trait-for-marker-trait-positive.rs:17:1
|
LL | impl Marker2 for dyn Object + Marker2 { }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
error: aborting due to 5 previous errors error: aborting due to 5 previous errors
Some errors have detailed explanations: E0117, E0321, E0371. Some errors have detailed explanations: E0117, E0321, E0371.

View file

@ -9,6 +9,27 @@ LL | impl Copy for i32 {}
| |
= note: define and implement a trait or new type instead = note: define and implement a trait or new type instead
error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`
--> $DIR/coherence-impls-copy.rs:28:1
|
LL | impl Copy for &'static NotSync {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> Copy for &T
where T: ?Sized;
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-copy.rs:33:1
|
LL | impl Copy for &'static [NotSync] {}
| ^^^^^^^^^^^^^^------------------
| | |
| | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-copy.rs:25:1 --> $DIR/coherence-impls-copy.rs:25:1
| |
@ -31,27 +52,6 @@ LL | impl Copy for [MyType] {}
| |
= note: define and implement a trait or new type instead = note: define and implement a trait or new type instead
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-copy.rs:33:1
|
LL | impl Copy for &'static [NotSync] {}
| ^^^^^^^^^^^^^^------------------
| | |
| | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync`
--> $DIR/coherence-impls-copy.rs:28:1
|
LL | impl Copy for &'static NotSync {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> Copy for &T
where T: ?Sized;
error[E0206]: the trait `Copy` may not be implemented for this type error[E0206]: the trait `Copy` may not be implemented for this type
--> $DIR/coherence-impls-copy.rs:21:15 --> $DIR/coherence-impls-copy.rs:21:15
| |

View file

@ -1,3 +1,14 @@
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-send.rs:25:1
|
LL | unsafe impl Send for &'static [NotSync] {}
| ^^^^^^^^^^^^^^^^^^^^^------------------
| | |
| | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-send.rs:16:1 --> $DIR/coherence-impls-send.rs:16:1
| |
@ -26,17 +37,6 @@ LL | unsafe impl Send for [MyType] {}
| |
= note: define and implement a trait or new type instead = note: define and implement a trait or new type instead
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-send.rs:25:1
|
LL | unsafe impl Send for &'static [NotSync] {}
| ^^^^^^^^^^^^^^^^^^^^^------------------
| | |
| | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error: aborting due to 4 previous errors error: aborting due to 4 previous errors
Some errors have detailed explanations: E0117, E0321. Some errors have detailed explanations: E0117, E0321.

View file

@ -1,36 +1,3 @@
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-sized.rs:20:1
|
LL | impl Sized for (MyType, MyType) {}
| ^^^^^^^^^^^^^^^----------------
| | |
| | this is not defined in the current crate because tuples are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-sized.rs:27:1
|
LL | impl Sized for [MyType] {}
| ^^^^^^^^^^^^^^^--------
| | |
| | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-sized.rs:31:1
|
LL | impl Sized for &'static [NotSync] {}
| ^^^^^^^^^^^^^^^------------------
| | |
| | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0322]: explicit impls for the `Sized` trait are not permitted error[E0322]: explicit impls for the `Sized` trait are not permitted
--> $DIR/coherence-impls-sized.rs:14:1 --> $DIR/coherence-impls-sized.rs:14:1
| |
@ -49,6 +16,17 @@ error[E0322]: explicit impls for the `Sized` trait are not permitted
LL | impl Sized for (MyType, MyType) {} LL | impl Sized for (MyType, MyType) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-sized.rs:20:1
|
LL | impl Sized for (MyType, MyType) {}
| ^^^^^^^^^^^^^^^----------------
| | |
| | this is not defined in the current crate because tuples are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0322]: explicit impls for the `Sized` trait are not permitted error[E0322]: explicit impls for the `Sized` trait are not permitted
--> $DIR/coherence-impls-sized.rs:24:1 --> $DIR/coherence-impls-sized.rs:24:1
| |
@ -61,12 +39,34 @@ error[E0322]: explicit impls for the `Sized` trait are not permitted
LL | impl Sized for [MyType] {} LL | impl Sized for [MyType] {}
| ^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed | ^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-sized.rs:27:1
|
LL | impl Sized for [MyType] {}
| ^^^^^^^^^^^^^^^--------
| | |
| | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error[E0322]: explicit impls for the `Sized` trait are not permitted error[E0322]: explicit impls for the `Sized` trait are not permitted
--> $DIR/coherence-impls-sized.rs:31:1 --> $DIR/coherence-impls-sized.rs:31:1
| |
LL | impl Sized for &'static [NotSync] {} LL | impl Sized for &'static [NotSync] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Sized` not allowed
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> $DIR/coherence-impls-sized.rs:31:1
|
LL | impl Sized for &'static [NotSync] {}
| ^^^^^^^^^^^^^^^------------------
| | |
| | this is not defined in the current crate because slices are always foreign
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
error: aborting due to 9 previous errors error: aborting due to 9 previous errors
Some errors have detailed explanations: E0117, E0322. Some errors have detailed explanations: E0117, E0322.

View file

@ -1,3 +1,12 @@
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
--> $DIR/coherence-with-closure.rs:12:1
|
LL | impl Trait for Wrapper<OpaqueClosure> {}
| ------------------------------------- first implementation here
LL |
LL | impl<T: Sync> Trait for Wrapper<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
error: cannot implement trait on type alias impl trait error: cannot implement trait on type alias impl trait
--> $DIR/coherence-with-closure.rs:10:24 --> $DIR/coherence-with-closure.rs:10:24
| |
@ -10,15 +19,6 @@ note: type alias impl trait defined here
LL | type OpaqueClosure = impl Sized; LL | type OpaqueClosure = impl Sized;
| ^^^^^^^^^^ | ^^^^^^^^^^
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueClosure>`
--> $DIR/coherence-with-closure.rs:12:1
|
LL | impl Trait for Wrapper<OpaqueClosure> {}
| ------------------------------------- first implementation here
LL |
LL | impl<T: Sync> Trait for Wrapper<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueClosure>`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`. For more information about this error, try `rustc --explain E0119`.

View file

@ -1,3 +1,12 @@
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
--> $DIR/coherence-with-generator.rs:16:1
|
LL | impl Trait for Wrapper<OpaqueGenerator> {}
| --------------------------------------- first implementation here
LL |
LL | impl<T: Sync> Trait for Wrapper<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
error: cannot implement trait on type alias impl trait error: cannot implement trait on type alias impl trait
--> $DIR/coherence-with-generator.rs:14:24 --> $DIR/coherence-with-generator.rs:14:24
| |
@ -10,15 +19,6 @@ note: type alias impl trait defined here
LL | type OpaqueGenerator = impl Sized; LL | type OpaqueGenerator = impl Sized;
| ^^^^^^^^^^ | ^^^^^^^^^^
error[E0119]: conflicting implementations of trait `Trait` for type `Wrapper<OpaqueGenerator>`
--> $DIR/coherence-with-generator.rs:16:1
|
LL | impl Trait for Wrapper<OpaqueGenerator> {}
| --------------------------------------- first implementation here
LL |
LL | impl<T: Sync> Trait for Wrapper<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Wrapper<OpaqueGenerator>`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`. For more information about this error, try `rustc --explain E0119`.

View file

@ -1,3 +1,12 @@
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
--> $DIR/auto-trait.rs:21:1
|
LL | impl<T: Send> AnotherTrait for T {}
| -------------------------------- first implementation here
...
LL | impl AnotherTrait for D<OpaqueType> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
error: cannot implement trait on type alias impl trait error: cannot implement trait on type alias impl trait
--> $DIR/auto-trait.rs:21:25 --> $DIR/auto-trait.rs:21:25
| |
@ -10,15 +19,6 @@ note: type alias impl trait defined here
LL | type OpaqueType = impl OpaqueTrait; LL | type OpaqueType = impl OpaqueTrait;
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
--> $DIR/auto-trait.rs:21:1
|
LL | impl<T: Send> AnotherTrait for T {}
| -------------------------------- first implementation here
...
LL | impl AnotherTrait for D<OpaqueType> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`. For more information about this error, try `rustc --explain E0119`.

View file

@ -1,3 +1,14 @@
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
--> $DIR/negative-reasoning.rs:19:1
|
LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
| ------------------------------------------- first implementation here
...
LL | impl AnotherTrait for D<OpaqueType> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
|
= note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
error: cannot implement trait on type alias impl trait error: cannot implement trait on type alias impl trait
--> $DIR/negative-reasoning.rs:19:25 --> $DIR/negative-reasoning.rs:19:25
| |
@ -10,17 +21,6 @@ note: type alias impl trait defined here
LL | type OpaqueType = impl OpaqueTrait; LL | type OpaqueType = impl OpaqueTrait;
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
--> $DIR/negative-reasoning.rs:19:1
|
LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
| ------------------------------------------- first implementation here
...
LL | impl AnotherTrait for D<OpaqueType> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
|
= note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`. For more information about this error, try `rustc --explain E0119`.

View file

@ -1,3 +1,11 @@
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
--> $DIR/issue-83613.rs:10:1
|
LL | impl<T: Send> AnotherTrait for T {}
| -------------------------------- first implementation here
LL | impl AnotherTrait for OpaqueType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
error: cannot implement trait on type alias impl trait error: cannot implement trait on type alias impl trait
--> $DIR/issue-83613.rs:10:23 --> $DIR/issue-83613.rs:10:23
| |
@ -10,14 +18,6 @@ note: type alias impl trait defined here
LL | type OpaqueType = impl OpaqueTrait; LL | type OpaqueType = impl OpaqueTrait;
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^
error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
--> $DIR/issue-83613.rs:10:1
|
LL | impl<T: Send> AnotherTrait for T {}
| -------------------------------- first implementation here
LL | impl AnotherTrait for OpaqueType {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0119`. For more information about this error, try `rustc --explain E0119`.

View file

@ -4,7 +4,6 @@ impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {} //~ ERROR cannot find type `U`
//~^ ERROR cannot find type `MISC` in this scope //~^ ERROR cannot find type `MISC` in this scope
//~| ERROR use of unstable library feature 'dispatch_from_dyn' //~| ERROR use of unstable library feature 'dispatch_from_dyn'
//~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures //~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures
//~| ERROR type parameter `T` must be covered by another type when it appears before the first
trait Foo: X<u32> {} trait Foo: X<u32> {}
trait X<T> { trait X<T> {
fn foo(self: Smaht<Self, T>); fn foo(self: Smaht<Self, T>);

View file

@ -50,22 +50,13 @@ LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
| |
= help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
--> $DIR/issue-78372.rs:3:6
|
LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`)
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
--> $DIR/issue-78372.rs:3:1 --> $DIR/issue-78372.rs:3:1
| |
LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {} LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 7 previous errors error: aborting due to 6 previous errors
Some errors have detailed explanations: E0210, E0378, E0412, E0658. Some errors have detailed explanations: E0378, E0412, E0658.
For more information about an error, try `rustc --explain E0210`. For more information about an error, try `rustc --explain E0378`.