Skip to content

Commit 1882e00

Browse files
authoredMar 6, 2025
Rollup merge of rust-lang#137764 - compiler-errors:always-applicable-negative-impl, r=lcnr
Ensure that negative auto impls are always applicable r? lcnr (or reassign if you dont want to review) rust-lang#68318 (comment)
2 parents 7d5a65f + 05a8060 commit 1882e00

23 files changed

+359
-151
lines changed
 

‎compiler/rustc_data_structures/src/marker.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::alloc::Allocator;
2+
13
#[rustc_on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \
24
Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`")]
35
// This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()`
@@ -28,8 +30,8 @@ impls_dyn_send_neg!(
2830
[*const T where T: ?Sized]
2931
[*mut T where T: ?Sized]
3032
[std::ptr::NonNull<T> where T: ?Sized]
31-
[std::rc::Rc<T> where T: ?Sized]
32-
[std::rc::Weak<T> where T: ?Sized]
33+
[std::rc::Rc<T, A> where T: ?Sized, A: Allocator]
34+
[std::rc::Weak<T, A> where T: ?Sized, A: Allocator]
3335
[std::sync::MutexGuard<'_, T> where T: ?Sized]
3436
[std::sync::RwLockReadGuard<'_, T> where T: ?Sized]
3537
[std::sync::RwLockWriteGuard<'_, T> where T: ?Sized]
@@ -96,8 +98,8 @@ impls_dyn_sync_neg!(
9698
[std::cell::RefCell<T> where T: ?Sized]
9799
[std::cell::UnsafeCell<T> where T: ?Sized]
98100
[std::ptr::NonNull<T> where T: ?Sized]
99-
[std::rc::Rc<T> where T: ?Sized]
100-
[std::rc::Weak<T> where T: ?Sized]
101+
[std::rc::Rc<T, A> where T: ?Sized, A: Allocator]
102+
[std::rc::Weak<T, A> where T: ?Sized, A: Allocator]
101103
[std::cell::OnceCell<T> where T]
102104
[std::sync::mpsc::Receiver<T> where T]
103105
[std::sync::mpsc::Sender<T> where T]

‎compiler/rustc_hir_analysis/src/check/dropck.rs ‎compiler/rustc_hir_analysis/src/check/always_applicable.rs

+110-41
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
1+
//! This module contains methods that assist in checking that impls are general
2+
//! enough, i.e. that they always apply to every valid instantaiton of the ADT
3+
//! they're implemented for.
4+
//!
5+
//! This is necessary for `Drop` and negative impls to be well-formed.
6+
17
use rustc_data_structures::fx::FxHashSet;
28
use rustc_errors::codes::*;
39
use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
410
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
511
use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
12+
use rustc_middle::span_bug;
613
use rustc_middle::ty::util::CheckRegions;
714
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypingMode};
815
use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -27,11 +34,12 @@ use crate::hir::def_id::{DefId, LocalDefId};
2734
/// 3. Any bounds on the generic parameters must be reflected in the
2835
/// struct/enum definition for the nominal type itself (i.e.
2936
/// cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
30-
///
3137
pub(crate) fn check_drop_impl(
3238
tcx: TyCtxt<'_>,
3339
drop_impl_did: DefId,
3440
) -> Result<(), ErrorGuaranteed> {
41+
let drop_impl_did = drop_impl_did.expect_local();
42+
3543
match tcx.impl_polarity(drop_impl_did) {
3644
ty::ImplPolarity::Positive => {}
3745
ty::ImplPolarity::Negative => {
@@ -45,55 +53,107 @@ pub(crate) fn check_drop_impl(
4553
}));
4654
}
4755
}
48-
let dtor_self_type = tcx.type_of(drop_impl_did).instantiate_identity();
49-
match dtor_self_type.kind() {
56+
57+
tcx.ensure_ok().orphan_check_impl(drop_impl_did)?;
58+
59+
let dtor_impl_trait_ref = tcx.impl_trait_ref(drop_impl_did).unwrap().instantiate_identity();
60+
61+
match dtor_impl_trait_ref.self_ty().kind() {
5062
ty::Adt(adt_def, adt_to_impl_args) => {
51-
ensure_drop_params_and_item_params_correspond(
63+
ensure_impl_params_and_item_params_correspond(
5264
tcx,
53-
drop_impl_did.expect_local(),
65+
drop_impl_did,
5466
adt_def.did(),
5567
adt_to_impl_args,
5668
)?;
5769

58-
ensure_drop_predicates_are_implied_by_item_defn(
70+
ensure_impl_predicates_are_implied_by_item_defn(
5971
tcx,
60-
drop_impl_did.expect_local(),
61-
adt_def.did().expect_local(),
72+
drop_impl_did,
73+
adt_def.did(),
6274
adt_to_impl_args,
6375
)
6476
}
6577
_ => {
66-
// Destructors only work on nominal types. This was
67-
// already checked by coherence, but compilation may
68-
// not have been terminated.
69-
let span = tcx.def_span(drop_impl_did);
70-
let reported = tcx.dcx().span_delayed_bug(
71-
span,
72-
format!("should have been rejected by coherence check: {dtor_self_type}"),
73-
);
74-
Err(reported)
78+
span_bug!(tcx.def_span(drop_impl_did), "incoherent impl of Drop");
7579
}
7680
}
7781
}
7882

79-
fn ensure_drop_params_and_item_params_correspond<'tcx>(
83+
pub(crate) fn check_negative_auto_trait_impl<'tcx>(
8084
tcx: TyCtxt<'tcx>,
81-
drop_impl_did: LocalDefId,
82-
self_type_did: DefId,
85+
impl_def_id: LocalDefId,
86+
impl_trait_ref: ty::TraitRef<'tcx>,
87+
polarity: ty::ImplPolarity,
88+
) -> Result<(), ErrorGuaranteed> {
89+
let ty::ImplPolarity::Negative = polarity else {
90+
return Ok(());
91+
};
92+
93+
if !tcx.trait_is_auto(impl_trait_ref.def_id) {
94+
return Ok(());
95+
}
96+
97+
if tcx.defaultness(impl_def_id).is_default() {
98+
tcx.dcx().span_delayed_bug(tcx.def_span(impl_def_id), "default impl cannot be negative");
99+
}
100+
101+
tcx.ensure_ok().orphan_check_impl(impl_def_id)?;
102+
103+
match impl_trait_ref.self_ty().kind() {
104+
ty::Adt(adt_def, adt_to_impl_args) => {
105+
ensure_impl_params_and_item_params_correspond(
106+
tcx,
107+
impl_def_id,
108+
adt_def.did(),
109+
adt_to_impl_args,
110+
)?;
111+
112+
ensure_impl_predicates_are_implied_by_item_defn(
113+
tcx,
114+
impl_def_id,
115+
adt_def.did(),
116+
adt_to_impl_args,
117+
)
118+
}
119+
_ => {
120+
if tcx.features().auto_traits() {
121+
// NOTE: We ignore the applicability check for negative auto impls
122+
// defined in libcore. In the (almost impossible) future where we
123+
// stabilize auto impls, then the proper applicability check MUST
124+
// be implemented here to handle non-ADT rigid types.
125+
Ok(())
126+
} else {
127+
span_bug!(tcx.def_span(impl_def_id), "incoherent impl of negative auto trait");
128+
}
129+
}
130+
}
131+
}
132+
133+
fn ensure_impl_params_and_item_params_correspond<'tcx>(
134+
tcx: TyCtxt<'tcx>,
135+
impl_def_id: LocalDefId,
136+
adt_def_id: DefId,
83137
adt_to_impl_args: GenericArgsRef<'tcx>,
84138
) -> Result<(), ErrorGuaranteed> {
85139
let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyParam) else {
86140
return Ok(());
87141
};
88142

89-
let drop_impl_span = tcx.def_span(drop_impl_did);
90-
let item_span = tcx.def_span(self_type_did);
91-
let self_descr = tcx.def_descr(self_type_did);
143+
let impl_span = tcx.def_span(impl_def_id);
144+
let item_span = tcx.def_span(adt_def_id);
145+
let self_descr = tcx.def_descr(adt_def_id);
146+
let polarity = match tcx.impl_polarity(impl_def_id) {
147+
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
148+
ty::ImplPolarity::Negative => "!",
149+
};
150+
let trait_name = tcx
151+
.item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait"));
92152
let mut err = struct_span_code_err!(
93153
tcx.dcx(),
94-
drop_impl_span,
154+
impl_span,
95155
E0366,
96-
"`Drop` impls cannot be specialized"
156+
"`{polarity}{trait_name}` impls cannot be specialized",
97157
);
98158
match arg {
99159
ty::util::NotUniqueParam::DuplicateParam(arg) => {
@@ -116,17 +176,22 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
116176
/// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be
117177
/// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are
118178
/// implied by the ADT being well formed.
119-
fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
179+
fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>(
120180
tcx: TyCtxt<'tcx>,
121-
drop_impl_def_id: LocalDefId,
122-
adt_def_id: LocalDefId,
181+
impl_def_id: LocalDefId,
182+
adt_def_id: DefId,
123183
adt_to_impl_args: GenericArgsRef<'tcx>,
124184
) -> Result<(), ErrorGuaranteed> {
125185
let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
126186
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
127187

128-
let impl_span = tcx.def_span(drop_impl_def_id.to_def_id());
129-
188+
let impl_span = tcx.def_span(impl_def_id.to_def_id());
189+
let trait_name = tcx
190+
.item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait"));
191+
let polarity = match tcx.impl_polarity(impl_def_id) {
192+
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
193+
ty::ImplPolarity::Negative => "!",
194+
};
130195
// Take the param-env of the adt and instantiate the args that show up in
131196
// the implementation's self type. This gives us the assumptions that the
132197
// self ty of the implementation is allowed to know just from it being a
@@ -145,17 +210,21 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
145210
let adt_env =
146211
ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args);
147212

148-
let fresh_impl_args = infcx.fresh_args_for_item(impl_span, drop_impl_def_id.to_def_id());
213+
let fresh_impl_args = infcx.fresh_args_for_item(impl_span, impl_def_id.to_def_id());
149214
let fresh_adt_ty =
150-
tcx.impl_trait_ref(drop_impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty();
215+
tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty();
151216

152217
ocx.eq(&ObligationCause::dummy_with_span(impl_span), adt_env, fresh_adt_ty, impl_adt_ty)
153-
.unwrap();
218+
.expect("equating fully generic trait ref should never fail");
154219

155-
for (clause, span) in tcx.predicates_of(drop_impl_def_id).instantiate(tcx, fresh_impl_args) {
156-
let normalize_cause = traits::ObligationCause::misc(span, adt_def_id);
220+
for (clause, span) in tcx.predicates_of(impl_def_id).instantiate(tcx, fresh_impl_args) {
221+
let normalize_cause = traits::ObligationCause::misc(span, impl_def_id);
157222
let pred = ocx.normalize(&normalize_cause, adt_env, clause);
158-
let cause = traits::ObligationCause::new(span, adt_def_id, ObligationCauseCode::DropImpl);
223+
let cause = traits::ObligationCause::new(
224+
span,
225+
impl_def_id,
226+
ObligationCauseCode::AlwaysApplicableImpl,
227+
);
159228
ocx.register_obligation(traits::Obligation::new(tcx, cause, adt_env, pred));
160229
}
161230

@@ -173,13 +242,13 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
173242
let root_predicate = error.root_obligation.predicate;
174243
if root_predicates.insert(root_predicate) {
175244
let item_span = tcx.def_span(adt_def_id);
176-
let self_descr = tcx.def_descr(adt_def_id.to_def_id());
245+
let self_descr = tcx.def_descr(adt_def_id);
177246
guar = Some(
178247
struct_span_code_err!(
179248
tcx.dcx(),
180249
error.root_obligation.cause.span,
181250
E0367,
182-
"`Drop` impl requires `{root_predicate}` \
251+
"`{polarity}{trait_name}` impl requires `{root_predicate}` \
183252
but the {self_descr} it is implemented for does not",
184253
)
185254
.with_span_note(item_span, "the implementor must specify the same requirement")
@@ -190,12 +259,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
190259
return Err(guar.unwrap());
191260
}
192261

193-
let errors = ocx.infcx.resolve_regions(adt_def_id, adt_env, []);
262+
let errors = ocx.infcx.resolve_regions(impl_def_id, adt_env, []);
194263
if !errors.is_empty() {
195264
let mut guar = None;
196265
for error in errors {
197266
let item_span = tcx.def_span(adt_def_id);
198-
let self_descr = tcx.def_descr(adt_def_id.to_def_id());
267+
let self_descr = tcx.def_descr(adt_def_id);
199268
let outlives = match error {
200269
RegionResolutionError::ConcreteFailure(_, a, b) => format!("{b}: {a}"),
201270
RegionResolutionError::GenericBoundFailure(_, generic, r) => {
@@ -212,7 +281,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
212281
tcx.dcx(),
213282
error.origin().span(),
214283
E0367,
215-
"`Drop` impl requires `{outlives}` \
284+
"`{polarity}{trait_name}` impl requires `{outlives}` \
216285
but the {self_descr} it is implemented for does not",
217286
)
218287
.with_span_note(item_span, "the implementor must specify the same requirement")

‎compiler/rustc_hir_analysis/src/check/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ a type parameter).
6262
6363
*/
6464

65+
pub mod always_applicable;
6566
mod check;
6667
mod compare_impl_item;
67-
pub mod dropck;
6868
mod entry;
6969
pub mod intrinsic;
7070
pub mod intrinsicck;
@@ -113,11 +113,11 @@ pub fn provide(providers: &mut Providers) {
113113
}
114114

115115
fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Destructor> {
116-
tcx.calculate_dtor(def_id.to_def_id(), dropck::check_drop_impl)
116+
tcx.calculate_dtor(def_id.to_def_id(), always_applicable::check_drop_impl)
117117
}
118118

119119
fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::AsyncDestructor> {
120-
tcx.calculate_async_dtor(def_id.to_def_id(), dropck::check_drop_impl)
120+
tcx.calculate_async_dtor(def_id.to_def_id(), always_applicable::check_drop_impl)
121121
}
122122

123123
/// Given a `DefId` for an opaque type in return position, find its parent item's return

‎compiler/rustc_hir_analysis/src/coherence/mod.rs

+17-9
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_span::{ErrorGuaranteed, sym};
1616
use rustc_type_ir::elaborate;
1717
use tracing::debug;
1818

19+
use crate::check::always_applicable;
1920
use crate::errors;
2021

2122
mod builtin;
@@ -24,11 +25,12 @@ mod inherent_impls_overlap;
2425
mod orphan;
2526
mod unsafety;
2627

27-
fn check_impl(
28-
tcx: TyCtxt<'_>,
28+
fn check_impl<'tcx>(
29+
tcx: TyCtxt<'tcx>,
2930
impl_def_id: LocalDefId,
30-
trait_ref: ty::TraitRef<'_>,
31-
trait_def: &ty::TraitDef,
31+
trait_ref: ty::TraitRef<'tcx>,
32+
trait_def: &'tcx ty::TraitDef,
33+
polarity: ty::ImplPolarity,
3234
) -> Result<(), ErrorGuaranteed> {
3335
debug!(
3436
"(checking implementation) adding impl for trait '{:?}', item '{}'",
@@ -44,6 +46,12 @@ fn check_impl(
4446

4547
enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id, trait_def)
4648
.and(enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id, trait_def))
49+
.and(always_applicable::check_negative_auto_trait_impl(
50+
tcx,
51+
impl_def_id,
52+
trait_ref,
53+
polarity,
54+
))
4755
}
4856

4957
fn enforce_trait_manually_implementable(
@@ -154,16 +162,16 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
154162
let mut res = tcx.ensure_ok().specialization_graph_of(def_id);
155163

156164
for &impl_def_id in impls {
157-
let trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
158-
let trait_ref = trait_header.trait_ref.instantiate_identity();
165+
let impl_header = tcx.impl_trait_header(impl_def_id).unwrap();
166+
let trait_ref = impl_header.trait_ref.instantiate_identity();
159167
let trait_def = tcx.trait_def(trait_ref.def_id);
160168

161169
res = res
162-
.and(check_impl(tcx, impl_def_id, trait_ref, trait_def))
170+
.and(check_impl(tcx, impl_def_id, trait_ref, trait_def, impl_header.polarity))
163171
.and(check_object_overlap(tcx, impl_def_id, trait_ref))
164-
.and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def))
172+
.and(unsafety::check_item(tcx, impl_def_id, impl_header, trait_def))
165173
.and(tcx.ensure_ok().orphan_check_impl(impl_def_id))
166-
.and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header));
174+
.and(builtin::check_trait(tcx, def_id, impl_def_id, impl_header));
167175
}
168176

169177
res

‎compiler/rustc_middle/src/traits/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,9 @@ pub enum ObligationCauseCode<'tcx> {
397397

398398
RustCall,
399399

400-
/// Obligations to prove that a `std::ops::Drop` impl is not stronger than
400+
/// Obligations to prove that a `Drop` or negative auto trait impl is not stronger than
401401
/// the ADT it's being implemented for.
402-
DropImpl,
402+
AlwaysApplicableImpl,
403403

404404
/// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy`
405405
ConstParam(Ty<'tcx>),

‎compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2695,7 +2695,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
26952695
| ObligationCauseCode::LetElse
26962696
| ObligationCauseCode::BinOp { .. }
26972697
| ObligationCauseCode::AscribeUserTypeProvePredicate(..)
2698-
| ObligationCauseCode::DropImpl
2698+
| ObligationCauseCode::AlwaysApplicableImpl
26992699
| ObligationCauseCode::ConstParam(_)
27002700
| ObligationCauseCode::ReferenceOutlivesReferent(..)
27012701
| ObligationCauseCode::ObjectTypeBound(..) => {}

‎library/core/src/convert/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,6 @@ impl<T> From<T> for T {
778778
///
779779
/// [#64715]: https://github.com/rust-lang/rust/issues/64715
780780
#[stable(feature = "convert_infallible", since = "1.34.0")]
781-
#[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead.
782781
#[rustc_reservation_impl = "permitting this impl would forbid us from adding \
783782
`impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"]
784783
impl<T> From<!> for T {

‎tests/rustdoc/impl-parts-crosscrate.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
extern crate rustdoc_impl_parts_crosscrate;
77

8-
pub struct Bar<T> { t: T }
8+
pub struct Bar<T: Copy + Send> { t: T }
99

1010
// The output file is html embedded in javascript, so the html tags
1111
// aren't stripped by the processing script and we can't check for the

‎tests/rustdoc/impl-parts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
pub auto trait AnAutoTrait {}
55

6-
pub struct Foo<T> { field: T }
6+
pub struct Foo<T: Clone + Sync> { field: T }
77

88
//@ has impl_parts/struct.Foo.html '//*[@class="impl"]//h3[@class="code-header"]' \
99
// "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"

‎tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ struct TestType<T>(::std::marker::PhantomData<T>);
88

99
unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
1010

11-
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation
11+
impl<T: MyTrait> !Send for TestType<T> {}
12+
//~^ ERROR found both positive and negative implementation
13+
//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
1214

13-
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
15+
unsafe impl<T: 'static> Send for TestType<T> {}
16+
//~^ ERROR conflicting implementations
1417

1518
impl !Send for TestType<i32> {}
19+
//~^ ERROR `!Send` impls cannot be specialized
1620

1721
fn main() {}

‎tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr

+28-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,40 @@ LL | impl<T: MyTrait> !Send for TestType<T> {}
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
99

1010
error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
11-
--> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
11+
--> $DIR/coherence-conflicting-negative-trait-impl.rs:15:1
1212
|
1313
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
1414
| ------------------------------------------------------ first implementation here
1515
...
1616
LL | unsafe impl<T: 'static> Send for TestType<T> {}
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
1818

19-
error: aborting due to 2 previous errors
19+
error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
20+
--> $DIR/coherence-conflicting-negative-trait-impl.rs:11:9
21+
|
22+
LL | impl<T: MyTrait> !Send for TestType<T> {}
23+
| ^^^^^^^
24+
|
25+
note: the implementor must specify the same requirement
26+
--> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1
27+
|
28+
LL | struct TestType<T>(::std::marker::PhantomData<T>);
29+
| ^^^^^^^^^^^^^^^^^^
30+
31+
error[E0366]: `!Send` impls cannot be specialized
32+
--> $DIR/coherence-conflicting-negative-trait-impl.rs:18:1
33+
|
34+
LL | impl !Send for TestType<i32> {}
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
36+
|
37+
= note: `i32` is not a generic parameter
38+
note: use the same sequence of generic lifetime, type and const parameters as the struct definition
39+
--> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1
40+
|
41+
LL | struct TestType<T>(::std::marker::PhantomData<T>);
42+
| ^^^^^^^^^^^^^^^^^^
43+
44+
error: aborting due to 4 previous errors
2045

21-
Some errors have detailed explanations: E0119, E0751.
46+
Some errors have detailed explanations: E0119, E0366, E0367, E0751.
2247
For more information about an error, try `rustc --explain E0119`.

‎tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
2-
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
3-
|
4-
LL | impl !Marker1 for dyn Object + Marker2 {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
6-
71
error[E0321]: traits with a default impl, like `Marker1`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)`
82
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
93
|
@@ -12,11 +6,11 @@ LL | impl !Marker1 for dyn Object + Marker2 {}
126
|
137
= note: a trait object implements `Marker1` if and only if `Marker1` is one of the trait object's trait bounds
148

15-
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
16-
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1
9+
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
10+
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
1711
|
18-
LL | impl !Marker2 for dyn Object + Marker2 {}
19-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
12+
LL | impl !Marker1 for dyn Object + Marker2 {}
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
2014

2115
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)`
2216
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1
@@ -26,6 +20,12 @@ LL | impl !Marker2 for dyn Object + Marker2 {}
2620
|
2721
= note: a trait object implements `Marker2` if and only if `Marker2` is one of the trait object's trait bounds
2822

23+
error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
24+
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1
25+
|
26+
LL | impl !Marker2 for dyn Object + Marker2 {}
27+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
28+
2929
error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + 'static)`
3030
--> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:26:1
3131
|

‎tests/ui/coherence/coherence-orphan.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ use lib::TheTrait;
88
struct TheType;
99

1010
impl TheTrait<usize> for isize {}
11-
//~^ ERROR E0117
11+
//~^ ERROR only traits defined in the current crate can be implemented for primitive types
1212

1313
impl TheTrait<TheType> for isize {}
1414

1515
impl TheTrait<isize> for TheType {}
1616

17-
impl !Send for Vec<isize> {} //~ ERROR E0117
17+
impl !Send for Vec<isize> {}
18+
//~^ ERROR only traits defined in the current crate can be implemented for types defined outside of the crate
1819

1920
fn main() {}

‎tests/ui/coherence/coherence-overlap-negative-impls.rs

-44
This file was deleted.

‎tests/ui/issues/issue-106755.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ struct TestType<T>(::std::marker::PhantomData<T>);
1010

1111
unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
1212

13-
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation
13+
impl<T: MyTrait> !Send for TestType<T> {}
14+
//~^ ERROR found both positive and negative implementation
15+
//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
1416

1517
unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
1618

1719
impl !Send for TestType<i32> {}
20+
//~^ ERROR `!Send` impls cannot be specialized
1821

1922
fn main() {}

‎tests/ui/issues/issue-106755.stderr

+28-3
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,40 @@ LL | impl<T: MyTrait> !Send for TestType<T> {}
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
99

1010
error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
11-
--> $DIR/issue-106755.rs:15:1
11+
--> $DIR/issue-106755.rs:17:1
1212
|
1313
LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
1414
| ------------------------------------------------------ first implementation here
1515
...
1616
LL | unsafe impl<T: 'static> Send for TestType<T> {}
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
1818

19-
error: aborting due to 2 previous errors
19+
error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
20+
--> $DIR/issue-106755.rs:13:9
21+
|
22+
LL | impl<T: MyTrait> !Send for TestType<T> {}
23+
| ^^^^^^^
24+
|
25+
note: the implementor must specify the same requirement
26+
--> $DIR/issue-106755.rs:9:1
27+
|
28+
LL | struct TestType<T>(::std::marker::PhantomData<T>);
29+
| ^^^^^^^^^^^^^^^^^^
30+
31+
error[E0366]: `!Send` impls cannot be specialized
32+
--> $DIR/issue-106755.rs:19:1
33+
|
34+
LL | impl !Send for TestType<i32> {}
35+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
36+
|
37+
= note: `i32` is not a generic parameter
38+
note: use the same sequence of generic lifetime, type and const parameters as the struct definition
39+
--> $DIR/issue-106755.rs:9:1
40+
|
41+
LL | struct TestType<T>(::std::marker::PhantomData<T>);
42+
| ^^^^^^^^^^^^^^^^^^
43+
44+
error: aborting due to 4 previous errors
2045

21-
Some errors have detailed explanations: E0119, E0751.
46+
Some errors have detailed explanations: E0119, E0366, E0367, E0751.
2247
For more information about an error, try `rustc --explain E0119`.

‎tests/ui/specialization/defaultimpl/validation.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@ struct Z;
66

77
default impl S {} //~ ERROR inherent impls cannot be `default`
88

9-
default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default
10-
//~^ ERROR `S` cannot be sent between threads safely
11-
default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default
12-
//~^ ERROR negative impls cannot be default impls
9+
default unsafe impl Send for S {}
10+
//~^ ERROR impls of auto traits cannot be default
11+
12+
default impl !Send for Z {}
13+
//~^ ERROR impls of auto traits cannot be default
14+
//~| ERROR negative impls cannot be default impls
15+
//~| ERROR `!Send` impl requires `Z: Send` but the struct it is implemented for does not
1316

1417
trait Tr {}
15-
default impl !Tr for S {} //~ ERROR negative impls cannot be default impls
18+
19+
default impl !Tr for S {}
20+
//~^ ERROR negative impls cannot be default impls
1621

1722
fn main() {}

‎tests/ui/specialization/defaultimpl/validation.stderr

+13-15
Original file line numberDiff line numberDiff line change
@@ -26,41 +26,39 @@ LL | default unsafe impl Send for S {}
2626
| |
2727
| default because of this
2828

29-
error[E0277]: `S` cannot be sent between threads safely
30-
--> $DIR/validation.rs:9:1
29+
error[E0367]: `!Send` impl requires `Z: Send` but the struct it is implemented for does not
30+
--> $DIR/validation.rs:12:1
3131
|
32-
LL | default unsafe impl Send for S {}
33-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `S` cannot be sent between threads safely
34-
|
35-
= help: the trait `Send` is not implemented for `S`
36-
= help: the trait `Send` is implemented for `S`
37-
= help: see issue #48214
38-
help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
32+
LL | default impl !Send for Z {}
33+
| ^^^^^^^^^^^^^^^^^^^^^^^^
3934
|
40-
LL + #![feature(trivial_bounds)]
35+
note: the implementor must specify the same requirement
36+
--> $DIR/validation.rs:5:1
4137
|
38+
LL | struct Z;
39+
| ^^^^^^^^
4240

4341
error: impls of auto traits cannot be default
44-
--> $DIR/validation.rs:11:15
42+
--> $DIR/validation.rs:12:15
4543
|
4644
LL | default impl !Send for Z {}
4745
| ------- ^^^^ auto trait
4846
| |
4947
| default because of this
5048

5149
error[E0750]: negative impls cannot be default impls
52-
--> $DIR/validation.rs:11:1
50+
--> $DIR/validation.rs:12:1
5351
|
5452
LL | default impl !Send for Z {}
5553
| ^^^^^^^ ^
5654

5755
error[E0750]: negative impls cannot be default impls
58-
--> $DIR/validation.rs:15:1
56+
--> $DIR/validation.rs:19:1
5957
|
6058
LL | default impl !Tr for S {}
6159
| ^^^^^^^ ^
6260

6361
error: aborting due to 6 previous errors; 1 warning emitted
6462

65-
Some errors have detailed explanations: E0277, E0750.
66-
For more information about an error, try `rustc --explain E0277`.
63+
Some errors have detailed explanations: E0367, E0750.
64+
For more information about an error, try `rustc --explain E0367`.

‎tests/ui/specialization/specialization-overlap-negative.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ trait MyTrait {}
66
struct TestType<T>(::std::marker::PhantomData<T>);
77

88
unsafe impl<T: Clone> Send for TestType<T> {}
9-
impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0751
9+
impl<T: MyTrait> !Send for TestType<T> {}
10+
//~^ ERROR found both positive and negative implementation of trait `Send` for type `TestType<_>`
11+
//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
1012

1113
fn main() {}

‎tests/ui/specialization/specialization-overlap-negative.stderr

+15-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@ LL | unsafe impl<T: Clone> Send for TestType<T> {}
1616
LL | impl<T: MyTrait> !Send for TestType<T> {}
1717
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
1818

19-
error: aborting due to 1 previous error; 1 warning emitted
19+
error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
20+
--> $DIR/specialization-overlap-negative.rs:9:9
21+
|
22+
LL | impl<T: MyTrait> !Send for TestType<T> {}
23+
| ^^^^^^^
24+
|
25+
note: the implementor must specify the same requirement
26+
--> $DIR/specialization-overlap-negative.rs:6:1
27+
|
28+
LL | struct TestType<T>(::std::marker::PhantomData<T>);
29+
| ^^^^^^^^^^^^^^^^^^
30+
31+
error: aborting due to 2 previous errors; 1 warning emitted
2032

21-
For more information about this error, try `rustc --explain E0751`.
33+
Some errors have detailed explanations: E0367, E0751.
34+
For more information about an error, try `rustc --explain E0367`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![feature(auto_traits, negative_impls)]
2+
3+
auto trait Foo {}
4+
5+
struct AdditionalLt<'a, T>(&'a (), T);
6+
impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {}
7+
//~^ ERROR `!Foo` impl requires `T: 'a` but the struct it is implemented for does not
8+
9+
struct AdditionalBound<T>(T);
10+
trait Bound {}
11+
impl<T: Bound> !Foo for AdditionalBound<T> {}
12+
//~^ ERROR `!Foo` impl requires `T: Bound` but the struct it is implemented for does not
13+
14+
struct TwoParam<T, U>(T, U);
15+
impl<T> !Foo for TwoParam<T, T> {}
16+
//~^ ERROR `!Foo` impls cannot be specialized
17+
18+
struct ConcreteParam<T>(T);
19+
impl !Foo for ConcreteParam<i32> {}
20+
//~^ ERROR `!Foo` impls cannot be specialized
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
error[E0367]: `!Foo` impl requires `T: 'a` but the struct it is implemented for does not
2+
--> $DIR/negated-auto-traits-validity-error.rs:6:13
3+
|
4+
LL | impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {}
5+
| ^^
6+
|
7+
note: the implementor must specify the same requirement
8+
--> $DIR/negated-auto-traits-validity-error.rs:5:1
9+
|
10+
LL | struct AdditionalLt<'a, T>(&'a (), T);
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
13+
error[E0367]: `!Foo` impl requires `T: Bound` but the struct it is implemented for does not
14+
--> $DIR/negated-auto-traits-validity-error.rs:11:9
15+
|
16+
LL | impl<T: Bound> !Foo for AdditionalBound<T> {}
17+
| ^^^^^
18+
|
19+
note: the implementor must specify the same requirement
20+
--> $DIR/negated-auto-traits-validity-error.rs:9:1
21+
|
22+
LL | struct AdditionalBound<T>(T);
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^
24+
25+
error[E0366]: `!Foo` impls cannot be specialized
26+
--> $DIR/negated-auto-traits-validity-error.rs:15:1
27+
|
28+
LL | impl<T> !Foo for TwoParam<T, T> {}
29+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30+
|
31+
= note: `T` is mentioned multiple times
32+
note: use the same sequence of generic lifetime, type and const parameters as the struct definition
33+
--> $DIR/negated-auto-traits-validity-error.rs:14:1
34+
|
35+
LL | struct TwoParam<T, U>(T, U);
36+
| ^^^^^^^^^^^^^^^^^^^^^
37+
38+
error[E0366]: `!Foo` impls cannot be specialized
39+
--> $DIR/negated-auto-traits-validity-error.rs:19:1
40+
|
41+
LL | impl !Foo for ConcreteParam<i32> {}
42+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43+
|
44+
= note: `i32` is not a generic parameter
45+
note: use the same sequence of generic lifetime, type and const parameters as the struct definition
46+
--> $DIR/negated-auto-traits-validity-error.rs:18:1
47+
|
48+
LL | struct ConcreteParam<T>(T);
49+
| ^^^^^^^^^^^^^^^^^^^^^^^
50+
51+
error: aborting due to 4 previous errors
52+
53+
Some errors have detailed explanations: E0366, E0367.
54+
For more information about an error, try `rustc --explain E0366`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@ check-pass
2+
3+
#![feature(auto_traits, negative_impls)]
4+
5+
auto trait Foo {}
6+
auto trait Bar {}
7+
8+
struct NeedsOutlives<'a, T>(&'a T);
9+
10+
impl<'a, T: 'a> !Foo for NeedsOutlives<'a, T> {}
11+
12+
// Leaving out the lifetime bound
13+
impl<'a, T> !Bar for NeedsOutlives<'a, T> {}
14+
15+
struct NeedsSend<T: Send>(T);
16+
17+
impl<T: Send> !Foo for NeedsSend<T> {}
18+
19+
// Leaving off the trait bound
20+
impl<T> !Bar for NeedsSend<T> {}
21+
22+
fn main() {}

0 commit comments

Comments
 (0)
Please sign in to comment.