diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs index 58e2a6e9bba46..414bcc874eac1 100644 --- a/src/libcore/num/dec2flt/parse.rs +++ b/src/libcore/num/dec2flt/parse.rs @@ -59,7 +59,12 @@ pub fn parse_decimal(s: &str) -> ParseResult { let s = s.as_bytes(); let (integral, s) = eat_digits(s); match s.first() { - None => Valid(Decimal::new(integral, b"", 0)), + None => { + if integral.is_empty() { + return Invalid; // No digits at all + } + Valid(Decimal::new(integral, b"", 0)) + } Some(&b'e') | Some(&b'E') => { if integral.is_empty() { return Invalid; // No digits before 'e' diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 406a5dffdb084..831616293cd8f 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -385,6 +385,13 @@ fnptr_impls_args! { A, B } fnptr_impls_args! { A, B, C } fnptr_impls_args! { A, B, C, D } fnptr_impls_args! { A, B, C, D, E } +fnptr_impls_args! { A, B, C, D, E, F } +fnptr_impls_args! { A, B, C, D, E, F, G } +fnptr_impls_args! { A, B, C, D, E, F, G, H } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K } +fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } // Comparison for pointers #[stable(feature = "rust1", since = "1.0.0")] diff --git a/src/libcoretest/num/dec2flt/mod.rs b/src/libcoretest/num/dec2flt/mod.rs index 131cf62957537..fb98e7e6f9adf 100644 --- a/src/libcoretest/num/dec2flt/mod.rs +++ b/src/libcoretest/num/dec2flt/mod.rs @@ -101,6 +101,18 @@ fn lonely_dot() { assert_eq!(".".parse(), Ok(0.0)); } +#[test] +fn lonely_sign() { + assert!("+".parse::().is_err()); + assert!("-".parse::().is_err()); +} + +#[test] +fn whitespace() { + assert!(" 1.0".parse::().is_err()); + assert!("1.0 ".parse::().is_err()); +} + #[test] fn nan() { assert!("NaN".parse::().unwrap().is_nan()); diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 917727907ba88..0c1c905c8dadb 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -43,7 +43,7 @@ use std::rc::Rc; use syntax::ast; use syntax::codemap; use syntax::codemap::{Span, DUMMY_SP}; -use util::nodemap::{FnvHashMap, NodeMap}; +use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap}; use self::combine::CombineFields; use self::region_inference::{RegionVarBindings, RegionSnapshot}; @@ -92,6 +92,10 @@ pub struct InferCtxt<'a, 'tcx: 'a> { pub fulfillment_cx: RefCell>, + // the set of predicates on which errors have been reported, to + // avoid reporting the same error twice. + pub reported_trait_errors: RefCell>>, + // This is a temporary field used for toggling on normalization in the inference context, // as we move towards the approach described here: // https://internals.rust-lang.org/t/flattening-the-contexts-for-fun-and-profit/2293 @@ -374,6 +378,7 @@ pub fn new_infer_ctxt<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>, region_vars: RegionVarBindings::new(tcx), parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()), fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)), + reported_trait_errors: RefCell::new(FnvHashSet()), normalize: false, err_count_on_creation: tcx.sess.err_count() } @@ -1389,9 +1394,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.resolve_type_vars_or_error(&ty) } + pub fn tables_are_tcx_tables(&self) -> bool { + let tables: &RefCell = &self.tables; + let tcx_tables: &RefCell = &self.tcx.tables; + tables as *const _ == tcx_tables as *const _ + } + pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool { let ty = self.resolve_type_vars_if_possible(&ty); - if ty.needs_infer() { + if ty.needs_infer() || + (ty.has_closure_types() && !self.tables_are_tcx_tables()) { // this can get called from typeck (by euv), and moves_by_default // rightly refuses to work with inference variables, but // moves_by_default has a cache, which we want to use in other diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 215368754c999..03374fa492e18 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -348,13 +348,17 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // this properly would result in the necessity of computing *type* // reachability, which might result in a compile time loss. fn mark_destructors_reachable(&mut self) { - for adt in self.tcx.adt_defs() { - if let Some(destructor_def_id) = adt.destructor() { - if destructor_def_id.is_local() { - self.reachable_symbols.insert(destructor_def_id.node); + let drop_trait = match self.tcx.lang_items.drop_trait() { + Some(id) => self.tcx.lookup_trait_def(id), None => { return } + }; + drop_trait.for_each_impl(self.tcx, |drop_impl| { + for destructor in &self.tcx.impl_items.borrow()[&drop_impl] { + let destructor_did = destructor.def_id(); + if destructor_did.is_local() { + self.reachable_symbols.insert(destructor_did.node); } } - } + }) } } diff --git a/src/librustc/middle/traits/error_reporting.rs b/src/librustc/middle/traits/error_reporting.rs index 2ed53f16afd28..4580e642d17df 100644 --- a/src/librustc/middle/traits/error_reporting.rs +++ b/src/librustc/middle/traits/error_reporting.rs @@ -28,11 +28,32 @@ use middle::def_id::DefId; use middle::infer::InferCtxt; use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef, Ty}; use middle::ty::fold::TypeFoldable; -use std::collections::HashMap; +use util::nodemap::{FnvHashMap, FnvHashSet}; + use std::fmt; use syntax::codemap::Span; use rustc_front::attr::{AttributeMethods, AttrMetaMethods}; +#[derive(Debug, PartialEq, Eq, Hash)] +pub struct TraitErrorKey<'tcx> { + is_warning: bool, + span: Span, + predicate: ty::Predicate<'tcx> +} + +impl<'tcx> TraitErrorKey<'tcx> { + fn from_error<'a>(infcx: &InferCtxt<'a, 'tcx>, + e: &FulfillmentError<'tcx>) -> Self { + 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) + } + } +} + pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, errors: &Vec>) { for error in errors { @@ -42,6 +63,13 @@ pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, error: &FulfillmentError<'tcx>) { + let error_key = TraitErrorKey::from_error(infcx, error); + debug!("report_fulfillment_errors({:?}) - key={:?}", + error, error_key); + if !infcx.reported_trait_errors.borrow_mut().insert(error_key) { + debug!("report_fulfillment_errors: skipping duplicate"); + return; + } match error.code { FulfillmentErrorCode::CodeSelectionError(ref e) => { report_selection_error(infcx, &error.obligation, e); @@ -97,7 +125,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>, (gen.name.as_str().to_string(), trait_ref.substs.types.get(param, i) .to_string()) - }).collect::>(); + }).collect::>(); generic_map.insert("Self".to_string(), trait_ref.self_ty().to_string()); let parser = Parser::new(&istring); @@ -302,7 +330,11 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>, "the trait `{}` cannot be made into an object", tcx.item_path_str(trait_def_id)); + let mut reported_violations = FnvHashSet(); for violation in object_safety_violations(tcx, trait_def_id) { + if !reported_violations.insert(violation.clone()) { + continue; + } match violation { ObjectSafetyViolation::SizedSelf => { tcx.sess.fileline_note( diff --git a/src/librustc/middle/traits/fulfill.rs b/src/librustc/middle/traits/fulfill.rs index 29032f0c4719a..d4e6f693d965d 100644 --- a/src/librustc/middle/traits/fulfill.rs +++ b/src/librustc/middle/traits/fulfill.rs @@ -49,6 +49,12 @@ pub struct FulfillmentContext<'tcx> { // than the `SelectionCache`: it avoids duplicate errors and // permits recursive obligations, which are often generated from // traits like `Send` et al. + // + // Note that because of type inference, a predicate can still + // occur twice in the predicates list, for example when 2 + // initially-distinct type variables are unified after being + // inserted. Deduplicating the predicate set on selection had a + // significant performance cost the last time I checked. duplicate_set: FulfilledPredicates<'tcx>, // A list of all obligations that have been registered with this diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs index b0d4d92e8e1b2..7f76cfaee5866 100644 --- a/src/librustc/middle/traits/mod.rs +++ b/src/librustc/middle/traits/mod.rs @@ -21,10 +21,12 @@ use middle::subst; use middle::ty::{self, HasTypeFlags, Ty}; use middle::ty::fold::TypeFoldable; use middle::infer::{self, fixup_err_to_string, InferCtxt}; + use std::rc::Rc; use syntax::ast; use syntax::codemap::{Span, DUMMY_SP}; +pub use self::error_reporting::TraitErrorKey; pub use self::error_reporting::report_fulfillment_errors; pub use self::error_reporting::report_overflow_error; pub use self::error_reporting::report_selection_error; diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs index 3a2602cd5b448..333d23e6eca8b 100644 --- a/src/librustc/middle/traits/object_safety.rs +++ b/src/librustc/middle/traits/object_safety.rs @@ -27,7 +27,7 @@ use middle::ty::{self, ToPolyTraitRef, Ty}; use std::rc::Rc; use syntax::ast; -#[derive(Debug)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum ObjectSafetyViolation<'tcx> { /// Self : Sized declared on the trait SizedSelf, diff --git a/src/librustc/middle/ty/context.rs b/src/librustc/middle/ty/context.rs index e3b6da56680da..ef9707967f39d 100644 --- a/src/librustc/middle/ty/context.rs +++ b/src/librustc/middle/ty/context.rs @@ -245,9 +245,6 @@ pub struct ctxt<'tcx> { /// True if the variance has been computed yet; false otherwise. pub variance_computed: Cell, - /// A method will be in this list if and only if it is a destructor. - pub destructors: RefCell, - /// Maps a DefId of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. @@ -475,7 +472,6 @@ impl<'tcx> ctxt<'tcx> { normalized_cache: RefCell::new(FnvHashMap()), lang_items: lang_items, provided_method_sources: RefCell::new(DefIdMap()), - destructors: RefCell::new(DefIdSet()), inherent_impls: RefCell::new(DefIdMap()), impl_items: RefCell::new(DefIdMap()), used_unsafe: RefCell::new(NodeSet()), diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index a8adb38864424..3025d7b58979f 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -272,6 +272,20 @@ impl<'tcx> Method<'tcx> { } } +impl<'tcx> PartialEq for Method<'tcx> { + #[inline] + fn eq(&self, other: &Self) -> bool { self.def_id == other.def_id } +} + +impl<'tcx> Eq for Method<'tcx> {} + +impl<'tcx> Hash for Method<'tcx> { + #[inline] + fn hash(&self, s: &mut H) { + self.def_id.hash(s) + } +} + #[derive(Clone, Copy, Debug)] pub struct AssociatedConst<'tcx> { pub name: Name, @@ -1681,7 +1695,6 @@ impl<'tcx, 'container> AdtDefData<'tcx, 'container> { } pub fn set_destructor(&self, dtor: DefId) { - assert!(self.destructor.get().is_none()); self.destructor.set(Some(dtor)); } @@ -2317,11 +2330,6 @@ impl<'tcx> ctxt<'tcx> { self.lookup_adt_def_master(did) } - /// Return the list of all interned ADT definitions - pub fn adt_defs(&self) -> Vec> { - self.adt_defs.borrow().values().cloned().collect() - } - /// Given the did of an item, returns its full set of predicates. pub fn lookup_predicates(&self, did: DefId) -> GenericPredicates<'tcx> { lookup_locally_or_in_crate_store( diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 4084f13e818f2..717690adddedd 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -557,14 +557,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { FfiSafe } - ty::TyInt(hir::TyIs) => { - FfiUnsafe("found Rust type `isize` in foreign module, while \ - `libc::c_int` or `libc::c_long` should be used") - } - ty::TyUint(hir::TyUs) => { - FfiUnsafe("found Rust type `usize` in foreign module, while \ - `libc::c_uint` or `libc::c_ulong` should be used") - } ty::TyChar => { FfiUnsafe("found Rust type `char` in foreign module, while \ `u32` or `libc::wchar_t` should be used") @@ -2599,16 +2591,16 @@ impl LintPass for DropWithReprExtern { fn get_lints(&self) -> LintArray { lint_array!(DROP_WITH_REPR_EXTERN) } + fn check_crate(&mut self, ctx: &Context, _: &hir::Crate) { - for dtor_did in ctx.tcx.destructors.borrow().iter() { - let (drop_impl_did, dtor_self_type) = - if dtor_did.is_local() { - let impl_did = ctx.tcx.map.get_parent_did(dtor_did.node); - let ty = ctx.tcx.lookup_item_type(impl_did).ty; - (impl_did, ty) - } else { - continue; - }; + let drop_trait = match ctx.tcx.lang_items.drop_trait() { + Some(id) => ctx.tcx.lookup_trait_def(id), None => { return } + }; + drop_trait.for_each_impl(ctx.tcx, |drop_impl_did| { + if !drop_impl_did.is_local() { + return; + } + let dtor_self_type = ctx.tcx.lookup_item_type(drop_impl_did).ty; match dtor_self_type.sty { ty::TyEnum(self_type_def, _) | @@ -2634,6 +2626,6 @@ impl LintPass for DropWithReprExtern { } _ => {} } - } + }) } } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 572ba7a848713..454c11db263e1 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -621,13 +621,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { ty::TraitContainer(trait_def_id) => { callee::check_legal_trait_for_method_call(self.fcx.ccx, self.span, trait_def_id) } - ty::ImplContainer(..) => { - // Since `drop` is a trait method, we expect that any - // potential calls to it will wind up in the other - // arm. But just to be sure, check that the method id - // does not appear in the list of destructors. - assert!(!self.tcx().destructors.borrow().contains(&pick.item.def_id())); - } + ty::ImplContainer(..) => {} } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 9dd7cfea43f69..b07168966c191 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -431,9 +431,11 @@ pub fn check_item_bodies(ccx: &CrateCtxt) { } pub fn check_drop_impls(ccx: &CrateCtxt) { - for drop_method_did in ccx.tcx.destructors.borrow().iter() { - if drop_method_did.is_local() { - let drop_impl_did = ccx.tcx.map.get_parent_did(drop_method_did.node); + let drop_trait = match ccx.tcx.lang_items.drop_trait() { + Some(id) => ccx.tcx.lookup_trait_def(id), None => { return } + }; + drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| { + if drop_impl_did.is_local() { match dropck::check_drop_impl(ccx.tcx, drop_impl_did) { Ok(()) => {} Err(()) => { @@ -441,7 +443,7 @@ pub fn check_drop_impls(ccx: &CrateCtxt) { } } } - } + }); ccx.tcx.sess.abort_if_errors(); } @@ -4151,8 +4153,13 @@ fn check_const_with_ty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, check_expr_with_hint(fcx, e, declty); demand::coerce(fcx, e.span, declty, e); - fcx.select_all_obligations_or_error(); + + fcx.select_all_obligations_and_apply_defaults(); + upvar::closure_analyze_const(&fcx, e); + fcx.select_obligations_where_possible(); fcx.check_casts(); + fcx.select_all_obligations_or_error(); + regionck::regionck_expr(fcx, e); writeback::resolve_type_vars_in_expr(fcx, e); } diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index f9f711a1a6316..10d7c4620e7d3 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -73,6 +73,20 @@ pub fn closure_analyze_fn(fcx: &FnCtxt, assert!(fcx.inh.deferred_call_resolutions.borrow().is_empty()); } +pub fn closure_analyze_const(fcx: &FnCtxt, + body: &hir::Expr) +{ + let mut seed = SeedBorrowKind::new(fcx); + seed.visit_expr(body); + let closures_with_inferred_kinds = seed.closures_with_inferred_kinds; + + let mut adjust = AdjustBorrowKind::new(fcx, &closures_with_inferred_kinds); + adjust.visit_expr(body); + + // it's our job to process these. + assert!(fcx.inh.deferred_call_resolutions.borrow().is_empty()); +} + /////////////////////////////////////////////////////////////////////////// // SEED BORROW KIND diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 9ba6f1398e471..8cffac67321f5 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // Populate the table of destructors. It might seem a bit strange to // do this here, but it's actually the most convenient place, since // the coherence tables contain the trait -> type mappings. - self.populate_destructor_table(); + self.populate_destructors(); // Check to make sure implementations of `Copy` are legal. self.check_implementations_of_copy(); @@ -286,7 +286,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { // Destructors // - fn populate_destructor_table(&self) { + fn populate_destructors(&self) { let tcx = self.crate_context.tcx; let drop_trait = match tcx.lang_items.drop_trait() { Some(id) => id, None => { return } @@ -309,9 +309,6 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> { ty::TyEnum(type_def, _) | ty::TyStruct(type_def, _) => { type_def.set_destructor(method_def_id.def_id()); - tcx.destructors - .borrow_mut() - .insert(method_def_id.def_id()); } _ => { // Destructors only work on nominal types. diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ff622859cf0b1..8d50cc099bd60 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5116,12 +5116,19 @@ impl<'a> Parser<'a> { try!(self.expect(&token::Semi)); let last_span = self.last_span; + + if visibility == ast::Public { + self.span_warn(mk_sp(lo, last_span.hi), + "`pub extern crate` does not work as expected and should not be used. \ + Likely to become an error. Prefer `extern crate` and `pub use`."); + } + Ok(self.mk_item(lo, - last_span.hi, - ident, - ItemExternCrate(maybe_path), - visibility, - attrs)) + last_span.hi, + ident, + ItemExternCrate(maybe_path), + visibility, + attrs)) } /// Parse `extern` for foreign ABIs diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs index 4aad828590a30..c5a47f3e5358f 100644 --- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs +++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs @@ -32,5 +32,4 @@ fn ice(a: A) { let r = loop {}; r = r + a; //~^ ERROR not implemented - //~| ERROR not implemented } diff --git a/src/test/compile-fail/associated-types-path-2.rs b/src/test/compile-fail/associated-types-path-2.rs index e603cca7f384b..c9374d4293800 100644 --- a/src/test/compile-fail/associated-types-path-2.rs +++ b/src/test/compile-fail/associated-types-path-2.rs @@ -39,7 +39,6 @@ pub fn f1_int_uint() { pub fn f1_uint_uint() { f1(2u32, 4u32); //~^ ERROR the trait `Foo` is not implemented - //~| ERROR the trait `Foo` is not implemented } pub fn f1_uint_int() { diff --git a/src/test/compile-fail/borrowck-in-static.rs b/src/test/compile-fail/borrowck-in-static.rs new file mode 100644 index 0000000000000..16b0e8638de39 --- /dev/null +++ b/src/test/compile-fail/borrowck-in-static.rs @@ -0,0 +1,22 @@ +// 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. + +// check that borrowck looks inside consts/statics + +static FN : &'static (Fn() -> (BoxBox>) + Sync) = &|| { + let x = Box::new(0); + Box::new(|| x) //~ ERROR cannot move out of captured outer variable +}; + +fn main() { + let f = (FN)(); + f(); + f(); +} diff --git a/src/test/compile-fail/coerce-unsafe-to-closure.rs b/src/test/compile-fail/coerce-unsafe-to-closure.rs index 27b4a04054f07..90cbbf242aad4 100644 --- a/src/test/compile-fail/coerce-unsafe-to-closure.rs +++ b/src/test/compile-fail/coerce-unsafe-to-closure.rs @@ -11,5 +11,4 @@ fn main() { let x: Option<&[u8]> = Some("foo").map(std::mem::transmute); //~^ ERROR E0277 - //~| ERROR E0277 } diff --git a/src/test/compile-fail/const-eval-overflow-4b.rs b/src/test/compile-fail/const-eval-overflow-4b.rs index 6322b56a82f00..a8f47ab92e529 100644 --- a/src/test/compile-fail/const-eval-overflow-4b.rs +++ b/src/test/compile-fail/const-eval-overflow-4b.rs @@ -23,7 +23,6 @@ const A_I8_T : [u32; (i8::MAX as i8 + 1u8) as usize] //~^ ERROR mismatched types //~| the trait `core::ops::Add` is not implemented for the type `i8` - //~| the trait `core::ops::Add` is not implemented for the type `i8` = [0; (i8::MAX as usize) + 1]; fn main() { @@ -33,4 +32,3 @@ fn main() { fn foo(x: T) { println!("{:?}", x); } - diff --git a/src/test/compile-fail/fn-variance-1.rs b/src/test/compile-fail/fn-variance-1.rs index 8e1e88a92e452..e9dd1cb719dbc 100644 --- a/src/test/compile-fail/fn-variance-1.rs +++ b/src/test/compile-fail/fn-variance-1.rs @@ -20,10 +20,8 @@ fn main() { apply(&3, takes_imm); apply(&3, takes_mut); //~^ ERROR (values differ in mutability) - //~| ERROR (values differ in mutability) apply(&mut 3, takes_mut); apply(&mut 3, takes_imm); //~^ ERROR (values differ in mutability) - //~| ERROR (values differ in mutability) } diff --git a/src/test/compile-fail/for-loop-bogosity.rs b/src/test/compile-fail/for-loop-bogosity.rs index 6bc0e74a2eb58..c77683045170e 100644 --- a/src/test/compile-fail/for-loop-bogosity.rs +++ b/src/test/compile-fail/for-loop-bogosity.rs @@ -25,9 +25,6 @@ pub fn main() { y: 2, }; for x in bogus { //~ ERROR `core::iter::Iterator` is not implemented for the type `MyStruct` - //~^ ERROR - //~^^ ERROR - // FIXME(#21528) not fulfilled obligation error should be reported once, not thrice drop(x); } } diff --git a/src/test/compile-fail/indexing-requires-a-uint.rs b/src/test/compile-fail/indexing-requires-a-uint.rs index 3ca00fcb66ac1..3d3b7bc1bcb43 100644 --- a/src/test/compile-fail/indexing-requires-a-uint.rs +++ b/src/test/compile-fail/indexing-requires-a-uint.rs @@ -14,7 +14,6 @@ fn main() { fn bar(_: T) {} [0][0u8]; //~ ERROR: the trait `core::ops::Index` is not implemented - //~^ ERROR: the trait `core::ops::Index` is not implemented [0][0]; // should infer to be a usize diff --git a/src/test/compile-fail/integral-indexing.rs b/src/test/compile-fail/integral-indexing.rs index e2fb0fa4f2fa5..f78d677679bc8 100644 --- a/src/test/compile-fail/integral-indexing.rs +++ b/src/test/compile-fail/integral-indexing.rs @@ -14,21 +14,13 @@ pub fn main() { v[3_usize]; v[3]; v[3u8]; //~ERROR the trait `core::ops::Index` is not implemented - //~^ ERROR the trait `core::ops::Index` is not implemented v[3i8]; //~ERROR the trait `core::ops::Index` is not implemented - //~^ ERROR the trait `core::ops::Index` is not implemented v[3u32]; //~ERROR the trait `core::ops::Index` is not implemented - //~^ ERROR the trait `core::ops::Index` is not implemented v[3i32]; //~ERROR the trait `core::ops::Index` is not implemented - //~^ ERROR the trait `core::ops::Index` is not implemented s.as_bytes()[3_usize]; s.as_bytes()[3]; s.as_bytes()[3u8]; //~ERROR the trait `core::ops::Index` is not implemented - //~^ ERROR the trait `core::ops::Index` is not implemented s.as_bytes()[3i8]; //~ERROR the trait `core::ops::Index` is not implemented - //~^ ERROR the trait `core::ops::Index` is not implemented s.as_bytes()[3u32]; //~ERROR the trait `core::ops::Index` is not implemented - //~^ ERROR the trait `core::ops::Index` is not implemented s.as_bytes()[3i32]; //~ERROR the trait `core::ops::Index` is not implemented - //~^ ERROR the trait `core::ops::Index` is not implemented } diff --git a/src/test/compile-fail/issue-11771.rs b/src/test/compile-fail/issue-11771.rs index 40fc6b1ed6aaa..69899105bc317 100644 --- a/src/test/compile-fail/issue-11771.rs +++ b/src/test/compile-fail/issue-11771.rs @@ -12,12 +12,10 @@ fn main() { let x = (); 1 + x //~^ ERROR E0277 - //~| ERROR E0277 ; let x: () = (); 1 + x //~^ ERROR E0277 - //~| ERROR E0277 ; } diff --git a/src/test/compile-fail/issue-13352.rs b/src/test/compile-fail/issue-13352.rs index 14128a0e6f7ec..13e677d72bc1e 100644 --- a/src/test/compile-fail/issue-13352.rs +++ b/src/test/compile-fail/issue-13352.rs @@ -18,5 +18,4 @@ fn main() { }); 2_usize + (loop {}); //~^ ERROR E0277 - //~| ERROR E0277 } diff --git a/src/test/compile-fail/issue-14084.rs b/src/test/compile-fail/issue-14084.rs index b33a6767274ea..26ed9d8c26ada 100644 --- a/src/test/compile-fail/issue-14084.rs +++ b/src/test/compile-fail/issue-14084.rs @@ -14,6 +14,5 @@ fn main() { box ( () ) 0; //~^ ERROR: the trait `core::ops::Placer<_>` is not implemented - //~| ERROR: the trait `core::ops::Placer<_>` is not implemented //~| WARN deprecated syntax } diff --git a/src/test/compile-fail/issue-16250.rs b/src/test/compile-fail/issue-16250.rs index b5aa3568122ad..288fe4a9abb82 100644 --- a/src/test/compile-fail/issue-16250.rs +++ b/src/test/compile-fail/issue-16250.rs @@ -10,8 +10,10 @@ #![deny(warnings)] +pub struct Foo; + extern { - pub fn foo(x: (isize)); //~ ERROR found Rust type `isize` in foreign module + pub fn foo(x: (Foo)); //~ ERROR found struct without } fn main() { diff --git a/src/test/compile-fail/issue-20605.rs b/src/test/compile-fail/issue-20605.rs index 87b7616db8ed2..f2d65af9cdfc8 100644 --- a/src/test/compile-fail/issue-20605.rs +++ b/src/test/compile-fail/issue-20605.rs @@ -11,9 +11,6 @@ fn changer<'a>(mut things: Box>) { for item in *things { *item = 0 } //~^ ERROR the trait `core::marker::Sized` is not implemented for the type `core::iter::Iterator -//~^^ ERROR -//~^^^ ERROR -// FIXME(#21528) error should be reported once, not thrice } fn main() {} diff --git a/src/test/compile-fail/issue-20692.rs b/src/test/compile-fail/issue-20692.rs new file mode 100644 index 0000000000000..62d775adac3c7 --- /dev/null +++ b/src/test/compile-fail/issue-20692.rs @@ -0,0 +1,23 @@ +// 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. + +trait Array: Sized {} + +fn f(x: &T) { + let _ = x + //~^ ERROR `Array` cannot be made into an object + //~| NOTE the trait cannot require that `Self : Sized` + as + &Array; + //~^ ERROR `Array` cannot be made into an object + //~| NOTE the trait cannot require that `Self : Sized` +} + +fn main() {} diff --git a/src/test/compile-fail/issue-2149.rs b/src/test/compile-fail/issue-2149.rs index bb170ef7d0036..256c5d8e6f72c 100644 --- a/src/test/compile-fail/issue-2149.rs +++ b/src/test/compile-fail/issue-2149.rs @@ -17,7 +17,6 @@ impl vec_monad for Vec { let mut r = panic!(); for elt in self { r = r + f(*elt); } //~^ ERROR E0277 - //~| ERROR E0277 } } fn main() { diff --git a/src/test/compile-fail/issue-22645.rs b/src/test/compile-fail/issue-22645.rs index 8677934fd646c..aa7fa82fa29ba 100644 --- a/src/test/compile-fail/issue-22645.rs +++ b/src/test/compile-fail/issue-22645.rs @@ -23,7 +23,5 @@ impl Add for Bob { fn main() { let b = Bob + 3.5; b + 3 //~ ERROR: is not implemented - //~^ ERROR: is not implemented - //~^^ ERROR: is not implemented - //~^^^ ERROR: mismatched types + //~^ ERROR: mismatched types } diff --git a/src/test/compile-fail/issue-24352.rs b/src/test/compile-fail/issue-24352.rs index 0fbc634826bc5..9936f67b3af3c 100644 --- a/src/test/compile-fail/issue-24352.rs +++ b/src/test/compile-fail/issue-24352.rs @@ -11,5 +11,4 @@ fn main() { 1.0f64 - 1.0; 1.0f64 - 1 //~ ERROR: is not implemented - //~^ ERROR: is not implemented } diff --git a/src/test/compile-fail/issue-28098.rs b/src/test/compile-fail/issue-28098.rs new file mode 100644 index 0000000000000..f565d24e1fd08 --- /dev/null +++ b/src/test/compile-fail/issue-28098.rs @@ -0,0 +1,35 @@ +// 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. + +fn main() { + let _ = Iterator::next(&mut ()); + //~^ ERROR the trait `core::iter::Iterator` is not implemented + + for _ in false {} + //~^ ERROR the trait `core::iter::Iterator` is not implemented + + let _ = Iterator::next(&mut ()); + //~^ ERROR the trait `core::iter::Iterator` is not implemented + + other() +} + +pub fn other() { + // check errors are still reported globally + + let _ = Iterator::next(&mut ()); + //~^ ERROR the trait `core::iter::Iterator` is not implemented + + let _ = Iterator::next(&mut ()); + //~^ ERROR the trait `core::iter::Iterator` is not implemented + + for _ in false {} + //~^ ERROR the trait `core::iter::Iterator` is not implemented +} diff --git a/src/test/compile-fail/issue-28113.rs b/src/test/compile-fail/issue-28113.rs new file mode 100644 index 0000000000000..c5c4fb070178a --- /dev/null +++ b/src/test/compile-fail/issue-28113.rs @@ -0,0 +1,15 @@ +// 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. + +const X: u8 = + || -> u8 { 5 }() //~ ERROR function calls in constants are limited +; + +fn main() {} diff --git a/src/test/compile-fail/issue-28568.rs b/src/test/compile-fail/issue-28568.rs new file mode 100644 index 0000000000000..36b4a57eb117f --- /dev/null +++ b/src/test/compile-fail/issue-28568.rs @@ -0,0 +1,23 @@ +// 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. + +struct MyStruct; + +impl Drop for MyStruct { +//~^ ERROR conflicting implementations for trait + fn drop(&mut self) { } +} + +impl Drop for MyStruct { +//~^ NOTE conflicting implementation here + fn drop(&mut self) { } +} + +fn main() {} diff --git a/src/test/compile-fail/lint-ctypes.rs b/src/test/compile-fail/lint-ctypes.rs index 4daba86679d5d..5c49098d87053 100644 --- a/src/test/compile-fail/lint-ctypes.rs +++ b/src/test/compile-fail/lint-ctypes.rs @@ -27,12 +27,11 @@ pub struct ZeroSize; pub type RustFn = fn(); pub type RustBadRet = extern fn() -> Box; pub type CVoidRet = (); +pub struct Foo; extern { - pub fn bare_type1(size: isize); //~ ERROR: found Rust type - pub fn bare_type2(size: usize); //~ ERROR: found Rust type - pub fn ptr_type1(size: *const isize); //~ ERROR: found Rust type - pub fn ptr_type2(size: *const usize); //~ ERROR: found Rust type + pub fn ptr_type1(size: *const Foo); //~ ERROR: found struct without + pub fn ptr_type2(size: *const Foo); //~ ERROR: found struct without pub fn slice_type(p: &[u32]); //~ ERROR: found Rust slice type pub fn str_type(p: &str); //~ ERROR: found Rust type pub fn box_type(p: Box); //~ ERROR found Rust type @@ -55,6 +54,8 @@ extern { pub fn good8(fptr: extern fn() -> !); pub fn good9() -> (); pub fn good10() -> CVoidRet; + pub fn good11(size: isize); + pub fn good12(size: usize); } fn main() { diff --git a/src/test/compile-fail/shift-various-bad-types.rs b/src/test/compile-fail/shift-various-bad-types.rs index 24b66213b39bd..c980572fa152f 100644 --- a/src/test/compile-fail/shift-various-bad-types.rs +++ b/src/test/compile-fail/shift-various-bad-types.rs @@ -18,15 +18,12 @@ struct Panolpy { fn foo(p: &Panolpy) { 22 >> p.char; //~^ ERROR E0277 - //~| ERROR E0277 22 >> p.str; //~^ ERROR E0277 - //~| ERROR E0277 22 >> p; //~^ ERROR E0277 - //~| ERROR E0277 let x; 22 >> x; // ambiguity error winds up being suppressed diff --git a/src/test/compile-fail/str-idx.rs b/src/test/compile-fail/str-idx.rs index ddd2a4eeedf76..6e48ae20d09f3 100644 --- a/src/test/compile-fail/str-idx.rs +++ b/src/test/compile-fail/str-idx.rs @@ -11,5 +11,4 @@ pub fn main() { let s: &str = "hello"; let c: u8 = s[4]; //~ ERROR the trait `core::ops::Index<_>` is not implemented - //~^ ERROR the trait `core::ops::Index<_>` is not implemented } diff --git a/src/test/compile-fail/str-mut-idx.rs b/src/test/compile-fail/str-mut-idx.rs index 73abe6cb59db2..ec6a14778a463 100644 --- a/src/test/compile-fail/str-mut-idx.rs +++ b/src/test/compile-fail/str-mut-idx.rs @@ -17,7 +17,6 @@ fn mutate(s: &mut str) { s[1usize] = bot(); //~^ ERROR `core::ops::Index` is not implemented for the type `str` //~| ERROR `core::ops::IndexMut` is not implemented for the type `str` - //~| ERROR `core::ops::Index` is not implemented for the type `str` } pub fn main() {} diff --git a/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs b/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs index dc7c70ba649d8..361df93a71669 100644 --- a/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs +++ b/src/test/compile-fail/unboxed-closures-unsafe-extern-fn.rs @@ -35,7 +35,6 @@ fn b() { fn c() { let z = call_it_once(square, 22); //~^ ERROR not implemented - //~| ERROR not implemented } fn main() { } diff --git a/src/test/compile-fail/unboxed-closures-wrong-abi.rs b/src/test/compile-fail/unboxed-closures-wrong-abi.rs index cdcb435b65a6a..ca15d1bb5eefc 100644 --- a/src/test/compile-fail/unboxed-closures-wrong-abi.rs +++ b/src/test/compile-fail/unboxed-closures-wrong-abi.rs @@ -35,7 +35,6 @@ fn b() { fn c() { let z = call_it_once(square, 22); //~^ ERROR not implemented - //~| ERROR not implemented } fn main() { } diff --git a/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs b/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs index 150bf36dcc286..b960362aad7cd 100644 --- a/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs +++ b/src/test/compile-fail/unboxed-closures-wrong-arg-type-extern-fn.rs @@ -36,7 +36,6 @@ fn b() { fn c() { let z = call_it_once(square, 22); //~^ ERROR not implemented - //~| ERROR not implemented } fn main() { } diff --git a/src/test/compile-fail/warn-pub-extern-crate.rs b/src/test/compile-fail/warn-pub-extern-crate.rs new file mode 100644 index 0000000000000..fec0b8e1a4cc1 --- /dev/null +++ b/src/test/compile-fail/warn-pub-extern-crate.rs @@ -0,0 +1,18 @@ +// 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. + +// Check that `pub extern crate` gives a warning. + + +pub extern crate core; //~WARN `pub extern crate` does not work +//~^ ERROR core + +fn main() { +} diff --git a/src/test/compile-fail/warn-foreign-int-types.rs b/src/test/run-pass/foreign-int-types.rs similarity index 73% rename from src/test/compile-fail/warn-foreign-int-types.rs rename to src/test/run-pass/foreign-int-types.rs index b77f25a0a344f..5ea0ef6c7ba3b 100644 --- a/src/test/compile-fail/warn-foreign-int-types.rs +++ b/src/test/run-pass/foreign-int-types.rs @@ -13,9 +13,8 @@ mod xx { extern { - pub fn strlen(str: *const u8) -> usize; //~ ERROR found Rust type `usize` - pub fn foo(x: isize, y: usize); //~ ERROR found Rust type `isize` - //~^ ERROR found Rust type `usize` + pub fn strlen(str: *const u8) -> usize; + pub fn foo(x: isize, y: usize); } } diff --git a/src/test/run-pass/issue-27890.rs b/src/test/run-pass/issue-27890.rs new file mode 100644 index 0000000000000..a33882a833185 --- /dev/null +++ b/src/test/run-pass/issue-27890.rs @@ -0,0 +1,16 @@ +// 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. + +static PLUS_ONE: &'static (Fn(i32) -> i32 + Sync) = (&|x: i32| { x + 1 }) + as &'static (Fn(i32) -> i32 + Sync); + +fn main() { + assert_eq!(PLUS_ONE(2), 3); +} diff --git a/src/test/run-pass/issue-28550.rs b/src/test/run-pass/issue-28550.rs new file mode 100644 index 0000000000000..f44a535e8176e --- /dev/null +++ b/src/test/run-pass/issue-28550.rs @@ -0,0 +1,25 @@ +// 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. + +struct AT,T>(F::Output); +struct BT,T>(A); + +// Removing Option causes it to compile. +fn fooT>(f: F) -> Option> { + Some(B(A(f()))) +} + +fn main() { + let v = (|| foo(||4))(); + match v { + Some(B(A(4))) => {}, + _ => unreachable!() + } +}