add error message for case
This commit is contained in:
parent
b5665e811b
commit
9196b2d0c8
@ -556,7 +556,12 @@ fn from(t: T) -> T { t }
|
||||
|
||||
#[stable(feature = "convert_infallible", since = "1.34.0")]
|
||||
#[cfg(not(boostrap_stdarch_ignore_this))]
|
||||
#[rustc_reservation_impl]
|
||||
#[rustc_reservation_impl="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."
|
||||
]
|
||||
impl<T> From<!> for T {
|
||||
fn from(t: !) -> T { t }
|
||||
}
|
||||
|
@ -43,6 +43,8 @@
|
||||
use rustc_data_structures::bit_set::GrowableBitSet;
|
||||
use rustc_data_structures::sync::Lock;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::attr;
|
||||
use syntax::symbol::sym;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cmp;
|
||||
use std::fmt::{self, Display};
|
||||
@ -99,6 +101,9 @@ pub enum IntercrateAmbiguityCause {
|
||||
trait_desc: String,
|
||||
self_desc: Option<String>,
|
||||
},
|
||||
ReservationImpl {
|
||||
message: String
|
||||
},
|
||||
}
|
||||
|
||||
impl IntercrateAmbiguityCause {
|
||||
@ -139,6 +144,11 @@ pub fn intercrate_ambiguity_hint(&self) -> String {
|
||||
trait_desc, self_desc
|
||||
)
|
||||
}
|
||||
&IntercrateAmbiguityCause::ReservationImpl {
|
||||
ref message
|
||||
} => {
|
||||
message.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1328,15 +1338,32 @@ fn in_task<OP, R>(&mut self, op: OP) -> (R, DepNodeIndex)
|
||||
|
||||
// Treat negative impls as unimplemented, and reservation impls as ambiguity.
|
||||
fn filter_negative_and_reservation_impls(
|
||||
&self,
|
||||
&mut self,
|
||||
candidate: SelectionCandidate<'tcx>,
|
||||
) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
|
||||
if let ImplCandidate(def_id) = candidate {
|
||||
match self.tcx().impl_polarity(def_id) {
|
||||
let tcx = self.tcx();
|
||||
match tcx.impl_polarity(def_id) {
|
||||
ty::ImplPolarity::Negative if !self.allow_negative_impls => {
|
||||
return Err(Unimplemented);
|
||||
}
|
||||
ty::ImplPolarity::Reservation => {
|
||||
if let Some(intercrate_ambiguity_clauses)
|
||||
= &mut self.intercrate_ambiguity_causes
|
||||
{
|
||||
let attrs = tcx.get_attrs(def_id);
|
||||
let attr = attr::find_by_name(&attrs, sym::rustc_reservation_impl);
|
||||
let value = attr.and_then(|a| a.value_str());
|
||||
if let Some(value) = value {
|
||||
debug!("filter_negative_and_reservation_impls: \
|
||||
reservation impl ambiguity on {:?}", def_id);
|
||||
intercrate_ambiguity_clauses.push(
|
||||
IntercrateAmbiguityCause::ReservationImpl {
|
||||
message: value.to_string()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
return Ok(None);
|
||||
}
|
||||
_ => {}
|
||||
|
@ -457,7 +457,6 @@ macro_rules! experimental {
|
||||
// ==========================================================================
|
||||
// Internal attributes, Misc:
|
||||
// ==========================================================================
|
||||
|
||||
gated!(
|
||||
lang, Normal, template!(NameValueStr: "name"), lang_items,
|
||||
"language items are subject to change",
|
||||
@ -498,7 +497,7 @@ macro_rules! experimental {
|
||||
overflow checking behavior of several libcore functions that are inlined \
|
||||
across crates and will never be stable",
|
||||
),
|
||||
rustc_attr!(rustc_reservation_impl, Normal, template!(Word),
|
||||
rustc_attr!(rustc_reservation_impl, Normal, template!(NameValueStr: "reservation message"),
|
||||
"the `#[rustc_reservation_impl]` attribute is internally used \
|
||||
for reserving for `for<T> From<!> for T` impl"
|
||||
),
|
||||
|
@ -6,6 +6,8 @@ LL | impl MyTrait for MyFoo {}
|
||||
LL | // This will conflict with the first impl if we impl `for<T> T: From<!>`.
|
||||
LL | impl<T> MyTrait for T where T: From<!> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyFoo`
|
||||
|
|
||||
= 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.
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
trait MyTrait {}
|
||||
#[rustc_reservation_impl]
|
||||
#[rustc_reservation_impl="this impl is reserved"]
|
||||
impl MyTrait for () {}
|
||||
|
||||
trait OtherTrait {}
|
||||
|
@ -5,6 +5,8 @@ LL | impl OtherTrait for () {}
|
||||
| ---------------------- first implementation here
|
||||
LL | impl<T: MyTrait> OtherTrait for T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
|
||||
|
|
||||
= note: this impl is reserved
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
trait MyTrait { fn foo(&self); }
|
||||
#[rustc_reservation_impl]
|
||||
#[rustc_reservation_impl = "foo"]
|
||||
impl MyTrait for () { fn foo(&self) {} }
|
||||
|
||||
fn main() {
|
||||
|
@ -11,7 +11,7 @@ trait MyTrait<S> {
|
||||
fn foo(&self, s: S) -> usize;
|
||||
}
|
||||
|
||||
#[rustc_reservation_impl]
|
||||
#[rustc_reservation_impl = "foo"]
|
||||
impl<T> MyTrait<u64> for T {
|
||||
fn foo(&self, _x: u64) -> usize { 0 }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user