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 @@
/// 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.
query orphan_check_crate(_: ()) -> &'tcx [LocalDefId] {
desc {
"checking whether the immpl in the this crate follow the orphan rules",
query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> {
desc { |tcx|
"checking whether impl `{}` follows the orphan rules",
tcx.def_path_str(key.to_def_id()),
}
}

View File

@ -452,7 +452,7 @@ fn decorate<G: EmissionGuarantee>(
match used_to_be_allowed {
None => {
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, "");
Some(decorate(

View File

@ -146,7 +146,7 @@ pub fn provide(providers: &mut Providers) {
use self::builtin::coerce_unsized_info;
use self::inherent_impls::{crate_incoherent_impls, crate_inherent_impls, inherent_impls};
use self::inherent_impls_overlap::crate_inherent_impls_overlap_check;
use self::orphan::orphan_check_crate;
use self::orphan::orphan_check_impl;
*providers = Providers {
coherent_trait,
@ -155,7 +155,7 @@ pub fn provide(providers: &mut Providers) {
inherent_impls,
crate_inherent_impls_overlap_check,
coerce_unsized_info,
orphan_check_crate,
orphan_check_impl,
..*providers
};
}
@ -171,23 +171,14 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) {
check_impl(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);
}
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`.
fn check_object_overlap<'tcx>(
tcx: TyCtxt<'tcx>,

View File

@ -18,26 +18,29 @@
use rustc_trait_selection::traits;
use std::ops::ControlFlow;
pub(super) fn orphan_check_crate(tcx: TyCtxt<'_>, (): ()) -> &[LocalDefId] {
let mut errors = Vec::new();
for (&trait_def_id, impls_of_trait) in tcx.all_local_trait_impls(()) {
for &impl_of_trait in impls_of_trait {
match orphan_check_impl(tcx, impl_of_trait) {
Ok(()) => {}
Err(_) => errors.push(impl_of_trait),
}
}
if tcx.trait_is_auto(trait_def_id) {
lint_auto_trait_impls(tcx, trait_def_id, impls_of_trait);
}
#[instrument(skip(tcx), level = "debug")]
pub(crate) fn orphan_check_impl(
tcx: TyCtxt<'_>,
impl_def_id: LocalDefId,
) -> Result<(), ErrorGuaranteed> {
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
if trait_ref.references_error() {
return Ok(());
}
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 orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
let trait_ref = tcx.impl_trait_ref(def_id).unwrap();
fn do_orphan_check_impl<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
def_id: LocalDefId,
) -> Result<(), ErrorGuaranteed> {
let trait_def_id = trait_ref.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
/// unsound or surprising effects on auto impls.
fn lint_auto_trait_impls(tcx: TyCtxt<'_>, trait_def_id: DefId, impls: &[LocalDefId]) {
let mut non_covering_impls = Vec::new();
for &impl_def_id in impls {
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
if trait_ref.references_error() {
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));
}
}
}
fn lint_auto_trait_impls<'tcx>(
tcx: TyCtxt<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
impl_def_id: LocalDefId,
) {
if tcx.impl_polarity(impl_def_id) != ImplPolarity::Positive {
return;
}
for &(impl_def_id, self_type_did, arg) in &non_covering_impls {
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 `{}`, \
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.
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",
tcx.def_path_str(trait_def_id),
));
match arg {
ty::util::NotUniqueParam::DuplicateParam(arg) => {
err.note(&format!("`{}` is mentioned multiple times", arg));
}
ty::util::NotUniqueParam::NotParam(arg) => {
err.note(&format!("`{}` is not a generic parameter", arg));
}
tcx.def_path_str(trait_ref.def_id),
));
match arg {
ty::util::NotUniqueParam::DuplicateParam(arg) => {
err.note(&format!("`{}` is mentioned multiple times", arg));
}
err.span_note(
item_span,
&format!(
"try using the same sequence of generic parameters as the {} definition",
self_descr,
),
);
err.emit();
},
);
}
ty::util::NotUniqueParam::NotParam(arg) => {
err.note(&format!("`{}` is not a generic parameter", arg));
}
}
err.span_note(
item_span,
&format!(
"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 {

View File

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

View File

@ -513,7 +513,15 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
})?;
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 {

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
--> $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 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
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
--> $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 {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
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
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
--> $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
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
--> $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
--> $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
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
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
--> $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) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
--> $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] {}
| ^^^^^^^^^^^^^^^^^^^^^^^ 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
--> $DIR/coherence-impls-sized.rs:31:1
|
LL | impl Sized for &'static [NotSync] {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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
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
--> $DIR/coherence-with-closure.rs:10:24
|
@ -10,15 +19,6 @@ note: type alias impl trait defined here
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
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
--> $DIR/coherence-with-generator.rs:14:24
|
@ -10,15 +19,6 @@ note: type alias impl trait defined here
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
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
--> $DIR/auto-trait.rs:21:25
|
@ -10,15 +19,6 @@ note: type alias impl trait defined here
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
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
--> $DIR/negative-reasoning.rs:19:25
|
@ -10,17 +21,6 @@ note: type alias impl trait defined here
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
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
--> $DIR/issue-83613.rs:10:23
|
@ -10,14 +18,6 @@ note: type alias impl trait defined here
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
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 use of unstable library feature 'dispatch_from_dyn'
//~| 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 X<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
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
--> $DIR/issue-78372.rs:3:1
|
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.
For more information about an error, try `rustc --explain E0210`.
Some errors have detailed explanations: E0378, E0412, E0658.
For more information about an error, try `rustc --explain E0378`.