auto merge of #17410 : jakub-/rust/dead-code, r=alexcrichton
This commit is contained in:
commit
4d69696ff6
src
libcore/fmt
librustc
back
diagnostics.rslint
middle
util
libsyntax
test
@ -28,21 +28,12 @@ pub enum ExponentFormat {
|
||||
/// Use exponential notation with the exponent having a base of 10 and the
|
||||
/// exponent sign being `e` or `E`. For example, 1000 would be printed
|
||||
/// 1e3.
|
||||
ExpDec,
|
||||
/// Use exponential notation with the exponent having a base of 2 and the
|
||||
/// exponent sign being `p` or `P`. For example, 8 would be printed 1p3.
|
||||
ExpBin,
|
||||
ExpDec
|
||||
}
|
||||
|
||||
/// The number of digits used for emitting the fractional part of a number, if
|
||||
/// any.
|
||||
pub enum SignificantDigits {
|
||||
/// All calculable digits will be printed.
|
||||
///
|
||||
/// Note that bignums or fractions may cause a surprisingly large number
|
||||
/// of digits to be printed.
|
||||
DigAll,
|
||||
|
||||
/// At most the given number of digits will be printed, truncating any
|
||||
/// trailing zeroes.
|
||||
DigMax(uint),
|
||||
@ -53,17 +44,11 @@ pub enum SignificantDigits {
|
||||
|
||||
/// How to emit the sign of a number.
|
||||
pub enum SignFormat {
|
||||
/// No sign will be printed. The exponent sign will also be emitted.
|
||||
SignNone,
|
||||
/// `-` will be printed for negative values, but no sign will be emitted
|
||||
/// for positive numbers.
|
||||
SignNeg,
|
||||
/// `+` will be printed for positive values, and `-` will be printed for
|
||||
/// negative values.
|
||||
SignAll,
|
||||
SignNeg
|
||||
}
|
||||
|
||||
static DIGIT_P_RADIX: uint = ('p' as uint) - ('a' as uint) + 11u;
|
||||
static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
|
||||
|
||||
/**
|
||||
@ -111,9 +96,6 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
|
||||
ExpDec if radix >= DIGIT_E_RADIX // decimal exponent 'e'
|
||||
=> fail!("float_to_str_bytes_common: radix {} incompatible with \
|
||||
use of 'e' as decimal exponent", radix),
|
||||
ExpBin if radix >= DIGIT_P_RADIX // binary exponent 'p'
|
||||
=> fail!("float_to_str_bytes_common: radix {} incompatible with \
|
||||
use of 'p' as binary exponent", radix),
|
||||
_ => ()
|
||||
}
|
||||
|
||||
@ -123,16 +105,10 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
|
||||
match num.classify() {
|
||||
FPNaN => return f("NaN".as_bytes()),
|
||||
FPInfinite if num > _0 => {
|
||||
return match sign {
|
||||
SignAll => return f("+inf".as_bytes()),
|
||||
_ => return f("inf".as_bytes()),
|
||||
};
|
||||
return f("inf".as_bytes());
|
||||
}
|
||||
FPInfinite if num < _0 => {
|
||||
return match sign {
|
||||
SignNone => return f("inf".as_bytes()),
|
||||
_ => return f("-inf".as_bytes()),
|
||||
};
|
||||
return f("-inf".as_bytes());
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -147,11 +123,10 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
|
||||
|
||||
let (num, exp) = match exp_format {
|
||||
ExpNone => (num, 0i32),
|
||||
ExpDec | ExpBin if num == _0 => (num, 0i32),
|
||||
ExpDec | ExpBin => {
|
||||
ExpDec if num == _0 => (num, 0i32),
|
||||
ExpDec => {
|
||||
let (exp, exp_base) = match exp_format {
|
||||
ExpDec => (num.abs().log10().floor(), cast::<f64, T>(10.0f64).unwrap()),
|
||||
ExpBin => (num.abs().log2().floor(), cast::<f64, T>(2.0f64).unwrap()),
|
||||
ExpNone => fail!("unreachable"),
|
||||
};
|
||||
|
||||
@ -185,21 +160,16 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
|
||||
|
||||
// If limited digits, calculate one digit more for rounding.
|
||||
let (limit_digits, digit_count, exact) = match digits {
|
||||
DigAll => (false, 0u, false),
|
||||
DigMax(count) => (true, count+1, false),
|
||||
DigExact(count) => (true, count+1, true)
|
||||
DigMax(count) => (true, count + 1, false),
|
||||
DigExact(count) => (true, count + 1, true)
|
||||
};
|
||||
|
||||
// Decide what sign to put in front
|
||||
match sign {
|
||||
SignNeg | SignAll if neg => {
|
||||
SignNeg if neg => {
|
||||
buf[end] = b'-';
|
||||
end += 1;
|
||||
}
|
||||
SignAll => {
|
||||
buf[end] = b'+';
|
||||
end += 1;
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
@ -329,8 +299,6 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
|
||||
buf[end] = match exp_format {
|
||||
ExpDec if exp_upper => 'E',
|
||||
ExpDec if !exp_upper => 'e',
|
||||
ExpBin if exp_upper => 'P',
|
||||
ExpBin if !exp_upper => 'p',
|
||||
_ => fail!("unreachable"),
|
||||
} as u8;
|
||||
end += 1;
|
||||
@ -356,11 +324,6 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
|
||||
fmt::write(&mut filler, args)
|
||||
}, "{:-}", exp);
|
||||
}
|
||||
SignNone | SignAll => {
|
||||
let _ = format_args!(|args| {
|
||||
fmt::write(&mut filler, args)
|
||||
}, "{}", exp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -397,13 +397,6 @@ pub fn get_cc_prog(sess: &Session) -> String {
|
||||
}.to_string()
|
||||
}
|
||||
|
||||
pub fn get_ar_prog(sess: &Session) -> String {
|
||||
match sess.opts.cg.ar {
|
||||
Some(ref ar) => (*ar).clone(),
|
||||
None => "ar".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(sess: &Session, path: &Path) {
|
||||
match fs::unlink(path) {
|
||||
Ok(..) => {}
|
||||
|
@ -114,7 +114,6 @@ register_diagnostics!(
|
||||
E0102,
|
||||
E0103,
|
||||
E0104,
|
||||
E0105,
|
||||
E0106,
|
||||
E0107,
|
||||
E0108,
|
||||
@ -152,7 +151,6 @@ register_diagnostics!(
|
||||
E0144,
|
||||
E0145,
|
||||
E0146,
|
||||
E0147,
|
||||
E0148,
|
||||
E0151,
|
||||
E0152,
|
||||
|
@ -1269,11 +1269,6 @@ impl LintPass for UnusedMut {
|
||||
}
|
||||
}
|
||||
|
||||
enum Allocation {
|
||||
VectorAllocation,
|
||||
BoxAllocation
|
||||
}
|
||||
|
||||
declare_lint!(UNNECESSARY_ALLOCATION, Warn,
|
||||
"detects unnecessary allocations that can be eliminated")
|
||||
|
||||
@ -1285,30 +1280,21 @@ impl LintPass for UnnecessaryAllocation {
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
|
||||
// Warn if boxing expressions are immediately borrowed.
|
||||
let allocation = match e.node {
|
||||
ast::ExprUnary(ast::UnUniq, _) |
|
||||
ast::ExprUnary(ast::UnBox, _) => BoxAllocation,
|
||||
|
||||
match e.node {
|
||||
ast::ExprUnary(ast::UnUniq, _) | ast::ExprUnary(ast::UnBox, _) => (),
|
||||
_ => return
|
||||
};
|
||||
}
|
||||
|
||||
match cx.tcx.adjustments.borrow().find(&e.id) {
|
||||
Some(adjustment) => {
|
||||
match *adjustment {
|
||||
ty::AdjustDerefRef(ty::AutoDerefRef { ref autoref, .. }) => {
|
||||
match (allocation, autoref) {
|
||||
(VectorAllocation, &Some(ty::AutoPtr(_, _, None))) => {
|
||||
cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
|
||||
"unnecessary allocation, the sigil can be removed");
|
||||
}
|
||||
(BoxAllocation,
|
||||
&Some(ty::AutoPtr(_, ast::MutImmutable, None))) => {
|
||||
match autoref {
|
||||
&Some(ty::AutoPtr(_, ast::MutImmutable, None)) => {
|
||||
cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
|
||||
"unnecessary allocation, use & instead");
|
||||
}
|
||||
(BoxAllocation,
|
||||
&Some(ty::AutoPtr(_, ast::MutMutable, None))) => {
|
||||
&Some(ty::AutoPtr(_, ast::MutMutable, None)) => {
|
||||
cx.span_lint(UNNECESSARY_ALLOCATION, e.span,
|
||||
"unnecessary allocation, use &mut instead");
|
||||
}
|
||||
|
@ -662,30 +662,6 @@ impl tr for MethodOrigin {
|
||||
}
|
||||
}
|
||||
|
||||
// ______________________________________________________________________
|
||||
// Encoding and decoding vtable_res
|
||||
|
||||
pub fn encode_vtable_res(ecx: &e::EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
dr: &typeck::vtable_res) {
|
||||
// can't autogenerate this code because automatic code of
|
||||
// ty::t doesn't work, and there is no way (atm) to have
|
||||
// hand-written encoding routines combine with auto-generated
|
||||
// ones. perhaps we should fix this.
|
||||
encode_vec_per_param_space(
|
||||
rbml_w, dr,
|
||||
|rbml_w, param_tables| encode_vtable_param_res(ecx, rbml_w,
|
||||
param_tables))
|
||||
}
|
||||
|
||||
pub fn encode_vtable_param_res(ecx: &e::EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
param_tables: &typeck::vtable_param_res) {
|
||||
rbml_w.emit_from_vec(param_tables.as_slice(), |rbml_w, vtable_origin| {
|
||||
Ok(encode_vtable_origin(ecx, rbml_w, vtable_origin))
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
|
||||
kind: ty::UnboxedClosureKind) {
|
||||
use serialize::Encoder;
|
||||
@ -714,55 +690,6 @@ pub fn encode_unboxed_closure_kind(ebml_w: &mut Encoder,
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
pub fn encode_vtable_origin(ecx: &e::EncodeContext,
|
||||
rbml_w: &mut Encoder,
|
||||
vtable_origin: &typeck::vtable_origin) {
|
||||
use serialize::Encoder;
|
||||
|
||||
rbml_w.emit_enum("vtable_origin", |rbml_w| {
|
||||
match *vtable_origin {
|
||||
typeck::vtable_static(def_id, ref substs, ref vtable_res) => {
|
||||
rbml_w.emit_enum_variant("vtable_static", 0u, 3u, |rbml_w| {
|
||||
rbml_w.emit_enum_variant_arg(0u, |rbml_w| {
|
||||
Ok(rbml_w.emit_def_id(def_id))
|
||||
});
|
||||
rbml_w.emit_enum_variant_arg(1u, |rbml_w| {
|
||||
Ok(rbml_w.emit_substs(ecx, substs))
|
||||
});
|
||||
rbml_w.emit_enum_variant_arg(2u, |rbml_w| {
|
||||
Ok(encode_vtable_res(ecx, rbml_w, vtable_res))
|
||||
})
|
||||
})
|
||||
}
|
||||
typeck::vtable_param(pn, bn) => {
|
||||
rbml_w.emit_enum_variant("vtable_param", 1u, 3u, |rbml_w| {
|
||||
rbml_w.emit_enum_variant_arg(0u, |rbml_w| {
|
||||
pn.encode(rbml_w)
|
||||
});
|
||||
rbml_w.emit_enum_variant_arg(1u, |rbml_w| {
|
||||
rbml_w.emit_uint(bn)
|
||||
})
|
||||
})
|
||||
}
|
||||
typeck::vtable_unboxed_closure(def_id) => {
|
||||
rbml_w.emit_enum_variant("vtable_unboxed_closure",
|
||||
2u,
|
||||
1u,
|
||||
|rbml_w| {
|
||||
rbml_w.emit_enum_variant_arg(0u, |rbml_w| {
|
||||
Ok(rbml_w.emit_def_id(def_id))
|
||||
})
|
||||
})
|
||||
}
|
||||
typeck::vtable_error => {
|
||||
rbml_w.emit_enum_variant("vtable_error", 3u, 3u, |_rbml_w| {
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
}).unwrap()
|
||||
}
|
||||
|
||||
pub trait vtable_decoder_helpers {
|
||||
fn read_vec_per_param_space<T>(&mut self,
|
||||
f: |&mut Self| -> T)
|
||||
|
@ -16,7 +16,6 @@ use middle::cfg;
|
||||
use middle::dataflow::DataFlowContext;
|
||||
use middle::dataflow::BitwiseOperator;
|
||||
use middle::dataflow::DataFlowOperator;
|
||||
use middle::def;
|
||||
use middle::expr_use_visitor as euv;
|
||||
use middle::mem_categorization as mc;
|
||||
use middle::ty;
|
||||
@ -243,12 +242,6 @@ struct BorrowStats {
|
||||
|
||||
pub type BckResult<T> = Result<T, BckError>;
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
pub enum PartialTotal {
|
||||
Partial, // Loan affects some portion
|
||||
Total // Loan affects entire path
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Loans and loan paths
|
||||
|
||||
@ -392,11 +385,6 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
self.tcx.region_maps.is_subregion_of(r_sub, r_sup)
|
||||
}
|
||||
|
||||
pub fn is_subscope_of(&self, r_sub: ast::NodeId, r_sup: ast::NodeId)
|
||||
-> bool {
|
||||
self.tcx.region_maps.is_subscope_of(r_sub, r_sup)
|
||||
}
|
||||
|
||||
pub fn mc(&self) -> mc::MemCategorizationContext<'a, ty::ctxt<'tcx>> {
|
||||
mc::MemCategorizationContext::new(self.tcx)
|
||||
}
|
||||
@ -410,82 +398,6 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cat_expr_unadjusted(&self, expr: &ast::Expr) -> mc::cmt {
|
||||
match self.mc().cat_expr_unadjusted(expr) {
|
||||
Ok(c) => c,
|
||||
Err(()) => {
|
||||
self.tcx.sess.span_bug(expr.span, "error in mem categorization");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cat_expr_autoderefd(&self,
|
||||
expr: &ast::Expr,
|
||||
adj: &ty::AutoAdjustment)
|
||||
-> mc::cmt {
|
||||
let r = match *adj {
|
||||
ty::AdjustDerefRef(
|
||||
ty::AutoDerefRef {
|
||||
autoderefs: autoderefs, ..}) => {
|
||||
self.mc().cat_expr_autoderefd(expr, autoderefs)
|
||||
}
|
||||
ty::AdjustAddEnv(..) => {
|
||||
// no autoderefs
|
||||
self.mc().cat_expr_unadjusted(expr)
|
||||
}
|
||||
};
|
||||
|
||||
match r {
|
||||
Ok(c) => c,
|
||||
Err(()) => {
|
||||
self.tcx.sess.span_bug(expr.span,
|
||||
"error in mem categorization");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cat_def(&self,
|
||||
id: ast::NodeId,
|
||||
span: Span,
|
||||
ty: ty::t,
|
||||
def: def::Def)
|
||||
-> mc::cmt {
|
||||
match self.mc().cat_def(id, span, ty, def) {
|
||||
Ok(c) => c,
|
||||
Err(()) => {
|
||||
self.tcx.sess.span_bug(span, "error in mem categorization");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cat_captured_var(&self,
|
||||
closure_id: ast::NodeId,
|
||||
closure_span: Span,
|
||||
upvar_def: def::Def)
|
||||
-> mc::cmt {
|
||||
// Create the cmt for the variable being borrowed, from the
|
||||
// caller's perspective
|
||||
let var_id = upvar_def.def_id().node;
|
||||
let var_ty = ty::node_id_to_type(self.tcx, var_id);
|
||||
self.cat_def(closure_id, closure_span, var_ty, upvar_def)
|
||||
}
|
||||
|
||||
pub fn cat_discr(&self, cmt: mc::cmt, match_id: ast::NodeId) -> mc::cmt {
|
||||
Rc::new(mc::cmt_ {
|
||||
cat: mc::cat_discr(cmt.clone(), match_id),
|
||||
mutbl: cmt.mutbl.inherit(),
|
||||
..*cmt
|
||||
})
|
||||
}
|
||||
|
||||
pub fn cat_pattern(&self,
|
||||
cmt: mc::cmt,
|
||||
pat: &ast::Pat,
|
||||
op: |mc::cmt, &ast::Pat|) {
|
||||
let r = self.mc().cat_pattern(cmt, pat, |_,x,y| op(x,y));
|
||||
assert!(r.is_ok());
|
||||
}
|
||||
|
||||
pub fn report(&self, err: BckError) {
|
||||
self.span_err(
|
||||
err.span,
|
||||
|
@ -568,22 +568,6 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn each_path_moved_by(&self,
|
||||
id: ast::NodeId,
|
||||
f: |&Move, &LoanPath| -> bool)
|
||||
-> bool {
|
||||
/*!
|
||||
* Iterates through each path moved by `id`
|
||||
*/
|
||||
|
||||
self.dfcx_moves.each_gen_bit(id, |index| {
|
||||
let move = self.move_data.moves.borrow();
|
||||
let move = move.get(index);
|
||||
let moved_path = move.path;
|
||||
f(move, &*self.move_data.path_loan_path(moved_path))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn kind_of_move_of_path(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath>)
|
||||
@ -665,13 +649,6 @@ impl<'a, 'tcx> FlowedMoveData<'a, 'tcx> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn is_assignee(&self,
|
||||
id: ast::NodeId)
|
||||
-> bool {
|
||||
//! True if `id` is the id of the LHS of an assignment
|
||||
self.move_data.assignee_ids.borrow().iter().any(|x| x == &id)
|
||||
}
|
||||
|
||||
pub fn each_assignment_of(&self,
|
||||
id: ast::NodeId,
|
||||
loan_path: &Rc<LoanPath>,
|
||||
|
@ -13,21 +13,20 @@
|
||||
// from live codes are live, and everything else is dead.
|
||||
|
||||
use middle::def;
|
||||
use lint;
|
||||
use middle::pat_util;
|
||||
use middle::privacy;
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
use lint;
|
||||
use util::nodemap::NodeSet;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util::{local_def, is_local, PostExpansionMethod};
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::attr;
|
||||
use syntax::attr::{mod, AttrMetaMethods};
|
||||
use syntax::codemap;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::visit;
|
||||
use syntax::visit::{mod, Visitor};
|
||||
|
||||
// Any local node that may call something in its body block should be
|
||||
// explored. For example, if it's a live NodeItem that is a
|
||||
@ -51,7 +50,8 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
|
||||
worklist: Vec<ast::NodeId>,
|
||||
tcx: &'a ty::ctxt<'tcx>,
|
||||
live_symbols: Box<HashSet<ast::NodeId>>,
|
||||
struct_has_extern_repr: bool
|
||||
struct_has_extern_repr: bool,
|
||||
ignore_paths: bool
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
@ -61,7 +61,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
worklist: worklist,
|
||||
tcx: tcx,
|
||||
live_symbols: box HashSet::new(),
|
||||
struct_has_extern_repr: false
|
||||
struct_has_extern_repr: false,
|
||||
ignore_paths: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,19 +74,18 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn lookup_and_handle_definition(&mut self, id: &ast::NodeId) {
|
||||
let def = match self.tcx.def_map.borrow().find(id) {
|
||||
Some(&def) => def,
|
||||
None => return
|
||||
};
|
||||
let def_id = match def {
|
||||
def::DefVariant(enum_id, _, _) => Some(enum_id),
|
||||
def::DefPrimTy(_) => None,
|
||||
_ => Some(def.def_id())
|
||||
};
|
||||
match def_id {
|
||||
Some(def_id) => self.check_def_id(def_id),
|
||||
None => (),
|
||||
}
|
||||
self.tcx.def_map.borrow().find(id).map(|def| {
|
||||
match def {
|
||||
&def::DefPrimTy(_) => (),
|
||||
&def::DefVariant(enum_id, variant_id, _) => {
|
||||
self.check_def_id(enum_id);
|
||||
self.check_def_id(variant_id);
|
||||
}
|
||||
_ => {
|
||||
self.check_def_id(def.def_id());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn lookup_and_handle_method(&mut self, id: ast::NodeId,
|
||||
@ -275,22 +275,27 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &ast::Pat) {
|
||||
let def_map = &self.tcx.def_map;
|
||||
match pat.node {
|
||||
ast::PatStruct(_, ref fields, _) => {
|
||||
self.handle_field_pattern_match(pat, fields.as_slice());
|
||||
}
|
||||
ast::PatIdent(_, _, _) => {
|
||||
_ if pat_util::pat_is_const(def_map, pat) => {
|
||||
// it might be the only use of a static:
|
||||
self.lookup_and_handle_definition(&pat.id)
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
self.ignore_paths = true;
|
||||
visit::walk_pat(self, pat);
|
||||
self.ignore_paths = false;
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
|
||||
self.lookup_and_handle_definition(&id);
|
||||
if !self.ignore_paths {
|
||||
self.lookup_and_handle_definition(&id);
|
||||
}
|
||||
visit::walk_path(self, path);
|
||||
}
|
||||
|
||||
@ -330,15 +335,19 @@ fn has_allow_dead_code_or_lang_attr(attrs: &[ast::Attribute]) -> bool {
|
||||
// 2) We are not sure to be live or not
|
||||
// * Implementation of a trait method
|
||||
struct LifeSeeder {
|
||||
worklist: Vec<ast::NodeId> ,
|
||||
worklist: Vec<ast::NodeId>
|
||||
}
|
||||
|
||||
impl<'v> Visitor<'v> for LifeSeeder {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
if has_allow_dead_code_or_lang_attr(item.attrs.as_slice()) {
|
||||
let allow_dead_code = has_allow_dead_code_or_lang_attr(item.attrs.as_slice());
|
||||
if allow_dead_code {
|
||||
self.worklist.push(item.id);
|
||||
}
|
||||
match item.node {
|
||||
ast::ItemEnum(ref enum_def, _) if allow_dead_code => {
|
||||
self.worklist.extend(enum_def.variants.iter().map(|variant| variant.node.id));
|
||||
}
|
||||
ast::ItemImpl(_, Some(ref _trait_ref), _, ref impl_items) => {
|
||||
for impl_item in impl_items.iter() {
|
||||
match *impl_item {
|
||||
@ -415,16 +424,6 @@ fn find_live(tcx: &ty::ctxt,
|
||||
symbol_visitor.live_symbols
|
||||
}
|
||||
|
||||
fn should_warn(item: &ast::Item) -> bool {
|
||||
match item.node {
|
||||
ast::ItemStatic(..)
|
||||
| ast::ItemFn(..)
|
||||
| ast::ItemEnum(..)
|
||||
| ast::ItemStruct(..) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn get_struct_ctor_id(item: &ast::Item) -> Option<ast::NodeId> {
|
||||
match item.node {
|
||||
ast::ItemStruct(ref struct_def, _) => struct_def.ctor_id,
|
||||
@ -438,6 +437,18 @@ struct DeadVisitor<'a, 'tcx: 'a> {
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
|
||||
fn should_warn_about_item(&mut self, item: &ast::Item) -> bool {
|
||||
let should_warn = match item.node {
|
||||
ast::ItemStatic(..)
|
||||
| ast::ItemFn(..)
|
||||
| ast::ItemEnum(..)
|
||||
| ast::ItemStruct(..) => true,
|
||||
_ => false
|
||||
};
|
||||
let ctor_id = get_struct_ctor_id(item);
|
||||
should_warn && !self.symbol_is_live(item.id, ctor_id)
|
||||
}
|
||||
|
||||
fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
|
||||
let is_named = node.ident().is_some();
|
||||
let field_type = ty::node_id_to_type(self.tcx, node.id);
|
||||
@ -451,6 +462,11 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
|
||||
&& !has_allow_dead_code_or_lang_attr(node.attrs.as_slice())
|
||||
}
|
||||
|
||||
fn should_warn_about_variant(&mut self, variant: &ast::Variant_) -> bool {
|
||||
!self.symbol_is_live(variant.id, None)
|
||||
&& !has_allow_dead_code_or_lang_attr(variant.attrs.as_slice())
|
||||
}
|
||||
|
||||
// id := node id of an item's definition.
|
||||
// ctor_id := `Some` if the item is a struct_ctor (tuple struct),
|
||||
// `None` otherwise.
|
||||
@ -491,7 +507,8 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
|
||||
fn warn_dead_code(&mut self,
|
||||
id: ast::NodeId,
|
||||
span: codemap::Span,
|
||||
ident: ast::Ident) {
|
||||
ident: ast::Ident,
|
||||
node_type: &str) {
|
||||
let name = ident.as_str();
|
||||
if !name.starts_with("_") {
|
||||
self.tcx
|
||||
@ -499,23 +516,34 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
|
||||
.add_lint(lint::builtin::DEAD_CODE,
|
||||
id,
|
||||
span,
|
||||
format!("code is never used: `{}`", name));
|
||||
format!("{} is never used: `{}`", node_type, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
let ctor_id = get_struct_ctor_id(item);
|
||||
if !self.symbol_is_live(item.id, ctor_id) && should_warn(item) {
|
||||
self.warn_dead_code(item.id, item.span, item.ident);
|
||||
if self.should_warn_about_item(item) {
|
||||
self.warn_dead_code(item.id, item.span, item.ident, item.node.descriptive_variant());
|
||||
} else {
|
||||
match item.node {
|
||||
ast::ItemEnum(ref enum_def, _) => {
|
||||
for variant in enum_def.variants.iter() {
|
||||
if self.should_warn_about_variant(&variant.node) {
|
||||
self.warn_dead_code(variant.node.id, variant.span,
|
||||
variant.node.name, "variant");
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
visit::walk_item(self, item);
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
|
||||
if !self.symbol_is_live(fi.id, None) {
|
||||
self.warn_dead_code(fi.id, fi.span, fi.ident);
|
||||
self.warn_dead_code(fi.id, fi.span, fi.ident, fi.node.descriptive_variant());
|
||||
}
|
||||
visit::walk_foreign_item(self, fi);
|
||||
}
|
||||
@ -527,7 +555,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
||||
match fk {
|
||||
visit::FkMethod(name, _, _) => {
|
||||
if !self.symbol_is_live(id, None) {
|
||||
self.warn_dead_code(id, span, name);
|
||||
self.warn_dead_code(id, span, name, "method");
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
@ -537,7 +565,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
|
||||
|
||||
fn visit_struct_field(&mut self, field: &ast::StructField) {
|
||||
if self.should_warn_about_field(&field.node) {
|
||||
self.warn_dead_code(field.node.id, field.span, field.node.ident().unwrap());
|
||||
self.warn_dead_code(field.node.id, field.span,
|
||||
field.node.ident().unwrap(), "struct field");
|
||||
}
|
||||
|
||||
visit::walk_struct_field(self, field);
|
||||
|
@ -355,17 +355,6 @@ pub fn check_freevar_bounds(cx: &Context, fn_span: Span, sp: Span, ty: ty::t,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn check_trait_cast_bounds(cx: &Context, sp: Span, ty: ty::t,
|
||||
bounds: ty::BuiltinBounds) {
|
||||
check_builtin_bounds(cx, ty, bounds, |missing| {
|
||||
span_err!(cx.tcx.sess, sp, E0147,
|
||||
"cannot pack type `{}`, which does not fulfill `{}`, as a trait bounded by {}",
|
||||
ty_to_string(cx.tcx, ty),
|
||||
missing.user_string(cx.tcx),
|
||||
bounds.user_string(cx.tcx));
|
||||
});
|
||||
}
|
||||
|
||||
fn check_copy(cx: &Context, ty: ty::t, sp: Span, reason: &str) {
|
||||
debug!("type_contents({})={}",
|
||||
ty_to_string(cx.tcx, ty),
|
||||
|
@ -735,10 +735,6 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn cat_deref_obj<N:ast_node>(&self, node: &N, base_cmt: cmt) -> cmt {
|
||||
self.cat_deref_common(node, base_cmt, 0, ty::mk_nil(), false)
|
||||
}
|
||||
|
||||
fn cat_deref<N:ast_node>(&self,
|
||||
node: &N,
|
||||
base_cmt: cmt,
|
||||
|
@ -488,7 +488,6 @@ enum ParentLink {
|
||||
#[deriving(PartialEq)]
|
||||
enum ModuleKind {
|
||||
NormalModuleKind,
|
||||
ExternModuleKind,
|
||||
TraitModuleKind,
|
||||
ImplModuleKind,
|
||||
AnonymousModuleKind,
|
||||
@ -3348,7 +3347,6 @@ impl<'a> Resolver<'a> {
|
||||
parents");
|
||||
return Failed(None);
|
||||
}
|
||||
ExternModuleKind |
|
||||
TraitModuleKind |
|
||||
ImplModuleKind |
|
||||
AnonymousModuleKind => {
|
||||
@ -3446,7 +3444,6 @@ impl<'a> Resolver<'a> {
|
||||
let new_module = new_module.upgrade().unwrap();
|
||||
match new_module.kind.get() {
|
||||
NormalModuleKind => return Some(new_module),
|
||||
ExternModuleKind |
|
||||
TraitModuleKind |
|
||||
ImplModuleKind |
|
||||
AnonymousModuleKind => module_ = new_module,
|
||||
@ -3462,7 +3459,6 @@ impl<'a> Resolver<'a> {
|
||||
-> Rc<Module> {
|
||||
match module_.kind.get() {
|
||||
NormalModuleKind => return module_,
|
||||
ExternModuleKind |
|
||||
TraitModuleKind |
|
||||
ImplModuleKind |
|
||||
AnonymousModuleKind => {
|
||||
|
@ -195,11 +195,6 @@ impl Substs {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_method_from(self, substs: &Substs) -> Substs {
|
||||
self.with_method(Vec::from_slice(substs.types.get_slice(FnSpace)),
|
||||
Vec::from_slice(substs.regions().get_slice(FnSpace)))
|
||||
}
|
||||
|
||||
pub fn with_method(self,
|
||||
m_types: Vec<ty::t>,
|
||||
m_regions: Vec<ty::Region>)
|
||||
@ -292,15 +287,6 @@ impl<T:fmt::Show> fmt::Show for VecPerParamSpace<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Clone> VecPerParamSpace<T> {
|
||||
pub fn push_all(&mut self, space: ParamSpace, values: &[T]) {
|
||||
// FIXME (#15435): slow; O(n^2); could enhance vec to make it O(n).
|
||||
for t in values.iter() {
|
||||
self.push(space, t.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> VecPerParamSpace<T> {
|
||||
fn limits(&self, space: ParamSpace) -> (uint, uint) {
|
||||
match space {
|
||||
@ -348,14 +334,6 @@ impl<T> VecPerParamSpace<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sort(t: Vec<T>, space: |&T| -> ParamSpace) -> VecPerParamSpace<T> {
|
||||
let mut result = VecPerParamSpace::empty();
|
||||
for t in t.into_iter() {
|
||||
result.push(space(&t), t);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/// Appends `value` to the vector associated with `space`.
|
||||
///
|
||||
/// Unlike the `push` method in `Vec`, this should not be assumed
|
||||
@ -435,12 +413,6 @@ impl<T> VecPerParamSpace<T> {
|
||||
&self.get_slice(space)[index]
|
||||
}
|
||||
|
||||
pub fn get_mut<'a>(&'a mut self,
|
||||
space: ParamSpace,
|
||||
index: uint) -> &'a mut T {
|
||||
&mut self.get_mut_slice(space)[index]
|
||||
}
|
||||
|
||||
pub fn iter<'a>(&'a self) -> Items<'a,T> {
|
||||
self.content.iter()
|
||||
}
|
||||
@ -476,30 +448,6 @@ impl<T> VecPerParamSpace<T> {
|
||||
f.into_iter().map(|p| pred(p)).collect())
|
||||
}
|
||||
|
||||
pub fn map_rev<U>(&self, pred: |&T| -> U) -> VecPerParamSpace<U> {
|
||||
/*!
|
||||
* Executes the map but in reverse order. For hacky reasons, we rely
|
||||
* on this in table.
|
||||
*
|
||||
* FIXME(#5527) -- order of eval becomes irrelevant with newer
|
||||
* trait reform, which features an idempotent algorithm that
|
||||
* can be run to a fixed point
|
||||
*/
|
||||
|
||||
let mut fns: Vec<U> = self.get_slice(FnSpace).iter().rev().map(|p| pred(p)).collect();
|
||||
|
||||
// NB: Calling foo.rev().map().rev() causes the calls to map
|
||||
// to occur in the wrong order. This was somewhat surprising
|
||||
// to me, though it makes total sense.
|
||||
fns.reverse();
|
||||
|
||||
let mut selfs: Vec<U> = self.get_slice(SelfSpace).iter().rev().map(|p| pred(p)).collect();
|
||||
selfs.reverse();
|
||||
let mut tys: Vec<U> = self.get_slice(TypeSpace).iter().rev().map(|p| pred(p)).collect();
|
||||
tys.reverse();
|
||||
VecPerParamSpace::new(tys, selfs, fns)
|
||||
}
|
||||
|
||||
pub fn split(self) -> (Vec<T>, Vec<T>, Vec<T>) {
|
||||
// FIXME (#15418): this does two traversals when in principle
|
||||
// one would suffice. i.e. change to use `move_iter`.
|
||||
|
@ -21,7 +21,6 @@ use middle::trans::base;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::foreign;
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
use syntax::abi;
|
||||
@ -285,37 +284,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||
(lldecl, true)
|
||||
}
|
||||
|
||||
// Used to identify cached monomorphized functions
|
||||
#[deriving(PartialEq, Eq, Hash)]
|
||||
pub struct MonoParamId {
|
||||
pub subst: ty::t,
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Eq, Hash)]
|
||||
pub struct MonoId {
|
||||
pub def: ast::DefId,
|
||||
pub params: subst::VecPerParamSpace<ty::t>
|
||||
}
|
||||
|
||||
pub fn make_vtable_id(_ccx: &CrateContext,
|
||||
origin: &typeck::vtable_origin)
|
||||
-> MonoId {
|
||||
match origin {
|
||||
&typeck::vtable_static(impl_id, ref substs, _) => {
|
||||
MonoId {
|
||||
def: impl_id,
|
||||
params: substs.types.clone()
|
||||
}
|
||||
}
|
||||
|
||||
&typeck::vtable_unboxed_closure(def_id) => {
|
||||
MonoId {
|
||||
def: def_id,
|
||||
params: subst::VecPerParamSpace::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
// can't this be checked at the callee?
|
||||
_ => fail!("make_vtable_id needs vtable_static")
|
||||
}
|
||||
}
|
||||
|
@ -1915,13 +1915,6 @@ pub fn fold_ty(cx: &ctxt, t0: t, fldop: |t| -> t) -> t {
|
||||
f.fold_ty(t0)
|
||||
}
|
||||
|
||||
pub fn walk_regions_and_ty(cx: &ctxt, ty: t, fldr: |r: Region|, fldt: |t: t|)
|
||||
-> t {
|
||||
ty_fold::RegionFolder::general(cx,
|
||||
|r| { fldr(r); r },
|
||||
|t| { fldt(t); t }).fold_ty(ty)
|
||||
}
|
||||
|
||||
impl ParamTy {
|
||||
pub fn new(space: subst::ParamSpace,
|
||||
index: uint,
|
||||
@ -3551,58 +3544,6 @@ pub fn unsize_ty(cx: &ctxt,
|
||||
}
|
||||
}
|
||||
|
||||
impl AutoRef {
|
||||
pub fn map_region(&self, f: |Region| -> Region) -> AutoRef {
|
||||
match *self {
|
||||
ty::AutoPtr(r, m, None) => ty::AutoPtr(f(r), m, None),
|
||||
ty::AutoPtr(r, m, Some(ref a)) => ty::AutoPtr(f(r), m, Some(box a.map_region(f))),
|
||||
ty::AutoUnsize(ref k) => ty::AutoUnsize(k.clone()),
|
||||
ty::AutoUnsizeUniq(ref k) => ty::AutoUnsizeUniq(k.clone()),
|
||||
ty::AutoUnsafe(m, None) => ty::AutoUnsafe(m, None),
|
||||
ty::AutoUnsafe(m, Some(ref a)) => ty::AutoUnsafe(m, Some(box a.map_region(f))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn method_call_type_param_defs<'tcx, T>(typer: &T,
|
||||
origin: &typeck::MethodOrigin)
|
||||
-> VecPerParamSpace<TypeParameterDef>
|
||||
where T: mc::Typer<'tcx> {
|
||||
match *origin {
|
||||
typeck::MethodStatic(did) => {
|
||||
ty::lookup_item_type(typer.tcx(), did).generics.types.clone()
|
||||
}
|
||||
typeck::MethodStaticUnboxedClosure(did) => {
|
||||
let def_id = typer.unboxed_closures()
|
||||
.borrow()
|
||||
.find(&did)
|
||||
.expect("method_call_type_param_defs: didn't \
|
||||
find unboxed closure")
|
||||
.kind
|
||||
.trait_did(typer.tcx());
|
||||
lookup_trait_def(typer.tcx(), def_id).generics.types.clone()
|
||||
}
|
||||
typeck::MethodTypeParam(typeck::MethodParam{
|
||||
trait_ref: ref trait_ref,
|
||||
method_num: n_mth,
|
||||
..
|
||||
}) |
|
||||
typeck::MethodTraitObject(typeck::MethodObject{
|
||||
trait_ref: ref trait_ref,
|
||||
method_num: n_mth,
|
||||
..
|
||||
}) => {
|
||||
match ty::trait_item(typer.tcx(), trait_ref.def_id, n_mth) {
|
||||
ty::MethodTraitItem(method) => method.generics.types.clone(),
|
||||
ty::TypeTraitItem(_) => {
|
||||
typer.tcx().sess.bug("method_call_type_param_defs() \
|
||||
called on associated type")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
|
||||
match tcx.def_map.borrow().find(&expr.id) {
|
||||
Some(&def) => def,
|
||||
@ -3821,22 +3762,6 @@ pub fn impl_or_trait_item_idx(id: ast::Ident, trait_items: &[ImplOrTraitItem])
|
||||
trait_items.iter().position(|m| m.ident() == id)
|
||||
}
|
||||
|
||||
/// Returns a vector containing the indices of all type parameters that appear
|
||||
/// in `ty`. The vector may contain duplicates. Probably should be converted
|
||||
/// to a bitset or some other representation.
|
||||
pub fn param_tys_in_type(ty: t) -> Vec<ParamTy> {
|
||||
let mut rslt = Vec::new();
|
||||
walk_ty(ty, |ty| {
|
||||
match get(ty).sty {
|
||||
ty_param(p) => {
|
||||
rslt.push(p);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
});
|
||||
rslt
|
||||
}
|
||||
|
||||
pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
|
||||
match get(t).sty {
|
||||
ty_nil | ty_bot | ty_bool | ty_char | ty_int(_) |
|
||||
@ -4706,17 +4631,6 @@ pub fn is_tuple_struct(cx: &ctxt, did: ast::DefId) -> bool {
|
||||
!fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field)
|
||||
}
|
||||
|
||||
pub fn lookup_struct_field(cx: &ctxt,
|
||||
parent: ast::DefId,
|
||||
field_id: ast::DefId)
|
||||
-> field_ty {
|
||||
let r = lookup_struct_fields(cx, parent);
|
||||
match r.iter().find(|f| f.id.node == field_id.node) {
|
||||
Some(t) => t.clone(),
|
||||
None => cx.sess.bug("struct ID not found in parent's fields")
|
||||
}
|
||||
}
|
||||
|
||||
// Returns a list of fields corresponding to the struct's items. trans uses
|
||||
// this. Takes a list of substs with which to instantiate field types.
|
||||
pub fn struct_fields(cx: &ctxt, did: ast::DefId, substs: &Substs)
|
||||
|
@ -77,17 +77,3 @@ pub fn coerce(fcx: &FnCtxt, sp: Span, expected: ty::t, expr: &ast::Expr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn coerce_with_fn(fcx: &FnCtxt,
|
||||
sp: Span,
|
||||
expected: ty::t,
|
||||
expr: &ast::Expr,
|
||||
handle_err: |Span, ty::t, ty::t, &ty::type_err|) {
|
||||
let expr_ty = fcx.expr_ty(expr);
|
||||
match fcx.mk_assignty(expr, expr_ty, expected) {
|
||||
result::Ok(()) => { /* ok */ }
|
||||
result::Err(ref err) => {
|
||||
handle_err(sp, expected, expr_ty, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1901,18 +1901,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn method_ty_substs(&self, id: ast::NodeId) -> subst::Substs {
|
||||
match self.inh.method_map.borrow().find(&MethodCall::expr(id)) {
|
||||
Some(method) => method.substs.clone(),
|
||||
None => {
|
||||
self.tcx().sess.bug(
|
||||
format!("no method entry for node {}: {} in fcx {}",
|
||||
id, self.tcx().map.node_to_string(id),
|
||||
self.tag()).as_slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn opt_node_ty_substs(&self,
|
||||
id: ast::NodeId,
|
||||
f: |&ty::ItemSubsts|) {
|
||||
@ -1984,18 +1972,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.infcx().type_error_message(sp, mk_msg, actual_ty, err);
|
||||
}
|
||||
|
||||
pub fn report_mismatched_return_types(&self,
|
||||
sp: Span,
|
||||
e: ty::t,
|
||||
a: ty::t,
|
||||
err: &ty::type_err) {
|
||||
// Derived error
|
||||
if ty::type_is_error(e) || ty::type_is_error(a) {
|
||||
return;
|
||||
}
|
||||
self.infcx().report_mismatched_types(sp, e, a, err)
|
||||
}
|
||||
|
||||
pub fn report_mismatched_types(&self,
|
||||
sp: Span,
|
||||
e: ty::t,
|
||||
@ -4663,24 +4639,6 @@ impl Repr for Expectation {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn require_uint(fcx: &FnCtxt, sp: Span, t: ty::t) {
|
||||
if !type_is_uint(fcx, sp, t) {
|
||||
fcx.type_error_message(sp, |actual| {
|
||||
format!("mismatched types: expected `uint` type, found `{}`",
|
||||
actual)
|
||||
}, t, None);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn require_integral(fcx: &FnCtxt, sp: Span, t: ty::t) {
|
||||
if !type_is_integral(fcx, sp, t) {
|
||||
fcx.type_error_message(sp, |actual| {
|
||||
format!("mismatched types: expected integral type, found `{}`",
|
||||
actual)
|
||||
}, t, None);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_decl_initializer(fcx: &FnCtxt,
|
||||
nid: ast::NodeId,
|
||||
init: &ast::Expr)
|
||||
@ -5602,51 +5560,6 @@ pub fn structure_of<'a>(fcx: &FnCtxt, sp: Span, typ: ty::t)
|
||||
&ty::get(structurally_resolved_type(fcx, sp, typ)).sty
|
||||
}
|
||||
|
||||
pub fn type_is_integral(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_integral(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_uint(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_uint(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_scalar(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_scalar(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_char(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_char(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_bare_fn(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_bare_fn(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_floating_point(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_floating_point(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_unsafe_ptr(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_unsafe_ptr(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_region_ptr(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_region_ptr(typ_s);
|
||||
}
|
||||
|
||||
pub fn type_is_c_like_enum(fcx: &FnCtxt, sp: Span, typ: ty::t) -> bool {
|
||||
let typ_s = structurally_resolved_type(fcx, sp, typ);
|
||||
return ty::type_is_c_like_enum(fcx.ccx.tcx, typ_s);
|
||||
}
|
||||
|
||||
// Returns true if b contains a break that can exit from b
|
||||
pub fn may_break(cx: &ty::ctxt, id: ast::NodeId, b: &ast::Block) -> bool {
|
||||
// First: is there an unlabeled break immediately
|
||||
|
@ -213,26 +213,6 @@ pub struct Rcx<'a, 'tcx: 'a> {
|
||||
repeating_scope: ast::NodeId,
|
||||
}
|
||||
|
||||
/// When entering a function, we can derive relationships from the
|
||||
/// signature between various regions and type parameters. Consider
|
||||
/// a function like:
|
||||
///
|
||||
/// fn foo<'a, A>(x: &'a A) { ... }
|
||||
///
|
||||
/// Here, we can derive that `A` must outlive `'a`, because otherwise
|
||||
/// the caller would be illegal. We record this by storing a series of
|
||||
/// pairs (in this case, `('a, A)`). These pairs will be consulted
|
||||
/// later during regionck.
|
||||
///
|
||||
/// In the case of nested fns, additional relationships may be
|
||||
/// derived. The result is a link list walking up the stack (hence
|
||||
/// the `previous` field).
|
||||
#[deriving(Clone)]
|
||||
pub struct RegionSubParamConstraints<'a> {
|
||||
pairs: Vec<(ty::Region, ty::ParamTy)>,
|
||||
previous: Option<&'a RegionSubParamConstraints<'a>>,
|
||||
}
|
||||
|
||||
fn region_of_def(fcx: &FnCtxt, def: def::Def) -> ty::Region {
|
||||
/*!
|
||||
* Returns the validity region of `def` -- that is, how long
|
||||
|
@ -25,17 +25,6 @@ use syntax::codemap::Span;
|
||||
use util::ppaux::UserString;
|
||||
use util::ppaux::Repr;
|
||||
|
||||
/// When reporting an error about a failed trait obligation, it's nice
|
||||
/// to include some context indicating why we were checking that
|
||||
/// obligation in the first place. The span is often enough but
|
||||
/// sometimes it's not. Currently this enum is a bit of a hack and I
|
||||
/// suspect it should be carried in the obligation or more deeply
|
||||
/// integrated somehow.
|
||||
pub enum ErrorReportingContext {
|
||||
GenericContext,
|
||||
ImplSupertraitCheck,
|
||||
}
|
||||
|
||||
pub fn check_object_cast(fcx: &FnCtxt,
|
||||
cast_expr: &ast::Expr,
|
||||
source_expr: &ast::Expr,
|
||||
|
@ -22,7 +22,6 @@ use middle::typeck::infer::{force_all, resolve_all, resolve_region};
|
||||
use middle::typeck::infer::resolve_type;
|
||||
use middle::typeck::infer;
|
||||
use middle::typeck::{MethodCall, MethodCallee};
|
||||
use middle::typeck::vtable_res;
|
||||
use middle::typeck::write_substs_to_tcx;
|
||||
use middle::typeck::write_ty_to_tcx;
|
||||
use util::ppaux::Repr;
|
||||
@ -67,17 +66,6 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
|
||||
wbcx.visit_object_cast_map();
|
||||
}
|
||||
|
||||
pub fn resolve_impl_res(infcx: &infer::InferCtxt,
|
||||
span: Span,
|
||||
vtable_res: &vtable_res)
|
||||
-> vtable_res {
|
||||
let errors = Cell::new(false); // nobody cares
|
||||
let mut resolver = Resolver::from_infcx(infcx,
|
||||
&errors,
|
||||
ResolvingImplRes(span));
|
||||
vtable_res.resolve_in(&mut resolver)
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// The Writerback context. This visitor walks the AST, checking the
|
||||
// fn-specific tables to find references to types or regions. It
|
||||
@ -361,7 +349,6 @@ enum ResolveReason {
|
||||
ResolvingLocal(Span),
|
||||
ResolvingPattern(Span),
|
||||
ResolvingUpvar(ty::UpvarId),
|
||||
ResolvingImplRes(Span),
|
||||
ResolvingUnboxedClosure(ast::DefId),
|
||||
}
|
||||
|
||||
@ -374,7 +361,6 @@ impl ResolveReason {
|
||||
ResolvingUpvar(upvar_id) => {
|
||||
ty::expr_span(tcx, upvar_id.closure_expr_id)
|
||||
}
|
||||
ResolvingImplRes(s) => s,
|
||||
ResolvingUnboxedClosure(did) => {
|
||||
if did.krate == ast::LOCAL_CRATE {
|
||||
ty::expr_span(tcx, did.node)
|
||||
@ -415,10 +401,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
|
||||
reason: ResolveReason)
|
||||
-> Resolver<'cx, 'tcx>
|
||||
{
|
||||
Resolver { infcx: fcx.infcx(),
|
||||
tcx: fcx.tcx(),
|
||||
writeback_errors: &fcx.writeback_errors,
|
||||
reason: reason }
|
||||
Resolver::from_infcx(fcx.infcx(), &fcx.writeback_errors, reason)
|
||||
}
|
||||
|
||||
fn from_infcx(infcx: &'cx infer::InferCtxt<'cx, 'tcx>,
|
||||
@ -462,11 +445,6 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
|
||||
infer::fixup_err_to_string(e));
|
||||
}
|
||||
|
||||
ResolvingImplRes(span) => {
|
||||
span_err!(self.tcx.sess, span, E0105,
|
||||
"cannot determine a type for impl supertrait");
|
||||
}
|
||||
|
||||
ResolvingUnboxedClosure(_) => {
|
||||
let span = self.reason.span(self.tcx);
|
||||
self.tcx.sess.span_err(span,
|
||||
|
@ -66,12 +66,6 @@ pub mod unify;
|
||||
|
||||
pub type Bound<T> = Option<T>;
|
||||
|
||||
#[deriving(PartialEq,Clone)]
|
||||
pub struct Bounds<T> {
|
||||
pub lb: Bound<T>,
|
||||
pub ub: Bound<T>
|
||||
}
|
||||
|
||||
pub type cres<T> = Result<T,ty::type_err>; // "combine result"
|
||||
pub type ures = cres<()>; // "unify result"
|
||||
pub type fres<T> = Result<T, fixup_err>; // "fixup result"
|
||||
@ -271,9 +265,7 @@ pub enum RegionVariableOrigin {
|
||||
pub enum fixup_err {
|
||||
unresolved_int_ty(IntVid),
|
||||
unresolved_float_ty(FloatVid),
|
||||
unresolved_ty(TyVid),
|
||||
unresolved_region(RegionVid),
|
||||
region_var_bound_by_region_var(RegionVid, RegionVid)
|
||||
unresolved_ty(TyVid)
|
||||
}
|
||||
|
||||
pub fn fixup_err_to_string(f: fixup_err) -> String {
|
||||
@ -287,11 +279,6 @@ pub fn fixup_err_to_string(f: fixup_err) -> String {
|
||||
the type explicitly".to_string()
|
||||
}
|
||||
unresolved_ty(_) => "unconstrained type".to_string(),
|
||||
unresolved_region(_) => "unconstrained region".to_string(),
|
||||
region_var_bound_by_region_var(r1, r2) => {
|
||||
format!("region var {:?} bound by another region var {:?}; \
|
||||
this is a bug in rustc", r1, r2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,17 +525,6 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn max_regions(&self,
|
||||
a: Region,
|
||||
b: Region)
|
||||
-> Option<Region>
|
||||
{
|
||||
match self.glb_concrete_regions(a, b) {
|
||||
Ok(r) => Some(r),
|
||||
Err(_) => None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_var(&self, rid: RegionVid) -> ty::Region {
|
||||
match *self.values.borrow() {
|
||||
None => {
|
||||
|
@ -25,7 +25,6 @@ use middle::ty::{ty_uniq, ty_trait, ty_int, ty_uint, ty_infer};
|
||||
use middle::ty;
|
||||
use middle::typeck;
|
||||
use middle::typeck::check::regionmanip;
|
||||
use middle::typeck::infer;
|
||||
|
||||
use std::rc::Rc;
|
||||
use syntax::abi;
|
||||
@ -1181,14 +1180,6 @@ impl Repr for ast::FloatTy {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Repr> Repr for infer::Bounds<T> {
|
||||
fn repr(&self, tcx: &ctxt) -> String {
|
||||
format!("({} <= {})",
|
||||
self.lb.repr(tcx),
|
||||
self.ub.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
impl Repr for ty::ExplicitSelfCategory {
|
||||
fn repr(&self, _: &ctxt) -> String {
|
||||
explicit_self_category_to_str(self).to_string()
|
||||
|
@ -1323,6 +1323,22 @@ pub enum Item_ {
|
||||
ItemMac(Mac),
|
||||
}
|
||||
|
||||
impl Item_ {
|
||||
pub fn descriptive_variant(&self) -> &str {
|
||||
match *self {
|
||||
ItemStatic(..) => "static item",
|
||||
ItemFn(..) => "function",
|
||||
ItemMod(..) => "module",
|
||||
ItemForeignMod(..) => "foreign module",
|
||||
ItemTy(..) => "type alias",
|
||||
ItemEnum(..) => "enum",
|
||||
ItemStruct(..) => "struct",
|
||||
ItemTrait(..) => "trait",
|
||||
_ => "item"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||
pub struct ForeignItem {
|
||||
pub ident: Ident,
|
||||
@ -1339,6 +1355,15 @@ pub enum ForeignItem_ {
|
||||
ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
|
||||
}
|
||||
|
||||
impl ForeignItem_ {
|
||||
pub fn descriptive_variant(&self) -> &str {
|
||||
match *self {
|
||||
ForeignItemFn(..) => "foreign function",
|
||||
ForeignItemStatic(..) => "foreign static item"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||
pub enum UnboxedClosureKind {
|
||||
FnUnboxedClosureKind,
|
||||
|
@ -24,8 +24,7 @@ use std::string;
|
||||
#[deriving(PartialEq)]
|
||||
enum ArgumentType {
|
||||
Known(string::String),
|
||||
Unsigned,
|
||||
String,
|
||||
Unsigned
|
||||
}
|
||||
|
||||
enum Position {
|
||||
@ -691,12 +690,6 @@ impl<'a, 'b> Context<'a, 'b> {
|
||||
}
|
||||
}
|
||||
}
|
||||
String => {
|
||||
return ecx.expr_call_global(sp, vec![
|
||||
ecx.ident_of("std"),
|
||||
ecx.ident_of("fmt"),
|
||||
ecx.ident_of("argumentstr")], vec![arg])
|
||||
}
|
||||
Unsigned => {
|
||||
return ecx.expr_call_global(sp, vec![
|
||||
ecx.ident_of("std"),
|
||||
|
@ -26,5 +26,5 @@ extern crate regex;
|
||||
// unused variable warning).
|
||||
|
||||
fn main() {
|
||||
static fubar: regex::Regex = regex!("abc"); //~ ERROR code is never used: `fubar`
|
||||
static fubar: regex::Regex = regex!("abc"); //~ ERROR static item is never used: `fubar`
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
#[phase(link, plugin)] extern crate core;
|
||||
|
||||
|
||||
fn foo() { //~ ERROR code is never used
|
||||
fn foo() { //~ ERROR function is never used
|
||||
|
||||
// none of these should have any dead_code exposed to the user
|
||||
fail!();
|
||||
|
@ -11,7 +11,7 @@
|
||||
#![deny(dead_code)]
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
fn foo() { //~ ERROR code is never used
|
||||
fn foo() { //~ ERROR function is never used
|
||||
|
||||
// none of these should have any dead_code exposed to the user
|
||||
fail!();
|
||||
|
@ -22,7 +22,7 @@ pub use foo2::Bar2;
|
||||
pub trait Sized {}
|
||||
|
||||
mod foo {
|
||||
pub struct Bar; //~ ERROR: code is never used
|
||||
pub struct Bar; //~ ERROR: struct is never used
|
||||
}
|
||||
|
||||
mod foo2 {
|
||||
@ -30,7 +30,7 @@ mod foo2 {
|
||||
}
|
||||
|
||||
pub static pub_static: int = 0;
|
||||
static priv_static: int = 0; //~ ERROR: code is never used
|
||||
static priv_static: int = 0; //~ ERROR: static item is never used
|
||||
static used_static: int = 0;
|
||||
pub static used_static2: int = used_static;
|
||||
static USED_STATIC: int = 0;
|
||||
@ -38,7 +38,7 @@ static STATIC_USED_IN_ENUM_DISCRIMINANT: int = 10;
|
||||
|
||||
pub type typ = *const UsedStruct4;
|
||||
pub struct PubStruct;
|
||||
struct PrivStruct; //~ ERROR: code is never used
|
||||
struct PrivStruct; //~ ERROR: struct is never used
|
||||
struct UsedStruct1 {
|
||||
#[allow(dead_code)]
|
||||
x: int
|
||||
@ -63,8 +63,12 @@ pub struct PubStruct2 {
|
||||
pub enum pub_enum { foo1, bar1 }
|
||||
pub enum pub_enum2 { a(*const StructUsedInEnum) }
|
||||
pub enum pub_enum3 { Foo = STATIC_USED_IN_ENUM_DISCRIMINANT }
|
||||
enum priv_enum { foo2, bar2 } //~ ERROR: code is never used
|
||||
enum used_enum { foo3, bar3 }
|
||||
|
||||
enum priv_enum { foo2, bar2 } //~ ERROR: enum is never used
|
||||
enum used_enum {
|
||||
foo3,
|
||||
bar3 //~ ERROR variant is never used
|
||||
}
|
||||
|
||||
fn f<T>() {}
|
||||
|
||||
@ -83,17 +87,17 @@ pub fn pub_fn() {
|
||||
}
|
||||
f::<StructUsedInGeneric>();
|
||||
}
|
||||
fn priv_fn() { //~ ERROR: code is never used
|
||||
fn priv_fn() { //~ ERROR: function is never used
|
||||
let unused_struct = PrivStruct;
|
||||
}
|
||||
fn used_fn() {}
|
||||
|
||||
fn foo() { //~ ERROR: code is never used
|
||||
fn foo() { //~ ERROR: function is never used
|
||||
bar();
|
||||
let unused_enum = foo2;
|
||||
}
|
||||
|
||||
fn bar() { //~ ERROR: code is never used
|
||||
fn bar() { //~ ERROR: function is never used
|
||||
foo();
|
||||
}
|
||||
|
||||
|
@ -28,10 +28,10 @@ impl Bar for Foo {
|
||||
|
||||
fn live_fn() {}
|
||||
|
||||
fn dead_fn() {} //~ ERROR: code is never used
|
||||
fn dead_fn() {} //~ ERROR: function is never used
|
||||
|
||||
#[main]
|
||||
fn dead_fn2() {} //~ ERROR: code is never used
|
||||
fn dead_fn2() {} //~ ERROR: function is never used
|
||||
|
||||
fn used_fn() {}
|
||||
|
||||
@ -44,7 +44,7 @@ fn start(_: int, _: *const *const u8) -> int {
|
||||
}
|
||||
|
||||
// this is not main
|
||||
fn main() { //~ ERROR: code is never used
|
||||
fn main() { //~ ERROR: function is never used
|
||||
dead_fn();
|
||||
dead_fn2();
|
||||
}
|
||||
|
@ -21,15 +21,15 @@ extern {
|
||||
fn extern_foo();
|
||||
}
|
||||
|
||||
struct Foo; //~ ERROR: code is never used
|
||||
struct Foo; //~ ERROR: struct is never used
|
||||
impl Foo {
|
||||
fn foo(&self) { //~ ERROR: code is never used
|
||||
fn foo(&self) { //~ ERROR: method is never used
|
||||
bar()
|
||||
}
|
||||
}
|
||||
|
||||
fn bar() { //~ ERROR: code is never used
|
||||
fn baz() {} //~ ERROR: code is never used
|
||||
fn bar() { //~ ERROR: function is never used
|
||||
fn baz() {} //~ ERROR: function is never used
|
||||
|
||||
Foo.foo();
|
||||
baz();
|
||||
@ -68,9 +68,9 @@ mod blah {
|
||||
}
|
||||
}
|
||||
|
||||
enum c_void {} //~ ERROR: code is never used
|
||||
enum c_void {} //~ ERROR: enum is never used
|
||||
extern {
|
||||
fn free(p: *const c_void); //~ ERROR: code is never used
|
||||
fn free(p: *const c_void); //~ ERROR: foreign function is never used
|
||||
}
|
||||
|
||||
// Check provided method
|
||||
|
@ -19,7 +19,7 @@ use std::num;
|
||||
|
||||
struct Foo {
|
||||
x: uint,
|
||||
b: bool, //~ ERROR: code is never used
|
||||
b: bool, //~ ERROR: struct field is never used
|
||||
marker: std::kinds::marker::NoCopy
|
||||
}
|
||||
|
||||
@ -28,10 +28,10 @@ fn field_read(f: Foo) -> uint {
|
||||
}
|
||||
|
||||
enum XYZ {
|
||||
X,
|
||||
Y {
|
||||
X, //~ ERROR variant is never used
|
||||
Y { //~ ERROR variant is never used
|
||||
a: String,
|
||||
b: int //~ ERROR: code is never used
|
||||
b: int //~ ERROR: struct field is never used
|
||||
},
|
||||
Z
|
||||
}
|
||||
@ -44,7 +44,7 @@ fn field_match_in_patterns(b: XYZ) -> String {
|
||||
}
|
||||
|
||||
struct Bar {
|
||||
x: uint, //~ ERROR: code is never used
|
||||
x: uint, //~ ERROR: struct field is never used
|
||||
b: bool,
|
||||
_guard: ()
|
||||
}
|
||||
|
41
src/test/compile-fail/lint-dead-code-5.rs
Normal file
41
src/test/compile-fail/lint-dead-code-5.rs
Normal file
@ -0,0 +1,41 @@
|
||||
// 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![feature(struct_variant)]
|
||||
#![allow(unused_variable)]
|
||||
#![deny(dead_code)]
|
||||
|
||||
enum Enum1 {
|
||||
Variant1(int),
|
||||
Variant2 //~ ERROR: variant is never used
|
||||
}
|
||||
|
||||
enum Enum2 {
|
||||
Variant3(bool),
|
||||
#[allow(dead_code)]
|
||||
Variant4(int),
|
||||
Variant5 { _x: int }, //~ ERROR: variant is never used: `Variant5`
|
||||
Variant6(int), //~ ERROR: variant is never used: `Variant6`
|
||||
_Variant7,
|
||||
}
|
||||
|
||||
enum Enum3 { //~ ERROR: enum is never used
|
||||
Variant8,
|
||||
Variant9
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let v = Variant1(1);
|
||||
match v {
|
||||
Variant1(_) => (),
|
||||
Variant2 => ()
|
||||
}
|
||||
let x = Variant3(true);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user