Skip to content

Commit e8a05e2

Browse files
committed
permit negative impls for non-auto traits
1 parent a17dd36 commit e8a05e2

35 files changed

+328
-101
lines changed

src/libcore/clone.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,9 @@ mod impls {
227227
*self
228228
}
229229
}
230+
231+
// Shared references can be cloned, but mutable references *cannot*!
232+
#[stable(feature = "rust1", since = "1.0.0")]
233+
#[cfg(not(bootstrap))]
234+
impl<T: ?Sized> !Clone for &mut T {}
230235
}

src/libcore/ops/deref.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ impl<T: ?Sized> Deref for &T {
8181
}
8282
}
8383

84+
#[cfg(not(bootstrap))]
85+
#[stable(feature = "rust1", since = "1.0.0")]
86+
impl<T: ?Sized> !DerefMut for &T {}
87+
8488
#[stable(feature = "rust1", since = "1.0.0")]
8589
impl<T: ?Sized> Deref for &mut T {
8690
type Target = T;

src/librustc_error_codes/error_codes.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ E0184: include_str!("./error_codes/E0184.md"),
9797
E0185: include_str!("./error_codes/E0185.md"),
9898
E0186: include_str!("./error_codes/E0186.md"),
9999
E0191: include_str!("./error_codes/E0191.md"),
100-
E0192: include_str!("./error_codes/E0192.md"),
101100
E0193: include_str!("./error_codes/E0193.md"),
102101
E0195: include_str!("./error_codes/E0195.md"),
103102
E0197: include_str!("./error_codes/E0197.md"),
@@ -426,6 +425,8 @@ E0745: include_str!("./error_codes/E0745.md"),
426425
E0746: include_str!("./error_codes/E0746.md"),
427426
E0747: include_str!("./error_codes/E0747.md"),
428427
E0748: include_str!("./error_codes/E0748.md"),
428+
E0749: include_str!("./error_codes/E0749.md"),
429+
E0750: include_str!("./error_codes/E0750.md"),
429430
;
430431
// E0006, // merged with E0005
431432
// E0008, // cannot bind by-move into a pattern guard
@@ -460,6 +461,7 @@ E0748: include_str!("./error_codes/E0748.md"),
460461
// E0188, // can not cast an immutable reference to a mutable pointer
461462
// E0189, // deprecated: can only cast a boxed pointer to a boxed object
462463
// E0190, // deprecated: can only cast a &-pointer to an &-object
464+
// E0192, // negative impl only applicable to auto traits
463465
// E0194, // merged into E0403
464466
// E0196, // cannot determine a type for this closure
465467
E0208,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Negative impls are not allowed to have any items. Negative impls
2+
declare that a trait is **not** implemented (and never will be) and
3+
hence there is no need to specify the values for trait methods or
4+
other items.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Negative impls cannot be default impls. A default impl supplies
2+
default values for the items within to be used by other impls, whereas
3+
a negative impl declares that there are no other impls. These don't
4+
make sense to combine.

src/librustc_typeck/check/mod.rs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,11 +1659,14 @@ fn check_opaque_for_inheriting_lifetimes(tcx: TyCtxt<'tcx>, def_id: DefId, span:
16591659
_ => unreachable!(),
16601660
};
16611661

1662-
tcx.sess.span_err(span, &format!(
1662+
tcx.sess.span_err(
1663+
span,
1664+
&format!(
16631665
"`{}` return type cannot contain a projection or `Self` that references lifetimes from \
16641666
a parent scope",
16651667
if is_async { "async fn" } else { "impl Trait" },
1666-
));
1668+
),
1669+
);
16671670
}
16681671
}
16691672

@@ -1841,8 +1844,8 @@ fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: DefId, span: Span)
18411844
Ok(ConstValue::ByRef { alloc, .. }) => {
18421845
if alloc.relocations().len() != 0 {
18431846
let msg = "statics with a custom `#[link_section]` must be a \
1844-
simple list of bytes on the wasm target with no \
1845-
extra levels of indirection such as references";
1847+
simple list of bytes on the wasm target with no \
1848+
extra levels of indirection such as references";
18461849
tcx.sess.span_err(span, msg);
18471850
}
18481851
}
@@ -1971,6 +1974,24 @@ fn check_impl_items_against_trait<'tcx>(
19711974
return;
19721975
}
19731976

1977+
// Negative impls are not expected to have any items
1978+
match tcx.impl_polarity(impl_id) {
1979+
ty::ImplPolarity::Reservation | ty::ImplPolarity::Positive => {}
1980+
ty::ImplPolarity::Negative => {
1981+
if !impl_item_refs.is_empty() {
1982+
let first_item_span = tcx.hir().impl_item(impl_item_refs[0].id).span;
1983+
struct_span_err!(
1984+
tcx.sess,
1985+
first_item_span,
1986+
E0749,
1987+
"negative impls cannot have any items"
1988+
)
1989+
.emit();
1990+
}
1991+
return;
1992+
}
1993+
}
1994+
19741995
// Locate trait definition and items
19751996
let trait_def = tcx.trait_def(impl_trait_ref.def_id);
19761997

@@ -2010,7 +2031,7 @@ fn check_impl_items_against_trait<'tcx>(
20102031
impl_item.span,
20112032
E0323,
20122033
"item `{}` is an associated const, \
2013-
which doesn't match its trait `{}`",
2034+
which doesn't match its trait `{}`",
20142035
ty_impl_item.ident,
20152036
impl_trait_ref.print_only_trait_path()
20162037
);
@@ -3554,7 +3575,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
35543575
let adjusted_ty = autoderef.unambiguous_final_ty(self);
35553576
debug!(
35563577
"try_index_step(expr={:?}, base_expr={:?}, adjusted_ty={:?}, \
3557-
index_ty={:?})",
3578+
index_ty={:?})",
35583579
expr, base_expr, adjusted_ty, index_ty
35593580
);
35603581

@@ -4705,7 +4726,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
47054726
err.span_label(
47064727
fn_span,
47074728
"implicitly returns `()` as its body has no tail or `return` \
4708-
expression",
4729+
expression",
47094730
);
47104731
}
47114732
},
@@ -5577,11 +5598,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
55775598
match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) {
55785599
Ok(ok) => self.register_infer_ok_obligations(ok),
55795600
Err(_) => {
5580-
self.tcx.sess.delay_span_bug(span, &format!(
5601+
self.tcx.sess.delay_span_bug(
5602+
span,
5603+
&format!(
55815604
"instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
55825605
self_ty,
55835606
impl_ty,
5584-
));
5607+
),
5608+
);
55855609
}
55865610
}
55875611
}
@@ -5767,7 +5791,7 @@ fn fatally_break_rust(sess: &Session) {
57675791
handler.note_without_error("the compiler expectedly panicked. this is a feature.");
57685792
handler.note_without_error(
57695793
"we would appreciate a joke overview: \
5770-
https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
5794+
https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675",
57715795
);
57725796
handler.note_without_error(&format!(
57735797
"rustc {} running on {}",

src/librustc_typeck/check/wfcheck.rs

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,16 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) {
124124
}
125125
(ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
126126
// FIXME(#27579): what amount of WF checking do we need for neg impls?
127-
if let (Some(of_trait), false) = (of_trait, is_auto) {
127+
if let hir::Defaultness::Default { .. } = defaultness {
128+
let mut spans = vec![span];
129+
spans.extend(defaultness_span);
128130
struct_span_err!(
129131
tcx.sess,
130-
span.to(of_trait.path.span),
131-
E0192,
132-
"invalid negative impl"
132+
spans,
133+
E0750,
134+
"negative impls cannot be default impls"
133135
)
134-
.note(
135-
"negative impls are only allowed for auto traits, like `Send` and \
136-
`Sync`",
137-
)
138-
.emit()
136+
.emit();
139137
}
140138
}
141139
(ty::ImplPolarity::Reservation, _) => {
@@ -902,13 +900,13 @@ fn check_opaque_types<'fcx, 'tcx>(
902900
.struct_span_err(
903901
span,
904902
"non-defining opaque type use \
905-
in defining scope",
903+
in defining scope",
906904
)
907905
.span_label(
908906
param_span,
909907
"cannot use static lifetime; use a bound lifetime \
910-
instead or remove the lifetime parameter from the \
911-
opaque type",
908+
instead or remove the lifetime parameter from the \
909+
opaque type",
912910
)
913911
.emit();
914912
} else {
@@ -923,13 +921,13 @@ fn check_opaque_types<'fcx, 'tcx>(
923921
.struct_span_err(
924922
span,
925923
"non-defining opaque type use \
926-
in defining scope",
924+
in defining scope",
927925
)
928926
.span_note(
929927
tcx.def_span(param.def_id),
930928
&format!(
931929
"used non-generic const {} for \
932-
generic parameter",
930+
generic parameter",
933931
ty,
934932
),
935933
)
@@ -944,7 +942,7 @@ fn check_opaque_types<'fcx, 'tcx>(
944942
.struct_span_err(
945943
span,
946944
"non-defining opaque type use \
947-
in defining scope",
945+
in defining scope",
948946
)
949947
.span_note(spans, "lifetime used multiple times")
950948
.emit();
@@ -1030,7 +1028,7 @@ fn check_method_receiver<'fcx, 'tcx>(
10301028
span,
10311029
&format!(
10321030
"`{}` cannot be used as the type of `self` without \
1033-
the `arbitrary_self_types` feature",
1031+
the `arbitrary_self_types` feature",
10341032
receiver_ty,
10351033
),
10361034
)

src/test/ui/error-codes/E0192.rs

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/test/ui/error-codes/E0192.stderr

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/test/ui/specialization/defaultimpl/validation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ default impl S {} //~ ERROR inherent impls cannot be `default`
88

99
default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default
1010
default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default
11+
//~^ ERROR negative impls cannot be default impls
1112

1213
trait Tr {}
13-
default impl !Tr for S {} //~ ERROR invalid negative impl
14+
default impl !Tr for S {} //~ ERROR negative impls cannot be default impls
1415

1516
fn main() {}

0 commit comments

Comments
 (0)