Skip to content

Commit 9196b2d

Browse files
committed
add error message for case
1 parent b5665e8 commit 9196b2d

File tree

8 files changed

+43
-8
lines changed

8 files changed

+43
-8
lines changed

src/libcore/convert.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,12 @@ impl<T> From<T> for T {
556556

557557
#[stable(feature = "convert_infallible", since = "1.34.0")]
558558
#[cfg(not(boostrap_stdarch_ignore_this))]
559-
#[rustc_reservation_impl]
559+
#[rustc_reservation_impl="a future version of Rust might implement `From<!>` for \
560+
all types. \
561+
However, it is OK to implement `From<!>` for types you own - \
562+
when the blanket impl will be added, coherence will be changed \
563+
to make these impls not be an error."
564+
]
560565
impl<T> From<!> for T {
561566
fn from(t: !) -> T { t }
562567
}

src/librustc/traits/select.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ use crate::hir;
4343
use rustc_data_structures::bit_set::GrowableBitSet;
4444
use rustc_data_structures::sync::Lock;
4545
use rustc_target::spec::abi::Abi;
46+
use syntax::attr;
47+
use syntax::symbol::sym;
4648
use std::cell::{Cell, RefCell};
4749
use std::cmp;
4850
use std::fmt::{self, Display};
@@ -99,6 +101,9 @@ pub enum IntercrateAmbiguityCause {
99101
trait_desc: String,
100102
self_desc: Option<String>,
101103
},
104+
ReservationImpl {
105+
message: String
106+
},
102107
}
103108

104109
impl IntercrateAmbiguityCause {
@@ -139,6 +144,11 @@ impl IntercrateAmbiguityCause {
139144
trait_desc, self_desc
140145
)
141146
}
147+
&IntercrateAmbiguityCause::ReservationImpl {
148+
ref message
149+
} => {
150+
message.clone()
151+
}
142152
}
143153
}
144154
}
@@ -1328,15 +1338,32 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13281338

13291339
// Treat negative impls as unimplemented, and reservation impls as ambiguity.
13301340
fn filter_negative_and_reservation_impls(
1331-
&self,
1341+
&mut self,
13321342
candidate: SelectionCandidate<'tcx>,
13331343
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
13341344
if let ImplCandidate(def_id) = candidate {
1335-
match self.tcx().impl_polarity(def_id) {
1345+
let tcx = self.tcx();
1346+
match tcx.impl_polarity(def_id) {
13361347
ty::ImplPolarity::Negative if !self.allow_negative_impls => {
13371348
return Err(Unimplemented);
13381349
}
13391350
ty::ImplPolarity::Reservation => {
1351+
if let Some(intercrate_ambiguity_clauses)
1352+
= &mut self.intercrate_ambiguity_causes
1353+
{
1354+
let attrs = tcx.get_attrs(def_id);
1355+
let attr = attr::find_by_name(&attrs, sym::rustc_reservation_impl);
1356+
let value = attr.and_then(|a| a.value_str());
1357+
if let Some(value) = value {
1358+
debug!("filter_negative_and_reservation_impls: \
1359+
reservation impl ambiguity on {:?}", def_id);
1360+
intercrate_ambiguity_clauses.push(
1361+
IntercrateAmbiguityCause::ReservationImpl {
1362+
message: value.to_string()
1363+
}
1364+
);
1365+
}
1366+
}
13401367
return Ok(None);
13411368
}
13421369
_ => {}

src/libsyntax/feature_gate/builtin_attrs.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
457457
// ==========================================================================
458458
// Internal attributes, Misc:
459459
// ==========================================================================
460-
461460
gated!(
462461
lang, Normal, template!(NameValueStr: "name"), lang_items,
463462
"language items are subject to change",
@@ -498,7 +497,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
498497
overflow checking behavior of several libcore functions that are inlined \
499498
across crates and will never be stable",
500499
),
501-
rustc_attr!(rustc_reservation_impl, Normal, template!(Word),
500+
rustc_attr!(rustc_reservation_impl, Normal, template!(NameValueStr: "reservation message"),
502501
"the `#[rustc_reservation_impl]` attribute is internally used \
503502
for reserving for `for<T> From<!> for T` impl"
504503
),

src/test/ui/never-from-impl-is-reserved.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ LL | impl MyTrait for MyFoo {}
66
LL | // This will conflict with the first impl if we impl `for<T> T: From<!>`.
77
LL | impl<T> MyTrait for T where T: From<!> {}
88
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFoo`
9+
|
10+
= note: a future version of Rust might implement `From<!>` for all types. However, it is OK to implement `From<!>` for types you own - when the blanket impl will be added, coherence will be changed to make these impls not be an error.
911

1012
error: aborting due to previous error
1113

src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#![feature(rustc_attrs)]
66

77
trait MyTrait {}
8-
#[rustc_reservation_impl]
8+
#[rustc_reservation_impl="this impl is reserved"]
99
impl MyTrait for () {}
1010

1111
trait OtherTrait {}

src/test/ui/traits/reservation-impls/reservation-impl-coherence-conflict.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | impl OtherTrait for () {}
55
| ---------------------- first implementation here
66
LL | impl<T: MyTrait> OtherTrait for T {}
77
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
8+
|
9+
= note: this impl is reserved
810

911
error: aborting due to previous error
1012

src/test/ui/traits/reservation-impls/reservation-impl-no-use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#![feature(rustc_attrs)]
66

77
trait MyTrait { fn foo(&self); }
8-
#[rustc_reservation_impl]
8+
#[rustc_reservation_impl = "foo"]
99
impl MyTrait for () { fn foo(&self) {} }
1010

1111
fn main() {

src/test/ui/traits/reservation-impls/reservation-impl-ok.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ trait MyTrait<S> {
1111
fn foo(&self, s: S) -> usize;
1212
}
1313

14-
#[rustc_reservation_impl]
14+
#[rustc_reservation_impl = "foo"]
1515
impl<T> MyTrait<u64> for T {
1616
fn foo(&self, _x: u64) -> usize { 0 }
1717
}

0 commit comments

Comments
 (0)