From dbf994bbaff214e6441a8e97df180db7b29e7189 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 15 Dec 2015 04:31:58 -0500 Subject: [PATCH] Make RFC 1214 warnings into errors, and rip out the "warn or err" associated machinery. Future such attempts should go through lints anyhow. There is a fair amount of fallout in the compile-fail tests, as WF checking now occurs earlier in the process. --- src/librustc/middle/infer/error_reporting.rs | 31 +- src/librustc/middle/infer/mod.rs | 7 - src/librustc/middle/traits/error_reporting.rs | 74 +- src/librustc/middle/traits/fulfill.rs | 33 +- src/librustc/middle/traits/mod.rs | 21 - src/librustc/middle/traits/select.rs | 26 +- src/librustc/middle/ty/outlives.rs | 28 +- src/librustc/middle/ty/wf.rs | 89 +-- src/librustc/session/mod.rs | 7 - src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/mod.rs | 16 - src/librustc_typeck/check/regionck.rs | 7 - src/librustc_typeck/check/wf.rs | 673 ------------------ src/librustc_typeck/check/wfcheck.rs | 10 +- src/librustc_typeck/coherence/overlap.rs | 16 +- src/librustc_typeck/diagnostics.rs | 9 +- src/librustc_typeck/lib.rs | 9 +- src/test/auxiliary/associated-types-cc-lib.rs | 2 +- src/test/auxiliary/static-methods-crate.rs | 2 +- ...associated-types-no-suitable-supertrait.rs | 5 +- .../builtin-superkinds-self-type.rs | 2 +- ...erence-impl-trait-for-trait-object-safe.rs | 6 +- src/test/compile-fail/cross-fn-cache-hole.rs | 11 +- src/test/compile-fail/issue-13853-2.rs | 2 +- src/test/compile-fail/issue-13853.rs | 7 +- src/test/compile-fail/issue-14853.rs | 2 +- src/test/compile-fail/issue-18959.rs | 6 +- src/test/compile-fail/issue-19380.rs | 2 +- src/test/compile-fail/issue-20005.rs | 9 +- src/test/compile-fail/issue-20831-debruijn.rs | 2 + src/test/compile-fail/issue-21974.rs | 4 +- src/test/compile-fail/issue-23041.rs | 2 +- src/test/compile-fail/issue-23305.rs | 2 +- src/test/compile-fail/issue-3907-2.rs | 2 +- .../compile-fail/object-safety-generics.rs | 5 +- .../object-safety-mentions-Self.rs | 18 +- .../compile-fail/object-safety-no-static.rs | 12 +- .../compile-fail/object-safety-sized-2.rs | 10 +- src/test/compile-fail/object-safety-sized.rs | 9 +- .../regions-close-object-into-object-5.rs | 6 +- .../regions-free-region-ordering-callee-4.rs | 21 + .../regions-free-region-ordering-callee.rs | 6 +- ...ions-implied-bounds-projection-gap-hr-1.rs | 15 +- .../compile-fail/regions-wf-trait-object.rs | 3 +- .../compile-fail/rfc1214-warn-and-error.rs | 37 - .../trait-bounds-impl-comparison-2.rs | 2 +- src/test/compile-fail/trait-test-2.rs | 1 - ...default-trait-impl-trait-where-clause-2.rs | 36 + ...k-default-trait-impl-trait-where-clause.rs | 11 +- .../variance-invariant-self-trait-match.rs | 4 +- src/test/compile-fail/wf-array-elem-sized.rs | 4 +- src/test/compile-fail/wf-enum-bound.rs | 4 +- src/test/compile-fail/wf-fn-where-clause.rs | 4 +- .../wf-impl-associated-type-region.rs | 4 +- .../wf-impl-associated-type-trait.rs | 4 +- src/test/compile-fail/wf-in-fn-type-static.rs | 6 +- .../compile-fail/wf-in-fn-where-clause.rs | 4 +- .../compile-fail/wf-in-obj-type-static.rs | 4 +- .../wf-inherent-impl-method-where-clause.rs | 4 +- .../wf-inherent-impl-where-clause.rs | 4 +- .../wf-outlives-ty-in-fn-or-trait.rs | 6 +- src/test/compile-fail/wf-struct-bound.rs | 4 +- .../wf-trait-associated-type-bound.rs | 4 +- .../wf-trait-associated-type-region.rs | 4 +- .../wf-trait-associated-type-trait.rs | 4 +- src/test/compile-fail/wf-trait-bound.rs | 4 +- .../compile-fail/wf-trait-default-fn-arg.rs | 4 +- .../compile-fail/wf-trait-default-fn-ret.rs | 5 +- .../wf-trait-default-fn-where-clause.rs | 4 +- src/test/compile-fail/wf-trait-fn-arg.rs | 5 +- src/test/compile-fail/wf-trait-fn-ret.rs | 5 +- .../compile-fail/wf-trait-fn-where-clause.rs | 4 +- src/test/compile-fail/wf-trait-superbound.rs | 5 +- src/test/run-pass/cycle-generic-bound.rs | 2 + src/test/run-pass/cycle-trait-type-trait.rs | 8 + src/test/run-pass/issue-25810.rs | 4 +- src/test/run-pass/issue-6898.rs | 2 +- src/test/run-pass/regions-issue-22246.rs | 2 +- .../regions-no-variance-from-fn-generics.rs | 6 +- src/test/run-pass/trait-inheritance-num0.rs | 2 +- src/test/run-pass/trait-inheritance-num1.rs | 2 +- src/test/run-pass/trait-inheritance-num3.rs | 2 +- src/test/run-pass/trait-inheritance-num5.rs | 2 +- .../trait-inheritance-self-in-supertype.rs | 2 +- src/test/run-pass/trait-inheritance-self.rs | 2 +- src/test/run-pass/trait-inheritance-subst.rs | 2 +- src/test/run-pass/trait-inheritance-subst2.rs | 2 +- src/test/run-pass/unsized2.rs | 16 +- 88 files changed, 291 insertions(+), 1187 deletions(-) delete mode 100644 src/librustc_typeck/check/wf.rs create mode 100644 src/test/compile-fail/regions-free-region-ordering-callee-4.rs delete mode 100644 src/test/compile-fail/rfc1214-warn-and-error.rs create mode 100644 src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index e894878e43ce1..787431b2167bc 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -578,11 +578,6 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { // where the error was detected. But that span is not readily // accessible. - let is_warning = match origin { - infer::RFC1214Subregion(_) => true, - _ => false, - }; - let labeled_user_string = match bound_kind { GenericKind::Param(ref p) => format!("the parameter type `{}`", p), @@ -593,8 +588,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { match sub { ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => { // Does the required lifetime have a nice name we can print? - span_err_or_warn!( - is_warning, self.tcx.sess, origin.span(), E0309, + span_err!( + self.tcx.sess, origin.span(), E0309, "{} may not live long enough", labeled_user_string); self.tcx.sess.fileline_help( origin.span(), @@ -606,8 +601,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { ty::ReStatic => { // Does the required lifetime have a nice name we can print? - span_err_or_warn!( - is_warning, self.tcx.sess, origin.span(), E0310, + span_err!( + self.tcx.sess, origin.span(), E0310, "{} may not live long enough", labeled_user_string); self.tcx.sess.fileline_help( origin.span(), @@ -618,8 +613,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { _ => { // If not, be less specific. - span_err_or_warn!( - is_warning, self.tcx.sess, origin.span(), E0311, + span_err!( + self.tcx.sess, origin.span(), E0311, "{} may not live long enough", labeled_user_string); self.tcx.sess.fileline_help( @@ -634,10 +629,6 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { } } - if is_warning { - self.tcx.sess.note_rfc_1214(origin.span()); - } - self.note_region_origin(&origin); } @@ -646,13 +637,6 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { sub: Region, sup: Region) { match origin { - infer::RFC1214Subregion(ref suborigin) => { - // Ideally, this would be a warning, but it doesn't - // seem to come up in practice, since the changes from - // RFC1214 mostly trigger errors in type definitions - // that don't wind up coming down this path. - self.report_concrete_failure((**suborigin).clone(), sub, sup); - } infer::Subtype(trace) => { let terr = TypeError::RegionsDoesNotOutlive(sup, sub); self.report_and_explain_type_error(trace, &terr); @@ -1599,9 +1583,6 @@ impl<'a, 'tcx> ErrorReportingHelpers<'tcx> for InferCtxt<'a, 'tcx> { fn note_region_origin(&self, origin: &SubregionOrigin<'tcx>) { match *origin { - infer::RFC1214Subregion(ref suborigin) => { - self.note_region_origin(suborigin); - } infer::Subtype(ref trace) => { let desc = match trace.origin { TypeOrigin::Misc(_) => { diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 119651f12e912..d0ffed56635f7 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -37,7 +37,6 @@ use middle::ty::relate::{Relate, RelateResult, TypeRelation}; use rustc_data_structures::unify::{self, UnificationTable}; use std::cell::{RefCell, Ref}; use std::fmt; -use std::rc::Rc; use syntax::ast; use syntax::codemap; use syntax::codemap::{Span, DUMMY_SP}; @@ -198,11 +197,6 @@ pub struct TypeTrace<'tcx> { /// See `error_reporting.rs` for more details #[derive(Clone, Debug)] pub enum SubregionOrigin<'tcx> { - // Marker to indicate a constraint that only arises due to new - // provisions from RFC 1214. This will result in a warning, not an - // error. - RFC1214Subregion(Rc>), - // Arose from a subtyping relation Subtype(TypeTrace<'tcx>), @@ -1568,7 +1562,6 @@ impl TypeOrigin { impl<'tcx> SubregionOrigin<'tcx> { pub fn span(&self) -> Span { match *self { - RFC1214Subregion(ref a) => a.span(), Subtype(ref a) => a.span(), InfStackClosure(a) => a, InvokeClosure(a) => a, diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 0931c138e46f4..9cf8043be3ba1 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -36,7 +36,6 @@ use syntax::attr::{AttributeMethods, AttrMetaMethods}; #[derive(Debug, PartialEq, Eq, Hash)] pub struct TraitErrorKey<'tcx> { - is_warning: bool, span: Span, predicate: ty::Predicate<'tcx> } @@ -47,7 +46,6 @@ impl<'tcx> TraitErrorKey<'tcx> { let predicate = infcx.resolve_type_vars_if_possible(&e.obligation.predicate); TraitErrorKey { - is_warning: is_warning(&e.obligation), span: e.obligation.cause.span, predicate: infcx.tcx.erase_regions(&predicate) } @@ -83,10 +81,6 @@ fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, } } -fn is_warning(obligation: &Obligation) -> bool { - obligation.cause.code.is_rfc1214() -} - pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, obligation: &PredicateObligation<'tcx>, error: &MismatchedProjectionTypes<'tcx>) @@ -100,8 +94,8 @@ pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, // then $X will be unified with TyError, but the error still needs to be // reported. if !infcx.tcx.sess.has_errors() || !predicate.references_error() { - span_err_or_warn!( - is_warning(obligation), infcx.tcx.sess, obligation.cause.span, E0271, + span_err!( + infcx.tcx.sess, obligation.cause.span, E0271, "type mismatch resolving `{}`: {}", predicate, error.err); @@ -208,12 +202,11 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, obligation: &PredicateObligation<'tcx>, error: &SelectionError<'tcx>) { - let is_warning = is_warning(obligation); match *error { SelectionError::Unimplemented => { if let ObligationCauseCode::CompareImplMethodObligation = obligation.cause.code { - span_err_or_warn!( - is_warning, infcx.tcx.sess, obligation.cause.span, E0276, + span_err!( + infcx.tcx.sess, obligation.cause.span, E0276, "the requirement `{}` appears on the impl \ method but not on the corresponding trait method", obligation.predicate); @@ -225,8 +218,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, if !infcx.tcx.sess.has_errors() || !trait_predicate.references_error() { let trait_ref = trait_predicate.to_poly_trait_ref(); - span_err_or_warn!( - is_warning, infcx.tcx.sess, obligation.cause.span, E0277, + span_err!( + infcx.tcx.sess, obligation.cause.span, E0277, "the trait `{}` is not implemented for the type `{}`", trait_ref, trait_ref.self_ty()); @@ -245,8 +238,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, let predicate = infcx.resolve_type_vars_if_possible(predicate); let err = infcx.equality_predicate(obligation.cause.span, &predicate).err().unwrap(); - span_err_or_warn!( - is_warning, infcx.tcx.sess, obligation.cause.span, E0278, + span_err!( + infcx.tcx.sess, obligation.cause.span, E0278, "the requirement `{}` is not satisfied (`{}`)", predicate, err); @@ -257,8 +250,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, let predicate = infcx.resolve_type_vars_if_possible(predicate); let err = infcx.region_outlives_predicate(obligation.cause.span, &predicate).err().unwrap(); - span_err_or_warn!( - is_warning, infcx.tcx.sess, obligation.cause.span, E0279, + span_err!( + infcx.tcx.sess, obligation.cause.span, E0279, "the requirement `{}` is not satisfied (`{}`)", predicate, err); @@ -268,8 +261,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => { let predicate = infcx.resolve_type_vars_if_possible(&obligation.predicate); - span_err_or_warn!( - is_warning, infcx.tcx.sess, obligation.cause.span, E0280, + span_err!( + infcx.tcx.sess, obligation.cause.span, E0280, "the requirement `{}` is not satisfied", predicate); note_obligation_cause(infcx, obligation); @@ -281,8 +274,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, report_object_safety_error(infcx.tcx, obligation.cause.span, trait_def_id, - violations, - is_warning); + violations); note_obligation_cause(infcx, obligation); } @@ -304,8 +296,8 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, let expected_trait_ref = infcx.resolve_type_vars_if_possible(&*expected_trait_ref); let actual_trait_ref = infcx.resolve_type_vars_if_possible(&*actual_trait_ref); if !actual_trait_ref.self_ty().references_error() { - span_err_or_warn!( - is_warning, infcx.tcx.sess, obligation.cause.span, E0281, + span_err!( + infcx.tcx.sess, obligation.cause.span, E0281, "type mismatch: the type `{}` implements the trait `{}`, \ but the trait `{}` is required ({})", expected_trait_ref.self_ty(), @@ -318,8 +310,7 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, TraitNotObjectSafe(did) => { let violations = object_safety_violations(infcx.tcx, did); - report_object_safety_error(infcx.tcx, obligation.cause.span, did, - violations, is_warning); + report_object_safety_error(infcx.tcx, obligation.cause.span, did, violations); note_obligation_cause(infcx, obligation); } } @@ -328,11 +319,10 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>, span: Span, trait_def_id: DefId, - violations: Vec, - is_warning: bool) + violations: Vec) { - span_err_or_warn!( - is_warning, tcx.sess, span, E0038, + span_err!( + tcx.sess, span, E0038, "the trait `{}` cannot be made into an object", tcx.item_path_str(trait_def_id)); @@ -402,7 +392,17 @@ pub fn maybe_report_ambiguity<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, let self_ty = trait_ref.self_ty(); let all_types = &trait_ref.substs().types; if all_types.references_error() { - } else if all_types.needs_infer() { + } else { + // Typically, this ambiguity should only happen if + // there are unresolved type inference variables + // (otherwise it would suggest a coherence + // failure). But given #21974 that is not necessarily + // the case -- we can have multiple where clauses that + // are only distinguished by a region, which results + // in an ambiguity even when all types are fully + // known, since we don't dispatch based on region + // relationships. + // This is kind of a hack: it frequently happens that some earlier // error prevents types from being fully inferred, and then we get // a bunch of uninteresting errors saying something like "(infcx: &InferCtxt<'a, 'tcx>, note_obligation_cause(infcx, obligation); } } - } else if !infcx.tcx.sess.has_errors() { - // Ambiguity. Coherence should have reported an error. - infcx.tcx.sess.span_bug( - obligation.cause.span, - &format!( - "coherence failed to report ambiguity: \ - cannot locate the impl of the trait `{}` for \ - the type `{}`", - trait_ref, - self_ty)); } } @@ -491,10 +481,6 @@ fn note_obligation_cause_code<'a, 'tcx, T>(infcx: &InferCtxt<'a, 'tcx>, let tcx = infcx.tcx; match *cause_code { ObligationCauseCode::MiscObligation => { } - ObligationCauseCode::RFC1214(ref subcode) => { - tcx.sess.note_rfc_1214(cause_span); - note_obligation_cause_code(infcx, predicate, cause_span, subcode); - } ObligationCauseCode::SliceOrArrayElem => { tcx.sess.fileline_note( cause_span, diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index d4e6f693d965d..b93961f1aa9d2 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -21,16 +21,14 @@ use super::CodeSelectionError; use super::is_object_safe; use super::FulfillmentError; use super::ObligationCause; -use super::ObligationCauseCode; use super::PredicateObligation; use super::project; -use super::RFC1214Warning; use super::select::SelectionContext; use super::Unimplemented; use super::util::predicate_for_builtin_bound; pub struct FulfilledPredicates<'tcx> { - set: FnvHashSet<(RFC1214Warning, ty::Predicate<'tcx>)> + set: FnvHashSet> } /// The fulfillment context is used to drive trait resolution. It @@ -194,9 +192,7 @@ impl<'tcx> FulfillmentContext<'tcx> { assert!(!obligation.has_escaping_regions()); - let w = RFC1214Warning(obligation.cause.code.is_rfc1214()); - - if self.is_duplicate_or_add(infcx.tcx, w, &obligation.predicate) { + if self.is_duplicate_or_add(infcx.tcx, &obligation.predicate) { debug!("register_predicate({:?}) -- already seen, skip", obligation); return; } @@ -261,7 +257,6 @@ impl<'tcx> FulfillmentContext<'tcx> { fn is_duplicate_or_add(&mut self, tcx: &ty::ctxt<'tcx>, - w: RFC1214Warning, predicate: &ty::Predicate<'tcx>) -> bool { // This is a kind of dirty hack to allow us to avoid "rederiving" @@ -276,12 +271,10 @@ impl<'tcx> FulfillmentContext<'tcx> { // evaluating the 'nested obligations'. This cache lets us // skip those. - let will_warn_due_to_rfc1214 = w.0; - let errors_will_be_reported = self.errors_will_be_reported && !will_warn_due_to_rfc1214; - if errors_will_be_reported && predicate.is_global() { - tcx.fulfilled_predicates.borrow_mut().is_duplicate_or_add(w, predicate) + if self.errors_will_be_reported && predicate.is_global() { + tcx.fulfilled_predicates.borrow_mut().is_duplicate_or_add(predicate) } else { - self.duplicate_set.is_duplicate_or_add(w, predicate) + self.duplicate_set.is_duplicate_or_add(predicate) } } @@ -496,12 +489,8 @@ fn process_predicate<'a,'tcx>(selcx: &mut SelectionContext<'a,'tcx>, } ty::Predicate::WellFormed(ty) => { - let rfc1214 = match obligation.cause.code { - ObligationCauseCode::RFC1214(_) => true, - _ => false, - }; match ty::wf::obligations(selcx.infcx(), obligation.cause.body_id, - ty, obligation.cause.span, rfc1214) { + ty, obligation.cause.span) { Some(obligations) => { new_obligations.extend(obligations); true @@ -539,13 +528,11 @@ impl<'tcx> FulfilledPredicates<'tcx> { } } - pub fn is_duplicate(&self, w: RFC1214Warning, p: &ty::Predicate<'tcx>) -> bool { - let key = (w, p.clone()); - self.set.contains(&key) + pub fn is_duplicate(&self, key: &ty::Predicate<'tcx>) -> bool { + self.set.contains(key) } - fn is_duplicate_or_add(&mut self, w: RFC1214Warning, p: &ty::Predicate<'tcx>) -> bool { - let key = (w, p.clone()); - !self.set.insert(key) + fn is_duplicate_or_add(&mut self, key: &ty::Predicate<'tcx>) -> bool { + !self.set.insert(key.clone()) } } diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index 691bac0cef865..255680465ca7f 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -106,9 +106,6 @@ pub enum ObligationCauseCode<'tcx> { /// Not well classified or should be obvious from span. MiscObligation, - /// Obligation that triggers warning until RFC 1214 is fully in place. - RFC1214(Rc>), - /// This is the trait reference from the given projection SliceOrArrayElem, @@ -554,24 +551,6 @@ impl<'tcx> ObligationCause<'tcx> { } } -/// This marker is used in some caches to record whether the -/// predicate, if it is found to be false, will yield a warning (due -/// to RFC1214) or an error. We separate these two cases in the cache -/// so that if we see the same predicate twice, first resulting in a -/// warning, and next resulting in an error, we still report the -/// error, rather than considering it a duplicate. -#[derive(Copy, Clone, PartialEq, Eq, Hash)] -pub struct RFC1214Warning(bool); - -impl<'tcx> ObligationCauseCode<'tcx> { - pub fn is_rfc1214(&self) -> bool { - match *self { - ObligationCauseCode::RFC1214(..) => true, - _ => false, - } - } -} - impl<'tcx, N> Vtable<'tcx, N> { pub fn nested_obligations(self) -> Vec { match self { diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 0b0f6c0b998fc..b0215675fca81 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -26,7 +26,6 @@ use super::{ObligationCauseCode, BuiltinDerivedObligation, ImplDerivedObligation use super::{SelectionError, Unimplemented, OutputTypeParameterMismatch}; use super::{ObjectCastObligation, Obligation}; use super::TraitNotObjectSafe; -use super::RFC1214Warning; use super::Selection; use super::SelectionResult; use super::{VtableBuiltin, VtableImpl, VtableParam, VtableClosure, @@ -463,8 +462,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // have been proven elsewhere. This cache only contains // predicates that are global in scope and hence unaffected by // the current environment. - let w = RFC1214Warning(false); - if self.tcx().fulfilled_predicates.borrow().is_duplicate(w, &obligation.predicate) { + if self.tcx().fulfilled_predicates.borrow().is_duplicate(&obligation.predicate) { return EvaluatedToOk; } @@ -485,8 +483,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::Predicate::WellFormed(ty) => { match ty::wf::obligations(self.infcx, obligation.cause.body_id, - ty, obligation.cause.span, - obligation.cause.code.is_rfc1214()) { + ty, obligation.cause.span) { Some(obligations) => self.evaluate_predicates_recursively(previous_stack, obligations.iter()), None => @@ -2906,22 +2903,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // chain. Ideally, we should have a way to configure this either // by using -Z verbose or just a CLI argument. if obligation.recursion_depth >= 0 { - let derived_code = match obligation.cause.code { - ObligationCauseCode::RFC1214(ref base_code) => { - let derived_cause = DerivedObligationCause { - parent_trait_ref: obligation.predicate.to_poly_trait_ref(), - parent_code: base_code.clone(), - }; - ObligationCauseCode::RFC1214(Rc::new(variant(derived_cause))) - } - _ => { - let derived_cause = DerivedObligationCause { - parent_trait_ref: obligation.predicate.to_poly_trait_ref(), - parent_code: Rc::new(obligation.cause.code.clone()) - }; - variant(derived_cause) - } + let derived_cause = DerivedObligationCause { + parent_trait_ref: obligation.predicate.to_poly_trait_ref(), + parent_code: Rc::new(obligation.cause.code.clone()) }; + let derived_code = variant(derived_cause); ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code) } else { obligation.cause.clone() diff --git a/src/librustc/middle/ty/outlives.rs b/src/librustc/middle/ty/outlives.rs index ea092ed977eda..7752367febb19 100644 --- a/src/librustc/middle/ty/outlives.rs +++ b/src/librustc/middle/ty/outlives.rs @@ -53,12 +53,6 @@ pub enum Component<'tcx> { // them. This gives us room to improve the regionck reasoning in // the future without breaking backwards compat. EscapingProjection(Vec>), - - // This is a temporary marker indicating "outlives components" - // that are due to the new rules introduced by RFC 1214. For the - // time being, violations of these requirements generally induce - // warnings, not errors. - RFC1214(Vec>), } /// Returns all the things that must outlive `'a` for the condition @@ -124,20 +118,6 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, } } - // Bare functions and traits are both binders. In the RFC, - // this means we would add the bound regions to the "bound - // regions list". In our representation, no such list is - // maintained explicitly, because bound regions themselves can - // be readily identified. However, because the outlives - // relation did not used to be applied to fn/trait-object - // arguments, we wrap the resulting components in an RFC1214 - // wrapper so we can issue warnings. - ty::TyBareFn(..) | ty::TyTrait(..) => { - // OutlivesFunction, OutlivesObject, OutlivesFragment - let subcomponents = capture_components(infcx, ty); - out.push(Component::RFC1214(subcomponents)); - } - // OutlivesTypeParameterEnv -- the actual checking that `X:'a` // is implied by the environment is done in regionck. ty::TyParam(p) => { @@ -202,7 +182,15 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>, ty::TyRawPtr(..) | // ... ty::TyRef(..) | // OutlivesReference ty::TyTuple(..) | // ... + ty::TyBareFn(..) | // OutlivesFunction (*) + ty::TyTrait(..) | // OutlivesObject, OutlivesFragment (*) ty::TyError => { + // (*) Bare functions and traits are both binders. In the + // RFC, this means we would add the bound regions to the + // "bound regions list". In our representation, no such + // list is maintained explicitly, because bound regions + // themselves can be readily identified. + push_region_constraints(out, ty.regions()); for subty in ty.walk_shallow() { compute_components(infcx, subty, out); diff --git a/src/librustc/middle/ty/wf.rs b/src/librustc/middle/ty/wf.rs index 20534f72666db..d015711fa64db 100644 --- a/src/librustc/middle/ty/wf.rs +++ b/src/librustc/middle/ty/wf.rs @@ -15,8 +15,6 @@ use middle::subst::Substs; use middle::traits; use middle::ty::{self, RegionEscape, ToPredicate, Ty}; use std::iter::once; -use std::mem; -use std::rc::Rc; use syntax::ast; use syntax::codemap::Span; use util::common::ErrorReported; @@ -30,15 +28,13 @@ use util::common::ErrorReported; pub fn obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>, body_id: ast::NodeId, ty: Ty<'tcx>, - span: Span, - rfc1214: bool) + span: Span) -> Option>> { let mut wf = WfPredicates { infcx: infcx, body_id: body_id, span: span, - out: vec![], - rfc1214: rfc1214 }; + out: vec![] }; if wf.compute(ty) { debug!("wf::obligations({:?}, body_id={:?}) = {:?}", ty, body_id, wf.out); let result = wf.normalize(); @@ -56,12 +52,10 @@ pub fn obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>, pub fn trait_obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>, body_id: ast::NodeId, trait_ref: &ty::TraitRef<'tcx>, - span: Span, - rfc1214: bool) + span: Span) -> Vec> { - let mut wf = WfPredicates { infcx: infcx, body_id: body_id, span: span, - out: vec![], rfc1214: rfc1214 }; + let mut wf = WfPredicates { infcx: infcx, body_id: body_id, span: span, out: vec![] }; wf.compute_trait_ref(trait_ref); wf.normalize() } @@ -69,12 +63,10 @@ pub fn trait_obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>, pub fn predicate_obligations<'a,'tcx>(infcx: &InferCtxt<'a, 'tcx>, body_id: ast::NodeId, predicate: &ty::Predicate<'tcx>, - span: Span, - rfc1214: bool) + span: Span) -> Vec> { - let mut wf = WfPredicates { infcx: infcx, body_id: body_id, span: span, - out: vec![], rfc1214: rfc1214 }; + let mut wf = WfPredicates { infcx: infcx, body_id: body_id, span: span, out: vec![] }; // (*) ok to skip binders, because wf code is prepared for it match *predicate { @@ -150,7 +142,7 @@ pub fn implied_bounds<'a,'tcx>( // than the ultimate set. (Note: normally there won't be // unresolved inference variables here anyway, but there might be // during typeck under some circumstances.) - let obligations = obligations(infcx, body_id, ty, span, false).unwrap_or(vec![]); + let obligations = obligations(infcx, body_id, ty, span).unwrap_or(vec![]); // From the full set of obligations, just filter down to the // region relationships. @@ -223,8 +215,6 @@ fn implied_bounds_from_components<'tcx>(sub_region: ty::Region, vec!(), Component::UnresolvedInferenceVariable(..) => vec!(), - Component::RFC1214(components) => - implied_bounds_from_components(sub_region, components), } }) .collect() @@ -235,24 +225,11 @@ struct WfPredicates<'a,'tcx:'a> { body_id: ast::NodeId, span: Span, out: Vec>, - rfc1214: bool } impl<'a,'tcx> WfPredicates<'a,'tcx> { - fn rfc1214) -> R>(&mut self, f: F) -> R { - let b = mem::replace(&mut self.rfc1214, true); - let r = f(self); - self.rfc1214 = b; - r - } - fn cause(&mut self, code: traits::ObligationCauseCode<'tcx>) -> traits::ObligationCause<'tcx> { - if !self.rfc1214 { - traits::ObligationCause::new(self.span, self.body_id, code) - } else { - let code = traits::ObligationCauseCode::RFC1214(Rc::new(code)); - traits::ObligationCause::new(self.span, self.body_id, code) - } + traits::ObligationCause::new(self.span, self.body_id, code) } fn normalize(&mut self) -> Vec> { @@ -268,14 +245,6 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> { .collect() } - fn compute_rfc1214(&mut self, ty: Ty<'tcx>) { - let b = mem::replace(&mut self.rfc1214, true); - for subty in ty.walk().skip(1) { - self.compute(subty); - } - self.rfc1214 = b; - } - /// Pushes the obligations required for `trait_ref` to be WF into /// `self.out`. fn compute_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) { @@ -329,21 +298,19 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> { ty::TySlice(subty) | ty::TyArray(subty, _) => { - self.rfc1214(|this| { - if !subty.has_escaping_regions() { - let cause = this.cause(traits::SliceOrArrayElem); - match traits::trait_ref_for_builtin_bound(this.infcx.tcx, - ty::BoundSized, - subty) { - Ok(trait_ref) => { - this.out.push( - traits::Obligation::new(cause, - trait_ref.to_predicate())); - } - Err(ErrorReported) => { } + if !subty.has_escaping_regions() { + let cause = self.cause(traits::SliceOrArrayElem); + match traits::trait_ref_for_builtin_bound(self.infcx.tcx, + ty::BoundSized, + subty) { + Ok(trait_ref) => { + self.out.push( + traits::Obligation::new(cause, + trait_ref.to_predicate())); } + Err(ErrorReported) => { } } - }) + } } ty::TyBox(_) | @@ -380,15 +347,16 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> { ty::TyClosure(..) => { // the types in a closure are always the types of // local variables (or possibly references to local - // variables), which are separately checked w/r/t - // WFedness. + // variables), we'll walk those. + // + // (Though, local variables are probably not + // needed, as they are separately checked w/r/t + // WFedness.) } ty::TyBareFn(..) => { - // process the bound types; because the old implicator - // did not do this, go into RFC1214 mode. - subtys.skip_current_subtree(); - self.compute_rfc1214(ty); + // let the loop iterator into the argument/return + // types appearing in the fn signature } ty::TyTrait(ref data) => { @@ -407,11 +375,6 @@ impl<'a,'tcx> WfPredicates<'a,'tcx> { traits::Obligation::new( cause, ty::Predicate::ObjectSafe(data.principal_def_id()))); - - // process the bound types; because the old implicator - // did not do this, go into RFC1214 mode. - subtys.skip_current_subtree(); - self.compute_rfc1214(ty); } // Inference variables are the complicated case, since we don't diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index b7bfc2f8db53e..9d285fb890e38 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -117,13 +117,6 @@ impl Session { None => self.diagnostic().span_err(sp, msg) } } - pub fn note_rfc_1214(&self, span: Span) { - self.span_note( - span, - &format!("this warning results from recent bug fixes and clarifications; \ - it will become a HARD ERROR in the next release. \ - See RFC 1214 for details.")); - } pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) { if self.opts.treat_err_as_bug { self.span_bug(sp, msg); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index feea38acdc7ef..98ae3071b87d2 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1136,7 +1136,7 @@ fn make_object_type<'tcx>(this: &AstConv<'tcx>, traits::astconv_object_safety_violations(tcx, principal.def_id()); if !object_safety_violations.is_empty() { traits::report_object_safety_error( - tcx, span, principal.def_id(), object_safety_violations, false); + tcx, span, principal.def_id(), object_safety_violations); return tcx.types.err; } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 9f453362d24bd..9491b9946575c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -139,7 +139,6 @@ pub mod coercion; pub mod demand; pub mod method; mod upvar; -mod wf; mod wfcheck; mod cast; mod closure; @@ -383,21 +382,6 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { } } -pub fn check_wf_old(ccx: &CrateCtxt) { - // If types are not well-formed, it leads to all manner of errors - // downstream, so stop reporting errors at this point. - ccx.tcx.sess.abort_if_new_errors(|| { - // FIXME(#25759). The new code below is much more reliable but (for now) - // only generates warnings. So as to ensure that we continue - // getting errors where we used to get errors, we run the old wf - // code first and abort if it encounters any errors. If no abort - // comes, we run the new code and issue warnings. - let krate = ccx.tcx.map.krate(); - let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx); - krate.visit_all_items(&mut visit); - }); -} - pub fn check_wf_new(ccx: &CrateCtxt) { ccx.tcx.sess.abort_if_new_errors(|| { let krate = ccx.tcx.map.krate(); diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 8777e38bb71d8..759d561a961b7 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -99,7 +99,6 @@ use middle::ty::adjustment; use middle::ty::wf::ImpliedBound; use std::mem; -use std::rc::Rc; use syntax::ast; use syntax::codemap::Span; use rustc_front::intravisit::{self, Visitor}; @@ -426,8 +425,6 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> { code: &traits::ObligationCauseCode<'tcx>) -> SubregionOrigin<'tcx> { match *code { - traits::ObligationCauseCode::RFC1214(ref code) => - infer::RFC1214Subregion(Rc::new(self.code_to_origin(span, sup_type, code))), traits::ObligationCauseCode::ReferenceOutlivesReferent(ref_type) => infer::ReferenceOutlivesReferent(ref_type, span), _ => @@ -1606,10 +1603,6 @@ fn components_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, origin.span(), &format!("unresolved inference variable in outlives: {:?}", v)); } - ty::outlives::Component::RFC1214(subcomponents) => { - let suborigin = infer::RFC1214Subregion(Rc::new(origin)); - components_must_outlive(rcx, suborigin, subcomponents, region); - } } } } diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs deleted file mode 100644 index ee2845c824e3b..0000000000000 --- a/src/librustc_typeck/check/wf.rs +++ /dev/null @@ -1,673 +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. - -use astconv::AstConv; -use check::{FnCtxt, Inherited, blank_fn_ctxt, regionck, wfcheck}; -use constrained_type_params::{identify_constrained_type_params, Parameter}; -use CrateCtxt; -use middle::region; -use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace}; -use middle::traits; -use middle::ty::{self, Ty}; -use middle::ty::fold::{TypeFolder, TypeFoldable, super_fold_ty}; - -use std::cell::RefCell; -use std::collections::HashSet; -use syntax::ast; -use syntax::codemap::{DUMMY_SP, Span}; -use syntax::parse::token::special_idents; - -use rustc_front::intravisit::{self, Visitor, FnKind}; -use rustc_front::hir; - -pub struct CheckTypeWellFormedVisitor<'ccx, 'tcx:'ccx> { - ccx: &'ccx CrateCtxt<'ccx, 'tcx>, - cache: HashSet> -} - -impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { - pub fn new(ccx: &'ccx CrateCtxt<'ccx, 'tcx>) -> CheckTypeWellFormedVisitor<'ccx, 'tcx> { - CheckTypeWellFormedVisitor { ccx: ccx, cache: HashSet::new() } - } - - fn tcx(&self) -> &ty::ctxt<'tcx> { - self.ccx.tcx - } - - /// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are - /// well-formed, meaning that they do not require any constraints not declared in the struct - /// definition itself. For example, this definition would be illegal: - /// - /// struct Ref<'a, T> { x: &'a T } - /// - /// because the type did not declare that `T:'a`. - /// - /// We do this check as a pre-pass before checking fn bodies because if these constraints are - /// not included it frequently leads to confusing errors in fn bodies. So it's better to check - /// the types first. - fn check_item_well_formed(&mut self, item: &hir::Item) { - let ccx = self.ccx; - debug!("check_item_well_formed(it.id={}, it.name={})", - item.id, - ccx.tcx.item_path_str(ccx.tcx.map.local_def_id(item.id))); - - match item.node { - /// Right now we check that every default trait implementation - /// has an implementation of itself. Basically, a case like: - /// - /// `impl Trait for T {}` - /// - /// has a requirement of `T: Trait` which was required for default - /// method implementations. Although this could be improved now that - /// there's a better infrastructure in place for this, it's being left - /// for a follow-up work. - /// - /// Since there's such a requirement, we need to check *just* positive - /// implementations, otherwise things like: - /// - /// impl !Send for T {} - /// - /// won't be allowed unless there's an *explicit* implementation of `Send` - /// for `T` - hir::ItemImpl(_, hir::ImplPolarity::Positive, _, _, _, _) => { - self.check_impl(item); - } - hir::ItemImpl(_, hir::ImplPolarity::Negative, _, Some(_), _, _) => { - let item_def_id = ccx.tcx.map.local_def_id(item.id); - let trait_ref = ccx.tcx.impl_trait_ref(item_def_id).unwrap(); - ccx.tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id); - match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) { - Some(ty::BoundSend) | Some(ty::BoundSync) => {} - Some(_) | None => { - if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) { - wfcheck::error_192(ccx, item.span); - } - } - } - } - hir::ItemFn(..) => { - self.check_item_type(item); - } - hir::ItemStatic(..) => { - self.check_item_type(item); - } - hir::ItemConst(..) => { - self.check_item_type(item); - } - hir::ItemStruct(ref struct_def, ref ast_generics) => { - self.check_type_defn(item, |fcx| { - vec![struct_variant(fcx, struct_def)] - }); - - self.check_variances_for_type_defn(item, ast_generics); - } - hir::ItemEnum(ref enum_def, ref ast_generics) => { - self.check_type_defn(item, |fcx| { - enum_variants(fcx, enum_def) - }); - - self.check_variances_for_type_defn(item, ast_generics); - } - hir::ItemTrait(_, _, _, ref items) => { - let trait_predicates = - ccx.tcx.lookup_predicates(ccx.tcx.map.local_def_id(item.id)); - reject_non_type_param_bounds(ccx.tcx, item.span, &trait_predicates); - if ccx.tcx.trait_has_default_impl(ccx.tcx.map.local_def_id(item.id)) { - if !items.is_empty() { - wfcheck::error_380(ccx, item.span); - } - } - } - _ => {} - } - } - - fn with_fcx(&mut self, item: &hir::Item, mut f: F) where - F: for<'fcx> FnMut(&mut CheckTypeWellFormedVisitor<'ccx, 'tcx>, &FnCtxt<'fcx, 'tcx>), - { - let ccx = self.ccx; - let item_def_id = ccx.tcx.map.local_def_id(item.id); - let type_scheme = ccx.tcx.lookup_item_type(item_def_id); - let type_predicates = ccx.tcx.lookup_predicates(item_def_id); - reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates); - let free_id_outlive = ccx.tcx.region_maps.item_extent(item.id); - let param_env = ccx.tcx.construct_parameter_environment(item.span, - &type_scheme.generics, - &type_predicates, - free_id_outlive); - let tables = RefCell::new(ty::Tables::empty()); - let inh = Inherited::new(ccx.tcx, &tables, param_env); - let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id); - f(self, &fcx); - fcx.select_all_obligations_or_error(); - regionck::regionck_item(&fcx, item.id, item.span, &[]); - } - - /// In a type definition, we check that to ensure that the types of the fields are well-formed. - fn check_type_defn(&mut self, item: &hir::Item, mut lookup_fields: F) where - F: for<'fcx> FnMut(&FnCtxt<'fcx, 'tcx>) -> Vec>, - { - self.with_fcx(item, |this, fcx| { - let variants = lookup_fields(fcx); - let mut bounds_checker = BoundsChecker::new(fcx, - item.id, - Some(&mut this.cache)); - debug!("check_type_defn at bounds_checker.scope: {:?}", bounds_checker.scope); - - for variant in &variants { - for field in &variant.fields { - // Regions are checked below. - bounds_checker.check_traits_in_ty(field.ty, field.span); - } - - // For DST, all intermediate types must be sized. - if let Some((_, fields)) = variant.fields.split_last() { - for field in fields { - fcx.register_builtin_bound( - field.ty, - ty::BoundSized, - traits::ObligationCause::new(field.span, - fcx.body_id, - traits::FieldSized)); - } - } - } - - for field in variants.iter().flat_map(|v| v.fields.iter()) { - fcx.register_old_wf_obligation(field.ty, field.span, traits::MiscObligation); - } - }); - } - - fn check_item_type(&mut self, - item: &hir::Item) - { - self.with_fcx(item, |this, fcx| { - let mut bounds_checker = BoundsChecker::new(fcx, - item.id, - Some(&mut this.cache)); - debug!("check_item_type at bounds_checker.scope: {:?}", bounds_checker.scope); - - let item_def_id = fcx.tcx().map.local_def_id(item.id); - let type_scheme = fcx.tcx().lookup_item_type(item_def_id); - let item_ty = fcx.instantiate_type_scheme(item.span, - &fcx.inh - .infcx - .parameter_environment - .free_substs, - &type_scheme.ty); - - bounds_checker.check_traits_in_ty(item_ty, item.span); - }); - } - - fn check_impl(&mut self, - item: &hir::Item) - { - self.with_fcx(item, |this, fcx| { - let mut bounds_checker = BoundsChecker::new(fcx, - item.id, - Some(&mut this.cache)); - debug!("check_impl at bounds_checker.scope: {:?}", bounds_checker.scope); - - // Find the impl self type as seen from the "inside" -- - // that is, with all type parameters converted from bound - // to free. - let self_ty = fcx.tcx().node_id_to_type(item.id); - let self_ty = fcx.instantiate_type_scheme(item.span, - &fcx.inh - .infcx - .parameter_environment - .free_substs, - &self_ty); - - bounds_checker.check_traits_in_ty(self_ty, item.span); - - // Similarly, obtain an "inside" reference to the trait - // that the impl implements. - let trait_ref = match fcx.tcx().impl_trait_ref(fcx.tcx().map.local_def_id(item.id)) { - None => { return; } - Some(t) => { t } - }; - - let trait_ref = fcx.instantiate_type_scheme(item.span, - &fcx.inh - .infcx - .parameter_environment - .free_substs, - &trait_ref); - - // We are stricter on the trait-ref in an impl than the - // self-type. In particular, we enforce region - // relationships. The reason for this is that (at least - // presently) "applying" an impl does not require that the - // application site check the well-formedness constraints on the - // trait reference. Instead, this is done at the impl site. - // Arguably this is wrong and we should treat the trait-reference - // the same way as we treat the self-type. - bounds_checker.check_trait_ref(&trait_ref, item.span); - - let cause = - traits::ObligationCause::new( - item.span, - fcx.body_id, - traits::ItemObligation(trait_ref.def_id)); - - // Find the supertrait bounds. This will add `int:Bar`. - let poly_trait_ref = ty::Binder(trait_ref); - let predicates = fcx.tcx().lookup_super_predicates(poly_trait_ref.def_id()); - let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref); - let predicates = { - let selcx = &mut traits::SelectionContext::new(fcx.infcx()); - traits::normalize(selcx, cause.clone(), &predicates) - }; - for predicate in predicates.value.predicates { - fcx.register_predicate(traits::Obligation::new(cause.clone(), predicate)); - } - for obligation in predicates.obligations { - fcx.register_predicate(obligation); - } - }); - } - - fn check_variances_for_type_defn(&self, - item: &hir::Item, - ast_generics: &hir::Generics) - { - let item_def_id = self.tcx().map.local_def_id(item.id); - let ty_predicates = self.tcx().lookup_predicates(item_def_id); - let variances = self.tcx().item_variances(item_def_id); - - let mut constrained_parameters: HashSet<_> = - variances.types - .iter_enumerated() - .filter(|&(_, _, &variance)| variance != ty::Bivariant) - .map(|(space, index, _)| self.param_ty(ast_generics, space, index)) - .map(|p| Parameter::Type(p)) - .collect(); - - identify_constrained_type_params(self.tcx(), - ty_predicates.predicates.as_slice(), - None, - &mut constrained_parameters); - - for (space, index, _) in variances.types.iter_enumerated() { - let param_ty = self.param_ty(ast_generics, space, index); - if constrained_parameters.contains(&Parameter::Type(param_ty)) { - continue; - } - let span = self.ty_param_span(ast_generics, item, space, index); - self.report_bivariance(span, param_ty.name); - } - - for (space, index, &variance) in variances.regions.iter_enumerated() { - if variance != ty::Bivariant { - continue; - } - - assert_eq!(space, TypeSpace); - let span = ast_generics.lifetimes[index].lifetime.span; - let name = ast_generics.lifetimes[index].lifetime.name; - self.report_bivariance(span, name); - } - } - - fn param_ty(&self, - ast_generics: &hir::Generics, - space: ParamSpace, - index: usize) - -> ty::ParamTy - { - let name = match space { - TypeSpace => ast_generics.ty_params[index].name, - SelfSpace => special_idents::type_self.name, - FnSpace => self.tcx().sess.bug("Fn space occupied?"), - }; - - ty::ParamTy { space: space, idx: index as u32, name: name } - } - - fn ty_param_span(&self, - ast_generics: &hir::Generics, - item: &hir::Item, - space: ParamSpace, - index: usize) - -> Span - { - match space { - TypeSpace => ast_generics.ty_params[index].span, - SelfSpace => item.span, - FnSpace => self.tcx().sess.span_bug(item.span, "Fn space occupied?"), - } - } - - fn report_bivariance(&self, - span: Span, - param_name: ast::Name) - { - wfcheck::error_392(self.tcx(), span, param_name); - - let suggested_marker_id = self.tcx().lang_items.phantom_data(); - match suggested_marker_id { - Some(def_id) => { - self.tcx().sess.fileline_help( - span, - &format!("consider removing `{}` or using a marker such as `{}`", - param_name, - self.tcx().item_path_str(def_id))); - } - None => { - // no lang items, no help! - } - } - } -} - -// Reject any predicates that do not involve a type parameter. -fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>, - span: Span, - predicates: &ty::GenericPredicates<'tcx>) { - for predicate in &predicates.predicates { - match predicate { - &ty::Predicate::Trait(ty::Binder(ref tr)) => { - let found_param = tr.input_types().iter() - .flat_map(|ty| ty.walk()) - .any(is_ty_param); - if !found_param { report_bound_error(tcx, span, tr.self_ty() )} - } - &ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(ty, _))) => { - let found_param = ty.walk().any(|t| is_ty_param(t)); - if !found_param { report_bound_error(tcx, span, ty) } - } - _ => {} - }; - } - - fn report_bound_error<'t>(tcx: &ty::ctxt<'t>, - span: Span, - bounded_ty: ty::Ty<'t>) { - span_err!(tcx.sess, span, E0193, - "cannot bound type `{}`, where clause \ - bounds may only be attached to types involving \ - type parameters", - bounded_ty) - } - - fn is_ty_param(ty: ty::Ty) -> bool { - match &ty.sty { - &ty::TyParam(_) => true, - _ => false - } - } -} - -fn reject_shadowing_type_parameters<'tcx>(tcx: &ty::ctxt<'tcx>, - span: Span, - generics: &ty::Generics<'tcx>) { - let impl_params = generics.types.get_slice(subst::TypeSpace).iter() - .map(|tp| tp.name).collect::>(); - - for method_param in generics.types.get_slice(subst::FnSpace) { - if impl_params.contains(&method_param.name) { - wfcheck::error_194(tcx, span, method_param.name); - } - } -} - -impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> { - fn visit_item(&mut self, i: &hir::Item) { - self.check_item_well_formed(i); - intravisit::walk_item(self, i); - } - - fn visit_fn(&mut self, - fk: FnKind<'v>, fd: &'v hir::FnDecl, - b: &'v hir::Block, span: Span, id: ast::NodeId) { - match fk { - FnKind::Closure | FnKind::ItemFn(..) => {} - FnKind::Method(..) => { - match self.tcx().impl_or_trait_item(self.tcx().map.local_def_id(id)) { - ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { - reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics) - } - _ => {} - } - } - } - intravisit::walk_fn(self, fk, fd, b, span) - } - - fn visit_trait_item(&mut self, trait_item: &'v hir::TraitItem) { - if let hir::MethodTraitItem(_, None) = trait_item.node { - match self.tcx().impl_or_trait_item(self.tcx().map.local_def_id(trait_item.id)) { - ty::ImplOrTraitItem::MethodTraitItem(ty_method) => { - reject_non_type_param_bounds( - self.tcx(), - trait_item.span, - &ty_method.predicates); - reject_shadowing_type_parameters( - self.tcx(), - trait_item.span, - &ty_method.generics); - } - _ => {} - } - } - - intravisit::walk_trait_item(self, trait_item) - } -} - -pub struct BoundsChecker<'cx,'tcx:'cx> { - fcx: &'cx FnCtxt<'cx,'tcx>, - span: Span, - - scope: region::CodeExtent, - - binding_count: usize, - cache: Option<&'cx mut HashSet>>, -} - -impl<'cx,'tcx> BoundsChecker<'cx,'tcx> { - pub fn new(fcx: &'cx FnCtxt<'cx,'tcx>, - scope: ast::NodeId, - cache: Option<&'cx mut HashSet>>) - -> BoundsChecker<'cx,'tcx> { - let scope = fcx.tcx().region_maps.item_extent(scope); - BoundsChecker { fcx: fcx, span: DUMMY_SP, scope: scope, - cache: cache, binding_count: 0 } - } - - /// Given a trait ref like `A : Trait`, where `Trait` is defined as (say): - /// - /// trait Trait : Copy { ... } - /// - /// This routine will check that `B : OtherTrait` and `A : Trait`. It will also recursively - /// check that the types `A` and `B` are well-formed. - /// - /// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated - /// to the point where impl `A : Trait` is implemented). - pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, span: Span) { - let trait_predicates = self.fcx.tcx().lookup_predicates(trait_ref.def_id); - - let bounds = self.fcx.instantiate_bounds(span, - trait_ref.substs, - &trait_predicates); - - self.fcx.add_obligations_for_parameters( - traits::ObligationCause::new( - span, - self.fcx.body_id, - traits::ItemObligation(trait_ref.def_id)), - &bounds); - - for &ty in &trait_ref.substs.types { - self.check_traits_in_ty(ty, span); - } - } - - fn check_traits_in_ty(&mut self, ty: Ty<'tcx>, span: Span) { - self.span = span; - // When checking types outside of a type def'n, we ignore - // region obligations. See discussion below in fold_ty(). - self.binding_count += 1; - ty.fold_with(self); - self.binding_count -= 1; - } -} - -impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> { - fn tcx(&self) -> &ty::ctxt<'tcx> { - self.fcx.tcx() - } - - fn fold_binder(&mut self, binder: &ty::Binder) -> ty::Binder - where T : TypeFoldable<'tcx> - { - self.binding_count += 1; - let value = self.fcx.tcx().liberate_late_bound_regions( - self.scope, - binder); - debug!("BoundsChecker::fold_binder: late-bound regions replaced: {:?} at scope: {:?}", - value, self.scope); - let value = value.fold_with(self); - self.binding_count -= 1; - ty::Binder(value) - } - - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - debug!("BoundsChecker t={:?}", - t); - - match self.cache { - Some(ref mut cache) => { - if !cache.insert(t) { - // Already checked this type! Don't check again. - debug!("cached"); - return t; - } - } - None => { } - } - - match t.sty{ - ty::TyStruct(def, substs) | - ty::TyEnum(def, substs) => { - let type_predicates = def.predicates(self.fcx.tcx()); - let bounds = self.fcx.instantiate_bounds(self.span, substs, - &type_predicates); - - if self.binding_count == 0 { - self.fcx.add_obligations_for_parameters( - traits::ObligationCause::new(self.span, - self.fcx.body_id, - traits::ItemObligation(def.did)), - &bounds); - } else { - // There are two circumstances in which we ignore - // region obligations. - // - // The first is when we are inside of a closure - // type. This is because in that case the region - // obligations for the parameter types are things - // that the closure body gets to assume and the - // caller must prove at the time of call. In other - // words, if there is a type like `<'a, 'b> | &'a - // &'b int |`, it is well-formed, and caller will - // have to show that `'b : 'a` at the time of - // call. - // - // The second is when we are checking for - // well-formedness outside of a type def'n or fn - // body. This is for a similar reason: in general, - // we only do WF checking for regions in the - // result of expressions and type definitions, so - // to as allow for implicit where clauses. - // - // (I believe we should do the same for traits, but - // that will require an RFC. -nmatsakis) - let bounds = filter_to_trait_obligations(bounds); - self.fcx.add_obligations_for_parameters( - traits::ObligationCause::new(self.span, - self.fcx.body_id, - traits::ItemObligation(def.did)), - &bounds); - } - - self.fold_substs(substs); - } - _ => { - super_fold_ty(self, t); - } - } - - t // we're not folding to produce a new type, so just return `t` here - } -} - -/////////////////////////////////////////////////////////////////////////// -// ADT - -struct AdtVariant<'tcx> { - fields: Vec>, -} - -struct AdtField<'tcx> { - ty: Ty<'tcx>, - span: Span, -} - -fn struct_variant<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, - struct_def: &hir::VariantData) - -> AdtVariant<'tcx> { - let fields = - struct_def.fields().iter() - .map(|field| { - let field_ty = fcx.tcx().node_id_to_type(field.node.id); - let field_ty = fcx.instantiate_type_scheme(field.span, - &fcx.inh - .infcx - .parameter_environment - .free_substs, - &field_ty); - AdtField { ty: field_ty, span: field.span } - }) - .collect(); - AdtVariant { fields: fields } -} - -fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, - enum_def: &hir::EnumDef) - -> Vec> { - enum_def.variants.iter() - .map(|variant| struct_variant(fcx, &variant.node.data)) - .collect() -} - -fn filter_to_trait_obligations<'tcx>(bounds: ty::InstantiatedPredicates<'tcx>) - -> ty::InstantiatedPredicates<'tcx> -{ - let mut result = ty::InstantiatedPredicates::empty(); - for (space, _, predicate) in bounds.predicates.iter_enumerated() { - match *predicate { - ty::Predicate::Trait(..) | - ty::Predicate::Projection(..) => { - result.predicates.push(space, predicate.clone()) - } - ty::Predicate::WellFormed(..) | - ty::Predicate::ObjectSafe(..) | - ty::Predicate::Equate(..) | - ty::Predicate::TypeOutlives(..) | - ty::Predicate::RegionOutlives(..) => { - } - } - } - result -} diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index ffe55c9b29b99..5d0e713012f2a 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -21,7 +21,6 @@ use middle::ty::fold::{TypeFolder}; use std::cell::RefCell; use std::collections::HashSet; -use std::rc::Rc; use syntax::ast; use syntax::codemap::{Span}; use syntax::parse::token::{special_idents}; @@ -38,8 +37,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { -> CheckTypeWellFormedVisitor<'ccx, 'tcx> { CheckTypeWellFormedVisitor { ccx: ccx, - code: traits::ObligationCauseCode::RFC1214( - Rc::new(traits::ObligationCauseCode::MiscObligation)) + code: traits::ObligationCauseCode::MiscObligation } } @@ -311,8 +309,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { ty::wf::trait_obligations(fcx.infcx(), fcx.body_id, &trait_ref, - ast_trait_ref.path.span, - true); + ast_trait_ref.path.span); for obligation in obligations { fcx.register_predicate(obligation); } @@ -343,8 +340,7 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> { .flat_map(|p| ty::wf::predicate_obligations(fcx.infcx(), fcx.body_id, p, - span, - true)); + span)); for obligation in obligations { fcx.register_predicate(obligation); diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 5cbe142ab1992..7d1f71967a2d5 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -190,7 +190,7 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { None => { } } } - hir::ItemImpl(_, _, _, Some(_), ref self_ty, _) => { + hir::ItemImpl(_, _, _, Some(_), _, _) => { let impl_def_id = self.tcx.map.local_def_id(item.id); let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); let trait_def_id = trait_ref.def_id; @@ -200,16 +200,10 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> { // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe. if !traits::is_object_safe(self.tcx, data.principal_def_id()) { - // FIXME(#27579). This just means the - // self-ty is illegal; WF will report this - // error. But it will do so as a warning - // for a release or two. For backwards - // compat reasons, then, we continue to - // report it here so that things which - // were errors remain errors. - span_err!(self.tcx.sess, self_ty.span, E0372, - "the trait `{}` cannot be made into an object", - self.tcx.item_path_str(data.principal_def_id())); + // This is an error, but it will be + // reported by wfcheck. Ignore it + // here. This is tested by + // `coherence-impl-trait-for-trait-object-safe.rs`. } else { let mut supertrait_def_ids = traits::supertrait_def_ids(self.tcx, data.principal_def_id()); diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 8c15892b7e119..e64fb6437a964 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -3114,14 +3114,6 @@ impl Baz for Bar { } // Note: This is OK ``` "##, -E0372: r##" -Trying to implement a trait for a trait object (as in `impl Trait1 for -Trait2 { ... }`) does not work if the trait is not object-safe. Please see the -[RFC 255] for more details on object safety rules. - -[RFC 255]: https://github.com/rust-lang/rfcs/pull/255 -"##, - E0379: r##" Trait methods cannot be declared `const` by design. For more information, see [RFC 911]. @@ -3486,6 +3478,7 @@ register_diagnostics! { // E0319, // trait impls for defaulted traits allowed just for structs/enums E0320, // recursive overflow during dropck E0328, // cannot implement Unsize explicitly +// E0372, // coherence not object safe E0374, // the trait `CoerceUnsized` may only be implemented for a coercion // between structures with one field being coerced, none found E0375, // the trait `CoerceUnsized` may only be implemented for a coercion diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index da246eff7da02..c0ede6370f1b1 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -346,8 +346,8 @@ pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) { coherence::check_coherence(&ccx)); }); - time(time_passes, "wf checking (old)", || - check::check_wf_old(&ccx)); + time(time_passes, "wf checking", || + check::check_wf_new(&ccx)); time(time_passes, "item-types checking", || check::check_item_types(&ccx)); @@ -358,11 +358,6 @@ pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) { time(time_passes, "drop-impl checking", || check::check_drop_impls(&ccx)); - // Do this last so that if there are errors in the old code, they - // get reported, and we don't get extra warnings. - time(time_passes, "wf checking (new)", || - check::check_wf_new(&ccx)); - check_for_entry_fn(&ccx); tcx.sess.abort_if_errors(); } diff --git a/src/test/auxiliary/associated-types-cc-lib.rs b/src/test/auxiliary/associated-types-cc-lib.rs index b3960c2707b4b..175e8730cbcd3 100644 --- a/src/test/auxiliary/associated-types-cc-lib.rs +++ b/src/test/auxiliary/associated-types-cc-lib.rs @@ -13,7 +13,7 @@ #![crate_type="lib"] -pub trait Bar { +pub trait Bar: Sized { type T; fn get(x: Option) -> ::T; diff --git a/src/test/auxiliary/static-methods-crate.rs b/src/test/auxiliary/static-methods-crate.rs index e61fb49add5b1..b8fd59bf7037d 100644 --- a/src/test/auxiliary/static-methods-crate.rs +++ b/src/test/auxiliary/static-methods-crate.rs @@ -11,7 +11,7 @@ #![crate_name="static_methods_crate"] #![crate_type = "lib"] -pub trait read { +pub trait read: Sized { fn readMaybe(s: String) -> Option; } diff --git a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs index 233532a608580..0b1d6a5b71ad2 100644 --- a/src/test/compile-fail/associated-types-no-suitable-supertrait.rs +++ b/src/test/compile-fail/associated-types-no-suitable-supertrait.rs @@ -25,10 +25,7 @@ trait Get { trait Other { fn uhoh(&self, foo: U, bar: ::Value) {} - // (note that we no longer catch the error here, since the - // error below aborts compilation. - // See also associated-types-no-suitable-supertrait-2.rs - // which checks that this error would be caught eventually.) + //~^ ERROR the trait `Get` is not implemented for the type `Self` } impl Other for T { diff --git a/src/test/compile-fail/builtin-superkinds-self-type.rs b/src/test/compile-fail/builtin-superkinds-self-type.rs index 037364c7a531c..3065ecfaa302d 100644 --- a/src/test/compile-fail/builtin-superkinds-self-type.rs +++ b/src/test/compile-fail/builtin-superkinds-self-type.rs @@ -13,7 +13,7 @@ use std::sync::mpsc::{channel, Sender}; -trait Foo : Sync+'static { +trait Foo : Sized+Sync+'static { fn foo(self, mut chan: Sender) { } } diff --git a/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs b/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs index b08e4bad1e9c9..8bb9556fcc075 100644 --- a/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs +++ b/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs @@ -13,9 +13,7 @@ // If the trait is not object-safe, we give a more tailored message // because we're such schnuckels: -trait NotObjectSafe { fn eq(&self, other: &Self); } -impl NotObjectSafe for NotObjectSafe { //~ ERROR E0372 - fn eq(&self, other: &Self) { panic!(); } -} +trait NotObjectSafe { fn eq(&self, other: Self); } +impl NotObjectSafe for NotObjectSafe { } //~ ERROR E0038 fn main() { } diff --git a/src/test/compile-fail/cross-fn-cache-hole.rs b/src/test/compile-fail/cross-fn-cache-hole.rs index 0aefd0ae28845..7d4c618de665c 100644 --- a/src/test/compile-fail/cross-fn-cache-hole.rs +++ b/src/test/compile-fail/cross-fn-cache-hole.rs @@ -21,14 +21,15 @@ trait Foo: Bar { trait Bar { } -fn vacuous() +// We don't always check where clauses for sanity, but in this case +// wfcheck does report an error here: +fn vacuous() //~ ERROR the trait `Bar` is not implemented for the type `i32` where i32: Foo { - // vacuous could never be called, because it requires that i32: - // Bar. But the code doesn't check that this could never be - // satisfied. + // ... the original intention was to check that we don't use that + // vacuous where clause (which could never be satisfied) to accept + // the following line and then mess up calls elsewhere. require::(); - //~^ ERROR the trait `Bar` is not implemented for the type `i32` } fn require() diff --git a/src/test/compile-fail/issue-13853-2.rs b/src/test/compile-fail/issue-13853-2.rs index ea0d880f4a1cc..1635a8f69a6cd 100644 --- a/src/test/compile-fail/issue-13853-2.rs +++ b/src/test/compile-fail/issue-13853-2.rs @@ -10,7 +10,7 @@ trait FromStructReader<'a> { } trait ResponseHook { - fn get<'a, T: FromStructReader<'a>>(&'a self); + fn get(&self); } fn foo(res : Box) { res.get } //~ ERROR attempted to take value of method fn main() {} diff --git a/src/test/compile-fail/issue-13853.rs b/src/test/compile-fail/issue-13853.rs index f5d158d64e19f..7643310298da3 100644 --- a/src/test/compile-fail/issue-13853.rs +++ b/src/test/compile-fail/issue-13853.rs @@ -13,11 +13,14 @@ trait Node { } trait Graph { - fn nodes<'a, I: Iterator>(&'a self) -> I; + fn nodes<'a, I: Iterator>(&'a self) -> I + where N: 'a; } impl Graph for Vec { - fn nodes<'a, I: Iterator>(&self) -> I { + fn nodes<'a, I: Iterator>(&self) -> I + where N: 'a + { self.iter() //~ ERROR mismatched types } } diff --git a/src/test/compile-fail/issue-14853.rs b/src/test/compile-fail/issue-14853.rs index 51deb99a4f2cd..c6c1a0fd17781 100644 --- a/src/test/compile-fail/issue-14853.rs +++ b/src/test/compile-fail/issue-14853.rs @@ -12,7 +12,7 @@ use std::fmt::Debug; trait Str {} -trait Something { +trait Something: Sized { fn yay(_: Option, thing: &[T]); } diff --git a/src/test/compile-fail/issue-18959.rs b/src/test/compile-fail/issue-18959.rs index 5f6216a898a0b..7a6d012a3b605 100644 --- a/src/test/compile-fail/issue-18959.rs +++ b/src/test/compile-fail/issue-18959.rs @@ -19,14 +19,12 @@ impl Foo for Thing { #[inline(never)] fn foo(b: &Bar) { + //~^ ERROR E0038 b.foo(&0) - //~^ ERROR the trait `Foo` is not implemented for the type `Bar` - //~| ERROR E0038 - //~| WARNING E0038 } fn main() { let mut thing = Thing; - let test: &Bar = &mut thing; //~ ERROR E0038 + let test: &Bar = &mut thing; foo(test); } diff --git a/src/test/compile-fail/issue-19380.rs b/src/test/compile-fail/issue-19380.rs index aae77c90b6bf2..322952ffef1e6 100644 --- a/src/test/compile-fail/issue-19380.rs +++ b/src/test/compile-fail/issue-19380.rs @@ -19,10 +19,10 @@ impl Qiz for Foo { struct Bar { foos: &'static [&'static (Qiz + 'static)] +//~^ ERROR E0038 } const FOO : Foo = Foo; const BAR : Bar = Bar { foos: &[&FOO]}; -//~^ ERROR E0038 fn main() { } diff --git a/src/test/compile-fail/issue-20005.rs b/src/test/compile-fail/issue-20005.rs index 041289c2ccdbd..aaf27ba527b18 100644 --- a/src/test/compile-fail/issue-20005.rs +++ b/src/test/compile-fail/issue-20005.rs @@ -15,13 +15,10 @@ trait From { } trait To { - fn to( - self //~ error: the trait `core::marker::Sized` is not implemented + fn to( //~ ERROR the trait `core::marker::Sized` is not implemented + self ) -> >::Result where Dst: From { - From::from( //~ error: the trait `core::marker::Sized` is not implemented - //~^ ERROR E0277 - self - ) + From::from(self) } } diff --git a/src/test/compile-fail/issue-20831-debruijn.rs b/src/test/compile-fail/issue-20831-debruijn.rs index a38278eae2411..3f96a9c342283 100644 --- a/src/test/compile-fail/issue-20831-debruijn.rs +++ b/src/test/compile-fail/issue-20831-debruijn.rs @@ -38,6 +38,8 @@ impl<'a> Publisher<'a> for MyStruct<'a> { fn subscribe(&mut self, t : Box::Output> + 'a>) { // Not obvious, but there is an implicit lifetime here -------^ //~^^ ERROR cannot infer + //~| ERROR cannot infer + //~| ERROR cannot infer // // The fact that `Publisher` is using an implicit lifetime is // what was causing the debruijn accounting to be off, so diff --git a/src/test/compile-fail/issue-21974.rs b/src/test/compile-fail/issue-21974.rs index f768d6c00ecdb..6ddfa4c8e3e57 100644 --- a/src/test/compile-fail/issue-21974.rs +++ b/src/test/compile-fail/issue-21974.rs @@ -17,11 +17,11 @@ trait Foo { fn foo(self); } -fn foo<'a,'b,T>(x: &'a T, y: &'b T) +fn foo<'a,'b,T>(x: &'a T, y: &'b T) //~ ERROR type annotations required where &'a T : Foo, &'b T : Foo { - x.foo(); //~ ERROR type annotations required + x.foo(); y.foo(); } diff --git a/src/test/compile-fail/issue-23041.rs b/src/test/compile-fail/issue-23041.rs index c08cdd72b3825..1a9bb4c29f3e0 100644 --- a/src/test/compile-fail/issue-23041.rs +++ b/src/test/compile-fail/issue-23041.rs @@ -13,5 +13,5 @@ fn main() { fn bar(x:i32) ->i32 { 3*x }; let b:Box = Box::new(bar as fn(_)->_); - b.downcast_ref::_>(); //~ ERROR E0101 + b.downcast_ref::_>(); //~ ERROR E0282 } diff --git a/src/test/compile-fail/issue-23305.rs b/src/test/compile-fail/issue-23305.rs index 68f053c357bed..4acb1f70d343c 100644 --- a/src/test/compile-fail/issue-23305.rs +++ b/src/test/compile-fail/issue-23305.rs @@ -13,6 +13,6 @@ pub trait ToNbt { } impl ToNbt {} //~ ERROR use of `Self` outside of an impl or trait -//~^ WARNING the trait `ToNbt` cannot be made into an object +//~^ ERROR the trait `ToNbt` cannot be made into an object fn main() {} diff --git a/src/test/compile-fail/issue-3907-2.rs b/src/test/compile-fail/issue-3907-2.rs index ee8bc7d6e2901..130647966f2d1 100644 --- a/src/test/compile-fail/issue-3907-2.rs +++ b/src/test/compile-fail/issue-3907-2.rs @@ -18,6 +18,6 @@ struct S { } fn bar(_x: Foo) {} -//~^ ERROR E0277 +//~^ ERROR E0038 fn main() {} diff --git a/src/test/compile-fail/object-safety-generics.rs b/src/test/compile-fail/object-safety-generics.rs index 63e5718537cf9..341736f7ab5ee 100644 --- a/src/test/compile-fail/object-safety-generics.rs +++ b/src/test/compile-fail/object-safety-generics.rs @@ -22,16 +22,13 @@ trait Quux { } fn make_bar(t: &T) -> &Bar { - t //~^ ERROR E0038 //~| NOTE method `bar` has generic type parameters + t } fn make_bar_explicit(t: &T) -> &Bar { t as &Bar - //~^ ERROR E0038 - //~| NOTE method `bar` has generic type parameters - //~| ERROR E0038 } fn make_quux(t: &T) -> &Quux { diff --git a/src/test/compile-fail/object-safety-mentions-Self.rs b/src/test/compile-fail/object-safety-mentions-Self.rs index 55b780906355a..edd31c1f79649 100644 --- a/src/test/compile-fail/object-safety-mentions-Self.rs +++ b/src/test/compile-fail/object-safety-mentions-Self.rs @@ -25,29 +25,15 @@ trait Quux { } fn make_bar(t: &T) -> &Bar { - t - //~^ ERROR E0038 - //~| NOTE method `bar` references the `Self` type in its arguments or return type -} - -fn make_bar_explicit(t: &T) -> &Bar { - t as &Bar //~^ ERROR E0038 //~| NOTE method `bar` references the `Self` type in its arguments or return type - //~| ERROR E0038 + loop { } } fn make_baz(t: &T) -> &Baz { - t //~^ ERROR E0038 //~| NOTE method `bar` references the `Self` type in its arguments or return type -} - -fn make_baz_explicit(t: &T) -> &Baz { - t as &Baz - //~^ ERROR E0038 - //~| NOTE method `bar` references the `Self` type in its arguments or return type - //~| ERROR E0038 + t } fn make_quux(t: &T) -> &Quux { diff --git a/src/test/compile-fail/object-safety-no-static.rs b/src/test/compile-fail/object-safety-no-static.rs index 2dc7983d1b561..dd1d5af3f4a12 100644 --- a/src/test/compile-fail/object-safety-no-static.rs +++ b/src/test/compile-fail/object-safety-no-static.rs @@ -16,16 +16,8 @@ trait Foo { } fn foo_implicit(b: Box) -> Box { - b - //~^ ERROR E0038 - //~| NOTE method `foo` has no receiver -} - -fn foo_explicit(b: Box) -> Box { - b as Box - //~^ ERROR E0038 - //~| NOTE method `foo` has no receiver - //~| ERROR E0038 + //~^ ERROR E0038 + loop { } } fn main() { diff --git a/src/test/compile-fail/object-safety-sized-2.rs b/src/test/compile-fail/object-safety-sized-2.rs index 401602bd681a3..3e1942d5a0188 100644 --- a/src/test/compile-fail/object-safety-sized-2.rs +++ b/src/test/compile-fail/object-safety-sized-2.rs @@ -18,16 +18,8 @@ trait Bar } fn make_bar(t: &T) -> &Bar { - t //~^ ERROR E0038 - //~| NOTE the trait cannot require that `Self : Sized` -} - -fn make_bar_explicit(t: &T) -> &Bar { - t as &Bar - //~^ ERROR E0038 - //~| NOTE the trait cannot require that `Self : Sized` - //~| ERROR E0038 + loop { } } fn main() { diff --git a/src/test/compile-fail/object-safety-sized.rs b/src/test/compile-fail/object-safety-sized.rs index 29b4e4db65c36..501d61d20fed1 100644 --- a/src/test/compile-fail/object-safety-sized.rs +++ b/src/test/compile-fail/object-safety-sized.rs @@ -16,16 +16,9 @@ trait Bar : Sized { } fn make_bar(t: &T) -> &Bar { - t - //~^ ERROR E0038 - //~| NOTE the trait cannot require that `Self : Sized` -} - -fn make_bar_explicit(t: &T) -> &Bar { - t as &Bar //~^ ERROR E0038 //~| NOTE the trait cannot require that `Self : Sized` - //~| ERROR E0038 + t } fn main() { diff --git a/src/test/compile-fail/regions-close-object-into-object-5.rs b/src/test/compile-fail/regions-close-object-into-object-5.rs index ac269a4d896f2..152c65cb69bf2 100644 --- a/src/test/compile-fail/regions-close-object-into-object-5.rs +++ b/src/test/compile-fail/regions-close-object-into-object-5.rs @@ -26,10 +26,10 @@ fn f<'a, T, U>(v: Box+'static>) -> Box { // oh dear! box B(&*v) as Box //~^ ERROR the parameter type `T` may not live long enough - //~| WARNING the parameter type `T` may not live long enough - //~| WARNING the parameter type `T` may not live long enough //~| ERROR the parameter type `T` may not live long enough - //~| WARNING the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough + //~| ERROR the parameter type `T` may not live long enough //~| ERROR the parameter type `T` may not live long enough //~| ERROR the parameter type `T` may not live long enough } diff --git a/src/test/compile-fail/regions-free-region-ordering-callee-4.rs b/src/test/compile-fail/regions-free-region-ordering-callee-4.rs new file mode 100644 index 0000000000000..bd31d1a5a90dc --- /dev/null +++ b/src/test/compile-fail/regions-free-region-ordering-callee-4.rs @@ -0,0 +1,21 @@ +// Copyright 2012 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. + +// Tests that callees correctly infer an ordering between free regions +// that appear in their parameter list. See also +// regions-free-region-ordering-caller.rs + +fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { + //~^ ERROR reference has a longer lifetime than the data it references + // Do not infer ordering from closure argument types. + let z: Option<&'a &'b usize> = None; +} + +fn main() {} diff --git a/src/test/compile-fail/regions-free-region-ordering-callee.rs b/src/test/compile-fail/regions-free-region-ordering-callee.rs index 22724081a1bce..1893395e2b007 100644 --- a/src/test/compile-fail/regions-free-region-ordering-callee.rs +++ b/src/test/compile-fail/regions-free-region-ordering-callee.rs @@ -30,11 +30,7 @@ fn ordering3<'a, 'b>(x: &'a usize, y: &'b usize) -> &'a &'b usize { panic!(); } -fn ordering4<'a, 'b, F>(a: &'a usize, b: &'b usize, x: F) where F: FnOnce(&'a &'b usize) { - // Do not infer ordering from closure argument types. - let z: Option<&'a &'b usize> = None; - //~^ ERROR reference has a longer lifetime than the data it references -} +// see regions-free-region-ordering-callee-4.rs fn ordering5<'a, 'b>(a: &'a usize, b: &'b usize, x: Option<&'a &'b usize>) { let z: Option<&'a &'b usize> = None; diff --git a/src/test/compile-fail/regions-implied-bounds-projection-gap-hr-1.rs b/src/test/compile-fail/regions-implied-bounds-projection-gap-hr-1.rs index 47985f931dd34..fd186d1655916 100644 --- a/src/test/compile-fail/regions-implied-bounds-projection-gap-hr-1.rs +++ b/src/test/compile-fail/regions-implied-bounds-projection-gap-hr-1.rs @@ -24,16 +24,13 @@ trait Trait2<'a, 'b> { type Foo; } -fn wf() { } - -// As a side-effect of the conservative process above, this argument -// is not automatically considered well-formed, since for it to be WF, -// we would need to know that `'y: 'x`, but we do not infer that. -fn callee<'x, 'y, T>( - t: &'x for<'z> Trait1< >::Foo >) -{ - wf::<&'x &'y i32>(); +// As a side-effect of the conservative process above, the type of +// this argument `t` is not automatically considered well-formed, +// since for it to be WF, we would need to know that `'y: 'x`, but we +// do not infer that. +fn callee<'x, 'y, T>(t: &'x for<'z> Trait1< >::Foo >) //~^ ERROR reference has a longer lifetime than the data it references +{ } fn main() { } diff --git a/src/test/compile-fail/regions-wf-trait-object.rs b/src/test/compile-fail/regions-wf-trait-object.rs index e1f1fdaeb341d..40b715cf3b14d 100644 --- a/src/test/compile-fail/regions-wf-trait-object.rs +++ b/src/test/compile-fail/regions-wf-trait-object.rs @@ -14,8 +14,7 @@ trait TheTrait<'t>: 't { } struct Foo<'a,'b> { - x: Box+'b> - //~^ ERROR reference has a longer lifetime + x: Box+'b> //~ ERROR E0478 } fn main() { } diff --git a/src/test/compile-fail/rfc1214-warn-and-error.rs b/src/test/compile-fail/rfc1214-warn-and-error.rs deleted file mode 100644 index 50fd3fc961c1d..0000000000000 --- a/src/test/compile-fail/rfc1214-warn-and-error.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 an RFC1214 warning from an earlier function (`foo`) does -// not suppress an error for the same problem (`WantEq`, -// `NotEq: !Eq`) in a later function (`bar)`. Earlier versions of the -// warning mechanism had an issue due to caching. - -#![allow(dead_code)] -#![allow(unused_variables)] - -struct WantEq { t: T } - -struct NotEq; - -trait Trait { } - -fn foo() { - let x: Box>> = loop { }; - //~^ WARN E0277 -} - -fn bar() { - wf::>(); - //~^ ERROR E0277 -} - -fn wf() { } - -fn main() { } diff --git a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs index beabdcea2bbe9..01910939a80eb 100644 --- a/src/test/compile-fail/trait-bounds-impl-comparison-2.rs +++ b/src/test/compile-fail/trait-bounds-impl-comparison-2.rs @@ -14,7 +14,7 @@ trait Iterator { fn next(&mut self) -> Option; } -trait IteratorUtil +trait IteratorUtil: Sized { fn zip>(self, other: U) -> ZipIterator; } diff --git a/src/test/compile-fail/trait-test-2.rs b/src/test/compile-fail/trait-test-2.rs index 73be7cf0dc032..2d4df77f96045 100644 --- a/src/test/compile-fail/trait-test-2.rs +++ b/src/test/compile-fail/trait-test-2.rs @@ -22,5 +22,4 @@ fn main() { //~^ ERROR E0038 //~| ERROR E0038 //~| ERROR E0277 - //~| WARNING E0038 } diff --git a/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs b/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs new file mode 100644 index 0000000000000..ad58ae92b46e2 --- /dev/null +++ b/src/test/compile-fail/typeck-default-trait-impl-trait-where-clause-2.rs @@ -0,0 +1,36 @@ +// 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. + +// ignore-tidy-linelength + +// Test that when a `..` impl applies, we also check that any +// supertrait conditions are met. + +#![feature(optin_builtin_traits)] + +trait NotImplemented { } + +trait MyTrait: Sized + where Option : NotImplemented +{} + +impl NotImplemented for i32 {} + +impl MyTrait for .. {} + +fn bar() { } + +fn test() { + bar::>(); + //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option` +} + +fn main() { +} 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 8057ca56621c1..ff8fbd4957491 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 @@ -17,7 +17,7 @@ trait NotImplemented { } -trait MyTrait +trait MyTrait: Sized where Option : NotImplemented {} @@ -26,20 +26,11 @@ impl NotImplemented for i32 {} impl MyTrait for .. {} fn foo() { - bar::>() //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option` - // // This should probably typecheck. This is #20671. } fn bar() { } -fn test() { - bar::>(); - //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option` -} - fn main() { - foo::(); - //~^ ERROR the trait `NotImplemented` is not implemented for the type `core::option::Option` } diff --git a/src/test/compile-fail/variance-invariant-self-trait-match.rs b/src/test/compile-fail/variance-invariant-self-trait-match.rs index b46cd302ae5ea..fe61dee23bc2a 100644 --- a/src/test/compile-fail/variance-invariant-self-trait-match.rs +++ b/src/test/compile-fail/variance-invariant-self-trait-match.rs @@ -15,13 +15,13 @@ trait Get { } fn get_min_from_max<'min, 'max, G>() - where 'max : 'min, &'max G : Get + where 'max : 'min, &'max G : Get, G : 'max { impls_get::<&'min G>(); //~ ERROR mismatched types } fn get_max_from_min<'min, 'max, G>() - where 'max : 'min, &'min G : Get + where 'max : 'min, &'min G : Get, G : 'min { impls_get::<&'max G>(); //~ ERROR mismatched types } diff --git a/src/test/compile-fail/wf-array-elem-sized.rs b/src/test/compile-fail/wf-array-elem-sized.rs index c8b7f35b3aa58..946341a1a75bb 100644 --- a/src/test/compile-fail/wf-array-elem-sized.rs +++ b/src/test/compile-fail/wf-array-elem-sized.rs @@ -14,8 +14,8 @@ #![allow(dead_code)] struct Foo { - foo: [[u8]], //~ WARN E0277 + foo: [[u8]], //~ ERROR E0277 } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-enum-bound.rs b/src/test/compile-fail/wf-enum-bound.rs index 1d271d1530a75..e3e79fdd940af 100644 --- a/src/test/compile-fail/wf-enum-bound.rs +++ b/src/test/compile-fail/wf-enum-bound.rs @@ -16,11 +16,11 @@ trait ExtraCopy { } -enum SomeEnum //~ WARN E0277 +enum SomeEnum //~ ERROR E0277 where T: ExtraCopy { SomeVariant(T,U) } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-fn-where-clause.rs b/src/test/compile-fail/wf-fn-where-clause.rs index 769894613c764..3ed9e5d9f1eb5 100644 --- a/src/test/compile-fail/wf-fn-where-clause.rs +++ b/src/test/compile-fail/wf-fn-where-clause.rs @@ -16,9 +16,9 @@ trait ExtraCopy { } -fn foo() where T: ExtraCopy //~ WARN E0277 +fn foo() where T: ExtraCopy //~ ERROR E0277 { } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-impl-associated-type-region.rs b/src/test/compile-fail/wf-impl-associated-type-region.rs index 2d7727fff3503..a319b676eeb88 100644 --- a/src/test/compile-fail/wf-impl-associated-type-region.rs +++ b/src/test/compile-fail/wf-impl-associated-type-region.rs @@ -17,8 +17,8 @@ pub trait Foo<'a> { } impl<'a, T> Foo<'a> for T { - type Bar = &'a T; //~ WARN E0309 + type Bar = &'a T; //~ ERROR E0309 } #[rustc_error] -fn main() { } //~ ERROR compilation +fn main() { } diff --git a/src/test/compile-fail/wf-impl-associated-type-trait.rs b/src/test/compile-fail/wf-impl-associated-type-trait.rs index 8a612c321570d..ba31de98e7f95 100644 --- a/src/test/compile-fail/wf-impl-associated-type-trait.rs +++ b/src/test/compile-fail/wf-impl-associated-type-trait.rs @@ -25,9 +25,9 @@ pub trait Foo { impl Foo for T { type Bar = MySet; - //~^ WARN the trait `MyHash` is not implemented for the type `T` + //~^ ERROR the trait `MyHash` is not implemented for the type `T` } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-in-fn-type-static.rs b/src/test/compile-fail/wf-in-fn-type-static.rs index 593c9435f6c75..8e3bca0975813 100644 --- a/src/test/compile-fail/wf-in-fn-type-static.rs +++ b/src/test/compile-fail/wf-in-fn-type-static.rs @@ -20,13 +20,13 @@ struct MustBeCopy { struct Foo { // needs T: 'static - x: fn() -> &'static T //~ WARN E0310 + x: fn() -> &'static T //~ ERROR E0310 } struct Bar { // needs T: Copy - x: fn(&'static T) //~ WARN E0310 + x: fn(&'static T) //~ ERROR E0310 } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-in-fn-where-clause.rs b/src/test/compile-fail/wf-in-fn-where-clause.rs index fc3d234aac252..c2f66a2a460c5 100644 --- a/src/test/compile-fail/wf-in-fn-where-clause.rs +++ b/src/test/compile-fail/wf-in-fn-where-clause.rs @@ -16,10 +16,10 @@ trait MustBeCopy { } -fn bar() //~ WARN E0277 +fn bar() //~ ERROR E0277 where T: MustBeCopy { } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-in-obj-type-static.rs b/src/test/compile-fail/wf-in-obj-type-static.rs index c697dfd50ad47..11535fb9f9e45 100644 --- a/src/test/compile-fail/wf-in-obj-type-static.rs +++ b/src/test/compile-fail/wf-in-obj-type-static.rs @@ -21,8 +21,8 @@ struct MustBeCopy { struct Foo { // needs T: 'static - x: Object<&'static T> //~ WARN E0310 + x: Object<&'static T> //~ ERROR E0310 } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-inherent-impl-method-where-clause.rs b/src/test/compile-fail/wf-inherent-impl-method-where-clause.rs index 44671be835533..78e12c47e24de 100644 --- a/src/test/compile-fail/wf-inherent-impl-method-where-clause.rs +++ b/src/test/compile-fail/wf-inherent-impl-method-where-clause.rs @@ -19,9 +19,9 @@ trait ExtraCopy { } struct Foo(T,U); impl Foo { - fn foo(self) where T: ExtraCopy //~ WARN E0277 + fn foo(self) where T: ExtraCopy //~ ERROR E0277 {} } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-inherent-impl-where-clause.rs b/src/test/compile-fail/wf-inherent-impl-where-clause.rs index a0f588c1961d1..7edbb11e24520 100644 --- a/src/test/compile-fail/wf-inherent-impl-where-clause.rs +++ b/src/test/compile-fail/wf-inherent-impl-where-clause.rs @@ -18,9 +18,9 @@ trait ExtraCopy { } struct Foo(T,U); -impl Foo where T: ExtraCopy //~ WARN E0277 +impl Foo where T: ExtraCopy //~ ERROR E0277 { } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-outlives-ty-in-fn-or-trait.rs b/src/test/compile-fail/wf-outlives-ty-in-fn-or-trait.rs index dc0cbeff153a9..c11b2e4c544e1 100644 --- a/src/test/compile-fail/wf-outlives-ty-in-fn-or-trait.rs +++ b/src/test/compile-fail/wf-outlives-ty-in-fn-or-trait.rs @@ -19,14 +19,14 @@ trait Trait { } struct Foo<'a,T> { f: &'a fn(T), - //~^ WARN E0309 + //~^ ERROR E0309 } struct Bar<'a,T> { f: &'a Trait, - //~^ WARN E0309 + //~^ ERROR E0309 } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-struct-bound.rs b/src/test/compile-fail/wf-struct-bound.rs index 43378061e40c0..e263b251aa379 100644 --- a/src/test/compile-fail/wf-struct-bound.rs +++ b/src/test/compile-fail/wf-struct-bound.rs @@ -16,11 +16,11 @@ trait ExtraCopy { } -struct SomeStruct //~ WARN E0277 +struct SomeStruct //~ ERROR E0277 where T: ExtraCopy { data: (T,U) } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-associated-type-bound.rs b/src/test/compile-fail/wf-trait-associated-type-bound.rs index 63a532138e3bd..8420edd66a180 100644 --- a/src/test/compile-fail/wf-trait-associated-type-bound.rs +++ b/src/test/compile-fail/wf-trait-associated-type-bound.rs @@ -16,9 +16,9 @@ trait ExtraCopy { } -trait SomeTrait { //~ WARN E0277 +trait SomeTrait { //~ ERROR E0277 type Type1: ExtraCopy; } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-associated-type-region.rs b/src/test/compile-fail/wf-trait-associated-type-region.rs index b3aa4e19c9656..95d9ffdf9d359 100644 --- a/src/test/compile-fail/wf-trait-associated-type-region.rs +++ b/src/test/compile-fail/wf-trait-associated-type-region.rs @@ -17,8 +17,8 @@ trait SomeTrait<'a> { type Type1; type Type2 = &'a Self::Type1; - //~^ WARN E0309 + //~^ ERROR E0309 } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-associated-type-trait.rs b/src/test/compile-fail/wf-trait-associated-type-trait.rs index 8c491e04c981d..902cbe2676b06 100644 --- a/src/test/compile-fail/wf-trait-associated-type-trait.rs +++ b/src/test/compile-fail/wf-trait-associated-type-trait.rs @@ -19,8 +19,8 @@ struct IsCopy { x: T } trait SomeTrait { type Type1; type Type2 = IsCopy; - //~^ WARN E0277 + //~^ ERROR E0277 } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-bound.rs b/src/test/compile-fail/wf-trait-bound.rs index 147b3ce236d42..ca15a6ab64863 100644 --- a/src/test/compile-fail/wf-trait-bound.rs +++ b/src/test/compile-fail/wf-trait-bound.rs @@ -16,10 +16,10 @@ trait ExtraCopy { } -trait SomeTrait //~ WARN E0277 +trait SomeTrait //~ ERROR E0277 where T: ExtraCopy { } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-default-fn-arg.rs b/src/test/compile-fail/wf-trait-default-fn-arg.rs index 57c6c1979f87e..453aa2428ce5d 100644 --- a/src/test/compile-fail/wf-trait-default-fn-arg.rs +++ b/src/test/compile-fail/wf-trait-default-fn-arg.rs @@ -19,11 +19,11 @@ struct Bar { value: Box } trait Foo { fn bar(&self, x: &Bar) { - //~^ WARN E0277 + //~^ ERROR E0277 // // Here, Eq ought to be implemented. } } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-default-fn-ret.rs b/src/test/compile-fail/wf-trait-default-fn-ret.rs index 939876403e54d..d94708d3e06a5 100644 --- a/src/test/compile-fail/wf-trait-default-fn-ret.rs +++ b/src/test/compile-fail/wf-trait-default-fn-ret.rs @@ -19,12 +19,11 @@ struct Bar { value: Box } trait Foo { fn bar(&self) -> Bar { - //~^ WARN E0277 + //~^ ERROR E0277 // // Here, Eq ought to be implemented. loop { } } } -#[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-default-fn-where-clause.rs b/src/test/compile-fail/wf-trait-default-fn-where-clause.rs index b1c0d71fc5b3b..29c85250583c7 100644 --- a/src/test/compile-fail/wf-trait-default-fn-where-clause.rs +++ b/src/test/compile-fail/wf-trait-default-fn-where-clause.rs @@ -19,11 +19,11 @@ trait Bar { } trait Foo { fn bar(&self) where A: Bar { - //~^ WARN E0277 + //~^ ERROR E0277 // // Here, Eq ought to be implemented. } } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-fn-arg.rs b/src/test/compile-fail/wf-trait-fn-arg.rs index ff263c85eb371..d88e36faeec60 100644 --- a/src/test/compile-fail/wf-trait-fn-arg.rs +++ b/src/test/compile-fail/wf-trait-fn-arg.rs @@ -18,10 +18,9 @@ struct Bar { value: Box } trait Foo { fn bar(&self, x: &Bar); - //~^ WARN E0277 + //~^ ERROR E0277 // // Here, Eq ought to be implemented. } -#[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-fn-ret.rs b/src/test/compile-fail/wf-trait-fn-ret.rs index 5c8f3030c2c21..c368ff9a4a82d 100644 --- a/src/test/compile-fail/wf-trait-fn-ret.rs +++ b/src/test/compile-fail/wf-trait-fn-ret.rs @@ -18,10 +18,9 @@ struct Bar { value: Box } trait Foo { fn bar(&self) -> &Bar; - //~^ WARN E0277 + //~^ ERROR E0277 // // Here, Eq ought to be implemented. } -#[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-fn-where-clause.rs b/src/test/compile-fail/wf-trait-fn-where-clause.rs index 51b5475e51fba..f59dca93bb90a 100644 --- a/src/test/compile-fail/wf-trait-fn-where-clause.rs +++ b/src/test/compile-fail/wf-trait-fn-where-clause.rs @@ -18,10 +18,10 @@ struct Bar { value: Box } trait Foo { fn bar(&self) where Bar: Copy; - //~^ WARN E0277 + //~^ ERROR E0277 // // Here, Eq ought to be implemented. } #[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/compile-fail/wf-trait-superbound.rs b/src/test/compile-fail/wf-trait-superbound.rs index 58ee766dad112..ea8b2fdf3a147 100644 --- a/src/test/compile-fail/wf-trait-superbound.rs +++ b/src/test/compile-fail/wf-trait-superbound.rs @@ -16,8 +16,7 @@ trait ExtraCopy { } -trait SomeTrait: ExtraCopy { //~ WARN E0277 +trait SomeTrait: ExtraCopy { //~ ERROR E0277 } -#[rustc_error] -fn main() { } //~ ERROR compilation successful +fn main() { } diff --git a/src/test/run-pass/cycle-generic-bound.rs b/src/test/run-pass/cycle-generic-bound.rs index 86b41284cdf35..b6d84f9d5a240 100644 --- a/src/test/run-pass/cycle-generic-bound.rs +++ b/src/test/run-pass/cycle-generic-bound.rs @@ -15,4 +15,6 @@ trait Chromosome> { } +impl Chromosome for i32 { } + fn main() { } diff --git a/src/test/run-pass/cycle-trait-type-trait.rs b/src/test/run-pass/cycle-trait-type-trait.rs index 50bc9e971fbe5..4ae5c599b43dd 100644 --- a/src/test/run-pass/cycle-trait-type-trait.rs +++ b/src/test/run-pass/cycle-trait-type-trait.rs @@ -22,4 +22,12 @@ trait Get { struct Struct { c: C } +impl Chromosome for i32 { } + +impl Get> for i32 { + fn get(&self) -> Struct { + Struct { c: *self } + } +} + fn main() { } diff --git a/src/test/run-pass/issue-25810.rs b/src/test/run-pass/issue-25810.rs index 49a0642ce184d..820872ad3fc50 100644 --- a/src/test/run-pass/issue-25810.rs +++ b/src/test/run-pass/issue-25810.rs @@ -14,7 +14,9 @@ fn main() { println!("{:?}",y); } -trait Foo { +trait Foo + where for<'a> &'a Self: Bar +{ fn foo<'a>(&'a self) -> <&'a Self as Bar>::Output; } diff --git a/src/test/run-pass/issue-6898.rs b/src/test/run-pass/issue-6898.rs index 8ea0804af18bf..e0d2f13ad6899 100644 --- a/src/test/run-pass/issue-6898.rs +++ b/src/test/run-pass/issue-6898.rs @@ -22,7 +22,7 @@ pub fn size_of_val(val: &T) -> usize { val.size_of_val() } -pub trait TypeInfo { +pub trait TypeInfo: Sized { fn size_of(_lame_type_hint: Option) -> usize; fn size_of_val(&self) -> usize; } diff --git a/src/test/run-pass/regions-issue-22246.rs b/src/test/run-pass/regions-issue-22246.rs index 16236f9465594..b6815d929678a 100644 --- a/src/test/run-pass/regions-issue-22246.rs +++ b/src/test/run-pass/regions-issue-22246.rs @@ -17,7 +17,7 @@ use std::ops::Deref; -pub trait ToOwned { +pub trait ToOwned: Sized { type Owned: Borrow; fn to_owned(&self) -> Self::Owned; } diff --git a/src/test/run-pass/regions-no-variance-from-fn-generics.rs b/src/test/run-pass/regions-no-variance-from-fn-generics.rs index d385804da5790..c339be25f8bb3 100644 --- a/src/test/run-pass/regions-no-variance-from-fn-generics.rs +++ b/src/test/run-pass/regions-no-variance-from-fn-generics.rs @@ -22,7 +22,7 @@ trait UseLife01 { } trait UseLife02 { - fn refs<'a, T, H: HasType<&'a T>>(&'a self) -> H; + fn refs<'a, T: 'a, H: HasType<&'a T>>(&'a self) -> H; } @@ -33,7 +33,7 @@ pub trait HasType trait UseLife03 { - fn refs<'a, H: HasType<&'a T>>(&'a self) -> H; + fn refs<'a, H: HasType<&'a T>>(&'a self) -> H where T: 'a; } @@ -45,7 +45,7 @@ pub fn top_refs_1<'a, H: HasLife<'a>>(_s: &'a ()) -> H { unimplemented!() } -pub fn top_refs_2<'a, T, H: HasType<&'a T>>(_s: &'a ()) -> H { +pub fn top_refs_2<'a, T: 'a, H: HasType<&'a T>>(_s: &'a ()) -> H { unimplemented!() } diff --git a/src/test/run-pass/trait-inheritance-num0.rs b/src/test/run-pass/trait-inheritance-num0.rs index 83c2a9ad33926..70515a088e2de 100644 --- a/src/test/run-pass/trait-inheritance-num0.rs +++ b/src/test/run-pass/trait-inheritance-num0.rs @@ -16,7 +16,7 @@ use std::cmp::PartialOrd; -pub trait NumCast { +pub trait NumCast: Sized { fn from(i: i32) -> Option; } diff --git a/src/test/run-pass/trait-inheritance-num1.rs b/src/test/run-pass/trait-inheritance-num1.rs index 14a6a9a0c664c..e21abdae730bc 100644 --- a/src/test/run-pass/trait-inheritance-num1.rs +++ b/src/test/run-pass/trait-inheritance-num1.rs @@ -10,7 +10,7 @@ // pretty-expanded FIXME #23616 -pub trait NumCast { +pub trait NumCast: Sized { fn from(i: i32) -> Option; } diff --git a/src/test/run-pass/trait-inheritance-num3.rs b/src/test/run-pass/trait-inheritance-num3.rs index abf8d2baf8732..fb56ae82b303e 100644 --- a/src/test/run-pass/trait-inheritance-num3.rs +++ b/src/test/run-pass/trait-inheritance-num3.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub trait NumCast { +pub trait NumCast: Sized { fn from(i: i32) -> Option; } diff --git a/src/test/run-pass/trait-inheritance-num5.rs b/src/test/run-pass/trait-inheritance-num5.rs index c6f8a5d4f1d99..bd442629243ee 100644 --- a/src/test/run-pass/trait-inheritance-num5.rs +++ b/src/test/run-pass/trait-inheritance-num5.rs @@ -10,7 +10,7 @@ // pretty-expanded FIXME #23616 -pub trait NumCast { +pub trait NumCast: Sized { fn from(i: i32) -> Option; } diff --git a/src/test/run-pass/trait-inheritance-self-in-supertype.rs b/src/test/run-pass/trait-inheritance-self-in-supertype.rs index c7e206cb474b8..e353be16b45e5 100644 --- a/src/test/run-pass/trait-inheritance-self-in-supertype.rs +++ b/src/test/run-pass/trait-inheritance-self-in-supertype.rs @@ -17,7 +17,7 @@ pub trait FuzzyEq { fn fuzzy_eq_eps(&self, other: &Self, epsilon: &Eps) -> bool; } -trait Float: FuzzyEq { +trait Float: Sized+FuzzyEq { fn two_pi() -> Self; } diff --git a/src/test/run-pass/trait-inheritance-self.rs b/src/test/run-pass/trait-inheritance-self.rs index 7d975da4a2491..a025be5d651bc 100644 --- a/src/test/run-pass/trait-inheritance-self.rs +++ b/src/test/run-pass/trait-inheritance-self.rs @@ -12,7 +12,7 @@ trait Foo { fn f(&self, x: &T); } -trait Bar : Foo { +trait Bar : Sized + Foo { fn g(&self); } diff --git a/src/test/run-pass/trait-inheritance-subst.rs b/src/test/run-pass/trait-inheritance-subst.rs index 3d82ee6792504..73bb4bacf64e1 100644 --- a/src/test/run-pass/trait-inheritance-subst.rs +++ b/src/test/run-pass/trait-inheritance-subst.rs @@ -13,7 +13,7 @@ pub trait Add { fn add(&self, rhs: &RHS) -> Result; } -trait MyNum : Add { } +trait MyNum : Sized + Add { } struct MyInt { val: isize } diff --git a/src/test/run-pass/trait-inheritance-subst2.rs b/src/test/run-pass/trait-inheritance-subst2.rs index 6a3639954350f..7d3ebc19e8f83 100644 --- a/src/test/run-pass/trait-inheritance-subst2.rs +++ b/src/test/run-pass/trait-inheritance-subst2.rs @@ -17,7 +17,7 @@ trait Add: Panda { fn add(&self, rhs: &RHS) -> Result; } -trait MyNum : Add { } +trait MyNum : Sized + Add { } struct MyInt { val: isize } diff --git a/src/test/run-pass/unsized2.rs b/src/test/run-pass/unsized2.rs index 1cce98ae6b725..5b9fa5230d1e0 100644 --- a/src/test/run-pass/unsized2.rs +++ b/src/test/run-pass/unsized2.rs @@ -67,26 +67,26 @@ fn f7(x: &X) { trait T4 { fn dummy(&self) { } - fn m1(x: &T4, y: X); - fn m2(x: &T5, y: X); + fn m1(&self, x: &T4, y: X); + fn m2(&self, x: &T5, y: X); } trait T5 { fn dummy(&self) { } // not an error (for now) - fn m1(x: &T4); - fn m2(x: &T5); + fn m1(&self, x: &T4); + fn m2(&self, x: &T5); } trait T6 { fn dummy(&self) { } - fn m1(x: &T4); - fn m2(x: &T5); + fn m1(&self, x: &T4); + fn m2(&self, x: &T5); } trait T7 { fn dummy(&self) { } // not an error (for now) - fn m1(x: &T4); - fn m2(x: &T5); + fn m1(&self, x: &T4); + fn m2(&self, x: &T5); } // The last field in a struct or variant may be unsized