From 13e80af159a709e5bb9a178b19b4319716261661 Mon Sep 17 00:00:00 2001 From: Gianni Ciccarelli Date: Tue, 24 Oct 2017 09:55:57 +0000 Subject: [PATCH] support `default impl` for specialization a default impl should never be considered as implementing the trait on its own -- regardless of whether it contains all items or not --- src/librustc/ich/impls_ty.rs | 3 +- src/librustc/traits/select.rs | 36 +----- src/librustc/traits/util.rs | 25 +--- src/librustc/ty/instance.rs | 119 +----------------- src/librustc/ty/mod.rs | 39 +----- src/librustc/ty/structural_impls.rs | 6 +- src/librustc/ty/sty.rs | 5 +- src/librustc/ty/trait_def.rs | 12 +- src/librustc/util/ppaux.rs | 8 +- src/librustc_mir/monomorphize/collector.rs | 17 +-- src/librustc_typeck/astconv.rs | 16 +-- src/librustc_typeck/check/dropck.rs | 12 +- src/librustc_typeck/check/wfcheck.rs | 23 +--- src/librustc_typeck/collect.rs | 52 ++------ .../defaultimpl/auxiliary/foo_trait.rs | 16 --- .../specialization-default-projection.rs | 46 ------- .../specialization-default-types.rs | 45 ------- ...method-not-implemented-cross-crate-impl.rs | 23 ---- ...tion-method-not-implemented-cross-crate.rs | 30 ----- .../specialization-method-not-implemented.rs | 30 ----- .../specialization-trait-bounds-casting.rs | 47 ------- .../specialization-trait-bounds-impl-item.rs | 38 ------ ...specialization-trait-bounds-super-trait.rs | 40 ------ .../specialization-trait-bounds-trait-item.rs | 34 ----- .../specialization-trait-bounds-vec.rs | 48 ------- ...cialization-trait-item-not-implemented.rs} | 17 ++- ...> specialization-trait-not-implemented.rs} | 12 +- .../specialization/defaultimpl/assoc-fns.rs | 37 ------ .../defaultimpl/auxiliary/cross_crate.rs | 82 ------------ .../auxiliary/cross_crate_defaults.rs | 49 -------- .../defaultimpl/auxiliary/foo_trait.rs | 30 ----- .../defaultimpl/basics-unsafe.rs | 106 ---------------- .../specialization/defaultimpl/basics.rs | 106 ---------------- .../defaultimpl/cross-crate-defaults.rs | 49 -------- .../defaultimpl/cross-crate-no-gate.rs | 29 ----- .../specialization/defaultimpl/cross-crate.rs | 58 --------- .../defaultimpl/default-methods.rs | 94 -------------- .../defaultimpl/projection-alias.rs | 32 ----- .../specialization-trait-bounds.rs | 40 ------ ...cialization-trait-item-not-implemented.rs} | 17 ++- ...-traits-impl-default-method-cross-crate.rs | 25 ---- ...ecialization-traits-impl-default-method.rs | 38 ------ 42 files changed, 66 insertions(+), 1525 deletions(-) delete mode 100644 src/test/compile-fail/specialization/defaultimpl/auxiliary/foo_trait.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-default-projection.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-default-types.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented-cross-crate-impl.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented-cross-crate.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-casting.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-impl-item.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-super-trait.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-trait-item.rs delete mode 100644 src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-vec.rs rename src/test/compile-fail/specialization/defaultimpl/{specialization-trait-bounds-fn.rs => specialization-trait-item-not-implemented.rs} (74%) rename src/test/compile-fail/specialization/defaultimpl/{auxiliary/foo_trait_default_impl.rs => specialization-trait-not-implemented.rs} (71%) delete mode 100644 src/test/run-pass/specialization/defaultimpl/assoc-fns.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate_defaults.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/auxiliary/foo_trait.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/basics-unsafe.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/basics.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/cross-crate-defaults.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/cross-crate-no-gate.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/cross-crate.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/default-methods.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/projection-alias.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/specialization-trait-bounds.rs rename src/test/run-pass/specialization/defaultimpl/{specialization-traits-impl.rs => specialization-trait-item-not-implemented.rs} (74%) delete mode 100644 src/test/run-pass/specialization/defaultimpl/specialization-traits-impl-default-method-cross-crate.rs delete mode 100644 src/test/run-pass/specialization/defaultimpl/specialization-traits-impl-default-method.rs diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 42724274eb7..107779ec3fa 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -218,8 +218,7 @@ fn hash_stable(&self, }); impl_stable_hash_for!(struct ty::TraitRef<'tcx> { def_id, substs }); -impl_stable_hash_for!(enum ty::DefaultImplCheck { Yes, No }); -impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref, default_impl_check }); +impl_stable_hash_for!(struct ty::TraitPredicate<'tcx> { trait_ref }); impl_stable_hash_for!(tuple_struct ty::EquatePredicate<'tcx> { t1, t2 }); impl_stable_hash_for!(struct ty::SubtypePredicate<'tcx> { a_is_expected, a, b }); diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index ee6bf4180dd..4ed25646d43 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1083,39 +1083,12 @@ fn in_task(&mut self, op: OP) -> (R, DepNodeIndex) } // Treat negative impls as unimplemented - fn filter_negative_and_default_impls<'o>(&self, - candidate: SelectionCandidate<'tcx>, - stack: &TraitObligationStack<'o, 'tcx>) - -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - + fn filter_negative_impls(&self, candidate: SelectionCandidate<'tcx>) + -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { if let ImplCandidate(def_id) = candidate { if self.tcx().impl_polarity(def_id) == hir::ImplPolarity::Negative { return Err(Unimplemented) } - - // if def_id is a default impl and it doesn't implement all the trait items, - // the impl doesn't implement the trait. - // An `Unimplemented` error is returned only if the default_impl_check is - // applicable to the trait predicate or the cause of the predicate is an - // `ObjectCastObligation` - if self.tcx().impl_is_default(def_id) && - !self.tcx().default_impl_implement_all_methods(def_id){ - match stack.obligation.cause.code { - ObligationCauseCode::ObjectCastObligation(_) => { - return Err(Unimplemented) - }, - ObligationCauseCode::ItemObligation(..) | - ObligationCauseCode::MiscObligation => { - if let ty::DefaultImplCheck::Yes = stack.obligation - .predicate - .skip_binder() - .default_impl_check { - return Err(Unimplemented) - } - }, - _ => {} - } - } } Ok(Some(candidate)) } @@ -1205,8 +1178,9 @@ fn candidate_from_obligation_no_cache<'o>(&mut self, // Instead, we select the right impl now but report `Bar does // not implement Clone`. if candidates.len() == 1 { - return self.filter_negative_and_default_impls(candidates.pop().unwrap(), stack); + return self.filter_negative_impls(candidates.pop().unwrap()); } + // Winnow, but record the exact outcome of evaluation, which // is needed for specialization. let mut candidates: Vec<_> = candidates.into_iter().filter_map(|c| { @@ -1265,7 +1239,7 @@ fn candidate_from_obligation_no_cache<'o>(&mut self, } // Just one candidate left. - self.filter_negative_and_default_impls(candidates.pop().unwrap().candidate, stack) + self.filter_negative_impls(candidates.pop().unwrap().candidate) } fn is_knowable<'o>(&mut self, diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 9e0859c67a0..898accb9021 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -22,11 +22,8 @@ fn anonymize_predicate<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, pred: &ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { match *pred { - ty::Predicate::Trait(ref data) => { - let anonymized_pred = ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)); - anonymized_pred.change_default_impl_check(ty::DefaultImplCheck::No) - .unwrap_or(anonymized_pred) - } + ty::Predicate::Trait(ref data) => + ty::Predicate::Trait(tcx.anonymize_late_bound_regions(data)), ty::Predicate::Equate(ref data) => ty::Predicate::Equate(tcx.anonymize_late_bound_regions(data)), @@ -557,24 +554,6 @@ pub fn impl_is_default(self, node_item_def_id: DefId) -> bool { pub fn impl_item_is_final(self, node_item: &NodeItem) -> bool { node_item.item.is_final() && !self.impl_is_default(node_item.node.def_id()) } - - pub fn default_impl_implement_all_methods(self, node_item_def_id: DefId) -> bool { - if let Some(impl_trait_ref) = self.impl_trait_ref(node_item_def_id) { - let trait_def = self.trait_def(impl_trait_ref.def_id); - for trait_item in self.associated_items(impl_trait_ref.def_id) { - let is_implemented = trait_def.ancestors(self, node_item_def_id) - .defs(self, trait_item.name, trait_item.kind, impl_trait_ref.def_id) - .next() - .map(|node_item| !node_item.node.is_from_trait()) - .unwrap_or(false); - - if !is_implemented { - return false; - } - } - } - true - } } pub enum TupleArgumentsFlag { Yes, No } diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index 0bc092d99eb..6c727c94f58 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -9,7 +9,7 @@ // except according to those terms. use hir::def_id::DefId; -use ty::{self, Ty, TypeFoldable, Substs, TyCtxt, AssociatedKind, AssociatedItemContainer}; +use ty::{self, Ty, TypeFoldable, Substs, TyCtxt}; use ty::subst::{Kind, Subst}; use traits; use syntax::abi::Abi; @@ -17,11 +17,6 @@ use std::fmt; -use syntax_pos::{BytePos, Span}; -use syntax::ext::hygiene::SyntaxContext; -use hir::map::Node::NodeTraitItem; -use hir; - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct Instance<'tcx> { pub def: InstanceDef<'tcx>, @@ -265,13 +260,6 @@ fn resolve_associated_item<'a, 'tcx>( traits::VtableImpl(impl_data) => { let (def_id, substs) = traits::find_associated_item( tcx, trait_item, rcvr_substs, &impl_data); - - check_unimplemented_trait_item(tcx, - impl_data.impl_def_id, - def_id, - trait_id, - trait_item); - let substs = tcx.erase_regions(&substs); Some(ty::Instance::new(def_id, substs)) } @@ -375,108 +363,3 @@ fn fn_once_adapter_instance<'a, 'tcx>( debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig); Instance { def, substs } } - -fn check_unimplemented_trait_item<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - impl_def_id: DefId, - trait_item_def_id: DefId, - trait_id: DefId, - trait_item: &ty::AssociatedItem) -{ - // if trait_item_def_id is a trait item and it doesn't have a default trait implementation - // the resolution has found an unimplemented trait item inside a default impl - if tcx.impl_is_default(impl_def_id) { - let is_unimplemented_trait_item = match tcx.hir.as_local_node_id(trait_item_def_id) { - Some(node_id) => - match tcx.hir.find(node_id) { - Some(NodeTraitItem(item)) => { - if let hir::TraitItemKind::Method(_, - hir::TraitMethod::Provided(_)) - = item.node { - false - } else { - true - } - }, - _ => false - } - None => { - let item = tcx.global_tcx().associated_item(trait_item_def_id); - match item.kind { - AssociatedKind::Method => match item.container { - AssociatedItemContainer::TraitContainer(_) => { - !item.defaultness.has_value() - } - _ => false - } - _ => false - } - } - }; - - if is_unimplemented_trait_item { - let mut err = tcx.sess.struct_err(&format!("the trait method `{}` \ - is not implemented", - trait_item.name)); - - let mut help_messages = Vec::new(); - help_messages.push( - if impl_def_id.is_local() { - let item = tcx.hir - .expect_item( - tcx.hir - .as_local_node_id(impl_def_id).unwrap() - ); - (item.span, format!("implement it inside this `default impl`")) - } else { - (Span::new ( - BytePos(0), - BytePos(0), - SyntaxContext::empty() - ), - format!("implement it inside the {} `default impl`", - tcx.item_path_str(impl_def_id))) - } - ); - - help_messages.push( - if trait_id.is_local() { - let trait_item = tcx.hir - .expect_item( - tcx.hir - .as_local_node_id(trait_id).unwrap() - ); - (trait_item.span, format!("provide a default method implementation \ - inside this `trait`")) - } else { - (Span::new ( - BytePos(0), - BytePos(0), - SyntaxContext::empty() - ), - format!("provide a default method implementation \ - inside the {} `trait`", - tcx.item_path_str(trait_id))) - } - ); - - help_messages.sort_by(|&(a,_), &(b,_)| a.partial_cmp(&b).unwrap()); - - let mut cnjs = vec!["or ", "either "]; - help_messages.iter().for_each(|&(span, ref msg)| { - let mut help_msg = String::from(cnjs.pop().unwrap_or("")); - help_msg.push_str(&msg); - - if span.data().lo == BytePos(0) && span.data().hi == BytePos(0) { - err.help(&help_msg); - } else { - err.span_help(span, &help_msg); - } - }); - - err.note(&format!("a `default impl` doesn't need to include all \ - items from the trait")); - err.emit(); - } - } -} \ No newline at end of file diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 31cb4a64286..f52f2ea0f9f 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1070,13 +1070,9 @@ pub fn subst_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] -pub enum DefaultImplCheck { Yes, No, } - #[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub struct TraitPredicate<'tcx> { - pub trait_ref: TraitRef<'tcx>, - pub default_impl_check: DefaultImplCheck + pub trait_ref: TraitRef<'tcx> } pub type PolyTraitPredicate<'tcx> = ty::Binder>; @@ -1184,8 +1180,7 @@ fn to_predicate(&self) -> Predicate<'tcx> { assert!(!self.has_escaping_regions()); ty::Predicate::Trait(ty::Binder(ty::TraitPredicate { - trait_ref: self.clone(), - default_impl_check: DefaultImplCheck::No + trait_ref: self.clone() })) } } @@ -1303,36 +1298,6 @@ pub fn to_opt_type_outlives(&self) -> Option> { } } } - - pub fn change_default_impl_check(&self, default_impl_check: ty::DefaultImplCheck) - -> Option> { - match *self { - Predicate::Trait(ref t) => { - if t.skip_binder().default_impl_check != default_impl_check { - Some( - Predicate::Trait(ty::Binder(ty::TraitPredicate { - trait_ref: t.skip_binder().trait_ref, - default_impl_check: default_impl_check - })) - ) - } else { - None - } - } - Predicate::Trait(..) | - Predicate::Projection(..) | - Predicate::Equate(..) | - Predicate::Subtype(..) | - Predicate::RegionOutlives(..) | - Predicate::WellFormed(..) | - Predicate::ObjectSafe(..) | - Predicate::ClosureKind(..) | - Predicate::TypeOutlives(..) | - Predicate::ConstEvaluatable(..) => { - None - } - } - } } /// Represents the bounds declared on a particular set of type diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 122a76ca625..0dc1338fff8 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -278,8 +278,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::TraitPredicate<'a> { fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { tcx.lift(&self.trait_ref).map(|trait_ref| ty::TraitPredicate { - trait_ref: trait_ref, - default_impl_check: self.default_impl_check + trait_ref, }) } } @@ -1128,8 +1127,7 @@ fn super_visit_with>(&self, visitor: &mut V) -> bool { impl<'tcx> TypeFoldable<'tcx> for ty::TraitPredicate<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { ty::TraitPredicate { - trait_ref: self.trait_ref.fold_with(folder), - default_impl_check: self.default_impl_check + trait_ref: self.trait_ref.fold_with(folder) } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 542bf12ecdd..1593b452cdf 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -582,10 +582,7 @@ pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator> + 'a pub fn to_poly_trait_predicate(&self) -> ty::PolyTraitPredicate<'tcx> { // Note that we preserve binding levels - Binder(ty::TraitPredicate { - trait_ref: self.0.clone(), - default_impl_check: ty::DefaultImplCheck::No - }) + Binder(ty::TraitPredicate { trait_ref: self.0.clone() }) } } diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 0fbf9f1bd58..33972df97fb 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -92,10 +92,16 @@ pub fn for_each_relevant_impl(self, self_ty: Ty<'tcx>, mut f: F) { + let mut emit_impl = |impl_def_id: DefId| { + if !self.impl_is_default(impl_def_id) { + f(impl_def_id); + } + }; + let impls = self.trait_impls_of(def_id); for &impl_def_id in impls.blanket_impls.iter() { - f(impl_def_id); + emit_impl(impl_def_id); } // simplify_type(.., false) basically replaces type parameters and @@ -126,13 +132,13 @@ pub fn for_each_relevant_impl(self, if let Some(simp) = fast_reject::simplify_type(self, self_ty, true) { if let Some(impls) = impls.non_blanket_impls.get(&simp) { for &impl_def_id in impls { - f(impl_def_id); + emit_impl(impl_def_id); } } } else { for v in impls.non_blanket_impls.values() { for &impl_def_id in v { - f(impl_def_id); + emit_impl(impl_def_id); } } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 8b7c9d505bc..37d1c568515 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -1230,12 +1230,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { define_print! { ('tcx) ty::TraitPredicate<'tcx>, (self, f, cx) { debug { - let default_impl_check_value = match self.default_impl_check { - ty::DefaultImplCheck::Yes => "default_impl_check: yes", - ty::DefaultImplCheck::No => "default_impl_check: no", - }; - write!(f, "TraitPredicate({:?}, {})", - self.trait_ref, default_impl_check_value) + write!(f, "TraitPredicate({:?})", + self.trait_ref) } display { print!(f, cx, print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref)) diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 0851075a092..f16187797d4 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -618,18 +618,6 @@ fn visit_terminator_kind(&mut self, self.output); } else { visit_fn_use(self.tcx, callee_ty, true, &mut self.output); - - if tcx.sess.has_errors() { - match func { - &mir::Operand::Consume(_) => {} - &mir::Operand::Constant(ref cst) => { - tcx.sess - .span_note_without_error(cst.span, - "the function call is here"); - } - } - tcx.sess.abort_if_errors(); - } } } mir::TerminatorKind::Drop { ref location, .. } | @@ -690,10 +678,7 @@ fn visit_fn_use<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv::empty(traits::Reveal::All), def_id, substs).unwrap(); - if !tcx.sess.has_errors() { - // continue only if no errors are encountered during monomorphization - visit_instance_use(tcx, instance, is_direct_call, output); - } + visit_instance_use(tcx, instance, is_direct_call, output); } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index dc42aa8dc1a..1139ea5fbd3 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1378,10 +1378,7 @@ pub struct Bounds<'tcx> { } impl<'a, 'gcx, 'tcx> Bounds<'tcx> { - pub fn predicates(&self, - tcx: TyCtxt<'a, 'gcx, 'tcx>, - param_ty: Ty<'tcx>, - default_impl_check: ty::DefaultImplCheck) + pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>) -> Vec> { let mut vec = Vec::new(); @@ -1405,16 +1402,7 @@ pub fn predicates(&self, } for bound_trait_ref in &self.trait_bounds { - vec.push( - if bound_trait_ref.skip_binder().def_id != - tcx.lang_items().sized_trait().unwrap() { - bound_trait_ref.to_predicate() - .change_default_impl_check(default_impl_check) - .unwrap_or(bound_trait_ref.to_predicate()) - } else { - bound_trait_ref.to_predicate() - } - ); + vec.push(bound_trait_ref.to_predicate()); } for projection in &self.projection_bounds { diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index d4180183aef..4aed688027f 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -189,13 +189,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( let generic_assumptions = tcx.predicates_of(self_type_did); let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs); - let assumptions_in_impl_context: Vec = - assumptions_in_impl_context.predicates - .iter() - .map(|predicate| { - predicate.change_default_impl_check(ty::DefaultImplCheck::No) - .unwrap_or(predicate.clone()) - }).collect(); + let assumptions_in_impl_context = assumptions_in_impl_context.predicates; // An earlier version of this code attempted to do this checking // via the traits::fulfill machinery. However, it ran into trouble @@ -217,9 +211,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>( // the analysis together via the fulfill , rather than the // repeated `contains` calls. - if !assumptions_in_impl_context.contains( - &predicate.change_default_impl_check(ty::DefaultImplCheck::No) - .unwrap_or(predicate.clone())) { + if !assumptions_in_impl_context.contains(&predicate) { let item_span = tcx.hir.span(self_type_node_id); struct_span_err!(tcx.sess, drop_impl_span, E0367, "The requirement `{}` is added only by the Drop impl.", predicate) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 9c233a7a15d..78113bdcc0e 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -25,7 +25,6 @@ use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir; -use rustc::ty::TypeFoldable; pub struct CheckTypeWellFormedVisitor<'a, 'tcx:'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -346,28 +345,10 @@ fn check_impl(&mut self, ast_trait_ref.path.span); // not registering predicates associcated with a `default impl` - // that doesn't implement all the trait items. - // it's left to the trait selection to select those trait predicates - // and trigger an `Unimplemented` error in case the defaul_impl_check - // is applicable - let impl_not_implement_trait = - if fcx.tcx.impl_is_default(item_def_id) && - !fcx.tcx.default_impl_implement_all_methods(item_def_id) { - true - } else { - false - }; - + let impl_is_default = fcx.tcx.impl_is_default(item_def_id); for obligation in obligations { let register = match obligation.predicate { - ty::Predicate::Trait(..) => { - if impl_not_implement_trait && - !obligation.predicate.has_param_types() { - false - } else { - true - } - } + ty::Predicate::Trait(..) => !impl_is_default, _ => true }; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 40d69855c49..d5328a18c22 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -677,7 +677,7 @@ fn super_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, SizedByDefault::No, item.span); - let superbounds1 = superbounds1.predicates(tcx, self_param_ty, ty::DefaultImplCheck::No); + let superbounds1 = superbounds1.predicates(tcx, self_param_ty); // Convert any explicit superbounds in the where clause, // e.g. `trait Foo where Self : Bar`: @@ -694,11 +694,7 @@ fn super_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty::GenericPredicates { parent: None, - predicates: superbounds.iter() - .map(|predicate| { - predicate.change_default_impl_check(ty::DefaultImplCheck::Yes) - .unwrap_or(predicate.clone()) - }).collect() + predicates: superbounds } } @@ -1368,39 +1364,17 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let node = tcx.hir.get(node_id); let mut is_trait = None; - let mut default_impl_check = ty::DefaultImplCheck::No; let icx = ItemCtxt::new(tcx, def_id); let no_generics = hir::Generics::empty(); let ast_generics = match node { - NodeTraitItem(item) => { - match item.node { - TraitItemKind::Method(ref sig, _) => { - default_impl_check = ty::DefaultImplCheck::Yes; - &item.generics - }, - _ => &item.generics - } - } - NodeImplItem(item) => { - match item.node { - ImplItemKind::Method(ref sig, _) => { - default_impl_check = ty::DefaultImplCheck::Yes; - &item.generics - }, - _ => &item.generics - } - } + NodeTraitItem(item) => &item.generics, + NodeImplItem(item) => &item.generics, NodeItem(item) => { match item.node { ItemFn(.., ref generics, _) | ItemImpl(_, _, _, ref generics, ..) | - ItemStruct(_, ref generics) => { - default_impl_check = ty::DefaultImplCheck::Yes; - generics - } - ItemTy(_, ref generics) | ItemEnum(_, ref generics) | ItemStruct(_, ref generics) | @@ -1441,7 +1415,7 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, debug!("explicit_predicates_of: bounds={:?}", bounds); - let predicates = bounds.predicates(tcx, anon_ty, ty::DefaultImplCheck::No); + let predicates = bounds.predicates(tcx, anon_ty); debug!("explicit_predicates_of: predicates={:?}", predicates); @@ -1502,7 +1476,7 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ¶m.bounds, SizedByDefault::Yes, param.span); - predicates.extend(bounds.predicates(tcx, param_ty, default_impl_check)); + predicates.extend(bounds.predicates(tcx, param_ty)); } // Add in the bounds that appear in the where-clause @@ -1522,16 +1496,8 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, poly_trait_ref, ty, &mut projections); - predicates.push( - if trait_ref.skip_binder().def_id != - tcx.lang_items().sized_trait().unwrap() { - trait_ref.to_predicate() - .change_default_impl_check(default_impl_check) - .unwrap_or(trait_ref.to_predicate()) - } else { - trait_ref.to_predicate() - } - ); + + predicates.push(trait_ref.to_predicate()); for projection in &projections { predicates.push(projection.to_predicate()); @@ -1586,7 +1552,7 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, SizedByDefault::Yes, trait_item.span); - bounds.predicates(tcx, assoc_ty, ty::DefaultImplCheck::No).into_iter() + bounds.predicates(tcx, assoc_ty).into_iter() })) } diff --git a/src/test/compile-fail/specialization/defaultimpl/auxiliary/foo_trait.rs b/src/test/compile-fail/specialization/defaultimpl/auxiliary/foo_trait.rs deleted file mode 100644 index 263f316f3c8..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/auxiliary/foo_trait.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -pub trait Foo { - fn foo_one(&self) -> &'static str; - fn foo_two(&self) -> &'static str; -} diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-default-projection.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-default-projection.rs deleted file mode 100644 index ad55f44255b..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-default-projection.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -// Make sure we can't project defaulted associated types - -trait Foo { - type Assoc; -} - -default impl Foo for T { - type Assoc = (); -} - -impl Foo for u8 { - type Assoc = String; -} - -fn generic() -> ::Assoc { - // `T` could be some downstream crate type that specializes (or, - // for that matter, `u8`). - - () //~ ERROR mismatched types -} - -fn monomorphic() -> () { - // Even though we know that `()` is not specialized in a - // downstream crate, typeck refuses to project here. - - generic::<()>() //~ ERROR mismatched types -} - -fn main() { - // No error here, we CAN project from `u8`, as there is no `default` - // in that impl. - let s: String = generic::(); - println!("{}", s); // bad news if this all compiles -} diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-default-types.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-default-types.rs deleted file mode 100644 index 7353f7ac8c5..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-default-types.rs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// It should not be possible to use the concrete value of a defaulted -// associated type in the impl defining it -- otherwise, what happens -// if it's overridden? - -#![feature(specialization)] - -trait Example { - type Output; - fn generate(self) -> Self::Output; -} - -default impl Example for T { - type Output = Box; - fn generate(self) -> Self::Output { - Box::new(self) //~ ERROR mismatched types - } -} - -impl Example for bool { - type Output = bool; - fn generate(self) -> bool { self } -} - -fn trouble(t: T) -> Box { - Example::generate(t) //~ ERROR mismatched types -} - -fn weaponize() -> bool { - let b: Box = trouble(true); - *b -} - -fn main() { - weaponize(); -} diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented-cross-crate-impl.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented-cross-crate-impl.rs deleted file mode 100644 index 54f6690aa9f..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented-cross-crate-impl.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:foo_trait_default_impl.rs - -#![feature(specialization)] - -extern crate foo_trait_default_impl; - -use foo_trait_default_impl::*; - -struct MyStruct; - -fn main() { - MyStruct.foo_two(); //~ NOTE the function call is here -} diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented-cross-crate.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented-cross-crate.rs deleted file mode 100644 index 8e2de42a099..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented-cross-crate.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:foo_trait.rs - -#![feature(specialization)] - -extern crate foo_trait; - -use foo_trait::{Foo}; - -struct MyStruct; - -default impl Foo for MyStruct { - fn foo_one(&self) -> &'static str { - "generic" - } -} -//~^^^^^ HELP implement it inside this `default impl` - -fn main() { - MyStruct.foo_two(); //~ NOTE the function call is here -} diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented.rs deleted file mode 100644 index d0db6e996d8..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-method-not-implemented.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -trait Foo { - fn foo_one(&self) -> &'static str; - fn foo_two(&self) -> &'static str; -} -//~^^^^ HELP provide a default method implementation inside this `trait` - -default impl Foo for T { - fn foo_one(&self) -> &'static str { - "generic" - } -} -//~^^^^^ HELP implement it inside this `default impl` - -struct MyStruct; - -fn main() { - MyStruct.foo_two(); //~ NOTE the function call is here -} diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-casting.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-casting.rs deleted file mode 100644 index 81b85f58998..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-casting.rs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern: the trait bound `MyStruct: Draw` is not satisfied - -#![feature(specialization)] - -trait Draw { - fn draw(&self); - fn draw2(&self); -} - -struct Screen { - pub components: Vec>, -} - -impl Screen { - pub fn run(&self) { - for component in self.components.iter() { - component.draw(); - } - } -} - -default impl Draw for T { - fn draw(&self) { - println!("draw"); - } -} - -struct MyStruct; - -fn main() { - let screen = Screen { - components: vec![ - Box::new(MyStruct) - ] - }; - screen.run(); -} diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-impl-item.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-impl-item.rs deleted file mode 100644 index 51a6a9e2c6b..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-impl-item.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern: the trait bound `MyStruct: Foo` is not satisfied - -#![feature(specialization)] - -trait Foo { - fn foo_one(&self) -> &'static str; - fn foo_two(&self) -> &'static str; -} - -default impl Foo for T { - fn foo_one(&self) -> &'static str { - "generic" - } -} - -struct FooS; - -impl FooS{ - fn foo(&self, x: T) -> &'static str{ - x.foo_one() - } -} - -struct MyStruct; - -fn main() { - println!("{:?}", FooS.foo(MyStruct)); -} \ No newline at end of file diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-super-trait.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-super-trait.rs deleted file mode 100644 index 3444dea39c2..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-super-trait.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern: the trait bound `MyStruct: SuperFoo` is not satisfied - -#![feature(specialization)] - -trait SuperFoo { - fn super_foo_one(&self) -> &'static str; - fn super_foo_two(&self) -> &'static str; -} - -trait Foo: SuperFoo { - fn foo(&self) -> &'static str; -} - -default impl SuperFoo for T { - fn super_foo_one(&self) -> &'static str { - "generic" - } -} - -struct MyStruct; - -impl Foo for MyStruct { - fn foo(&self) -> &'static str { - "foo" - } -} - -fn main() { - println!("{:?}", MyStruct.foo()); -} \ No newline at end of file diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-trait-item.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-trait-item.rs deleted file mode 100644 index 6af69e89316..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-trait-item.rs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -trait Foo { - fn dummy(&self, t: T); -} - -trait Bar { - fn method(&self) where A: Foo; -} - -struct S; -struct X; - -default impl Foo for X {} - -impl Bar for isize { - fn method(&self) where X: Foo { - } -} - -fn main() { - 1.method::(); - //~^ ERROR the trait bound `X: Foo` is not satisfied -} diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-vec.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-vec.rs deleted file mode 100644 index a2ea087220f..00000000000 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-vec.rs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern: the trait bound `MyStruct: Draw` is not satisfied - -#![feature(specialization)] - -trait Draw { - fn draw(&self); - fn draw2(&self); -} - -struct Screen { - pub components: Vec, -} - -impl Screen - where T: Draw { - pub fn run(&self) { - for component in self.components.iter() { - component.draw(); - } - } -} - -default impl Draw for MyStruct { - fn draw(&self) { - println!("draw"); - } -} - -struct MyStruct; - -fn main() { - let screen = Screen { - components: vec![ - MyStruct - ] - }; - screen.run(); -} diff --git a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-fn.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-trait-item-not-implemented.rs similarity index 74% rename from src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-fn.rs rename to src/test/compile-fail/specialization/defaultimpl/specialization-trait-item-not-implemented.rs index 00cceeb4db3..323ff7b2db9 100644 --- a/src/test/compile-fail/specialization/defaultimpl/specialization-trait-bounds-fn.rs +++ b/src/test/compile-fail/specialization/defaultimpl/specialization-trait-item-not-implemented.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: the trait bound `MyStruct: Foo` is not satisfied - #![feature(specialization)] trait Foo { @@ -17,18 +15,17 @@ trait Foo { fn foo_two(&self) -> &'static str; } +struct MyStruct; + default impl Foo for T { fn foo_one(&self) -> &'static str { "generic" } } -fn foo(x: T) -> &'static str { - x.foo_one() -} - -struct MyStruct; +impl Foo for MyStruct {} +//~^ ERROR not all trait items implemented, missing: `foo_two` [E0046] fn main() { - println!("{:?}", foo(MyStruct)); -} + println!("{}", MyStruct.foo_one()); +} \ No newline at end of file diff --git a/src/test/compile-fail/specialization/defaultimpl/auxiliary/foo_trait_default_impl.rs b/src/test/compile-fail/specialization/defaultimpl/specialization-trait-not-implemented.rs similarity index 71% rename from src/test/compile-fail/specialization/defaultimpl/auxiliary/foo_trait_default_impl.rs rename to src/test/compile-fail/specialization/defaultimpl/specialization-trait-not-implemented.rs index cee6fcf7d9a..36945e98b08 100644 --- a/src/test/compile-fail/specialization/defaultimpl/auxiliary/foo_trait_default_impl.rs +++ b/src/test/compile-fail/specialization/defaultimpl/specialization-trait-not-implemented.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -10,13 +10,21 @@ #![feature(specialization)] -pub trait Foo { +trait Foo { fn foo_one(&self) -> &'static str; fn foo_two(&self) -> &'static str; } +struct MyStruct; + default impl Foo for T { fn foo_one(&self) -> &'static str { "generic" } } + + +fn main() { + println!("{}", MyStruct.foo_one()); + //~^ ERROR no method named `foo_one` found for type `MyStruct` in the current scope +} \ No newline at end of file diff --git a/src/test/run-pass/specialization/defaultimpl/assoc-fns.rs b/src/test/run-pass/specialization/defaultimpl/assoc-fns.rs deleted file mode 100644 index b99ba3d0f1c..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/assoc-fns.rs +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that non-method associated functions can be specialized - -#![feature(specialization)] - -trait Foo { - fn mk() -> Self; -} - -default impl Foo for T { - fn mk() -> T { - T::default() - } -} - -impl Foo for Vec { - fn mk() -> Vec { - vec![0] - } -} - -fn main() { - let v1: Vec = Foo::mk(); - let v2: Vec = Foo::mk(); - - assert!(v1.len() == 0); - assert!(v2.len() == 1); -} diff --git a/src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate.rs b/src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate.rs deleted file mode 100644 index 71dd7c99009..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate.rs +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -pub trait Foo { - fn foo(&self) -> &'static str; -} - -default impl Foo for T { - fn foo(&self) -> &'static str { - "generic" - } -} - -default impl Foo for T { - fn foo(&self) -> &'static str { - "generic Clone" - } -} - -default impl Foo for (T, U) where T: Clone, U: Clone { - fn foo(&self) -> &'static str { - "generic pair" - } -} - -default impl Foo for (T, T) { - fn foo(&self) -> &'static str { - "generic uniform pair" - } -} - -default impl Foo for (u8, u32) { - fn foo(&self) -> &'static str { - "(u8, u32)" - } -} - -default impl Foo for (u8, u8) { - fn foo(&self) -> &'static str { - "(u8, u8)" - } -} - -default impl Foo for Vec { - fn foo(&self) -> &'static str { - "generic Vec" - } -} - -impl Foo for Vec { - fn foo(&self) -> &'static str { - "Vec" - } -} - -impl Foo for String { - fn foo(&self) -> &'static str { - "String" - } -} - -impl Foo for i32 { - fn foo(&self) -> &'static str { - "i32" - } -} - -pub trait MyMarker {} -default impl Foo for T { - fn foo(&self) -> &'static str { - "generic Clone + MyMarker" - } -} diff --git a/src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate_defaults.rs b/src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate_defaults.rs deleted file mode 100644 index 9d0ea64fed4..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/auxiliary/cross_crate_defaults.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -#![feature(specialization)] - -// First, test only use of explicit `default` items: - -pub trait Foo { - fn foo(&self) -> bool; -} - -default impl Foo for T { - fn foo(&self) -> bool { false } -} - -impl Foo for i32 {} - -impl Foo for i64 { - fn foo(&self) -> bool { true } -} - -// Next, test mixture of explicit `default` and provided methods: - -pub trait Bar { - fn bar(&self) -> i32 { 0 } -} - -impl Bar for T {} // use the provided method - -impl Bar for i32 { - fn bar(&self) -> i32 { 1 } -} -impl<'a> Bar for &'a str {} - -default impl Bar for Vec { - fn bar(&self) -> i32 { 2 } -} -impl Bar for Vec {} -impl Bar for Vec { - fn bar(&self) -> i32 { 3 } -} diff --git a/src/test/run-pass/specialization/defaultimpl/auxiliary/foo_trait.rs b/src/test/run-pass/specialization/defaultimpl/auxiliary/foo_trait.rs deleted file mode 100644 index 752b0190ea6..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/auxiliary/foo_trait.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -pub trait Foo { - fn foo_one(&self) -> &'static str; - fn foo_two(&self) -> &'static str { - "generic Trait" - } -} - -default impl Foo for T { - fn foo_one(&self) -> &'static str { - "generic" - } -} - -default impl Foo for T { - fn foo_two(&self) -> &'static str { - "generic Clone" - } -} \ No newline at end of file diff --git a/src/test/run-pass/specialization/defaultimpl/basics-unsafe.rs b/src/test/run-pass/specialization/defaultimpl/basics-unsafe.rs deleted file mode 100644 index 7daecc842f3..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/basics-unsafe.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -// Tests a variety of basic specialization scenarios and method -// dispatch for them. - -unsafe trait Foo { - fn foo(&self) -> &'static str; -} - -default unsafe impl Foo for T { - fn foo(&self) -> &'static str { - "generic" - } -} - -default unsafe impl Foo for T { - fn foo(&self) -> &'static str { - "generic Clone" - } -} - -default unsafe impl Foo for (T, U) where T: Clone, U: Clone { - fn foo(&self) -> &'static str { - "generic pair" - } -} - -default unsafe impl Foo for (T, T) { - fn foo(&self) -> &'static str { - "generic uniform pair" - } -} - -default unsafe impl Foo for (u8, u32) { - fn foo(&self) -> &'static str { - "(u8, u32)" - } -} - -default unsafe impl Foo for (u8, u8) { - fn foo(&self) -> &'static str { - "(u8, u8)" - } -} - -default unsafe impl Foo for Vec { - fn foo(&self) -> &'static str { - "generic Vec" - } -} - -default unsafe impl Foo for Vec { - fn foo(&self) -> &'static str { - "Vec" - } -} - -default unsafe impl Foo for String { - fn foo(&self) -> &'static str { - "String" - } -} - -default unsafe impl Foo for i32 { - fn foo(&self) -> &'static str { - "i32" - } -} - -struct NotClone; - -unsafe trait MyMarker {} -default unsafe impl Foo for T { - fn foo(&self) -> &'static str { - "generic Clone + MyMarker" - } -} - -#[derive(Clone)] -struct MarkedAndClone; -unsafe impl MyMarker for MarkedAndClone {} - -fn main() { - assert!(NotClone.foo() == "generic"); - assert!(0u8.foo() == "generic Clone"); - assert!(vec![NotClone].foo() == "generic"); - assert!(vec![0u8].foo() == "generic Vec"); - assert!(vec![0i32].foo() == "Vec"); - assert!(0i32.foo() == "i32"); - assert!(String::new().foo() == "String"); - assert!(((), 0).foo() == "generic pair"); - assert!(((), ()).foo() == "generic uniform pair"); - assert!((0u8, 0u32).foo() == "(u8, u32)"); - assert!((0u8, 0u8).foo() == "(u8, u8)"); - assert!(MarkedAndClone.foo() == "generic Clone + MyMarker"); -} diff --git a/src/test/run-pass/specialization/defaultimpl/basics.rs b/src/test/run-pass/specialization/defaultimpl/basics.rs deleted file mode 100644 index 594f1e4fcdf..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/basics.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -// Tests a variety of basic specialization scenarios and method -// dispatch for them. - -trait Foo { - fn foo(&self) -> &'static str; -} - -default impl Foo for T { - fn foo(&self) -> &'static str { - "generic" - } -} - -default impl Foo for T { - fn foo(&self) -> &'static str { - "generic Clone" - } -} - -default impl Foo for (T, U) where T: Clone, U: Clone { - fn foo(&self) -> &'static str { - "generic pair" - } -} - -default impl Foo for (T, T) { - fn foo(&self) -> &'static str { - "generic uniform pair" - } -} - -default impl Foo for (u8, u32) { - fn foo(&self) -> &'static str { - "(u8, u32)" - } -} - -default impl Foo for (u8, u8) { - fn foo(&self) -> &'static str { - "(u8, u8)" - } -} - -default impl Foo for Vec { - fn foo(&self) -> &'static str { - "generic Vec" - } -} - -impl Foo for Vec { - fn foo(&self) -> &'static str { - "Vec" - } -} - -impl Foo for String { - fn foo(&self) -> &'static str { - "String" - } -} - -impl Foo for i32 { - fn foo(&self) -> &'static str { - "i32" - } -} - -struct NotClone; - -trait MyMarker {} -default impl Foo for T { - fn foo(&self) -> &'static str { - "generic Clone + MyMarker" - } -} - -#[derive(Clone)] -struct MarkedAndClone; -impl MyMarker for MarkedAndClone {} - -fn main() { - assert!(NotClone.foo() == "generic"); - assert!(0u8.foo() == "generic Clone"); - assert!(vec![NotClone].foo() == "generic"); - assert!(vec![0u8].foo() == "generic Vec"); - assert!(vec![0i32].foo() == "Vec"); - assert!(0i32.foo() == "i32"); - assert!(String::new().foo() == "String"); - assert!(((), 0).foo() == "generic pair"); - assert!(((), ()).foo() == "generic uniform pair"); - assert!((0u8, 0u32).foo() == "(u8, u32)"); - assert!((0u8, 0u8).foo() == "(u8, u8)"); - assert!(MarkedAndClone.foo() == "generic Clone + MyMarker"); -} diff --git a/src/test/run-pass/specialization/defaultimpl/cross-crate-defaults.rs b/src/test/run-pass/specialization/defaultimpl/cross-crate-defaults.rs deleted file mode 100644 index 19e1af15bdd..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/cross-crate-defaults.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:cross_crate_defaults.rs - -#![feature(specialization)] - -extern crate cross_crate_defaults; - -use cross_crate_defaults::*; - -struct LocalDefault; -struct LocalOverride; - -impl Foo for LocalDefault {} - -impl Foo for LocalOverride { - fn foo(&self) -> bool { true } -} - -fn test_foo() { - assert!(!0i8.foo()); - assert!(!0i32.foo()); - assert!(0i64.foo()); - - assert!(!LocalDefault.foo()); - assert!(LocalOverride.foo()); -} - -fn test_bar() { - assert!(0u8.bar() == 0); - assert!(0i32.bar() == 1); - assert!("hello".bar() == 0); - assert!(vec![()].bar() == 2); - assert!(vec![0i32].bar() == 2); - assert!(vec![0i64].bar() == 3); -} - -fn main() { - test_foo(); - test_bar(); -} diff --git a/src/test/run-pass/specialization/defaultimpl/cross-crate-no-gate.rs b/src/test/run-pass/specialization/defaultimpl/cross-crate-no-gate.rs deleted file mode 100644 index 67cc694ae12..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/cross-crate-no-gate.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Test that specialization works even if only the upstream crate enables it - -// aux-build:cross_crate.rs - -extern crate cross_crate; - -use cross_crate::*; - -fn main() { - assert!(0u8.foo() == "generic Clone"); - assert!(vec![0u8].foo() == "generic Vec"); - assert!(vec![0i32].foo() == "Vec"); - assert!(0i32.foo() == "i32"); - assert!(String::new().foo() == "String"); - assert!(((), 0).foo() == "generic pair"); - assert!(((), ()).foo() == "generic uniform pair"); - assert!((0u8, 0u32).foo() == "(u8, u32)"); - assert!((0u8, 0u8).foo() == "(u8, u8)"); -} diff --git a/src/test/run-pass/specialization/defaultimpl/cross-crate.rs b/src/test/run-pass/specialization/defaultimpl/cross-crate.rs deleted file mode 100644 index f1ad105db8f..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/cross-crate.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:cross_crate.rs - -#![feature(specialization)] - -extern crate cross_crate; - -use cross_crate::*; - -struct NotClone; - -#[derive(Clone)] -struct MarkedAndClone; -impl MyMarker for MarkedAndClone {} - -struct MyType(T); -default impl Foo for MyType { - fn foo(&self) -> &'static str { - "generic MyType" - } -} - -impl Foo for MyType { - fn foo(&self) -> &'static str { - "MyType" - } -} - -struct MyOtherType; -impl Foo for MyOtherType {} - -fn main() { - assert!(NotClone.foo() == "generic"); - assert!(0u8.foo() == "generic Clone"); - assert!(vec![NotClone].foo() == "generic"); - assert!(vec![0u8].foo() == "generic Vec"); - assert!(vec![0i32].foo() == "Vec"); - assert!(0i32.foo() == "i32"); - assert!(String::new().foo() == "String"); - assert!(((), 0).foo() == "generic pair"); - assert!(((), ()).foo() == "generic uniform pair"); - assert!((0u8, 0u32).foo() == "(u8, u32)"); - assert!((0u8, 0u8).foo() == "(u8, u8)"); - assert!(MarkedAndClone.foo() == "generic Clone + MyMarker"); - - assert!(MyType(()).foo() == "generic MyType"); - assert!(MyType(0u8).foo() == "MyType"); - assert!(MyOtherType.foo() == "generic"); -} diff --git a/src/test/run-pass/specialization/defaultimpl/default-methods.rs b/src/test/run-pass/specialization/defaultimpl/default-methods.rs deleted file mode 100644 index 4ac9afc1c89..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/default-methods.rs +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -// Test that default methods are cascaded correctly - -// First, test only use of explicit `default` items: - -trait Foo { - fn foo(&self) -> bool; -} - -// Specialization tree for Foo: -// -// T -// / \ -// i32 i64 - -default impl Foo for T { - fn foo(&self) -> bool { false } -} - -impl Foo for i32 {} - -impl Foo for i64 { - fn foo(&self) -> bool { true } -} - -fn test_foo() { - assert!(!0i8.foo()); - assert!(!0i32.foo()); - assert!(0i64.foo()); -} - -// Next, test mixture of explicit `default` and provided methods: - -trait Bar { - fn bar(&self) -> i32 { 0 } -} - -// Specialization tree for Bar. -// Uses of $ designate that method is provided -// -// $Bar (the trait) -// | -// T -// /|\ -// / | \ -// / | \ -// / | \ -// / | \ -// / | \ -// $i32 &str $Vec -// /\ -// / \ -// Vec $Vec - -// use the provided method -impl Bar for T {} - -impl Bar for i32 { - fn bar(&self) -> i32 { 1 } -} -impl<'a> Bar for &'a str {} - -default impl Bar for Vec { - fn bar(&self) -> i32 { 2 } -} -impl Bar for Vec {} -impl Bar for Vec { - fn bar(&self) -> i32 { 3 } -} - -fn test_bar() { - assert!(0u8.bar() == 0); - assert!(0i32.bar() == 1); - assert!("hello".bar() == 0); - assert!(vec![()].bar() == 2); - assert!(vec![0i32].bar() == 2); - assert!(vec![0i64].bar() == 3); -} - -fn main() { - test_foo(); - test_bar(); -} diff --git a/src/test/run-pass/specialization/defaultimpl/projection-alias.rs b/src/test/run-pass/specialization/defaultimpl/projection-alias.rs deleted file mode 100644 index 2397c3e2bff..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/projection-alias.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -// Regression test for ICE when combining specialized associated types and type -// aliases - -trait Id_ { - type Out; -} - -type Id = ::Out; - -default impl Id_ for T { - type Out = T; -} - -fn test_proection() { - let x: Id = panic!(); -} - -fn main() { - -} diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-trait-bounds.rs b/src/test/run-pass/specialization/defaultimpl/specialization-trait-bounds.rs deleted file mode 100644 index 4ed37b311ef..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/specialization-trait-bounds.rs +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -trait Foo { - fn foo_one(&self) -> &'static str; - fn foo_two(&self) -> &'static str; -} - -default impl Foo for T { - fn foo_one(&self) -> &'static str { - "generic one" - } - fn foo_two(&self) -> &'static str { - "generic two" - } -} - -fn foo_one(x: T) -> &'static str { - x.foo_one() -} - -fn foo_two(x: T) -> &'static str { - x.foo_two() -} - -struct MyStruct; - -fn main() { - assert!(foo_one(MyStruct) == "generic one"); - assert!(foo_two(MyStruct) == "generic two"); -} diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-traits-impl.rs b/src/test/run-pass/specialization/defaultimpl/specialization-trait-item-not-implemented.rs similarity index 74% rename from src/test/run-pass/specialization/defaultimpl/specialization-traits-impl.rs rename to src/test/run-pass/specialization/defaultimpl/specialization-trait-item-not-implemented.rs index 409d2c78e77..f8eb57bad77 100644 --- a/src/test/run-pass/specialization/defaultimpl/specialization-traits-impl.rs +++ b/src/test/run-pass/specialization/defaultimpl/specialization-trait-item-not-implemented.rs @@ -1,4 +1,4 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -15,21 +15,20 @@ trait Foo { fn foo_two(&self) -> &'static str; } +struct MyStruct; + default impl Foo for T { fn foo_one(&self) -> &'static str { "generic" } } -default impl Foo for T { +impl Foo for MyStruct { fn foo_two(&self) -> &'static str { - "generic Clone" + self.foo_one() } } -struct MyStruct; - -fn main() { - assert!(MyStruct.foo_one() == "generic"); - assert!(0u8.foo_two() == "generic Clone"); -} +fn main() { + assert!(MyStruct.foo_two() == "generic"); +} \ No newline at end of file diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-traits-impl-default-method-cross-crate.rs b/src/test/run-pass/specialization/defaultimpl/specialization-traits-impl-default-method-cross-crate.rs deleted file mode 100644 index 5c0547b0341..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/specialization-traits-impl-default-method-cross-crate.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:foo_trait.rs - -#![feature(specialization)] - -extern crate foo_trait; - -use foo_trait::*; - -struct MyStruct; - -fn main() { - assert!(MyStruct.foo_one() == "generic"); - assert!(0u8.foo_two() == "generic Clone"); - assert!(MyStruct.foo_two() == "generic Trait"); -} diff --git a/src/test/run-pass/specialization/defaultimpl/specialization-traits-impl-default-method.rs b/src/test/run-pass/specialization/defaultimpl/specialization-traits-impl-default-method.rs deleted file mode 100644 index 254d3bebb90..00000000000 --- a/src/test/run-pass/specialization/defaultimpl/specialization-traits-impl-default-method.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(specialization)] - -trait Foo { - fn foo_one(&self) -> &'static str; - fn foo_two(&self) -> &'static str { - "generic Trait" - } -} - -default impl Foo for T { - fn foo_one(&self) -> &'static str { - "generic" - } -} - -default impl Foo for T { - fn foo_two(&self) -> &'static str { - "generic Clone" - } -} - -struct MyStruct; - -fn main() { - assert!(MyStruct.foo_one() == "generic"); - assert!(0u8.foo_two() == "generic Clone"); - assert!(MyStruct.foo_two() == "generic Trait"); -} -- GitLab