Perform coherence checking per impl.
This commit is contained in:
parent
21e9336fe8
commit
0ff8c65d6f
@ -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()),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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>,
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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`.
|
||||
|
@ -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`.
|
||||
|
@ -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`.
|
||||
|
@ -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`.
|
||||
|
@ -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`.
|
||||
|
@ -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>);
|
||||
|
@ -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`.
|
||||
|
Loading…
Reference in New Issue
Block a user