Skip to content

Commit 20eba40

Browse files
committed
Merge pull request #29112 from brson/beta-next
Beta next
2 parents cce6ece + f492cf7 commit 20eba40

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+344
-108
lines changed

src/libcore/num/dec2flt/parse.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ pub fn parse_decimal(s: &str) -> ParseResult {
5959
let s = s.as_bytes();
6060
let (integral, s) = eat_digits(s);
6161
match s.first() {
62-
None => Valid(Decimal::new(integral, b"", 0)),
62+
None => {
63+
if integral.is_empty() {
64+
return Invalid; // No digits at all
65+
}
66+
Valid(Decimal::new(integral, b"", 0))
67+
}
6368
Some(&b'e') | Some(&b'E') => {
6469
if integral.is_empty() {
6570
return Invalid; // No digits before 'e'

src/libcore/ptr.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,13 @@ fnptr_impls_args! { A, B }
385385
fnptr_impls_args! { A, B, C }
386386
fnptr_impls_args! { A, B, C, D }
387387
fnptr_impls_args! { A, B, C, D, E }
388+
fnptr_impls_args! { A, B, C, D, E, F }
389+
fnptr_impls_args! { A, B, C, D, E, F, G }
390+
fnptr_impls_args! { A, B, C, D, E, F, G, H }
391+
fnptr_impls_args! { A, B, C, D, E, F, G, H, I }
392+
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J }
393+
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K }
394+
fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L }
388395

389396
// Comparison for pointers
390397
#[stable(feature = "rust1", since = "1.0.0")]

src/libcoretest/num/dec2flt/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,18 @@ fn lonely_dot() {
101101
assert_eq!(".".parse(), Ok(0.0));
102102
}
103103

104+
#[test]
105+
fn lonely_sign() {
106+
assert!("+".parse::<f32>().is_err());
107+
assert!("-".parse::<f64>().is_err());
108+
}
109+
110+
#[test]
111+
fn whitespace() {
112+
assert!(" 1.0".parse::<f32>().is_err());
113+
assert!("1.0 ".parse::<f64>().is_err());
114+
}
115+
104116
#[test]
105117
fn nan() {
106118
assert!("NaN".parse::<f32>().unwrap().is_nan());

src/librustc/middle/infer/mod.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use std::rc::Rc;
4343
use syntax::ast;
4444
use syntax::codemap;
4545
use syntax::codemap::{Span, DUMMY_SP};
46-
use util::nodemap::{FnvHashMap, NodeMap};
46+
use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
4747

4848
use self::combine::CombineFields;
4949
use self::region_inference::{RegionVarBindings, RegionSnapshot};
@@ -92,6 +92,10 @@ pub struct InferCtxt<'a, 'tcx: 'a> {
9292

9393
pub fulfillment_cx: RefCell<traits::FulfillmentContext<'tcx>>,
9494

95+
// the set of predicates on which errors have been reported, to
96+
// avoid reporting the same error twice.
97+
pub reported_trait_errors: RefCell<FnvHashSet<traits::TraitErrorKey<'tcx>>>,
98+
9599
// This is a temporary field used for toggling on normalization in the inference context,
96100
// as we move towards the approach described here:
97101
// 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>,
374378
region_vars: RegionVarBindings::new(tcx),
375379
parameter_environment: param_env.unwrap_or(tcx.empty_parameter_environment()),
376380
fulfillment_cx: RefCell::new(traits::FulfillmentContext::new(errors_will_be_reported)),
381+
reported_trait_errors: RefCell::new(FnvHashSet()),
377382
normalize: false,
378383
err_count_on_creation: tcx.sess.err_count()
379384
}
@@ -1389,9 +1394,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
13891394
self.resolve_type_vars_or_error(&ty)
13901395
}
13911396

1397+
pub fn tables_are_tcx_tables(&self) -> bool {
1398+
let tables: &RefCell<ty::Tables> = &self.tables;
1399+
let tcx_tables: &RefCell<ty::Tables> = &self.tcx.tables;
1400+
tables as *const _ == tcx_tables as *const _
1401+
}
1402+
13921403
pub fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
13931404
let ty = self.resolve_type_vars_if_possible(&ty);
1394-
if ty.needs_infer() {
1405+
if ty.needs_infer() ||
1406+
(ty.has_closure_types() && !self.tables_are_tcx_tables()) {
13951407
// this can get called from typeck (by euv), and moves_by_default
13961408
// rightly refuses to work with inference variables, but
13971409
// moves_by_default has a cache, which we want to use in other

src/librustc/middle/reachable.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -348,13 +348,17 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
348348
// this properly would result in the necessity of computing *type*
349349
// reachability, which might result in a compile time loss.
350350
fn mark_destructors_reachable(&mut self) {
351-
for adt in self.tcx.adt_defs() {
352-
if let Some(destructor_def_id) = adt.destructor() {
353-
if destructor_def_id.is_local() {
354-
self.reachable_symbols.insert(destructor_def_id.node);
351+
let drop_trait = match self.tcx.lang_items.drop_trait() {
352+
Some(id) => self.tcx.lookup_trait_def(id), None => { return }
353+
};
354+
drop_trait.for_each_impl(self.tcx, |drop_impl| {
355+
for destructor in &self.tcx.impl_items.borrow()[&drop_impl] {
356+
let destructor_did = destructor.def_id();
357+
if destructor_did.is_local() {
358+
self.reachable_symbols.insert(destructor_did.node);
355359
}
356360
}
357-
}
361+
})
358362
}
359363
}
360364

src/librustc/middle/traits/error_reporting.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,32 @@ use middle::def_id::DefId;
2828
use middle::infer::InferCtxt;
2929
use middle::ty::{self, ToPredicate, HasTypeFlags, ToPolyTraitRef, TraitRef, Ty};
3030
use middle::ty::fold::TypeFoldable;
31-
use std::collections::HashMap;
31+
use util::nodemap::{FnvHashMap, FnvHashSet};
32+
3233
use std::fmt;
3334
use syntax::codemap::Span;
3435
use rustc_front::attr::{AttributeMethods, AttrMetaMethods};
3536

37+
#[derive(Debug, PartialEq, Eq, Hash)]
38+
pub struct TraitErrorKey<'tcx> {
39+
is_warning: bool,
40+
span: Span,
41+
predicate: ty::Predicate<'tcx>
42+
}
43+
44+
impl<'tcx> TraitErrorKey<'tcx> {
45+
fn from_error<'a>(infcx: &InferCtxt<'a, 'tcx>,
46+
e: &FulfillmentError<'tcx>) -> Self {
47+
let predicate =
48+
infcx.resolve_type_vars_if_possible(&e.obligation.predicate);
49+
TraitErrorKey {
50+
is_warning: is_warning(&e.obligation),
51+
span: e.obligation.cause.span,
52+
predicate: infcx.tcx.erase_regions(&predicate)
53+
}
54+
}
55+
}
56+
3657
pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
3758
errors: &Vec<FulfillmentError<'tcx>>) {
3859
for error in errors {
@@ -42,6 +63,13 @@ pub fn report_fulfillment_errors<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
4263

4364
fn report_fulfillment_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
4465
error: &FulfillmentError<'tcx>) {
66+
let error_key = TraitErrorKey::from_error(infcx, error);
67+
debug!("report_fulfillment_errors({:?}) - key={:?}",
68+
error, error_key);
69+
if !infcx.reported_trait_errors.borrow_mut().insert(error_key) {
70+
debug!("report_fulfillment_errors: skipping duplicate");
71+
return;
72+
}
4573
match error.code {
4674
FulfillmentErrorCode::CodeSelectionError(ref e) => {
4775
report_selection_error(infcx, &error.obligation, e);
@@ -97,7 +125,7 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
97125
(gen.name.as_str().to_string(),
98126
trait_ref.substs.types.get(param, i)
99127
.to_string())
100-
}).collect::<HashMap<String, String>>();
128+
}).collect::<FnvHashMap<String, String>>();
101129
generic_map.insert("Self".to_string(),
102130
trait_ref.self_ty().to_string());
103131
let parser = Parser::new(&istring);
@@ -302,7 +330,11 @@ pub fn report_object_safety_error<'tcx>(tcx: &ty::ctxt<'tcx>,
302330
"the trait `{}` cannot be made into an object",
303331
tcx.item_path_str(trait_def_id));
304332

333+
let mut reported_violations = FnvHashSet();
305334
for violation in object_safety_violations(tcx, trait_def_id) {
335+
if !reported_violations.insert(violation.clone()) {
336+
continue;
337+
}
306338
match violation {
307339
ObjectSafetyViolation::SizedSelf => {
308340
tcx.sess.fileline_note(

src/librustc/middle/traits/fulfill.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ pub struct FulfillmentContext<'tcx> {
4949
// than the `SelectionCache`: it avoids duplicate errors and
5050
// permits recursive obligations, which are often generated from
5151
// traits like `Send` et al.
52+
//
53+
// Note that because of type inference, a predicate can still
54+
// occur twice in the predicates list, for example when 2
55+
// initially-distinct type variables are unified after being
56+
// inserted. Deduplicating the predicate set on selection had a
57+
// significant performance cost the last time I checked.
5258
duplicate_set: FulfilledPredicates<'tcx>,
5359

5460
// A list of all obligations that have been registered with this

src/librustc/middle/traits/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ use middle::subst;
2121
use middle::ty::{self, HasTypeFlags, Ty};
2222
use middle::ty::fold::TypeFoldable;
2323
use middle::infer::{self, fixup_err_to_string, InferCtxt};
24+
2425
use std::rc::Rc;
2526
use syntax::ast;
2627
use syntax::codemap::{Span, DUMMY_SP};
2728

29+
pub use self::error_reporting::TraitErrorKey;
2830
pub use self::error_reporting::report_fulfillment_errors;
2931
pub use self::error_reporting::report_overflow_error;
3032
pub use self::error_reporting::report_selection_error;

src/librustc/middle/traits/object_safety.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use middle::ty::{self, ToPolyTraitRef, Ty};
2727
use std::rc::Rc;
2828
use syntax::ast;
2929

30-
#[derive(Debug)]
30+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
3131
pub enum ObjectSafetyViolation<'tcx> {
3232
/// Self : Sized declared on the trait
3333
SizedSelf,

src/librustc/middle/ty/context.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,6 @@ pub struct ctxt<'tcx> {
245245
/// True if the variance has been computed yet; false otherwise.
246246
pub variance_computed: Cell<bool>,
247247

248-
/// A method will be in this list if and only if it is a destructor.
249-
pub destructors: RefCell<DefIdSet>,
250-
251248
/// Maps a DefId of a type to a list of its inherent impls.
252249
/// Contains implementations of methods that are inherent to a type.
253250
/// Methods in these implementations don't need to be exported.
@@ -475,7 +472,6 @@ impl<'tcx> ctxt<'tcx> {
475472
normalized_cache: RefCell::new(FnvHashMap()),
476473
lang_items: lang_items,
477474
provided_method_sources: RefCell::new(DefIdMap()),
478-
destructors: RefCell::new(DefIdSet()),
479475
inherent_impls: RefCell::new(DefIdMap()),
480476
impl_items: RefCell::new(DefIdMap()),
481477
used_unsafe: RefCell::new(NodeSet()),

0 commit comments

Comments
 (0)