parent
f18c99072e
commit
352fac95ad
5 changed files with 70 additions and 16 deletions
|
|
@ -762,6 +762,16 @@ pub struct GenericPredicates<'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
|
||||
pub fn empty() -> GenericPredicates<'tcx> {
|
||||
GenericPredicates {
|
||||
predicates: VecPerParamSpace::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.predicates.is_empty()
|
||||
}
|
||||
|
||||
pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
|
||||
-> InstantiatedPredicates<'tcx> {
|
||||
let mut instantiated = InstantiatedPredicates::empty();
|
||||
|
|
|
|||
|
|
@ -251,6 +251,36 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||
});
|
||||
}
|
||||
|
||||
fn check_auto_trait(&mut self,
|
||||
trait_def_id: DefId,
|
||||
span: Span)
|
||||
{
|
||||
let predicates = self.tcx().lookup_predicates(trait_def_id);
|
||||
|
||||
// If we must exclude the Self : Trait predicate contained by all
|
||||
// traits.
|
||||
let no_refl_predicates : Vec<_> =
|
||||
predicates.predicates.iter().filter(|predicate| {
|
||||
match *predicate {
|
||||
&ty::Predicate::Trait(ref poly_trait_ref) =>
|
||||
poly_trait_ref.def_id() != trait_def_id,
|
||||
_ => true,
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let trait_def = self.tcx().lookup_trait_def(trait_def_id);
|
||||
|
||||
// We use an if-else here, since the generics will also trigger
|
||||
// an extraneous error message when we find predicates like
|
||||
// `T : Sized` for a trait like: `trait Magic<T>`.
|
||||
if !trait_def.generics.types.get_slice(ParamSpace::TypeSpace).is_empty() {
|
||||
error_566(self.ccx, span);
|
||||
} else if !no_refl_predicates.is_empty() {
|
||||
error_565(self.ccx, span);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn check_trait(&mut self,
|
||||
item: &hir::Item,
|
||||
items: &[hir::TraitItem])
|
||||
|
|
@ -258,9 +288,18 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||
let trait_def_id = self.tcx().map.local_def_id(item.id);
|
||||
|
||||
if self.tcx().trait_has_default_impl(trait_def_id) {
|
||||
// We want to both ensure:
|
||||
// 1) that there are no items contained within
|
||||
// the trait defintion
|
||||
//
|
||||
// 2) that the definition doesn't violate the no-super trait rule
|
||||
// for auto traits.
|
||||
|
||||
if !items.is_empty() {
|
||||
error_380(self.ccx, item.span);
|
||||
}
|
||||
|
||||
self.check_auto_trait(trait_def_id, item.span);
|
||||
}
|
||||
|
||||
self.for_item(item).with_fcx(|fcx, this| {
|
||||
|
|
@ -272,6 +311,8 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
fn check_item_fn(&mut self,
|
||||
item: &hir::Item,
|
||||
body: &hir::Block)
|
||||
|
|
@ -637,6 +678,18 @@ fn error_380(ccx: &CrateCtxt, span: Span) {
|
|||
Trait for ..`) must have no methods or associated items")
|
||||
}
|
||||
|
||||
fn error_565(ccx: &CrateCtxt, span: Span) {
|
||||
span_err!(ccx.tcx.sess, span, E0565,
|
||||
"traits with default impls (`e.g. unsafe impl \
|
||||
Trait for ..`) can not have predicates")
|
||||
}
|
||||
|
||||
fn error_566(ccx: &CrateCtxt, span: Span) {
|
||||
span_err!(ccx.tcx.sess, span, E0566,
|
||||
"traits with default impls (`e.g. unsafe impl \
|
||||
Trait for ..`) can not have type parameters")
|
||||
}
|
||||
|
||||
fn error_392<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, span: Span, param_name: ast::Name)
|
||||
-> DiagnosticBuilder<'tcx> {
|
||||
let mut err = struct_span_err!(ccx.tcx.sess, span, E0392,
|
||||
|
|
|
|||
|
|
@ -4072,4 +4072,6 @@ register_diagnostics! {
|
|||
E0563, // cannot determine a type for this `impl Trait`: {}
|
||||
E0564, // only named lifetimes are allowed in `impl Trait`,
|
||||
// but `{}` was found in the type `{}`
|
||||
E0565, // auto-traits can not have predicates,
|
||||
E0566, // auto traits can not have type parameters
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,16 +10,5 @@
|
|||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Magic: Copy {}
|
||||
impl Magic for .. {}
|
||||
impl<T:Magic> Magic for T {}
|
||||
|
||||
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
|
||||
#[derive(Debug)]
|
||||
struct NoClone;
|
||||
|
||||
fn main() {
|
||||
let (a, b) = copy(NoClone); //~ ERROR E0277
|
||||
println!("{:?} {:?}", a, b);
|
||||
}
|
||||
trait Magic<T> {} //~ E0566
|
||||
impl Magic<isize> for .. {}
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
trait Magic: Copy {}
|
||||
impl Magic for .. {}
|
||||
trait Magic: Copy {} //~ ERROR E0565
|
||||
impl Magic for .. {}
|
||||
impl<T:Magic> Magic for T {}
|
||||
|
||||
fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
||||
|
|
@ -20,6 +20,6 @@ fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
|
|||
struct NoClone;
|
||||
|
||||
fn main() {
|
||||
let (a, b) = copy(NoClone); //~ ERROR E0277
|
||||
let (a, b) = copy(NoClone);
|
||||
println!("{:?} {:?}", a, b);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue