diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index a9d6997359085..7cc963bed358f 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -39,7 +39,7 @@ //! distribution. //! //! * `rust_begin_unwind` - This function takes three arguments, a -//! `fmt::Arguments`, a `&str`, and a `uint`. These three arguments dictate +//! `fmt::Arguments`, a `&str`, and a `usize`. These three arguments dictate //! the panic message, the file at which panic was invoked, and the line. //! It is up to consumers of this core library to define this panic //! function; it is only required to never return. @@ -88,14 +88,12 @@ mod int_macros; #[macro_use] mod uint_macros; -#[path = "num/int.rs"] pub mod int; #[path = "num/isize.rs"] pub mod isize; #[path = "num/i8.rs"] pub mod i8; #[path = "num/i16.rs"] pub mod i16; #[path = "num/i32.rs"] pub mod i32; #[path = "num/i64.rs"] pub mod i64; -#[path = "num/uint.rs"] pub mod uint; #[path = "num/usize.rs"] pub mod usize; #[path = "num/u8.rs"] pub mod u8; #[path = "num/u16.rs"] pub mod u16; diff --git a/src/libcore/num/int.rs b/src/libcore/num/int.rs deleted file mode 100644 index 2132b9516abad..0000000000000 --- a/src/libcore/num/int.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2012-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. - -//! Deprecated: replaced by `isize`. -//! -//! The rollout of the new type will gradually take place over the -//! alpha cycle along with the development of clearer conventions -//! around integer types. - -#![unstable(feature = "core")] -#![deprecated(since = "1.0.0", reason = "replaced by isize")] - -#[cfg(target_pointer_width = "32")] int_module! { int, 32 } -#[cfg(target_pointer_width = "64")] int_module! { int, 64 } diff --git a/src/libcore/num/uint.rs b/src/libcore/num/uint.rs deleted file mode 100644 index f66a0eed97161..0000000000000 --- a/src/libcore/num/uint.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2012-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. - -//! Deprecated: replaced by `usize`. -//! -//! The rollout of the new type will gradually take place over the -//! alpha cycle along with the development of clearer conventions -//! around integer types. - -#![unstable(feature = "core")] -#![deprecated(since = "1.0.0", reason = "replaced by usize")] - -uint_module! { uint, int, ::int::BITS } diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 8a27400389f4a..abf88583c03ff 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -12,7 +12,7 @@ use core::iter::*; use core::iter::order::*; use core::iter::MinMaxResult::*; use core::num::SignedInt; -use core::uint; +use core::usize; use core::cmp; use test::Bencher; @@ -292,7 +292,7 @@ fn test_unfoldr() { fn test_cycle() { let cycle_len = 3; let it = count(0, 1).take(cycle_len).cycle(); - assert_eq!(it.size_hint(), (uint::MAX, None)); + assert_eq!(it.size_hint(), (usize::MAX, None)); for (i, x) in it.take(100).enumerate() { assert_eq!(i % cycle_len, x); } @@ -365,19 +365,19 @@ fn test_iterator_size_hint() { let v2 = &[10, 11, 12]; let vi = v.iter(); - assert_eq!(c.size_hint(), (uint::MAX, None)); + assert_eq!(c.size_hint(), (usize::MAX, None)); assert_eq!(vi.clone().size_hint(), (10, Some(10))); assert_eq!(c.clone().take(5).size_hint(), (5, Some(5))); assert_eq!(c.clone().skip(5).size_hint().1, None); assert_eq!(c.clone().take_while(|_| false).size_hint(), (0, None)); assert_eq!(c.clone().skip_while(|_| false).size_hint(), (0, None)); - assert_eq!(c.clone().enumerate().size_hint(), (uint::MAX, None)); - assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (uint::MAX, None)); + assert_eq!(c.clone().enumerate().size_hint(), (usize::MAX, None)); + assert_eq!(c.clone().chain(vi.clone().cloned()).size_hint(), (usize::MAX, None)); assert_eq!(c.clone().zip(vi.clone()).size_hint(), (10, Some(10))); assert_eq!(c.clone().scan(0, |_,_| Some(0)).size_hint(), (0, None)); assert_eq!(c.clone().filter(|_| false).size_hint(), (0, None)); - assert_eq!(c.clone().map(|_| 0).size_hint(), (uint::MAX, None)); + assert_eq!(c.clone().map(|_| 0).size_hint(), (usize::MAX, None)); assert_eq!(c.filter_map(|_| Some(0)).size_hint(), (0, None)); assert_eq!(vi.clone().take(5).size_hint(), (5, Some(5))); @@ -753,7 +753,7 @@ fn test_range() { assert_eq!((0..100).size_hint(), (100, Some(100))); // this test is only meaningful when sizeof uint < sizeof u64 - assert_eq!((uint::MAX - 1..uint::MAX).size_hint(), (1, Some(1))); + assert_eq!((usize::MAX - 1..usize::MAX).size_hint(), (1, Some(1))); assert_eq!((-10..-1).size_hint(), (9, Some(9))); assert_eq!((-1..-10).size_hint(), (0, Some(0))); } diff --git a/src/libcoretest/num/int.rs b/src/libcoretest/num/int.rs deleted file mode 100644 index be8dfd02ee196..0000000000000 --- a/src/libcoretest/num/int.rs +++ /dev/null @@ -1,11 +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. - -int_module!(int, int); diff --git a/src/libcoretest/num/int_macros.rs b/src/libcoretest/num/int_macros.rs index c33729876ccf3..d1bfb475b074b 100644 --- a/src/libcoretest/num/int_macros.rs +++ b/src/libcoretest/num/int_macros.rs @@ -12,7 +12,7 @@ macro_rules! int_module { ($T:ty, $T_i:ident) => ( #[cfg(test)] mod tests { use core::$T_i::*; - use core::int; + use core::isize; use core::num::{FromStrRadix, Int, SignedInt}; use core::ops::{Shl, Shr, Not, BitXor, BitAnd, BitOr}; use num; @@ -153,7 +153,7 @@ mod tests { fn test_signed_checked_div() { assert!(10.checked_div(2) == Some(5)); assert!(5.checked_div(0) == None); - assert!(int::MIN.checked_div(-1) == None); + assert!(isize::MIN.checked_div(-1) == None); } #[test] diff --git a/src/libcoretest/num/mod.rs b/src/libcoretest/num/mod.rs index 03f6e51a3498a..1cd1989c11dc3 100644 --- a/src/libcoretest/num/mod.rs +++ b/src/libcoretest/num/mod.rs @@ -21,7 +21,6 @@ mod i8; mod i16; mod i32; mod i64; -mod int; #[macro_use] mod uint_macros; @@ -30,7 +29,6 @@ mod u8; mod u16; mod u32; mod u64; -mod uint; /// Helper function for testing numeric operations pub fn test_num(ten: T, two: T) where diff --git a/src/libcoretest/num/uint.rs b/src/libcoretest/num/uint.rs deleted file mode 100644 index 395e55cf255d2..0000000000000 --- a/src/libcoretest/num/uint.rs +++ /dev/null @@ -1,11 +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. - -uint_module!(uint, uint); diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 4e329897e1ab2..6240b0e6afdd5 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -963,7 +963,7 @@ fn test_split_within() { "little lamb".to_string(), "Little lamb".to_string() ]); - t("\nMary had a little lamb\nLittle lamb\n", ::std::uint::MAX, + t("\nMary had a little lamb\nLittle lamb\n", ::std::usize::MAX, &["Mary had a little lamb\nLittle lamb".to_string()]); } diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs index 74a95b3aba056..42143b06ca0e3 100644 --- a/src/liblibc/lib.rs +++ b/src/liblibc/lib.rs @@ -1115,7 +1115,6 @@ pub mod types { pub mod posix88 { pub type off_t = i64; pub type dev_t = u32; - pub type ino_t = u32; pub type pid_t = i32; pub type uid_t = u32; pub type gid_t = u32; diff --git a/src/librand/rand_impls.rs b/src/librand/rand_impls.rs index d5c5d5004657e..74d2c408060cb 100644 --- a/src/librand/rand_impls.rs +++ b/src/librand/rand_impls.rs @@ -12,18 +12,18 @@ use core::prelude::*; use core::char; -use core::int; -use core::uint; +use core::isize; +use core::usize; use {Rand,Rng}; -impl Rand for int { +impl Rand for isize { #[inline] - fn rand(rng: &mut R) -> int { - if int::BITS == 32 { - rng.gen::() as int + fn rand(rng: &mut R) -> isize { + if isize::BITS == 32 { + rng.gen::() as isize } else { - rng.gen::() as int + rng.gen::() as isize } } } @@ -56,13 +56,13 @@ impl Rand for i64 { } } -impl Rand for uint { +impl Rand for usize { #[inline] - fn rand(rng: &mut R) -> uint { - if uint::BITS == 32 { - rng.gen::() as uint + fn rand(rng: &mut R) -> usize { + if usize::BITS == 32 { + rng.gen::() as usize } else { - rng.gen::() as uint + rng.gen::() as usize } } } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 2b968736ffd9a..f635c77af9b2a 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -612,7 +612,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> { } fn visit_trait_item(&mut self, m: &ast::TraitItem) { - run_lints!(self, check_trait_method, m); + run_lints!(self, check_trait_item, m); visit::walk_trait_item(self, m); } diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index f3fa3b8846ca2..506d20133bdc7 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -144,7 +144,7 @@ pub trait LintPass { fn check_fn(&mut self, _: &Context, _: FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { } fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { } - fn check_trait_method(&mut self, _: &Context, _: &ast::TraitItem) { } + fn check_trait_item(&mut self, _: &Context, _: &ast::TraitItem) { } fn check_struct_def(&mut self, _: &Context, _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { } fn check_struct_def_post(&mut self, _: &Context, diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 2ac019aa964dc..5cb034667cc64 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -51,8 +51,8 @@ //! enclosing function. On the way down the tree, it identifies those AST //! nodes and variable IDs that will be needed for the liveness analysis //! and assigns them contiguous IDs. The liveness id for an AST node is -//! called a `live_node` (it's a newtype'd uint) and the id for a variable -//! is called a `variable` (another newtype'd uint). +//! called a `live_node` (it's a newtype'd usize) and the id for a variable +//! is called a `variable` (another newtype'd usize). //! //! On the way back up the tree, as we are about to exit from a function //! declaration we allocate a `liveness` instance. Now that we know @@ -118,7 +118,7 @@ use middle::ty::ClosureTyper; use lint; use util::nodemap::NodeMap; -use std::{fmt, old_io, uint}; +use std::{fmt, old_io, usize}; use std::rc::Rc; use std::iter::repeat; use syntax::ast::{self, NodeId, Expr}; @@ -138,17 +138,17 @@ enum LoopKind<'a> { } #[derive(Copy, PartialEq)] -struct Variable(uint); +struct Variable(usize); #[derive(Copy, PartialEq)] -struct LiveNode(uint); +struct LiveNode(usize); impl Variable { - fn get(&self) -> uint { let Variable(v) = *self; v } + fn get(&self) -> usize { let Variable(v) = *self; v } } impl LiveNode { - fn get(&self) -> uint { let LiveNode(v) = *self; v } + fn get(&self) -> usize { let LiveNode(v) = *self; v } } impl Clone for LiveNode { @@ -232,11 +232,11 @@ impl fmt::Debug for Variable { impl LiveNode { fn is_valid(&self) -> bool { - self.get() != uint::MAX + self.get() != usize::MAX } } -fn invalid_node() -> LiveNode { LiveNode(uint::MAX) } +fn invalid_node() -> LiveNode { LiveNode(usize::MAX) } struct CaptureInfo { ln: LiveNode, @@ -260,8 +260,8 @@ enum VarKind { struct IrMaps<'a, 'tcx: 'a> { tcx: &'a ty::ctxt<'tcx>, - num_live_nodes: uint, - num_vars: uint, + num_live_nodes: usize, + num_vars: usize, live_node_map: NodeMap, variable_map: NodeMap, capture_info_map: NodeMap>>, @@ -540,9 +540,9 @@ struct Specials { clean_exit_var: Variable } -static ACC_READ: uint = 1; -static ACC_WRITE: uint = 2; -static ACC_USE: uint = 4; +static ACC_READ: u32 = 1; +static ACC_WRITE: u32 = 2; +static ACC_USE: u32 = 4; struct Liveness<'a, 'tcx: 'a> { ir: &'a mut IrMaps<'a, 'tcx>, @@ -631,7 +631,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { succ } - fn idx(&self, ln: LiveNode, var: Variable) -> uint { + fn idx(&self, ln: LiveNode, var: Variable) -> usize { ln.get() * self.ir.num_vars + var.get() } @@ -670,7 +670,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn indices2(&mut self, ln: LiveNode, succ_ln: LiveNode, mut op: F) where - F: FnMut(&mut Liveness<'a, 'tcx>, uint, uint), + F: FnMut(&mut Liveness<'a, 'tcx>, usize, usize), { let node_base_idx = self.idx(ln, Variable(0)); let succ_base_idx = self.idx(succ_ln, Variable(0)); @@ -684,7 +684,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { ln: LiveNode, mut test: F) -> old_io::IoResult<()> where - F: FnMut(uint) -> LiveNode, + F: FnMut(usize) -> LiveNode, { let node_base_idx = self.idx(ln, Variable(0)); for var_idx in 0..self.ir.num_vars { @@ -807,7 +807,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } // Either read, write, or both depending on the acc bitset - fn acc(&mut self, ln: LiveNode, var: Variable, acc: uint) { + fn acc(&mut self, ln: LiveNode, var: Variable, acc: u32) { debug!("{:?} accesses[{:x}] {:?}: {}", ln, acc, var, self.ln_str(ln)); @@ -1283,7 +1283,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } // see comment on propagate_through_lvalue() - fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: uint) + fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: u32) -> LiveNode { match expr.node { ast::ExprPath(..) => { @@ -1298,7 +1298,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } } - fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: uint) + fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: u32) -> LiveNode { match self.ir.tcx.def_map.borrow()[expr.id].full_def() { DefLocal(nid) => { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index d0fccf6495a0a..fe047d2334eec 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -28,8 +28,6 @@ //! Use the former for unit-like structs and the latter for structs with //! a `pub fn new()`. -use self::MethodContext::*; - use metadata::{csearch, decoder}; use middle::def::*; use middle::subst::Substs; @@ -228,7 +226,9 @@ impl LintPass for TypeLimits { ast::LitInt(v, ast::UnsuffixedIntLit(ast::Plus)) => { let int_type = if let ast::TyIs(_) = t { cx.sess().target.int_type - } else { t }; + } else { + t + }; let (min, max) = int_ty_range(int_type); let negative = self.negated_expr_id == e.id; @@ -245,14 +245,16 @@ impl LintPass for TypeLimits { ty::ty_uint(t) => { let uint_type = if let ast::TyUs(_) = t { cx.sess().target.uint_type - } else { t }; + } else { + t + }; let (min, max) = uint_ty_range(uint_type); let lit_val: u64 = match lit.node { ast::LitByte(_v) => return, // _v is u8, within range by definition ast::LitInt(v, _) => v, _ => panic!() }; - if lit_val < min || lit_val > max { + if lit_val < min || lit_val > max { cx.span_lint(OVERFLOWING_LITERALS, e.span, &*format!("literal out of range for {:?}", t)); } @@ -262,9 +264,9 @@ impl LintPass for TypeLimits { let lit_val: f64 = match lit.node { ast::LitFloat(ref v, _) | ast::LitFloatUnsuffixed(ref v) => { - match v.parse().ok() { - Some(f) => f, - None => return + match v.parse() { + Ok(f) => f, + Err(_) => return } } _ => panic!() @@ -302,52 +304,52 @@ impl LintPass for TypeLimits { }) } - // for int & uint, be conservative with the warnings, so that the + // for isize & usize, be conservative with the warnings, so that the // warnings are consistent between 32- and 64-bit platforms fn int_ty_range(int_ty: ast::IntTy) -> (i64, i64) { match int_ty { - ast::TyIs(_) => (i64::MIN, i64::MAX), - ast::TyI8 => (i8::MIN as i64, i8::MAX as i64), - ast::TyI16 => (i16::MIN as i64, i16::MAX as i64), - ast::TyI32 => (i32::MIN as i64, i32::MAX as i64), - ast::TyI64 => (i64::MIN, i64::MAX) + ast::TyIs(_) => (i64::MIN, i64::MAX), + ast::TyI8 => (i8::MIN as i64, i8::MAX as i64), + ast::TyI16 => (i16::MIN as i64, i16::MAX as i64), + ast::TyI32 => (i32::MIN as i64, i32::MAX as i64), + ast::TyI64 => (i64::MIN, i64::MAX) } } fn uint_ty_range(uint_ty: ast::UintTy) -> (u64, u64) { match uint_ty { - ast::TyUs(_) => (u64::MIN, u64::MAX), - ast::TyU8 => (u8::MIN as u64, u8::MAX as u64), - ast::TyU16 => (u16::MIN as u64, u16::MAX as u64), - ast::TyU32 => (u32::MIN as u64, u32::MAX as u64), - ast::TyU64 => (u64::MIN, u64::MAX) + ast::TyUs(_) => (u64::MIN, u64::MAX), + ast::TyU8 => (u8::MIN as u64, u8::MAX as u64), + ast::TyU16 => (u16::MIN as u64, u16::MAX as u64), + ast::TyU32 => (u32::MIN as u64, u32::MAX as u64), + ast::TyU64 => (u64::MIN, u64::MAX) } } fn float_ty_range(float_ty: ast::FloatTy) -> (f64, f64) { match float_ty { - ast::TyF32 => (f32::MIN as f64, f32::MAX as f64), - ast::TyF64 => (f64::MIN, f64::MAX) + ast::TyF32 => (f32::MIN as f64, f32::MAX as f64), + ast::TyF64 => (f64::MIN, f64::MAX) } } fn int_ty_bits(int_ty: ast::IntTy, target_int_ty: ast::IntTy) -> u64 { match int_ty { - ast::TyIs(_) => int_ty_bits(target_int_ty, target_int_ty), - ast::TyI8 => i8::BITS as u64, - ast::TyI16 => i16::BITS as u64, - ast::TyI32 => i32::BITS as u64, - ast::TyI64 => i64::BITS as u64 + ast::TyIs(_) => int_ty_bits(target_int_ty, target_int_ty), + ast::TyI8 => i8::BITS as u64, + ast::TyI16 => i16::BITS as u64, + ast::TyI32 => i32::BITS as u64, + ast::TyI64 => i64::BITS as u64 } } fn uint_ty_bits(uint_ty: ast::UintTy, target_uint_ty: ast::UintTy) -> u64 { match uint_ty { - ast::TyUs(_) => uint_ty_bits(target_uint_ty, target_uint_ty), - ast::TyU8 => u8::BITS as u64, - ast::TyU16 => u16::BITS as u64, - ast::TyU32 => u32::BITS as u64, - ast::TyU64 => u64::BITS as u64 + ast::TyUs(_) => uint_ty_bits(target_uint_ty, target_uint_ty), + ast::TyU8 => u8::BITS as u64, + ast::TyU16 => u16::BITS as u64, + ast::TyU32 => u32::BITS as u64, + ast::TyU64 => u64::BITS as u64 } } @@ -360,7 +362,11 @@ impl LintPass for TypeLimits { }; // Normalize the binop so that the literal is always on the RHS in // the comparison - let norm_binop = if swap { rev_binop(binop) } else { binop }; + let norm_binop = if swap { + rev_binop(binop) + } else { + binop + }; match ty::expr_ty(tcx, expr).sty { ty::ty_int(int_ty) => { let (min, max) = int_ty_range(int_ty); @@ -432,9 +438,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { if !ty::is_ffi_safe(self.cx.tcx, tty) { self.cx.span_lint(IMPROPER_CTYPES, sp, - "found type without foreign-function-safe - representation annotation in foreign module, consider \ - adding a #[repr(...)] attribute to the type"); + "found type without foreign-function-safe \ + representation annotation in foreign module, consider \ + adding a #[repr(...)] attribute to the type"); } } _ => () @@ -595,7 +601,7 @@ impl LintPass for RawPointerDerive { fn check_item(&mut self, cx: &Context, item: &ast::Item) { if !attr::contains_name(&item.attrs, "automatically_derived") { - return + return; } let did = match item.node { ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => { @@ -603,7 +609,7 @@ impl LintPass for RawPointerDerive { if let &Some(ref trait_ref) = t_ref_opt { let def_id = ty::trait_ref_to_def_id(cx.tcx, trait_ref); if Some(def_id) == cx.tcx.lang_items.copy_trait() { - return + return; } } @@ -615,12 +621,16 @@ impl LintPass for RawPointerDerive { } _ => return, }; - if !ast_util::is_local(did) { return } + if !ast_util::is_local(did) { + return; + } let item = match cx.tcx.map.find(did.node) { Some(ast_map::NodeItem(item)) => item, _ => return, }; - if !self.checked_raw_pointers.insert(item.id) { return } + if !self.checked_raw_pointers.insert(item.id) { + return; + } match item.node { ast::ItemStruct(..) | ast::ItemEnum(..) => { let mut visitor = RawPtrDeriveVisitor { cx: cx }; @@ -646,6 +656,7 @@ impl LintPass for UnusedAttributes { } fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) { + // Note that check_name() marks the attribute as used if it matches. for &(ref name, ty) in KNOWN_ATTRIBUTES { match ty { AttributeType::Whitelisted @@ -730,23 +741,24 @@ impl LintPass for UnusedResults { } let t = ty::expr_ty(cx.tcx, expr); - let mut warned = false; - match t.sty { + let warned = match t.sty { ty::ty_tup(ref tys) if tys.is_empty() => return, ty::ty_bool => return, ty::ty_struct(did, _) | ty::ty_enum(did, _) => { if ast_util::is_local(did) { if let ast_map::NodeItem(it) = cx.tcx.map.get(did.node) { - warned |= check_must_use(cx, &it.attrs, s.span); + check_must_use(cx, &it.attrs, s.span) + } else { + false } } else { let attrs = csearch::get_item_attrs(&cx.sess().cstore, did); - warned |= check_must_use(cx, &attrs[..], s.span); + check_must_use(cx, &attrs[..], s.span) } } - _ => {} - } + _ => false, + }; if !warned { cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); } @@ -785,7 +797,9 @@ impl NonCamelCaseTypes { fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) { fn is_camel_case(ident: ast::Ident) -> bool { let ident = token::get_ident(ident); - if ident.is_empty() { return true; } + if ident.is_empty() { + return true; + } let ident = ident.trim_matches('_'); // start with a non-lowercase letter rather than non-uppercase @@ -795,8 +809,11 @@ impl NonCamelCaseTypes { fn to_camel_case(s: &str) -> String { s.split('_').flat_map(|word| word.chars().enumerate().map(|(i, c)| - if i == 0 { c.to_uppercase() } - else { c } + if i == 0 { + c.to_uppercase() + } else { + c + } )).collect() } @@ -820,11 +837,13 @@ impl LintPass for NonCamelCaseTypes { } fn check_item(&mut self, cx: &Context, it: &ast::Item) { - let has_extern_repr = it.attrs.iter().map(|attr| { + let has_extern_repr = it.attrs.iter().any(|attr| { attr::find_repr_attrs(cx.tcx.sess.diagnostic(), attr).iter() .any(|r| r == &attr::ReprExtern) - }).any(|x| x); - if has_extern_repr { return } + }); + if has_extern_repr { + return; + } match it.node { ast::ItemTy(..) | ast::ItemStruct(..) => { @@ -834,7 +853,9 @@ impl LintPass for NonCamelCaseTypes { self.check_case(cx, "trait", it.ident, it.span) } ast::ItemEnum(ref enum_definition, _) => { - if has_extern_repr { return } + if has_extern_repr { + return; + } self.check_case(cx, "type", it.ident, it.span); for variant in &enum_definition.variants { self.check_case(cx, "variant", variant.node.name, variant.span); @@ -866,32 +887,28 @@ fn method_context(cx: &Context, m: &ast::Method) -> MethodContext { match cx.tcx.impl_or_trait_items.borrow().get(&did).cloned() { None => cx.sess().span_bug(m.span, "missing method descriptor?!"), - Some(md) => { - match md { - ty::MethodTraitItem(md) => { - match md.container { - ty::TraitContainer(..) => TraitDefaultImpl, - ty::ImplContainer(cid) => { - match ty::impl_trait_ref(cx.tcx, cid) { - Some(..) => TraitImpl, - None => PlainImpl - } - } + Some(ty::MethodTraitItem(md)) => { + match md.container { + ty::TraitContainer(..) => MethodContext::TraitDefaultImpl, + ty::ImplContainer(cid) => { + match ty::impl_trait_ref(cx.tcx, cid) { + Some(..) => MethodContext::TraitImpl, + None => MethodContext::PlainImpl } } - ty::TypeTraitItem(typedef) => { - match typedef.container { - ty::TraitContainer(..) => TraitDefaultImpl, - ty::ImplContainer(cid) => { - match ty::impl_trait_ref(cx.tcx, cid) { - Some(..) => TraitImpl, - None => PlainImpl - } - } + } + }, + Some(ty::TypeTraitItem(typedef)) => { + match typedef.container { + ty::TraitContainer(..) => MethodContext::TraitDefaultImpl, + ty::ImplContainer(cid) => { + match ty::impl_trait_ref(cx.tcx, cid) { + Some(..) => MethodContext::TraitImpl, + None => MethodContext::PlainImpl } } } - } + }, } } @@ -912,12 +929,16 @@ impl NonSnakeCase { if c == '_' { words.push(String::new()); true - } else { false } + } else { + false + } }); for s in str.split('_') { let mut last_upper = false; let mut buf = String::new(); - if s.is_empty() { continue; } + if s.is_empty() { + continue; + } for ch in s.chars() { if !buf.is_empty() && buf != "'" && ch.is_uppercase() @@ -936,7 +957,9 @@ impl NonSnakeCase { fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) { fn is_snake_case(ident: ast::Ident) -> bool { let ident = token::get_ident(ident); - if ident.is_empty() { return true; } + if ident.is_empty() { + return true; + } let ident = ident.trim_left_matches('\''); let ident = ident.trim_matches('_'); @@ -979,14 +1002,17 @@ impl LintPass for NonSnakeCase { _: &ast::Block, span: Span, _: ast::NodeId) { match fk { visit::FkMethod(ident, _, m) => match method_context(cx, m) { - PlainImpl - => self.check_snake_case(cx, "method", ident, span), - TraitDefaultImpl - => self.check_snake_case(cx, "trait method", ident, span), + MethodContext::PlainImpl => { + self.check_snake_case(cx, "method", ident, span) + }, + MethodContext::TraitDefaultImpl => { + self.check_snake_case(cx, "trait method", ident, span) + }, _ => (), }, - visit::FkItemFn(ident, _, _, _) - => self.check_snake_case(cx, "function", ident, span), + visit::FkItemFn(ident, _, _, _) => { + self.check_snake_case(cx, "function", ident, span) + }, _ => (), } } @@ -1015,7 +1041,7 @@ impl LintPass for NonSnakeCase { } fn check_struct_def(&mut self, cx: &Context, s: &ast::StructDef, - _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { + _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { for sf in &s.fields { if let ast::StructField_ { kind: ast::NamedField(ident, _), .. } = sf.node { self.check_snake_case(cx, "structure field", ident, sf.span); @@ -1094,13 +1120,12 @@ pub struct UnusedParens; impl UnusedParens { fn check_unused_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str, - struct_lit_needs_parens: bool) { + struct_lit_needs_parens: bool) { if let ast::ExprParen(ref inner) = value.node { let necessary = struct_lit_needs_parens && contains_exterior_struct_lit(&**inner); if !necessary { cx.span_lint(UNUSED_PARENS, value.span, - &format!("unnecessary parentheses around {}", - msg)) + &format!("unnecessary parentheses around {}", msg)) } } @@ -1193,26 +1218,17 @@ impl LintPass for UnusedImportBraces { } fn check_item(&mut self, cx: &Context, item: &ast::Item) { - match item.node { - ast::ItemUse(ref view_path) => { - match view_path.node { - ast::ViewPathList(_, ref items) => { - if items.len() == 1 { - match items[0].node { - ast::PathListIdent {ref name, ..} => { - let m = format!("braces around {} is unnecessary", - &token::get_ident(*name)); - cx.span_lint(UNUSED_IMPORT_BRACES, item.span, - &m[..]); - }, - _ => () - } - } + if let ast::ItemUse(ref view_path) = item.node { + if let ast::ViewPathList(_, ref items) = view_path.node { + if items.len() == 1 { + if let ast::PathListIdent {ref name, ..} = items[0].node { + let m = format!("braces around {} is unnecessary", + &token::get_ident(*name)); + cx.span_lint(UNUSED_IMPORT_BRACES, item.span, + &m[..]); } - _ => () } - }, - _ => () + } } } } @@ -1234,9 +1250,10 @@ impl LintPass for NonShorthandFieldPatterns { fn check_pat(&mut self, cx: &Context, pat: &ast::Pat) { let def_map = cx.tcx.def_map.borrow(); if let ast::PatStruct(_, ref v, _) = pat.node { - let field_pats = v.iter() - .filter(|fieldpat| !fieldpat.node.is_shorthand) - .filter(|fieldpat| { + let field_pats = v.iter().filter(|fieldpat| { + if fieldpat.node.is_shorthand { + return false; + } let def = def_map.get(&fieldpat.node.pat.id).map(|d| d.full_def()); def == Some(def::DefLocal(fieldpat.node.pat.id)) }); @@ -1482,10 +1499,14 @@ impl MissingDoc { desc: &'static str) { // If we're building a test harness, then warning about // documentation is probably not really relevant right now. - if cx.sess().opts.test { return } + if cx.sess().opts.test { + return; + } // `#[doc(hidden)]` disables missing_docs check. - if self.doc_hidden() { return } + if self.doc_hidden() { + return; + } // Only check publicly-visible items, using the result from the privacy pass. // It's an option so the crate root can also use this function (it doesn't @@ -1504,7 +1525,7 @@ impl MissingDoc { }); if !has_doc { cx.span_lint(MISSING_DOCS, sp, - &format!("missing documentation for {}", desc)); + &format!("missing documentation for {}", desc)); } } } @@ -1528,20 +1549,19 @@ impl LintPass for MissingDoc { self.doc_hidden_stack.pop().expect("empty doc_hidden_stack"); } - fn check_struct_def(&mut self, _: &Context, - _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, id: ast::NodeId) { + fn check_struct_def(&mut self, _: &Context, _: &ast::StructDef, + _: ast::Ident, _: &ast::Generics, id: ast::NodeId) { self.struct_def_stack.push(id); } - fn check_struct_def_post(&mut self, _: &Context, - _: &ast::StructDef, _: ast::Ident, _: &ast::Generics, id: ast::NodeId) { + fn check_struct_def_post(&mut self, _: &Context, _: &ast::StructDef, + _: ast::Ident, _: &ast::Generics, id: ast::NodeId) { let popped = self.struct_def_stack.pop().expect("empty struct_def_stack"); assert!(popped == id); } fn check_crate(&mut self, cx: &Context, krate: &ast::Crate) { - self.check_missing_docs_attrs(cx, None, &krate.attrs, - krate.span, "crate"); + self.check_missing_docs_attrs(cx, None, &krate.attrs, krate.span, "crate"); } fn check_item(&mut self, cx: &Context, it: &ast::Item) { @@ -1554,30 +1574,28 @@ impl LintPass for MissingDoc { ast::ItemTy(..) => "a type alias", _ => return }; - self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, - it.span, desc); + self.check_missing_docs_attrs(cx, Some(it.id), &it.attrs, it.span, desc); } - fn check_fn(&mut self, cx: &Context, - fk: visit::FnKind, _: &ast::FnDecl, - _: &ast::Block, _: Span, _: ast::NodeId) { + fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl, + _: &ast::Block, _: Span, _: ast::NodeId) { if let visit::FkMethod(_, _, m) = fk { // If the method is an impl for a trait, don't doc. - if method_context(cx, m) == TraitImpl { return; } + if method_context(cx, m) == MethodContext::TraitImpl { + return; + } // Otherwise, doc according to privacy. This will also check // doc for default methods defined on traits. - self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs, - m.span, "a method"); + self.check_missing_docs_attrs(cx, Some(m.id), &m.attrs, m.span, "a method"); } } fn check_ty_method(&mut self, cx: &Context, tm: &ast::TypeMethod) { - self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs, - tm.span, "a type method"); + self.check_missing_docs_attrs(cx, Some(tm.id), &tm.attrs, tm.span, "a type method"); } - fn check_trait_method(&mut self, cx: &Context, it: &ast::TraitItem) { + fn check_trait_item(&mut self, cx: &Context, it: &ast::TraitItem) { if let ast::TraitItem::TypeTraitItem(ref ty) = *it { let assoc_ty = &ty.ty_param; self.check_missing_docs_attrs(cx, Some(assoc_ty.id), &ty.attrs, @@ -1598,8 +1616,7 @@ impl LintPass for MissingDoc { } fn check_variant(&mut self, cx: &Context, v: &ast::Variant, _: &ast::Generics) { - self.check_missing_docs_attrs(cx, Some(v.node.id), &v.node.attrs, - v.span, "a variant"); + self.check_missing_docs_attrs(cx, Some(v.node.id), &v.node.attrs, v.span, "a variant"); assert!(!self.in_variant); self.in_variant = true; } @@ -1626,18 +1643,18 @@ impl LintPass for MissingCopyImplementations { fn check_item(&mut self, cx: &Context, item: &ast::Item) { if !cx.exported_items.contains(&item.id) { - return + return; } if cx.tcx .destructor_for_type .borrow() .contains_key(&ast_util::local_def(item.id)) { - return + return; } let ty = match item.node { ast::ItemStruct(_, ref ast_generics) => { if ast_generics.is_parameterized() { - return + return; } ty::mk_struct(cx.tcx, ast_util::local_def(item.id), @@ -1645,7 +1662,7 @@ impl LintPass for MissingCopyImplementations { } ast::ItemEnum(_, ref ast_generics) => { if ast_generics.is_parameterized() { - return + return; } ty::mk_enum(cx.tcx, ast_util::local_def(item.id), @@ -1655,7 +1672,7 @@ impl LintPass for MissingCopyImplementations { }; let parameter_environment = ty::empty_parameter_environment(cx.tcx); if !ty::type_moves_by_default(¶meter_environment, item.span, ty) { - return + return; } if ty::can_type_implement_copy(¶meter_environment, item.span, ty).is_ok() { cx.span_lint(MISSING_COPY_IMPLEMENTATIONS, @@ -1709,10 +1726,10 @@ impl LintPass for MissingDebugImplementations { let impls = match impls.get(&debug) { Some(impls) => { impls.borrow().iter() - .filter(|d| d.krate == ast::LOCAL_CRATE) - .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node))) - .map(|d| d.node) - .collect() + .filter(|d| d.krate == ast::LOCAL_CRATE) + .filter_map(|d| ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node))) + .map(|d| d.node) + .collect() } None => NodeSet(), }; @@ -1741,8 +1758,7 @@ pub struct Stability; impl Stability { fn lint(&self, cx: &Context, _id: ast::DefId, span: Span, stability: &Option) { - - // deprecated attributes apply in-crate and cross-crate + // Deprecated attributes apply in-crate and cross-crate. let (lint, label) = match *stability { Some(attr::Stability { deprecated_since: Some(_), .. }) => (DEPRECATED, "deprecated"), @@ -1857,25 +1873,27 @@ impl LintPass for UnconditionalRecursion { let mut visited = BitSet::new(); while let Some(idx) = work_queue.pop() { - let cfg_id = idx.node_id(); if idx == cfg.exit { // found a path! reached_exit_without_self_call = true; - break - } else if visited.contains(&cfg_id) { + break; + } + + let cfg_id = idx.node_id(); + if visited.contains(&cfg_id) { // already done - continue + continue; } visited.insert(cfg_id); + let node_id = cfg.graph.node_data(idx).id(); // is this a recursive call? if node_id != ast::DUMMY_NODE_ID && checker(cx.tcx, impl_node_id, id, name, node_id) { - self_call_spans.push(cx.tcx.map.span(node_id)); // this is a self call, so we shouldn't explore past // this node in the CFG. - continue + continue; } // add the successors of this node to explore the graph further. cfg.graph.each_outgoing_edge(idx, |_, edge| { @@ -1888,7 +1906,7 @@ impl LintPass for UnconditionalRecursion { }); } - // check the number of sell calls because a function that + // Check the number of self calls because a function that // doesn't return (e.g. calls a `-> !` function or `loop { /* // no break */ }`) shouldn't be linted unless it actually // recurs. @@ -1920,7 +1938,7 @@ impl LintPass for UnconditionalRecursion { _: ast::Ident, id: ast::NodeId) -> bool { tcx.def_map.borrow().get(&id) - .map_or(false, |def| def.def_id() == ast_util::local_def(fn_id)) + .map_or(false, |def| def.def_id() == ast_util::local_def(fn_id)) } // check if the method call `id` refers to method `method_id` @@ -1962,7 +1980,7 @@ impl LintPass for UnconditionalRecursion { tcx.map.span(id), "non-method call expr behaving like a method call?") }; - // it matches if it comes from the same impl, + // It matches if it comes from the same impl, // and has the same method name. return ast_util::is_local(impl_def_id) && impl_def_id.node == impl_id @@ -2013,7 +2031,7 @@ impl LintPass for PluginAsLibrary { if decoder::get_plugin_registrar_fn(md.data()).is_some() { cx.span_lint(PLUGIN_AS_LIBRARY, it.span, - "compiler plugin used as an ordinary library"); + "compiler plugin used as an ordinary library"); } } } @@ -2069,7 +2087,7 @@ impl LintPass for InvalidNoMangleItems { // Const items do not refer to a particular location in memory, and therefore // don't have anything to attach a symbol to let msg = "const items should never be #[no_mangle], consider instead using \ - `pub static`"; + `pub static`"; cx.span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg); } } @@ -2082,15 +2100,17 @@ impl LintPass for InvalidNoMangleItems { #[derive(Copy)] pub struct UnstableFeatures; -declare_lint!(UNSTABLE_FEATURES, Allow, - "enabling unstable features"); +declare_lint! { + UNSTABLE_FEATURES, + Allow, + "enabling unstable features" +} impl LintPass for UnstableFeatures { fn get_lints(&self) -> LintArray { lint_array!(UNSTABLE_FEATURES) } fn check_attribute(&mut self, ctx: &Context, attr: &ast::Attribute) { - use syntax::attr; if attr::contains_name(&[attr.node.value.clone()], "feature") { ctx.span_lint(UNSTABLE_FEATURES, attr.span, "unstable feature"); } diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 48ff4c8332022..2ab6f5b0f9521 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -789,7 +789,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option { // Irrefutable columns always go first, they'd only be duplicated in the branches. if total_score == 0 { - std::uint::MAX + std::usize::MAX } else { total_score } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index fdeef11f36c84..1f578ac0bdbab 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -2435,21 +2435,19 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty< use middle::ty::{BrAnon, ReLateBound}; let function_type; - let (fn_sig, abi, has_env) = match fn_ty.sty { - ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, false), + let (fn_sig, abi, env_ty) = match fn_ty.sty { + ty::ty_bare_fn(_, ref f) => (&f.sig, f.abi, None), ty::ty_closure(closure_did, _, substs) => { let typer = common::NormalizingClosureTyper::new(ccx.tcx()); function_type = typer.closure_type(closure_did, substs); - (&function_type.sig, RustCall, true) + let self_type = self_type_for_closure(ccx, closure_did, fn_ty); + (&function_type.sig, RustCall, Some(self_type)) } _ => ccx.sess().bug("expected closure or function.") }; let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig); - // Since index 0 is the return value of the llvm func, we start - // at either 1 or 2 depending on whether there's an env slot or not - let mut first_arg_offset = if has_env { 2 } else { 1 }; let mut attrs = llvm::AttrBuilder::new(); let ret_ty = fn_sig.output; @@ -2460,7 +2458,11 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty< assert!(abi == RustCall); match fn_sig.inputs[0].sty { - ty::ty_tup(ref inputs) => inputs.clone(), + ty::ty_tup(ref inputs) => { + let mut full_inputs = vec![env_ty.expect("Missing closure environment")]; + full_inputs.push_all(inputs); + full_inputs + } _ => ccx.sess().bug("expected tuple'd inputs") } }, @@ -2478,6 +2480,8 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty< _ => fn_sig.inputs.clone() }; + // Index 0 is the return value of the llvm func, so we start at 1 + let mut first_arg_offset = 1; if let ty::FnConverging(ret_ty) = ret_ty { // A function pointer is called without the declaration // available, so we have to apply any attributes with ABI diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 4f234fac9a4a0..861233bafdfac 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -603,7 +603,18 @@ pub fn trans_method_call<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let _icx = push_ctxt("trans_method_call"); debug!("trans_method_call(call_expr={})", call_expr.repr(bcx.tcx())); let method_call = MethodCall::expr(call_expr.id); - let method_ty = (*bcx.tcx().method_map.borrow())[method_call].ty; + let method_ty = match bcx.tcx().method_map.borrow().get(&method_call) { + Some(method) => match method.origin { + ty::MethodTraitObject(_) => match method.ty.sty { + ty::ty_bare_fn(_, ref fty) => { + ty::mk_bare_fn(bcx.tcx(), None, meth::opaque_method_ty(bcx.tcx(), fty)) + } + _ => method.ty + }, + _ => method.ty + }, + None => panic!("method not found in trans_method_call") + }; trans_call_inner( bcx, call_expr.debug_loc(), @@ -927,20 +938,21 @@ fn trans_args_under_call_abi<'blk, 'tcx>( tuple_expr.id)); let repr = adt::represent_type(bcx.ccx(), tuple_type); let repr_ptr = &*repr; - for i in 0..field_types.len() { + llargs.extend(field_types.iter().enumerate().map(|(i, field_type)| { let arg_datum = tuple_lvalue_datum.get_element( bcx, - field_types[i], + field_type, |srcval| { adt::trans_field_ptr(bcx, repr_ptr, srcval, 0, i) - }); - let arg_datum = arg_datum.to_expr_datum(); - let arg_datum = - unpack_datum!(bcx, arg_datum.to_rvalue_datum(bcx, "arg")); - let arg_datum = - unpack_datum!(bcx, arg_datum.to_appropriate_datum(bcx)); - llargs.push(arg_datum.add_clean(bcx.fcx, arg_cleanup_scope)); - } + }).to_expr_datum(); + unpack_result!(bcx, trans_arg_datum( + bcx, + field_type, + arg_datum, + arg_cleanup_scope, + DontAutorefArg) + ) + })); } _ => { bcx.sess().span_bug(tuple_expr.span, diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 4423cd2774446..67f1c39c6e094 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -589,15 +589,16 @@ pub fn trans_object_shim<'a, 'tcx>( }; let fty = monomorphize::apply_param_substs(tcx, &object_substs, &method_ty.fty); let fty = tcx.mk_bare_fn(fty); - debug!("trans_object_shim: fty={}", fty.repr(tcx)); + let method_ty = opaque_method_ty(tcx, fty); + debug!("trans_object_shim: fty={} method_ty={}", fty.repr(tcx), method_ty.repr(tcx)); // - let method_bare_fn_ty = - ty::mk_bare_fn(tcx, None, fty); + let shim_fn_ty = ty::mk_bare_fn(tcx, None, fty); + let method_bare_fn_ty = ty::mk_bare_fn(tcx, None, method_ty); let function_name = - link::mangle_internal_name_by_type_and_seq(ccx, method_bare_fn_ty, "object_shim"); + link::mangle_internal_name_by_type_and_seq(ccx, shim_fn_ty, "object_shim"); let llfn = - decl_internal_rust_fn(ccx, method_bare_fn_ty, &function_name); + decl_internal_rust_fn(ccx, shim_fn_ty, &function_name); let sig = ty::erase_late_bound_regions(ccx.tcx(), &fty.sig); @@ -866,3 +867,20 @@ pub fn trans_trait_cast<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, bcx } + +/// Replace the self type (&Self or Box) with an opaque pointer. +pub fn opaque_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>, method_ty: &ty::BareFnTy<'tcx>) + -> &'tcx ty::BareFnTy<'tcx> { + let mut inputs = method_ty.sig.0.inputs.clone(); + inputs[0] = ty::mk_mut_ptr(tcx, ty::mk_mach_int(tcx, ast::TyI8)); + + tcx.mk_bare_fn(ty::BareFnTy { + unsafety: method_ty.unsafety, + abi: method_ty.abi, + sig: ty::Binder(ty::FnSig { + inputs: inputs, + output: method_ty.sig.0.output, + variadic: method_ty.sig.0.variadic, + }), + }) +} diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 083523f7ba92f..cffd74ccd7218 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -14,8 +14,9 @@ use middle::infer; use middle::region; use middle::subst; use middle::ty::{self, Ty}; -use util::ppaux::{Repr}; +use util::ppaux::{Repr, UserString}; +use syntax::ast; use syntax::codemap::Span; pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>, @@ -28,29 +29,98 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx> // types that have been traversed so far by `traverse_type_if_unseen` let mut breadcrumbs: Vec> = Vec::new(); - iterate_over_potentially_unsafe_regions_in_type( + let result = iterate_over_potentially_unsafe_regions_in_type( rcx, &mut breadcrumbs, + TypeContext::Root, typ, span, scope, + 0, 0); + match result { + Ok(()) => {} + Err(Error::Overflow(ref ctxt, ref detected_on_typ)) => { + let tcx = rcx.tcx(); + span_err!(tcx.sess, span, E0320, + "overflow while adding drop-check rules for {}", + typ.user_string(rcx.tcx())); + match *ctxt { + TypeContext::Root => { + // no need for an additional note if the overflow + // was somehow on the root. + } + TypeContext::EnumVariant { def_id, variant, arg_index } => { + // FIXME (pnkfelix): eventually lookup arg_name + // for the given index on struct variants. + span_note!( + rcx.tcx().sess, + span, + "overflowed on enum {} variant {} argument {} type: {}", + ty::item_path_str(tcx, def_id), + variant, + arg_index, + detected_on_typ.user_string(rcx.tcx())); + } + TypeContext::Struct { def_id, field } => { + span_note!( + rcx.tcx().sess, + span, + "overflowed on struct {} field {} type: {}", + ty::item_path_str(tcx, def_id), + field, + detected_on_typ.user_string(rcx.tcx())); + } + } + } + } +} + +enum Error<'tcx> { + Overflow(TypeContext, ty::Ty<'tcx>), +} + +enum TypeContext { + Root, + EnumVariant { + def_id: ast::DefId, + variant: ast::Name, + arg_index: usize, + }, + Struct { + def_id: ast::DefId, + field: ast::Name, + } } +// The `depth` counts the number of calls to this function; +// the `xref_depth` counts the subset of such calls that go +// across a `Box` or `PhantomData`. fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( rcx: &mut Rcx<'a, 'tcx>, breadcrumbs: &mut Vec>, + context: TypeContext, ty_root: ty::Ty<'tcx>, span: Span, scope: region::CodeExtent, - depth: uint) + depth: uint, + xref_depth: uint) -> Result<(), Error<'tcx>> { + // Issue #22443: Watch out for overflow. While we are careful to + // handle regular types properly, non-regular ones cause problems. + let recursion_limit = rcx.tcx().sess.recursion_limit.get(); + if xref_depth >= recursion_limit { + return Err(Error::Overflow(context, ty_root)) + } + let origin = || infer::SubregionOrigin::SafeDestructor(span); let mut walker = ty_root.walk(); let opt_phantom_data_def_id = rcx.tcx().lang_items.phantom_data(); let destructor_for_type = rcx.tcx().destructor_for_type.borrow(); + let xref_depth_orig = xref_depth; + while let Some(typ) = walker.next() { // Avoid recursing forever. if breadcrumbs.contains(&typ) { @@ -61,20 +131,33 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( // If we encounter `PhantomData`, then we should replace it // with `T`, the type it represents as owned by the // surrounding context, before doing further analysis. - let typ = if let ty::ty_struct(struct_did, substs) = typ.sty { - if opt_phantom_data_def_id == Some(struct_did) { - let item_type = ty::lookup_item_type(rcx.tcx(), struct_did); - let tp_def = item_type.generics.types - .opt_get(subst::TypeSpace, 0).unwrap(); - let new_typ = substs.type_for_def(tp_def); - debug!("replacing phantom {} with {}", + let (typ, xref_depth) = match typ.sty { + ty::ty_struct(struct_did, substs) => { + if opt_phantom_data_def_id == Some(struct_did) { + let item_type = ty::lookup_item_type(rcx.tcx(), struct_did); + let tp_def = item_type.generics.types + .opt_get(subst::TypeSpace, 0).unwrap(); + let new_typ = substs.type_for_def(tp_def); + debug!("replacing phantom {} with {}", + typ.repr(rcx.tcx()), new_typ.repr(rcx.tcx())); + (new_typ, xref_depth_orig + 1) + } else { + (typ, xref_depth_orig) + } + } + + // Note: When ty_uniq is removed from compiler, the + // definition of `Box` must carry a PhantomData that + // puts us into the previous case. + ty::ty_uniq(new_typ) => { + debug!("replacing ty_uniq {} with {}", typ.repr(rcx.tcx()), new_typ.repr(rcx.tcx())); - new_typ - } else { - typ + (new_typ, xref_depth_orig + 1) + } + + _ => { + (typ, xref_depth_orig) } - } else { - typ }; let opt_type_did = match typ.sty { @@ -87,9 +170,9 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( opt_type_did.and_then(|did| destructor_for_type.get(&did)); debug!("iterate_over_potentially_unsafe_regions_in_type \ - {}typ: {} scope: {:?} opt_dtor: {:?}", + {}typ: {} scope: {:?} opt_dtor: {:?} xref: {}", (0..depth).map(|_| ' ').collect::(), - typ.repr(rcx.tcx()), scope, opt_dtor); + typ.repr(rcx.tcx()), scope, opt_dtor, xref_depth); // If `typ` has a destructor, then we must ensure that all // borrowed data reachable via `typ` must outlive the parent @@ -228,6 +311,8 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( match typ.sty { ty::ty_struct(struct_did, substs) => { + debug!("typ: {} is struct; traverse structure and not type-expression", + typ.repr(rcx.tcx())); // Don't recurse; we extract type's substructure, // so do not process subparts of type expression. walker.skip_current_subtree(); @@ -240,17 +325,24 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( struct_did, field.id, substs); - iterate_over_potentially_unsafe_regions_in_type( + try!(iterate_over_potentially_unsafe_regions_in_type( rcx, breadcrumbs, + TypeContext::Struct { + def_id: struct_did, + field: field.name, + }, field_type, span, scope, - depth+1) + depth+1, + xref_depth)) } } ty::ty_enum(enum_did, substs) => { + debug!("typ: {} is enum; traverse structure and not type-expression", + typ.repr(rcx.tcx())); // Don't recurse; we extract type's substructure, // so do not process subparts of type expression. walker.skip_current_subtree(); @@ -260,14 +352,20 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( enum_did, substs); for variant_info in all_variant_info.iter() { - for argument_type in variant_info.args.iter() { - iterate_over_potentially_unsafe_regions_in_type( + for (i, arg_type) in variant_info.args.iter().enumerate() { + try!(iterate_over_potentially_unsafe_regions_in_type( rcx, breadcrumbs, - *argument_type, + TypeContext::EnumVariant { + def_id: enum_did, + variant: variant_info.name, + arg_index: i, + }, + *arg_type, span, scope, - depth+1) + depth+1, + xref_depth)); } } } @@ -290,4 +388,6 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>( // is done. } } + + return Ok(()); } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 7b43a9fef06dc..3bd15fbc7dbea 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -174,7 +174,8 @@ register_diagnostics! { E0249, // expected constant expr for array length E0250, // expected constant expr for array length E0318, // can't create default impls for traits outside their crates - E0319 // trait impls for defaulted traits allowed just for structs/enums + E0319, // trait impls for defaulted traits allowed just for structs/enums + E0320 // recursive overflow during dropck } __build_diagnostic_array! { DIAGNOSTICS } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index b5bdeb7f181b0..7957bc35b76b5 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -109,7 +109,7 @@ #![feature(box_syntax)] #![feature(collections)] #![feature(core)] -#![feature(int_uint)] +#![feature(hash)] #![feature(lang_items)] #![feature(libc)] #![feature(linkage, thread_local, asm)] @@ -221,14 +221,12 @@ mod int_macros; mod uint_macros; #[path = "num/isize.rs"] pub mod isize; -pub use isize as int; #[path = "num/i8.rs"] pub mod i8; #[path = "num/i16.rs"] pub mod i16; #[path = "num/i32.rs"] pub mod i32; #[path = "num/i64.rs"] pub mod i64; #[path = "num/usize.rs"] pub mod usize; -pub use usize as uint; #[path = "num/u8.rs"] pub mod u8; #[path = "num/u16.rs"] pub mod u16; #[path = "num/u32.rs"] pub mod u32; diff --git a/src/test/compile-fail/dropck_no_diverge_on_nonregular_1.rs b/src/test/compile-fail/dropck_no_diverge_on_nonregular_1.rs new file mode 100644 index 0000000000000..f096885381989 --- /dev/null +++ b/src/test/compile-fail/dropck_no_diverge_on_nonregular_1.rs @@ -0,0 +1,37 @@ +// 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. + +// Issue 22443: Reject code using non-regular types that would +// otherwise cause dropck to loop infinitely. + +use std::marker::PhantomData; + +struct Digit { + elem: T +} + +struct Node { m: PhantomData<&'static T> } + + +enum FingerTree { + Single(T), + // Bug report said Digit after Box would stack overflow (versus + // Digit before Box; see dropck_no_diverge_on_nonregular_2). + Deep( + Box>>, + Digit, + ) +} + +fn main() { + let ft = //~ ERROR overflow while adding drop-check rules for FingerTree + FingerTree::Single(1); + //~^ ERROR overflow while adding drop-check rules for FingerTree +} diff --git a/src/test/compile-fail/dropck_no_diverge_on_nonregular_2.rs b/src/test/compile-fail/dropck_no_diverge_on_nonregular_2.rs new file mode 100644 index 0000000000000..886bd6bea20d7 --- /dev/null +++ b/src/test/compile-fail/dropck_no_diverge_on_nonregular_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. + +// Issue 22443: Reject code using non-regular types that would +// otherwise cause dropck to loop infinitely. + +use std::marker::PhantomData; + +struct Digit { + elem: T +} + +struct Node { m: PhantomData<&'static T> } + +enum FingerTree { + Single(T), + // Bug report said Digit before Box would infinite loop (versus + // Digit after Box; see dropck_no_diverge_on_nonregular_1). + Deep( + Digit, + Box>>, + ) +} + +fn main() { + let ft = //~ ERROR overflow while adding drop-check rules for FingerTree + FingerTree::Single(1); + //~^ ERROR overflow while adding drop-check rules for FingerTree +} diff --git a/src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs b/src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs new file mode 100644 index 0000000000000..f7eb6e10ca788 --- /dev/null +++ b/src/test/compile-fail/dropck_no_diverge_on_nonregular_3.rs @@ -0,0 +1,46 @@ +// 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. + +// Issue 22443: Reject code using non-regular types that would +// otherwise cause dropck to loop infinitely. +// +// This version is just checking that we still sanely handle a trivial +// wrapper around the non-regular type. (It also demonstrates how the +// error messages will report different types depending on which type +// dropck is analyzing.) + +use std::marker::PhantomData; + +struct Digit { + elem: T +} + +struct Node { m: PhantomData<&'static T> } + +enum FingerTree { + Single(T), + // According to the bug report, Digit before Box would infinite loop. + Deep( + Digit, + Box>>, + ) +} + +enum Wrapper { + Simple, + Other(FingerTree), +} + +fn main() { + let w = //~ ERROR overflow while adding drop-check rules for core::option + Some(Wrapper::Simple::); + //~^ ERROR overflow while adding drop-check rules for core::option::Option + //~| ERROR overflow while adding drop-check rules for Wrapper +} diff --git a/src/test/compile-fail/issue-8460-const.rs b/src/test/compile-fail/issue-8460-const.rs index 954ae8ebc48dd..9c2e8d278ab0b 100644 --- a/src/test/compile-fail/issue-8460-const.rs +++ b/src/test/compile-fail/issue-8460-const.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::{int, i8, i16, i32, i64}; +use std::{isize, i8, i16, i32, i64}; use std::thread; fn main() { - assert!(thread::spawn(move|| { int::MIN / -1; }).join().is_err()); + assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); //~^ ERROR attempted to divide with overflow in a constant expression assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); //~^ ERROR attempted to divide with overflow in a constant expression @@ -32,7 +32,7 @@ fn main() { //~^ ERROR attempted to divide by zero in a constant expression assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); //~^ ERROR attempted to divide by zero in a constant expression - assert!(thread::spawn(move|| { int::MIN % -1; }).join().is_err()); + assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); //~^ ERROR attempted remainder with overflow in a constant expression assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); //~^ ERROR attempted remainder with overflow in a constant expression diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs index 964db6e9a4546..5f3744712ccb4 100644 --- a/src/test/compile-fail/unnecessary-private.rs +++ b/src/test/compile-fail/unnecessary-private.rs @@ -9,7 +9,7 @@ // except according to those terms. fn main() { - pub use std::uint; //~ ERROR: visibility has no effect + pub use std::usize; //~ ERROR: visibility has no effect pub struct A; //~ ERROR: visibility has no effect pub enum B {} //~ ERROR: visibility has no effect pub trait C { //~ ERROR: visibility has no effect diff --git a/src/test/run-fail/bounds-check-no-overflow.rs b/src/test/run-fail/bounds-check-no-overflow.rs index be4ad0781f272..c15c4b83828a3 100644 --- a/src/test/run-fail/bounds-check-no-overflow.rs +++ b/src/test/run-fail/bounds-check-no-overflow.rs @@ -10,10 +10,10 @@ // error-pattern:index out of bounds: the len is 3 but the index is -use std::uint; +use std::usize; use std::mem::size_of; fn main() { let xs = [1, 2, 3]; - xs[uint::MAX / size_of::() + 1]; + xs[usize::MAX / size_of::() + 1]; } diff --git a/src/test/run-fail/hashmap-capacity-overflow.rs b/src/test/run-fail/hashmap-capacity-overflow.rs index c86f8a38f63c4..2c7c0875227d9 100644 --- a/src/test/run-fail/hashmap-capacity-overflow.rs +++ b/src/test/run-fail/hashmap-capacity-overflow.rs @@ -11,11 +11,11 @@ // error-pattern:capacity overflow use std::collections::hash_map::HashMap; -use std::uint; +use std::usize; use std::mem::size_of; fn main() { - let threshold = uint::MAX / size_of::<(u64, u64, u64)>(); + let threshold = usize::MAX / size_of::<(u64, u64, u64)>(); let mut h = HashMap::::with_capacity(threshold + 100); h.insert(0, 0); } diff --git a/src/test/run-pass/issue-16671.rs b/src/test/run-pass/issue-16671.rs index b06c4923c16c1..82543f543da83 100644 --- a/src/test/run-pass/issue-16671.rs +++ b/src/test/run-pass/issue-16671.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// DON'T REENABLE THIS UNLESS YOU'VE ACTUALLY FIXED THE UNDERLYING ISSUE +// ignore-android seems to block forever #![forbid(warnings)] diff --git a/src/test/run-pass/issue-22777.rs b/src/test/run-pass/issue-22777.rs new file mode 100644 index 0000000000000..cab33beda405f --- /dev/null +++ b/src/test/run-pass/issue-22777.rs @@ -0,0 +1,55 @@ +// 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. + +// This test is reduced from libsyntax. It is just checking that we +// can successfully deal with a "deep" structure, which the drop-check +// was hitting a recursion limit on at one point. + +#![allow(non_camel_case_types)] + +pub fn noop_fold_impl_item() -> SmallVector { + loop { } +} + +pub struct SmallVector(P); +pub struct ImplItem(P); + +struct P(Box); + +struct S01_Method(P); +struct S02_Generics(P); +struct S03_TyParam(P); +struct S04_TyParamBound(S05_PolyTraitRef); +struct S05_PolyTraitRef(S06_TraitRef); +struct S06_TraitRef(S07_Path); +struct S07_Path(Vec); +struct S08_PathSegment(S09_PathParameters); +struct S09_PathParameters(P); +struct S10_ParenthesizedParameterData(Option>); +struct S11_Ty(P); +struct S12_Expr(P); +struct S13_Block(Vec>); +struct S14_Stmt(P); +struct S15_Decl(P); +struct S16_Local(P); +struct S17_Pat(P); +struct S18_Mac(Vec>); +struct S19_TokenTree(P); +struct S20_Token(P); +struct S21_Nonterminal(P); +struct S22_Item(P); +struct S23_EnumDef(Vec>); +struct S24_Variant(P); +struct S25_VariantKind(P); +struct S26_StructDef(Vec>); +struct S27_StructField(P); +struct S28_StructFieldKind; + +pub fn main() {}