From 1296719c061fb4dd594f5c84e223be30d8611d95 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 21 Oct 2021 15:36:35 +0200 Subject: [PATCH 1/2] no overlap errors after failing the orphan check --- compiler/rustc_middle/src/query/mod.rs | 13 +- .../src/traits/specialize/mod.rs | 8 +- compiler/rustc_typeck/src/coherence/mod.rs | 8 +- compiler/rustc_typeck/src/coherence/orphan.rs | 464 +++++++++--------- .../coherence-cross-crate-conflict.rs | 4 +- .../coherence-cross-crate-conflict.stderr | 14 +- ...mpl-trait-for-marker-trait-negative.stderr | 24 +- ...mpl-trait-for-marker-trait-positive.stderr | 24 +- src/test/ui/coherence/coherence-impls-copy.rs | 6 +- .../ui/coherence/coherence-impls-copy.stderr | 83 ++-- src/test/ui/coherence/coherence-impls-send.rs | 3 +- .../ui/coherence/coherence-impls-send.stderr | 15 +- .../ui/coherence/coherence-impls-sized.stderr | 66 +-- src/test/ui/coherence/coherence-orphan.stderr | 22 +- src/test/ui/dropck/drop-on-non-struct.stderr | 12 +- src/test/ui/error-codes/E0117.stderr | 12 +- src/test/ui/error-codes/e0119/complex-impl.rs | 1 - .../ui/error-codes/e0119/complex-impl.stderr | 15 +- src/test/ui/error-codes/e0119/issue-28981.rs | 1 - .../ui/error-codes/e0119/issue-28981.stderr | 15 +- src/test/ui/issues/issue-41974.rs | 6 +- src/test/ui/issues/issue-41974.stderr | 27 +- .../const-and-non-const-impl.rs | 9 +- .../const-and-non-const-impl.stderr | 95 +++- src/test/ui/traits/alias/issue-83613.stderr | 16 +- src/test/ui/traits/issue-78372.stderr | 12 +- .../incoherent-assoc-imp-trait.rs | 3 +- .../incoherent-assoc-imp-trait.stderr | 15 +- 28 files changed, 496 insertions(+), 497 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index a9f94b74c5efb..9a58009a173d4 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -822,6 +822,14 @@ rustc_queries! { desc { "check for overlap between inherent impls defined in this crate" } } + /// 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", + } + } + /// Check whether the function has any recursion that could cause the inliner to trigger /// a cycle. Returns the call stack causing the cycle. The call stack does not contain the /// current function, just all intermediate functions. @@ -1056,11 +1064,6 @@ rustc_queries! { } /// Return all `impl` blocks in the current crate. - /// - /// To allow caching this between crates, you must pass in [`LOCAL_CRATE`] as the crate number. - /// Passing in any other crate will cause an ICE. - /// - /// [`LOCAL_CRATE`]: rustc_hir::def_id::LOCAL_CRATE query all_local_trait_impls(_: ()) -> &'tcx BTreeMap> { desc { "local trait impls" } } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index f81a74a67dce5..96ab399424e20 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -443,8 +443,12 @@ fn report_conflicting_impls( match used_to_be_allowed { None => { sg.has_errored = true; - let err = struct_span_err!(tcx.sess, impl_span, E0119, ""); - decorate(LintDiagnosticBuilder::new(err)); + if overlap.with_impl.is_local() || !tcx.orphan_check_crate(()).contains(&impl_def_id) { + let err = struct_span_err!(tcx.sess, impl_span, E0119, ""); + decorate(LintDiagnosticBuilder::new(err)); + } else { + tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check"); + } } Some(kind) => { let lint = match kind { diff --git a/compiler/rustc_typeck/src/coherence/mod.rs b/compiler/rustc_typeck/src/coherence/mod.rs index 079604f128d43..377ebf1fe2a9f 100644 --- a/compiler/rustc_typeck/src/coherence/mod.rs +++ b/compiler/rustc_typeck/src/coherence/mod.rs @@ -168,6 +168,7 @@ pub fn provide(providers: &mut Providers) { use self::builtin::coerce_unsized_info; use self::inherent_impls::{crate_inherent_impls, inherent_impls}; use self::inherent_impls_overlap::crate_inherent_impls_overlap_check; + use self::orphan::orphan_check_crate; *providers = Providers { coherent_trait, @@ -175,6 +176,7 @@ pub fn provide(providers: &mut Providers) { inherent_impls, crate_inherent_impls_overlap_check, coerce_unsized_info, + orphan_check_crate, ..*providers }; } @@ -195,13 +197,13 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) { } 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); } - tcx.sess.time("unsafety_checking", || unsafety::check(tcx)); - tcx.sess.time("orphan_checking", || orphan::check(tcx)); - // these queries are executed for side-effects (error reporting): tcx.ensure().crate_inherent_impls(()); tcx.ensure().crate_inherent_impls_overlap_check(()); diff --git a/compiler/rustc_typeck/src/coherence/orphan.rs b/compiler/rustc_typeck/src/coherence/orphan.rs index 0326d1fd74f62..b450d3f6c08ab 100644 --- a/compiler/rustc_typeck/src/coherence/orphan.rs +++ b/compiler/rustc_typeck/src/coherence/orphan.rs @@ -2,250 +2,266 @@ //! crate or pertains to a type defined in this crate. use rustc_errors::struct_span_err; +use rustc_errors::ErrorReported; use rustc_hir as hir; -use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::ty::{self, TyCtxt}; +use rustc_span::def_id::LocalDefId; +use rustc_span::Span; use rustc_trait_selection::traits; -pub fn check(tcx: TyCtxt<'_>) { - let mut orphan = OrphanChecker { tcx }; - tcx.hir().visit_all_item_likes(&mut orphan); +pub(super) fn orphan_check_crate(tcx: TyCtxt<'_>, (): ()) -> &[LocalDefId] { + let mut errors = Vec::new(); + for (_trait, 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(ErrorReported) => errors.push(impl_of_trait), + } + } + } + tcx.arena.alloc_slice(&errors) } -struct OrphanChecker<'tcx> { - tcx: TyCtxt<'tcx>, -} +#[instrument(skip(tcx), level = "debug")] +fn orphan_check_impl(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorReported> { + let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); + let trait_def_id = trait_ref.def_id; -impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { - /// Checks exactly one impl for orphan rules and other such - /// restrictions. In this fn, it can happen that multiple errors - /// apply to a specific impl, so just return after reporting one - /// to prevent inundating the user with a bunch of similar error - /// reports. - fn visit_item(&mut self, item: &hir::Item<'_>) { - // "Trait" impl - if let hir::ItemKind::Impl(hir::Impl { - generics, of_trait: Some(ref tr), self_ty, .. - }) = &item.kind - { - debug!( - "coherence2::orphan check: trait impl {}", - self.tcx.hir().node_to_string(item.hir_id()) - ); - let trait_ref = self.tcx.impl_trait_ref(item.def_id).unwrap(); - let trait_def_id = trait_ref.def_id; - let sm = self.tcx.sess.source_map(); - let sp = sm.guess_head_span(item.span); - match traits::orphan_check(self.tcx, item.def_id.to_def_id()) { - Ok(()) => {} - Err(traits::OrphanCheckErr::NonLocalInputType(tys)) => { - let mut err = struct_span_err!( - self.tcx.sess, - sp, - E0117, - "only traits defined in the current crate can be implemented for \ - arbitrary types" - ); - err.span_label(sp, "impl doesn't use only types from inside the current crate"); - for (ty, is_target_ty) in &tys { - let mut ty = *ty; - self.tcx.infer_ctxt().enter(|infcx| { - // Remove the lifetimes unnecessary for this error. - ty = infcx.freshen(ty); - }); - ty = match ty.kind() { - // Remove the type arguments from the output, as they are not relevant. - // You can think of this as the reverse of `resolve_vars_if_possible`. - // That way if we had `Vec`, we will properly attribute the - // problem to `Vec` and avoid confusing the user if they were to see - // `MyType` in the error. - ty::Adt(def, _) => self.tcx.mk_adt(def, ty::List::empty()), - _ => ty, - }; - let this = "this".to_string(); - let (ty, postfix) = match &ty.kind() { - ty::Slice(_) => (this, " because slices are always foreign"), - ty::Array(..) => (this, " because arrays are always foreign"), - ty::Tuple(..) => (this, " because tuples are always foreign"), - _ => (format!("`{}`", ty), ""), - }; - let msg = format!("{} is not defined in the current crate{}", ty, postfix); - if *is_target_ty { - // Point at `D` in `impl for C in D` - err.span_label(self_ty.span, &msg); - } else { - // Point at `C` in `impl for C in D` - err.span_label(tr.path.span, &msg); - } - } - err.note("define and implement a trait or new type instead"); - err.emit(); - return; - } - Err(traits::OrphanCheckErr::UncoveredTy(param_ty, local_type)) => { - let mut sp = sp; - for param in generics.params { - if param.name.ident().to_string() == param_ty.to_string() { - sp = param.span; - } - } + let item = tcx.hir().item(hir::ItemId { def_id }); + let impl_ = match item.kind { + hir::ItemKind::Impl(ref impl_) => impl_, + _ => bug!("{:?} is not an impl: {:?}", def_id, item), + }; + let sp = tcx.sess.source_map().guess_head_span(item.span); + let tr = impl_.of_trait.as_ref().unwrap(); + match traits::orphan_check(tcx, item.def_id.to_def_id()) { + Ok(()) => {} + Err(err) => emit_orphan_check_error( + tcx, + sp, + tr.path.span, + impl_.self_ty.span, + &impl_.generics, + err, + )?, + } + + // In addition to the above rules, we restrict impls of auto traits + // so that they can only be implemented on nominal types, such as structs, + // enums or foreign types. To see why this restriction exists, consider the + // following example (#22978). Imagine that crate A defines an auto trait + // `Foo` and a fn that operates on pairs of types: + // + // ``` + // // Crate A + // auto trait Foo { } + // fn two_foos(..) { + // one_foo::<(A,B)>(..) + // } + // fn one_foo(..) { .. } + // ``` + // + // This type-checks fine; in particular the fn + // `two_foos` is able to conclude that `(A,B):Foo` + // because `A:Foo` and `B:Foo`. + // + // Now imagine that crate B comes along and does the following: + // + // ``` + // struct A { } + // struct B { } + // impl Foo for A { } + // impl Foo for B { } + // impl !Send for (A, B) { } + // ``` + // + // This final impl is legal according to the orphan + // rules, but it invalidates the reasoning from + // `two_foos` above. + debug!( + "trait_ref={:?} trait_def_id={:?} trait_is_auto={}", + trait_ref, + trait_def_id, + tcx.trait_is_auto(trait_def_id) + ); + + if tcx.trait_is_auto(trait_def_id) && !trait_def_id.is_local() { + let self_ty = trait_ref.self_ty(); + let opt_self_def_id = match *self_ty.kind() { + ty::Adt(self_def, _) => Some(self_def.did), + ty::Foreign(did) => Some(did), + _ => None, + }; - match local_type { - Some(local_type) => { - struct_span_err!( - self.tcx.sess, - sp, - E0210, - "type parameter `{}` must be covered by another type \ - when it appears before the first local type (`{}`)", - param_ty, - local_type - ) - .span_label( - sp, - format!( - "type parameter `{}` must be covered by another type \ - when it appears before the first local type (`{}`)", - param_ty, local_type - ), - ) - .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 for T0`, \ - where `T0` is the first and `Tn` is the last", - ) - .emit(); - } - None => { - struct_span_err!( - self.tcx.sess, - sp, - E0210, - "type parameter `{}` must be used as the type parameter for some \ - local type (e.g., `MyStruct<{}>`)", - param_ty, - param_ty - ).span_label(sp, format!( - "type parameter `{}` must be used as the type parameter for some \ - local type", - param_ty, - )).note("implementing a foreign trait is only possible if at \ - least one of the types for which it is implemented is local" - ).note("only traits defined in the current crate can be \ - implemented for a type parameter" - ).emit(); - } - }; - return; + let msg = match opt_self_def_id { + // We only want to permit nominal types, but not *all* nominal types. + // They must be local to the current crate, so that people + // can't do `unsafe impl Send for Rc` or + // `impl !Send for Box`. + Some(self_def_id) => { + if self_def_id.is_local() { + None + } else { + Some(( + format!( + "cross-crate traits with a default impl, like `{}`, \ + can only be implemented for a struct/enum type \ + defined in the current crate", + tcx.def_path_str(trait_def_id) + ), + "can't implement cross-crate trait for type in another crate", + )) } } + _ => Some(( + format!( + "cross-crate traits with a default impl, like `{}`, can \ + only be implemented for a struct/enum type, not `{}`", + tcx.def_path_str(trait_def_id), + self_ty + ), + "can't implement cross-crate trait with a default impl for \ + non-struct/enum type", + )), + }; - // In addition to the above rules, we restrict impls of auto traits - // so that they can only be implemented on nominal types, such as structs, - // enums or foreign types. To see why this restriction exists, consider the - // following example (#22978). Imagine that crate A defines an auto trait - // `Foo` and a fn that operates on pairs of types: - // - // ``` - // // Crate A - // auto trait Foo { } - // fn two_foos(..) { - // one_foo::<(A,B)>(..) - // } - // fn one_foo(..) { .. } - // ``` - // - // This type-checks fine; in particular the fn - // `two_foos` is able to conclude that `(A,B):Foo` - // because `A:Foo` and `B:Foo`. - // - // Now imagine that crate B comes along and does the following: - // - // ``` - // struct A { } - // struct B { } - // impl Foo for A { } - // impl Foo for B { } - // impl !Send for (A, B) { } - // ``` - // - // This final impl is legal according to the orphan - // rules, but it invalidates the reasoning from - // `two_foos` above. - debug!( - "trait_ref={:?} trait_def_id={:?} trait_is_auto={}", - trait_ref, - trait_def_id, - self.tcx.trait_is_auto(trait_def_id) + if let Some((msg, label)) = msg { + struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit(); + return Err(ErrorReported); + } + } + + if let ty::Opaque(def_id, _) = *trait_ref.self_ty().kind() { + tcx.sess + .struct_span_err(sp, "cannot implement trait on type alias impl trait") + .span_note(tcx.def_span(def_id), "type alias impl trait defined here") + .emit(); + return Err(ErrorReported); + } + + Ok(()) +} + +fn emit_orphan_check_error( + tcx: TyCtxt<'tcx>, + sp: Span, + trait_span: Span, + self_ty_span: Span, + generics: &hir::Generics<'tcx>, + err: traits::OrphanCheckErr<'tcx>, +) -> Result { + match err { + traits::OrphanCheckErr::NonLocalInputType(tys) => { + let mut err = struct_span_err!( + tcx.sess, + sp, + E0117, + "only traits defined in the current crate can be implemented for \ + arbitrary types" ); - if self.tcx.trait_is_auto(trait_def_id) && !trait_def_id.is_local() { - let self_ty = trait_ref.self_ty(); - let opt_self_def_id = match *self_ty.kind() { - ty::Adt(self_def, _) => Some(self_def.did), - ty::Foreign(did) => Some(did), - _ => None, + err.span_label(sp, "impl doesn't use only types from inside the current crate"); + for (ty, is_target_ty) in &tys { + let mut ty = *ty; + tcx.infer_ctxt().enter(|infcx| { + // Remove the lifetimes unnecessary for this error. + ty = infcx.freshen(ty); + }); + ty = match ty.kind() { + // Remove the type arguments from the output, as they are not relevant. + // You can think of this as the reverse of `resolve_vars_if_possible`. + // That way if we had `Vec`, we will properly attribute the + // problem to `Vec` and avoid confusing the user if they were to see + // `MyType` in the error. + ty::Adt(def, _) => tcx.mk_adt(def, ty::List::empty()), + _ => ty, }; - - let msg = match opt_self_def_id { - // We only want to permit nominal types, but not *all* nominal types. - // They must be local to the current crate, so that people - // can't do `unsafe impl Send for Rc` or - // `impl !Send for Box`. - Some(self_def_id) => { - if self_def_id.is_local() { - None - } else { - Some(( - format!( - "cross-crate traits with a default impl, like `{}`, \ - can only be implemented for a struct/enum type \ - defined in the current crate", - self.tcx.def_path_str(trait_def_id) - ), - "can't implement cross-crate trait for type in another crate", - )) - } - } - _ => Some(( - format!( - "cross-crate traits with a default impl, like `{}`, can \ - only be implemented for a struct/enum type, not `{}`", - self.tcx.def_path_str(trait_def_id), - self_ty - ), - "can't implement cross-crate trait with a default impl for \ - non-struct/enum type", - )), + let this = "this".to_string(); + let (ty, postfix) = match &ty.kind() { + ty::Slice(_) => (this, " because slices are always foreign"), + ty::Array(..) => (this, " because arrays are always foreign"), + ty::Tuple(..) => (this, " because tuples are always foreign"), + _ => (format!("`{}`", ty), ""), }; - - if let Some((msg, label)) = msg { - struct_span_err!(self.tcx.sess, sp, E0321, "{}", msg) - .span_label(sp, label) - .emit(); - return; + let msg = format!("{} is not defined in the current crate{}", ty, postfix); + if *is_target_ty { + // Point at `D` in `impl for C in D` + err.span_label(self_ty_span, &msg); + } else { + // Point at `C` in `impl for C in D` + err.span_label(trait_span, &msg); + } + } + err.note("define and implement a trait or new type instead"); + err.emit() + } + traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => { + let mut sp = sp; + for param in generics.params { + if param.name.ident().to_string() == param_ty.to_string() { + sp = param.span; } } - if let ty::Opaque(def_id, _) = *trait_ref.self_ty().kind() { - self.tcx - .sess - .struct_span_err(sp, "cannot implement trait on type alias impl trait") - .span_note(self.tcx.def_span(def_id), "type alias impl trait defined here") - .emit(); + match local_type { + Some(local_type) => struct_span_err!( + tcx.sess, + sp, + E0210, + "type parameter `{}` must be covered by another type \ + when it appears before the first local type (`{}`)", + param_ty, + local_type + ) + .span_label( + sp, + format!( + "type parameter `{}` must be covered by another type \ + when it appears before the first local type (`{}`)", + param_ty, local_type + ), + ) + .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 for T0`, \ + where `T0` is the first and `Tn` is the last", + ) + .emit(), + None => struct_span_err!( + tcx.sess, + sp, + E0210, + "type parameter `{}` must be used as the type parameter for some \ + local type (e.g., `MyStruct<{}>`)", + param_ty, + param_ty + ) + .span_label( + sp, + format!( + "type parameter `{}` must be used as the type parameter for some \ + local type", + param_ty, + ), + ) + .note( + "implementing a foreign trait is only possible if at \ + least one of the types for which it is implemented is local", + ) + .note( + "only traits defined in the current crate can be \ + implemented for a type parameter", + ) + .emit(), } } } - fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {} - - fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {} - - fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {} + Err(ErrorReported) } diff --git a/src/test/ui/coherence/coherence-cross-crate-conflict.rs b/src/test/ui/coherence/coherence-cross-crate-conflict.rs index 648e290a4b888..588630957c94a 100644 --- a/src/test/ui/coherence/coherence-cross-crate-conflict.rs +++ b/src/test/ui/coherence/coherence-cross-crate-conflict.rs @@ -6,9 +6,7 @@ extern crate trait_impl_conflict; use trait_impl_conflict::Foo; -impl Foo for A { - //~^ ERROR E0119 - //~| ERROR E0210 +impl Foo for A { //~ ERROR E0210 } fn main() { diff --git a/src/test/ui/coherence/coherence-cross-crate-conflict.stderr b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr index d0d86c72ffc68..3d253d56a4565 100644 --- a/src/test/ui/coherence/coherence-cross-crate-conflict.stderr +++ b/src/test/ui/coherence/coherence-cross-crate-conflict.stderr @@ -1,12 +1,3 @@ -error[E0119]: conflicting implementations of trait `trait_impl_conflict::Foo` for type `isize` - --> $DIR/coherence-cross-crate-conflict.rs:9:1 - | -LL | impl Foo for A { - | ^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `trait_impl_conflict`: - - impl Foo for isize; - error[E0210]: type parameter `A` must be used as the type parameter for some local type (e.g., `MyStruct`) --> $DIR/coherence-cross-crate-conflict.rs:9:6 | @@ -16,7 +7,6 @@ LL | impl Foo for A { = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0119, E0210. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr index c364c707ff9ea..912891480790e 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr @@ -1,15 +1,3 @@ -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 | @@ -33,6 +21,18 @@ 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. diff --git a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr index b80429794f92c..056198374a4cc 100644 --- a/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr +++ b/src/test/ui/coherence/coherence-impl-trait-for-marker-trait-positive.stderr @@ -1,15 +1,3 @@ -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 | @@ -33,6 +21,18 @@ 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. diff --git a/src/test/ui/coherence/coherence-impls-copy.rs b/src/test/ui/coherence/coherence-impls-copy.rs index a86ca0e5eacdc..4204fecc37e15 100644 --- a/src/test/ui/coherence/coherence-impls-copy.rs +++ b/src/test/ui/coherence/coherence-impls-copy.rs @@ -3,8 +3,7 @@ use std::marker::Copy; impl Copy for i32 {} -//~^ ERROR E0119 -//~| ERROR E0117 +//~^ ERROR E0117 enum TestE { A } @@ -32,7 +31,6 @@ impl Copy for [MyType] {} //~^ ERROR E0206 //~| ERROR E0117 impl Copy for &'static [NotSync] {} -//~^ ERROR E0119 -//~| ERROR E0117 +//~^ ERROR E0117 fn main() { } diff --git a/src/test/ui/coherence/coherence-impls-copy.stderr b/src/test/ui/coherence/coherence-impls-copy.stderr index 2ac0706d72e57..a7d6968a2967c 100644 --- a/src/test/ui/coherence/coherence-impls-copy.stderr +++ b/src/test/ui/coherence/coherence-impls-copy.stderr @@ -1,50 +1,3 @@ -error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `i32` - --> $DIR/coherence-impls-copy.rs:5:1 - | -LL | impl Copy for i32 {} - | ^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `core`: - - impl Copy for i32; - -error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&NotSync` - --> $DIR/coherence-impls-copy.rs:29:1 - | -LL | impl Copy for &'static NotSync {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `core`: - - impl Copy for &T - where T: ?Sized; - -error[E0119]: conflicting implementations of trait `std::marker::Copy` for type `&[NotSync]` - --> $DIR/coherence-impls-copy.rs:34:1 - | -LL | impl Copy for &'static [NotSync] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `core`: - - impl Copy for &T - where T: ?Sized; - -error[E0206]: the trait `Copy` may not be implemented for this type - --> $DIR/coherence-impls-copy.rs:22:15 - | -LL | impl Copy for &'static mut MyType {} - | ^^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration - -error[E0206]: the trait `Copy` may not be implemented for this type - --> $DIR/coherence-impls-copy.rs:26:15 - | -LL | impl Copy for (MyType, MyType) {} - | ^^^^^^^^^^^^^^^^ type is not a structure or enumeration - -error[E0206]: the trait `Copy` may not be implemented for this type - --> $DIR/coherence-impls-copy.rs:31:15 - | -LL | impl Copy for [MyType] {} - | ^^^^^^^^ type is not a structure or enumeration - error[E0117]: only traits defined in the current crate can be implemented for arbitrary types --> $DIR/coherence-impls-copy.rs:5:1 | @@ -57,7 +10,7 @@ LL | impl Copy for i32 {} = 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:26:1 + --> $DIR/coherence-impls-copy.rs:25:1 | LL | impl Copy for (MyType, MyType) {} | ^^^^^^^^^^^^^^---------------- @@ -68,7 +21,7 @@ LL | impl Copy for (MyType, 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:31:1 + --> $DIR/coherence-impls-copy.rs:30:1 | LL | impl Copy for [MyType] {} | ^^^^^^^^^^^^^^-------- @@ -79,7 +32,7 @@ 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:34:1 + --> $DIR/coherence-impls-copy.rs:33:1 | LL | impl Copy for &'static [NotSync] {} | ^^^^^^^^^^^^^^------------------ @@ -89,7 +42,35 @@ LL | impl Copy for &'static [NotSync] {} | = note: define and implement a trait or new type instead -error: aborting due to 10 previous errors +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 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 + | +LL | impl Copy for &'static mut MyType {} + | ^^^^^^^^^^^^^^^^^^^ type is not a structure or enumeration + +error[E0206]: the trait `Copy` may not be implemented for this type + --> $DIR/coherence-impls-copy.rs:25:15 + | +LL | impl Copy for (MyType, MyType) {} + | ^^^^^^^^^^^^^^^^ type is not a structure or enumeration + +error[E0206]: the trait `Copy` may not be implemented for this type + --> $DIR/coherence-impls-copy.rs:30:15 + | +LL | impl Copy for [MyType] {} + | ^^^^^^^^ type is not a structure or enumeration + +error: aborting due to 8 previous errors Some errors have detailed explanations: E0117, E0119, E0206. For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-impls-send.rs b/src/test/ui/coherence/coherence-impls-send.rs index e00cb9a7c5b51..b7b57c602b8d1 100644 --- a/src/test/ui/coherence/coherence-impls-send.rs +++ b/src/test/ui/coherence/coherence-impls-send.rs @@ -23,7 +23,6 @@ unsafe impl Send for [MyType] {} //~^ ERROR E0117 unsafe impl Send for &'static [NotSync] {} -//~^ ERROR conflicting implementations of trait -//~| ERROR only traits defined in the current crate +//~^ ERROR only traits defined in the current crate fn main() {} diff --git a/src/test/ui/coherence/coherence-impls-send.stderr b/src/test/ui/coherence/coherence-impls-send.stderr index 46e9e7e986c34..dd1fd1b0dce24 100644 --- a/src/test/ui/coherence/coherence-impls-send.stderr +++ b/src/test/ui/coherence/coherence-impls-send.stderr @@ -1,14 +1,3 @@ -error[E0119]: conflicting implementations of trait `std::marker::Send` for type `&[NotSync]` - --> $DIR/coherence-impls-send.rs:25:1 - | -LL | unsafe impl Send for &'static [NotSync] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `core`: - - impl Send for &T - where T: Sync, T: ?Sized; - = note: upstream crates may add a new impl of trait `std::marker::Sync` for type `[NotSync]` in future versions - error[E0117]: only traits defined in the current crate can be implemented for arbitrary types --> $DIR/coherence-impls-send.rs:16:1 | @@ -48,7 +37,7 @@ LL | unsafe impl Send for &'static [NotSync] {} | = note: define and implement a trait or new type instead -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0117, E0119, E0321. +Some errors have detailed explanations: E0117, E0321. For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/coherence/coherence-impls-sized.stderr b/src/test/ui/coherence/coherence-impls-sized.stderr index 3b0a9fc60a2e0..9cf5ed38c9c6b 100644 --- a/src/test/ui/coherence/coherence-impls-sized.stderr +++ b/src/test/ui/coherence/coherence-impls-sized.stderr @@ -1,3 +1,36 @@ +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 | @@ -34,39 +67,6 @@ error[E0322]: explicit impls for the `Sized` trait are not permitted 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: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: aborting due to 9 previous errors Some errors have detailed explanations: E0117, E0322. diff --git a/src/test/ui/coherence/coherence-orphan.stderr b/src/test/ui/coherence/coherence-orphan.stderr index 52d2cc88cbe7f..051a519ee1477 100644 --- a/src/test/ui/coherence/coherence-orphan.stderr +++ b/src/test/ui/coherence/coherence-orphan.stderr @@ -1,22 +1,22 @@ error[E0117]: only traits defined in the current crate can be implemented for arbitrary types - --> $DIR/coherence-orphan.rs:10:1 + --> $DIR/coherence-orphan.rs:17:1 | -LL | impl TheTrait for isize { } - | ^^^^^---------------^^^^^----- - | | | | - | | | `isize` is not defined in the current crate - | | `usize` is not defined in the current crate +LL | impl !Send for Vec { } + | ^^^^^^^^^^^^^^^---------- + | | | + | | `Vec` is not defined in the current crate | 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-orphan.rs:17:1 + --> $DIR/coherence-orphan.rs:10:1 | -LL | impl !Send for Vec { } - | ^^^^^^^^^^^^^^^---------- - | | | - | | `Vec` is not defined in the current crate +LL | impl TheTrait for isize { } + | ^^^^^---------------^^^^^----- + | | | | + | | | `isize` is not defined in the current crate + | | `usize` is not defined in the current crate | impl doesn't use only types from inside the current crate | = note: define and implement a trait or new type instead diff --git a/src/test/ui/dropck/drop-on-non-struct.stderr b/src/test/ui/dropck/drop-on-non-struct.stderr index 3991c44f2edce..e52728f3781f8 100644 --- a/src/test/ui/dropck/drop-on-non-struct.stderr +++ b/src/test/ui/dropck/drop-on-non-struct.stderr @@ -4,12 +4,6 @@ error[E0412]: cannot find type `Nonexistent` in this scope LL | impl Drop for Nonexistent { | ^^^^^^^^^^^ not found in this scope -error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions - --> $DIR/drop-on-non-struct.rs:1:19 - | -LL | impl<'a> Drop for &'a mut isize { - | ^^^^^^^^^^^^^ must be a struct, enum, or union - error[E0117]: only traits defined in the current crate can be implemented for arbitrary types --> $DIR/drop-on-non-struct.rs:1:1 | @@ -21,6 +15,12 @@ LL | impl<'a> Drop for &'a mut isize { | = note: define and implement a trait or new type instead +error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions + --> $DIR/drop-on-non-struct.rs:1:19 + | +LL | impl<'a> Drop for &'a mut isize { + | ^^^^^^^^^^^^^ must be a struct, enum, or union + error: aborting due to 3 previous errors Some errors have detailed explanations: E0117, E0120, E0412. diff --git a/src/test/ui/error-codes/E0117.stderr b/src/test/ui/error-codes/E0117.stderr index b48a1d8e50d4d..cdbafff2a202b 100644 --- a/src/test/ui/error-codes/E0117.stderr +++ b/src/test/ui/error-codes/E0117.stderr @@ -1,9 +1,3 @@ -error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions - --> $DIR/E0117.rs:1:15 - | -LL | impl Drop for u32 {} - | ^^^ must be a struct, enum, or union - error[E0117]: only traits defined in the current crate can be implemented for arbitrary types --> $DIR/E0117.rs:1:1 | @@ -15,6 +9,12 @@ LL | impl Drop for u32 {} | = note: define and implement a trait or new type instead +error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions + --> $DIR/E0117.rs:1:15 + | +LL | impl Drop for u32 {} + | ^^^ must be a struct, enum, or union + error: aborting due to 2 previous errors Some errors have detailed explanations: E0117, E0120. diff --git a/src/test/ui/error-codes/e0119/complex-impl.rs b/src/test/ui/error-codes/e0119/complex-impl.rs index 7dbf93ada5e5b..9149e4ce58e76 100644 --- a/src/test/ui/error-codes/e0119/complex-impl.rs +++ b/src/test/ui/error-codes/e0119/complex-impl.rs @@ -7,6 +7,5 @@ use complex_impl_support::{External, M}; struct Q; impl External for (Q, R) {} //~ ERROR only traits defined -//~^ ERROR conflicting implementations of trait fn main() {} diff --git a/src/test/ui/error-codes/e0119/complex-impl.stderr b/src/test/ui/error-codes/e0119/complex-impl.stderr index 6a1a502749a75..654073eec2602 100644 --- a/src/test/ui/error-codes/e0119/complex-impl.stderr +++ b/src/test/ui/error-codes/e0119/complex-impl.stderr @@ -1,13 +1,3 @@ -error[E0119]: conflicting implementations of trait `complex_impl_support::External` for type `(Q, complex_impl_support::M<'_, '_, '_, std::boxed::Box<_>, _, _>)` - --> $DIR/complex-impl.rs:9:1 - | -LL | impl External for (Q, R) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `complex_impl_support`: - - impl<'a, 'b, 'c, T, U, V, W> External for (T, M<'a, 'b, 'c, Box, V, W>) - where >::Output == V, ::Item == T, 'b: 'a, T: 'a, U: 'static, U: FnOnce<(T,)>, V: Iterator, V: Clone, W: Add, ::Output: Copy; - error[E0117]: only traits defined in the current crate can be implemented for arbitrary types --> $DIR/complex-impl.rs:9:1 | @@ -19,7 +9,6 @@ LL | impl External for (Q, R) {} | = note: define and implement a trait or new type instead -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0117, E0119. -For more information about an error, try `rustc --explain E0117`. +For more information about this error, try `rustc --explain E0117`. diff --git a/src/test/ui/error-codes/e0119/issue-28981.rs b/src/test/ui/error-codes/e0119/issue-28981.rs index c31b212b25a0d..5fb7e9a9913ab 100644 --- a/src/test/ui/error-codes/e0119/issue-28981.rs +++ b/src/test/ui/error-codes/e0119/issue-28981.rs @@ -3,6 +3,5 @@ use std::ops::Deref; struct Foo; impl Deref for Foo { } //~ ERROR must be used -//~^ ERROR conflicting implementations fn main() {} diff --git a/src/test/ui/error-codes/e0119/issue-28981.stderr b/src/test/ui/error-codes/e0119/issue-28981.stderr index 56e8e1eb54002..97b570bc7aca3 100644 --- a/src/test/ui/error-codes/e0119/issue-28981.stderr +++ b/src/test/ui/error-codes/e0119/issue-28981.stderr @@ -1,13 +1,3 @@ -error[E0119]: conflicting implementations of trait `std::ops::Deref` for type `&_` - --> $DIR/issue-28981.rs:5:1 - | -LL | impl Deref for Foo { } - | ^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `core`: - - impl Deref for &T - where T: ?Sized; - error[E0210]: type parameter `Foo` must be used as the type parameter for some local type (e.g., `MyStruct`) --> $DIR/issue-28981.rs:5:6 | @@ -17,7 +7,6 @@ LL | impl Deref for Foo { } = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0119, E0210. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0210`. diff --git a/src/test/ui/issues/issue-41974.rs b/src/test/ui/issues/issue-41974.rs index 7875b432d7be4..10c363479a374 100644 --- a/src/test/ui/issues/issue-41974.rs +++ b/src/test/ui/issues/issue-41974.rs @@ -4,9 +4,9 @@ struct Flags; trait A { } -impl Drop for T where T: A { //~ ERROR E0119 - //~^ ERROR E0120 - //~| ERROR E0210 +impl Drop for T where T: A { + //~^ ERROR E0120 + //~| ERROR E0210 fn drop(&mut self) { } } diff --git a/src/test/ui/issues/issue-41974.stderr b/src/test/ui/issues/issue-41974.stderr index 11d77857d60cc..fcbb4014025f1 100644 --- a/src/test/ui/issues/issue-41974.stderr +++ b/src/test/ui/issues/issue-41974.stderr @@ -1,13 +1,11 @@ -error[E0119]: conflicting implementations of trait `std::ops::Drop` for type `std::boxed::Box<_, _>` - --> $DIR/issue-41974.rs:7:1 +error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) + --> $DIR/issue-41974.rs:7:6 | LL | impl Drop for T where T: A { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^ type parameter `T` must be used as the type parameter for some local type | - = note: conflicting implementation in crate `alloc`: - - impl Drop for Box - where A: Allocator, T: ?Sized; - = note: downstream crates may implement trait `A` for type `std::boxed::Box<_, _>` + = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local + = note: only traits defined in the current crate can be implemented for a type parameter error[E0120]: the `Drop` trait may only be implemented for structs, enums, and unions --> $DIR/issue-41974.rs:7:18 @@ -15,16 +13,7 @@ error[E0120]: the `Drop` trait may only be implemented for structs, enums, and u LL | impl Drop for T where T: A { | ^ must be a struct, enum, or union -error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct`) - --> $DIR/issue-41974.rs:7:6 - | -LL | impl Drop for T where T: A { - | ^ type parameter `T` must be used as the type parameter for some local type - | - = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local - = note: only traits defined in the current crate can be implemented for a type parameter - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0119, E0120, E0210. -For more information about an error, try `rustc --explain E0119`. +Some errors have detailed explanations: E0120, E0210. +For more information about an error, try `rustc --explain E0120`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs index 4b2f049b99d9e..961968186de24 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs @@ -2,9 +2,8 @@ pub struct Int(i32); -impl const std::ops::Add for i32 { - //~^ ERROR conflicting implementations of trait - //~| ERROR only traits defined in the current crate can be implemented for arbitrary types +impl const std::ops::Add for i32 { //~ ERROR type annotations needed + //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types type Output = Self; fn add(self, rhs: Self) -> Self { @@ -12,7 +11,7 @@ impl const std::ops::Add for i32 { } } -impl std::ops::Add for Int { +impl std::ops::Add for Int { //~ ERROR type annotations needed type Output = Self; fn add(self, rhs: Self) -> Self { @@ -20,7 +19,7 @@ impl std::ops::Add for Int { } } -impl const std::ops::Add for Int { +impl const std::ops::Add for Int { //~ ERROR type annotations needed //~^ ERROR conflicting implementations of trait type Output = Self; diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr index a0960a21d46f8..785095c29ae4e 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr @@ -1,14 +1,17 @@ -error[E0119]: conflicting implementations of trait `std::ops::Add` for type `i32` +error[E0117]: only traits defined in the current crate can be implemented for arbitrary types --> $DIR/const-and-non-const-impl.rs:5:1 | LL | impl const std::ops::Add for i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^-------------^^^^^--- + | | | | + | | | `i32` is not defined in the current crate + | | `i32` is not defined in the current crate + | impl doesn't use only types from inside the current crate | - = note: conflicting implementation in crate `core`: - - impl Add for i32; + = note: define and implement a trait or new type instead error[E0119]: conflicting implementations of trait `std::ops::Add` for type `Int` - --> $DIR/const-and-non-const-impl.rs:23:1 + --> $DIR/const-and-non-const-impl.rs:22:1 | LL | impl std::ops::Add for Int { | -------------------------- first implementation here @@ -16,19 +19,83 @@ LL | impl std::ops::Add for Int { LL | impl const std::ops::Add for Int { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Int` -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0283]: type annotations needed + --> $DIR/const-and-non-const-impl.rs:5:12 + | +LL | impl const std::ops::Add for i32 { + | ^^^^^^^^^^^^^ cannot infer type for type `i32` + | +note: multiple `impl`s satisfying `i32: Add` found --> $DIR/const-and-non-const-impl.rs:5:1 | LL | impl const std::ops::Add for i32 { - | ^^^^^^^^^^^-------------^^^^^--- - | | | | - | | | `i32` is not defined in the current crate - | | `i32` is not defined in the current crate - | impl doesn't use only types from inside the current crate + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: and another `impl` found in the `core` crate: `impl Add for i32;` +note: required by a bound in `Add` + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL | - = note: define and implement a trait or new type instead +LL | / pub trait Add { +LL | | /// The resulting type after applying the `+` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn add(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ required by this bound in `Add` + +error[E0283]: type annotations needed + --> $DIR/const-and-non-const-impl.rs:14:6 + | +LL | impl std::ops::Add for Int { + | ^^^^^^^^^^^^^ cannot infer type for struct `Int` + | +note: multiple `impl`s satisfying `Int: Add` found + --> $DIR/const-and-non-const-impl.rs:14:1 + | +LL | impl std::ops::Add for Int { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl const std::ops::Add for Int { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `Add` + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Add { +LL | | /// The resulting type after applying the `+` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn add(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ required by this bound in `Add` + +error[E0283]: type annotations needed + --> $DIR/const-and-non-const-impl.rs:22:12 + | +LL | impl const std::ops::Add for Int { + | ^^^^^^^^^^^^^ cannot infer type for struct `Int` + | +note: multiple `impl`s satisfying `Int: Add` found + --> $DIR/const-and-non-const-impl.rs:14:1 + | +LL | impl std::ops::Add for Int { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl const std::ops::Add for Int { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `Add` + --> $SRC_DIR/core/src/ops/arith.rs:LL:COL + | +LL | / pub trait Add { +LL | | /// The resulting type after applying the `+` operator. +LL | | #[stable(feature = "rust1", since = "1.0.0")] +LL | | type Output; +... | +LL | | fn add(self, rhs: Rhs) -> Self::Output; +LL | | } + | |_^ required by this bound in `Add` -error: aborting due to 3 previous errors +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0117, E0119. +Some errors have detailed explanations: E0117, E0119, E0283. For more information about an error, try `rustc --explain E0117`. diff --git a/src/test/ui/traits/alias/issue-83613.stderr b/src/test/ui/traits/alias/issue-83613.stderr index 0ab39ae667288..6a3498a389375 100644 --- a/src/test/ui/traits/alias/issue-83613.stderr +++ b/src/test/ui/traits/alias/issue-83613.stderr @@ -1,11 +1,3 @@ -error[E0119]: conflicting implementations of trait `AnotherTrait` for type `impl OpaqueTrait` - --> $DIR/issue-83613.rs:10:1 - | -LL | impl AnotherTrait for T {} - | -------------------------------- first implementation here -LL | impl AnotherTrait for OpaqueType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `impl OpaqueTrait` - error: cannot implement trait on type alias impl trait --> $DIR/issue-83613.rs:10:1 | @@ -18,6 +10,14 @@ note: type alias impl trait defined here LL | type OpaqueType = impl OpaqueTrait; | ^^^^^^^^^^^^^^^^ +error[E0119]: conflicting implementations of trait `AnotherTrait` for type `impl OpaqueTrait` + --> $DIR/issue-83613.rs:10:1 + | +LL | impl AnotherTrait for T {} + | -------------------------------- first implementation here +LL | impl AnotherTrait for OpaqueType {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `impl OpaqueTrait` + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0119`. diff --git a/src/test/ui/traits/issue-78372.stderr b/src/test/ui/traits/issue-78372.stderr index 0150ff41303ae..49a9f47936876 100644 --- a/src/test/ui/traits/issue-78372.stderr +++ b/src/test/ui/traits/issue-78372.stderr @@ -50,12 +50,6 @@ LL | impl DispatchFromDyn> for T {} | = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable -error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures - --> $DIR/issue-78372.rs:3:1 - | -LL | impl DispatchFromDyn> for T {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 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 | @@ -65,6 +59,12 @@ LL | impl DispatchFromDyn> for T {} = 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 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 DispatchFromDyn> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 7 previous errors Some errors have detailed explanations: E0210, E0378, E0412, E0658. diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs index c46c4715924e5..685d76ee36f33 100644 --- a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs +++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.rs @@ -8,8 +8,7 @@ trait MyTrait {} impl MyTrait for () {} impl FnOnce<()> for &F { - //~^ ERROR conflicting implementations - //~| ERROR type parameter `F` must be used + //~^ ERROR type parameter `F` must be used type Output = impl MyTrait; extern "rust-call" fn call_once(self, _: ()) -> Self::Output {} } diff --git a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr index e1e259187f5f9..b93ea955c89f5 100644 --- a/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr +++ b/src/test/ui/type-alias-impl-trait/incoherent-assoc-imp-trait.stderr @@ -1,13 +1,3 @@ -error[E0119]: conflicting implementations of trait `std::ops::FnOnce<()>` for type `&_` - --> $DIR/incoherent-assoc-imp-trait.rs:10:1 - | -LL | impl FnOnce<()> for &F { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: conflicting implementation in crate `core`: - - impl FnOnce for &F - where F: Fn, F: ?Sized; - error[E0210]: type parameter `F` must be used as the type parameter for some local type (e.g., `MyStruct`) --> $DIR/incoherent-assoc-imp-trait.rs:10:6 | @@ -17,7 +7,6 @@ LL | impl FnOnce<()> for &F { = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local = note: only traits defined in the current crate can be implemented for a type parameter -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0119, E0210. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0210`. From f55ff4103f4e75309954cfe93ea0994646430fbb Mon Sep 17 00:00:00 2001 From: lcnr Date: Sat, 23 Oct 2021 21:05:03 +0200 Subject: [PATCH 2/2] don't inline `report_overlap_conflict` --- compiler/rustc_trait_selection/src/traits/specialize/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 96ab399424e20..b64c55592272e 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -291,6 +291,11 @@ pub(super) fn specialization_graph_provider( sg } +// This function is only used when +// encountering errors and inlining +// it negatively impacts perf. +#[cold] +#[inline(never)] fn report_overlap_conflict( tcx: TyCtxt<'_>, overlap: OverlapError,