From 6d1844c8065c5c680b0a86c83152902b47bc856c Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Fri, 20 Feb 2015 15:46:50 +0100 Subject: [PATCH] Record default implementations in a separate step --- src/librustc/middle/traits/select.rs | 23 ++++++++++++++++++- src/libtest/stats.rs | 1 + .../coherence-default-trait-impl.rs | 4 +++- ...-default-trait-impl-constituent-types-2.rs | 4 +++- ...ck-default-trait-impl-constituent-types.rs | 7 +++--- .../typeck-default-trait-impl-negation.rs | 6 +++-- .../typeck-default-trait-impl-supertrait.rs | 4 +++- ...k-default-trait-impl-trait-where-clause.rs | 6 +++-- 8 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 1eb1c650e7c..a328c5c2d75 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -847,6 +847,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.assemble_candidates_from_projected_tys(obligation, &mut candidates); try!(self.assemble_candidates_from_caller_bounds(stack, &mut candidates)); + // Default implementations have lower priority, so we only + // consider triggering a default if there is no other impl that can apply. + if candidates.vec.len() == 0 { + try!(self.assemble_candidates_from_default_impls(obligation, &mut candidates)); + } debug!("candidate list size: {}", candidates.vec.len()); Ok(candidates) } @@ -1142,6 +1147,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); } + Ok(()) + } + + fn assemble_candidates_from_default_impls(&mut self, + obligation: &TraitObligation<'tcx>, + candidates: &mut SelectionCandidateSet<'tcx>) + -> Result<(), SelectionError<'tcx>> + { + + let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); + debug!("assemble_candidates_from_default_impls(self_ty={})", self_ty.repr(self.tcx())); + + let def_id = obligation.predicate.def_id(); + if ty::trait_has_default_impl(self.tcx(), def_id) { match self_ty.sty { ty::ty_trait(..) | @@ -1323,7 +1342,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } (&DefaultImplCandidate(_), _) => { // Prefer other candidates over default implementations. - true + self.tcx().sess.bug( + "default implementations shouldn't be recorded \ + when there are other valid candidates"); } (&ProjectionCandidate, &ParamCandidate(_)) => { // FIXME(#20297) -- this gives where clauses precedent diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 4e94be59ade..7cc07e926b2 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -332,6 +332,7 @@ pub fn winsorize(samples: &mut [T], pct: T) { /// Returns a HashMap with the number of occurrences of every element in the /// sequence that the iterator exposes. +#[cfg(not(stage0))] pub fn freq_count(iter: T) -> hash_map::HashMap where T: Iterator, U: Eq + Clone + Hash { diff --git a/src/test/compile-fail/coherence-default-trait-impl.rs b/src/test/compile-fail/coherence-default-trait-impl.rs index bcc3353ba02..ab653b3a554 100644 --- a/src/test/compile-fail/coherence-default-trait-impl.rs +++ b/src/test/compile-fail/coherence-default-trait-impl.rs @@ -12,7 +12,9 @@ #![feature(optin_builtin_traits)] -trait MyTrait {} +use std::marker::MarkerTrait; + +trait MyTrait: MarkerTrait {} impl MyTrait for .. {} diff --git a/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs b/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs index a27f7f7ebbe..0f3453da431 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-constituent-types-2.rs @@ -10,7 +10,9 @@ #![feature(optin_builtin_traits)] -trait MyTrait {} +use std::marker::MarkerTrait; + +trait MyTrait: MarkerTrait {} impl MyTrait for .. {} diff --git a/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs b/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs index 556a0a1a0f3..524f467e017 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-constituent-types.rs @@ -10,7 +10,9 @@ #![feature(optin_builtin_traits)] -trait MyTrait {} +use std::marker::MarkerTrait; + +trait MyTrait: MarkerTrait {} impl MyTrait for .. {} impl !MyTrait for *mut T {} @@ -30,7 +32,4 @@ fn main() { is_mytrait::(); //~^ ERROR the trait `MyTrait` is not implemented for the type `MyS2` - - is_mytrait::>(); - //~^ ERROR the trait `MyTrait` is not implemented for the type `*mut MyS3` } diff --git a/src/test/compile-fail/typeck-default-trait-impl-negation.rs b/src/test/compile-fail/typeck-default-trait-impl-negation.rs index 4b91d0b7a73..a1ca0e3e0fa 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-negation.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-negation.rs @@ -10,11 +10,13 @@ #![feature(optin_builtin_traits)] -trait MyTrait {} +use std::marker::MarkerTrait; + +trait MyTrait: MarkerTrait {} impl MyTrait for .. {} -unsafe trait MyUnsafeTrait {} +unsafe trait MyUnsafeTrait: MarkerTrait {} unsafe impl MyUnsafeTrait for .. {} diff --git a/src/test/compile-fail/typeck-default-trait-impl-supertrait.rs b/src/test/compile-fail/typeck-default-trait-impl-supertrait.rs index c9bfdff6c0e..7f24058e475 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-supertrait.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-supertrait.rs @@ -13,7 +13,9 @@ #![feature(optin_builtin_traits)] -trait NotImplemented { } +use std::marker::MarkerTrait; + +trait NotImplemented: MarkerTrait { } trait MyTrait : NotImplemented {} diff --git a/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs b/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs index 4f572e87639..c970aaaf5d4 100644 --- a/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs +++ b/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause.rs @@ -15,9 +15,11 @@ #![feature(optin_builtin_traits)] -trait NotImplemented { } +use std::marker::MarkerTrait; -trait MyTrait +trait NotImplemented: MarkerTrait { } + +trait MyTrait: MarkerTrait where Option : NotImplemented {}