This commit is contained in:
Mikhail Modin 2016-08-05 19:01:48 +03:00
commit e7e5cfe312
73 changed files with 1033 additions and 178 deletions

View File

@ -23,7 +23,7 @@ code example:
#[deny(const_err)]
const X: i32 = 42 / 0;
// error: attempted to divide by zero in a constant expression
// error: attempt to divide by zero in a constant expression
```
"##,

View File

@ -19,7 +19,7 @@ use session::Session;
use lint;
use middle::cstore::LOCAL_CRATE;
use hir::def::Def;
use hir::def_id::{CRATE_DEF_INDEX, DefId};
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
use ty::{self, TyCtxt};
use middle::privacy::AccessLevels;
use syntax::parse::token::InternedString;
@ -61,12 +61,46 @@ enum AnnotationKind {
Container,
}
/// An entry in the `depr_map`.
#[derive(Clone)]
pub struct DeprecationEntry {
/// The metadata of the attribute associated with this entry.
pub attr: Deprecation,
/// The def id where the attr was originally attached. `None` for non-local
/// `DefId`'s.
origin: Option<DefIndex>,
}
impl DeprecationEntry {
fn local(attr: Deprecation, id: DefId) -> DeprecationEntry {
assert!(id.is_local());
DeprecationEntry {
attr: attr,
origin: Some(id.index),
}
}
fn external(attr: Deprecation) -> DeprecationEntry {
DeprecationEntry {
attr: attr,
origin: None,
}
}
pub fn same_origin(&self, other: &DeprecationEntry) -> bool {
match (self.origin, other.origin) {
(Some(o1), Some(o2)) => o1 == o2,
_ => false
}
}
}
/// A stability index, giving the stability level for items and methods.
pub struct Index<'tcx> {
/// This is mostly a cache, except the stabilities of local items
/// are filled by the annotator.
stab_map: DefIdMap<Option<&'tcx Stability>>,
depr_map: DefIdMap<Option<Deprecation>>,
depr_map: DefIdMap<Option<DeprecationEntry>>,
/// Maps for each crate whether it is part of the staged API.
staged_api: FnvHashMap<ast::CrateNum, bool>
@ -77,7 +111,7 @@ struct Annotator<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
index: &'a mut Index<'tcx>,
parent_stab: Option<&'tcx Stability>,
parent_depr: Option<Deprecation>,
parent_depr: Option<DeprecationEntry>,
access_levels: &'a AccessLevels,
in_trait_impl: bool,
}
@ -184,14 +218,15 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> {
// `Deprecation` is just two pointers, no need to intern it
let def_id = self.tcx.map.local_def_id(id);
self.index.depr_map.insert(def_id, Some(depr.clone()));
let depr_entry = Some(DeprecationEntry::local(depr, def_id));
self.index.depr_map.insert(def_id, depr_entry.clone());
let orig_parent_depr = replace(&mut self.parent_depr, Some(depr));
let orig_parent_depr = replace(&mut self.parent_depr, depr_entry);
visit_children(self);
self.parent_depr = orig_parent_depr;
} else if let Some(depr) = self.parent_depr.clone() {
} else if let parent_depr @ Some(_) = self.parent_depr.clone() {
let def_id = self.tcx.map.local_def_id(id);
self.index.depr_map.insert(def_id, Some(depr));
self.index.depr_map.insert(def_id, parent_depr);
visit_children(self);
} else {
visit_children(self);
@ -351,7 +386,7 @@ struct Checker<'a, 'tcx: 'a> {
impl<'a, 'tcx> Checker<'a, 'tcx> {
fn check(&mut self, id: DefId, span: Span,
stab: &Option<&Stability>, _depr: &Option<Deprecation>) {
stab: &Option<&Stability>, _depr: &Option<DeprecationEntry>) {
if !is_staged_api(self.tcx, id) {
return;
}
@ -476,7 +511,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
warn_about_defns: bool,
cb: &mut FnMut(DefId, Span,
&Option<&Stability>,
&Option<Deprecation>)) {
&Option<DeprecationEntry>)) {
match item.node {
hir::ItemExternCrate(_) => {
// compiler-generated `extern crate` items have a dummy span.
@ -515,7 +550,7 @@ pub fn check_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub fn check_expr<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, e: &hir::Expr,
cb: &mut FnMut(DefId, Span,
&Option<&Stability>,
&Option<Deprecation>)) {
&Option<DeprecationEntry>)) {
let span;
let id = match e.node {
hir::ExprMethodCall(i, _, _) => {
@ -579,7 +614,7 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
path: &hir::Path, id: ast::NodeId,
cb: &mut FnMut(DefId, Span,
&Option<&Stability>,
&Option<Deprecation>)) {
&Option<DeprecationEntry>)) {
// Paths in import prefixes may have no resolution.
match tcx.expect_def_or_none(id) {
Some(Def::PrimTy(..)) => {}
@ -595,7 +630,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
item: &hir::PathListItem,
cb: &mut FnMut(DefId, Span,
&Option<&Stability>,
&Option<Deprecation>)) {
&Option<DeprecationEntry>)) {
match tcx.expect_def(item.node.id()) {
Def::PrimTy(..) => {}
def => {
@ -607,7 +642,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat,
cb: &mut FnMut(DefId, Span,
&Option<&Stability>,
&Option<Deprecation>)) {
&Option<DeprecationEntry>)) {
debug!("check_pat(pat = {:?})", pat);
if is_internal(tcx, pat.span) { return; }
@ -638,7 +673,7 @@ fn maybe_do_stability_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
id: DefId, span: Span,
cb: &mut FnMut(DefId, Span,
&Option<&Stability>,
&Option<Deprecation>)) {
&Option<DeprecationEntry>)) {
if is_internal(tcx, span) {
debug!("maybe_do_stability_check: \
skipping span={:?} since it is internal", span);
@ -647,7 +682,7 @@ fn maybe_do_stability_check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let (stability, deprecation) = if is_staged_api(tcx, id) {
(tcx.lookup_stability(id), None)
} else {
(None, tcx.lookup_deprecation(id))
(None, tcx.lookup_deprecation_entry(id))
};
debug!("maybe_do_stability_check: \
inspecting id={:?} span={:?} of stability={:?}", id, span, stability);
@ -685,6 +720,10 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
}
pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
self.lookup_deprecation_entry(id).map(|depr| depr.attr)
}
pub fn lookup_deprecation_entry(self, id: DefId) -> Option<DeprecationEntry> {
if let Some(depr) = self.stability.borrow().depr_map.get(&id) {
return depr.clone();
}
@ -703,12 +742,12 @@ impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
}
}
fn lookup_deprecation_uncached(self, id: DefId) -> Option<Deprecation> {
fn lookup_deprecation_uncached(self, id: DefId) -> Option<DeprecationEntry> {
debug!("lookup(id={:?})", id);
if id.is_local() {
None // The stability cache is filled partially lazily
} else {
self.sess.cstore.deprecation(id)
self.sess.cstore.deprecation(id).map(DeprecationEntry::external)
}
}
}

View File

@ -57,18 +57,18 @@ impl ConstMathErr {
UnequalTypes(BitOr) => "tried to bitor two values of different types",
UnequalTypes(BitXor) => "tried to xor two values of different types",
UnequalTypes(_) => unreachable!(),
Overflow(Add) => "attempted to add with overflow",
Overflow(Sub) => "attempted to subtract with overflow",
Overflow(Mul) => "attempted to multiply with overflow",
Overflow(Div) => "attempted to divide with overflow",
Overflow(Rem) => "attempted to calculate the remainder with overflow",
Overflow(Neg) => "attempted to negate with overflow",
Overflow(Shr) => "attempted to shift right with overflow",
Overflow(Shl) => "attempted to shift left with overflow",
Overflow(Add) => "attempt to add with overflow",
Overflow(Sub) => "attempt to subtract with overflow",
Overflow(Mul) => "attempt to multiply with overflow",
Overflow(Div) => "attempt to divide with overflow",
Overflow(Rem) => "attempt to calculate the remainder with overflow",
Overflow(Neg) => "attempt to negate with overflow",
Overflow(Shr) => "attempt to shift right with overflow",
Overflow(Shl) => "attempt to shift left with overflow",
Overflow(_) => unreachable!(),
ShiftNegative => "attempted to shift by a negative amount",
DivisionByZero => "attempted to divide by zero",
RemainderByZero => "attempted to calculate the remainder with a divisor of zero",
ShiftNegative => "attempt to shift by a negative amount",
DivisionByZero => "attempt to divide by zero",
RemainderByZero => "attempt to calculate the remainder with a divisor of zero",
UnsignedNegation => "unary negation of unsigned integer",
ULitOutOfRange(ast::UintTy::U8) => "literal out of range for u8",
ULitOutOfRange(ast::UintTy::U16) => "literal out of range for u16",

View File

@ -995,6 +995,8 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
passes.push_pass(box mir::transform::no_landing_pads::NoLandingPads);
passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("elaborate-drops"));
passes.push_pass(box mir::transform::deaggregator::Deaggregator);
passes.push_pass(box mir::transform::add_call_guards::AddCallGuards);
passes.push_pass(box mir::transform::dump_mir::Marker("PreTrans"));

View File

@ -567,18 +567,36 @@ declare_lint! {
}
/// Checks for use of items with `#[deprecated]` or `#[rustc_deprecated]` attributes
#[derive(Copy, Clone)]
pub struct Deprecated;
#[derive(Clone)]
pub struct Deprecated {
/// Tracks the `NodeId` of the current item.
///
/// This is required since not all node ids are present in the hir map.
current_item: ast::NodeId,
}
impl Deprecated {
pub fn new() -> Deprecated {
Deprecated {
current_item: ast::CRATE_NODE_ID,
}
}
fn lint(&self, cx: &LateContext, _id: DefId, span: Span,
stability: &Option<&attr::Stability>, deprecation: &Option<attr::Deprecation>) {
stability: &Option<&attr::Stability>,
deprecation: &Option<stability::DeprecationEntry>) {
// Deprecated attributes apply in-crate and cross-crate.
if let Some(&attr::Stability{rustc_depr: Some(attr::RustcDeprecation{ref reason, ..}), ..})
= *stability {
output(cx, DEPRECATED, span, Some(&reason))
} else if let Some(attr::Deprecation{ref note, ..}) = *deprecation {
output(cx, DEPRECATED, span, note.as_ref().map(|x| &**x))
} else if let Some(ref depr_entry) = *deprecation {
if let Some(parent_depr) = cx.tcx.lookup_deprecation_entry(self.parent_def(cx)) {
if parent_depr.same_origin(depr_entry) {
return;
}
}
output(cx, DEPRECATED, span, depr_entry.attr.note.as_ref().map(|x| &**x))
}
fn output(cx: &LateContext, lint: &'static Lint, span: Span, note: Option<&str>) {
@ -591,6 +609,19 @@ impl Deprecated {
cx.span_lint(lint, span, &msg);
}
}
fn push_item(&mut self, item_id: ast::NodeId) {
self.current_item = item_id;
}
fn item_post(&mut self, cx: &LateContext, item_id: ast::NodeId) {
assert_eq!(self.current_item, item_id);
self.current_item = cx.tcx.map.get_parent(item_id);
}
fn parent_def(&self, cx: &LateContext) -> DefId {
cx.tcx.map.local_def_id(self.current_item)
}
}
impl LintPass for Deprecated {
@ -601,11 +632,16 @@ impl LintPass for Deprecated {
impl LateLintPass for Deprecated {
fn check_item(&mut self, cx: &LateContext, item: &hir::Item) {
self.push_item(item.id);
stability::check_item(cx.tcx, item, false,
&mut |id, sp, stab, depr|
self.lint(cx, id, sp, &stab, &depr));
}
fn check_item_post(&mut self, cx: &LateContext, item: &hir::Item) {
self.item_post(cx, item.id);
}
fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) {
stability::check_expr(cx.tcx, e,
&mut |id, sp, stab, depr|
@ -629,6 +665,30 @@ impl LateLintPass for Deprecated {
&mut |id, sp, stab, depr|
self.lint(cx, id, sp, &stab, &depr));
}
fn check_impl_item(&mut self, _: &LateContext, item: &hir::ImplItem) {
self.push_item(item.id);
}
fn check_impl_item_post(&mut self, cx: &LateContext, item: &hir::ImplItem) {
self.item_post(cx, item.id);
}
fn check_trait_item(&mut self, _: &LateContext, item: &hir::TraitItem) {
self.push_item(item.id);
}
fn check_trait_item_post(&mut self, cx: &LateContext, item: &hir::TraitItem) {
self.item_post(cx, item.id);
}
fn check_foreign_item(&mut self, _: &LateContext, item: &hir::ForeignItem) {
self.push_item(item.id);
}
fn check_foreign_item_post(&mut self, cx: &LateContext, item: &hir::ForeignItem) {
self.item_post(cx, item.id);
}
}
declare_lint! {

View File

@ -124,7 +124,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
UnusedAllocation,
MissingCopyImplementations,
UnstableFeatures,
Deprecated,
UnconditionalRecursion,
InvalidNoMangleItems,
PluginAsLibrary,
@ -133,6 +132,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
);
add_builtin_with_new!(sess,
Deprecated,
TypeLimits,
MissingDoc,
MissingDebugImplementations,

View File

@ -0,0 +1,116 @@
// Copyright 2016 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.
use rustc::ty::TyCtxt;
use rustc::mir::repr::*;
use rustc::mir::transform::{MirPass, MirSource, Pass};
use rustc_data_structures::indexed_vec::Idx;
use rustc::ty::VariantKind;
pub struct Deaggregator;
impl Pass for Deaggregator {}
impl<'tcx> MirPass<'tcx> for Deaggregator {
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource, mir: &mut Mir<'tcx>) {
let node_id = source.item_id();
let node_path = tcx.item_path_str(tcx.map.local_def_id(node_id));
debug!("running on: {:?}", node_path);
// we only run when mir_opt_level > 1
match tcx.sess.opts.debugging_opts.mir_opt_level {
Some(0) |
Some(1) |
None => { return; },
_ => {}
};
// Do not trigger on constants. Could be revised in future
if let MirSource::Fn(_) = source {} else { return; }
// In fact, we might not want to trigger in other cases.
// Ex: when we could use SROA. See issue #35259
let mut curr: usize = 0;
for bb in mir.basic_blocks_mut() {
let idx = match get_aggregate_statement(curr, &bb.statements) {
Some(idx) => idx,
None => continue,
};
// do the replacement
debug!("removing statement {:?}", idx);
let src_info = bb.statements[idx].source_info;
let suffix_stmts = bb.statements.split_off(idx+1);
let orig_stmt = bb.statements.pop().unwrap();
let StatementKind::Assign(ref lhs, ref rhs) = orig_stmt.kind;
let (agg_kind, operands) = match rhs {
&Rvalue::Aggregate(ref agg_kind, ref operands) => (agg_kind, operands),
_ => span_bug!(src_info.span, "expected aggregate, not {:?}", rhs),
};
let (adt_def, variant, substs) = match agg_kind {
&AggregateKind::Adt(adt_def, variant, substs) => (adt_def, variant, substs),
_ => span_bug!(src_info.span, "expected struct, not {:?}", rhs),
};
let n = bb.statements.len();
bb.statements.reserve(n + operands.len() + suffix_stmts.len());
for (i, op) in operands.iter().enumerate() {
let ref variant_def = adt_def.variants[variant];
let ty = variant_def.fields[i].ty(tcx, substs);
let rhs = Rvalue::Use(op.clone());
// since we don't handle enums, we don't need a cast
let lhs_cast = lhs.clone();
// FIXME we cannot deaggregate enums issue: #35186
let lhs_proj = Lvalue::Projection(Box::new(LvalueProjection {
base: lhs_cast,
elem: ProjectionElem::Field(Field::new(i), ty),
}));
let new_statement = Statement {
source_info: src_info,
kind: StatementKind::Assign(lhs_proj, rhs),
};
debug!("inserting: {:?} @ {:?}", new_statement, idx + i);
bb.statements.push(new_statement);
}
curr = bb.statements.len();
bb.statements.extend(suffix_stmts);
}
}
}
fn get_aggregate_statement<'a, 'tcx, 'b>(curr: usize,
statements: &Vec<Statement<'tcx>>)
-> Option<usize> {
for i in curr..statements.len() {
let ref statement = statements[i];
let StatementKind::Assign(_, ref rhs) = statement.kind;
let (kind, operands) = match rhs {
&Rvalue::Aggregate(ref kind, ref operands) => (kind, operands),
_ => continue,
};
let (adt_def, variant) = match kind {
&AggregateKind::Adt(adt_def, variant, _) => (adt_def, variant),
_ => continue,
};
if operands.len() == 0 || adt_def.variants.len() > 1 {
// don't deaggregate ()
// don't deaggregate enums ... for now
continue;
}
debug!("getting variant {:?}", variant);
debug!("for adt_def {:?}", adt_def);
let variant_def = &adt_def.variants[variant];
if variant_def.kind == VariantKind::Struct {
return Some(i);
}
};
None
}

View File

@ -17,3 +17,4 @@ pub mod add_call_guards;
pub mod promote_consts;
pub mod qualify_consts;
pub mod dump_mir;
pub mod deaggregator;

View File

@ -55,6 +55,17 @@ impl<'a> AstValidator<'a> {
err.emit();
}
}
fn check_decl_no_pat<ReportFn: Fn(Span, bool)>(&self, decl: &FnDecl, report_err: ReportFn) {
for arg in &decl.inputs {
match arg.pat.node {
PatKind::Ident(BindingMode::ByValue(Mutability::Immutable), _, None) |
PatKind::Wild => {}
PatKind::Ident(..) => report_err(arg.pat.span, true),
_ => report_err(arg.pat.span, false),
}
}
}
}
impl<'a> Visitor for AstValidator<'a> {
@ -82,6 +93,23 @@ impl<'a> Visitor for AstValidator<'a> {
visit::walk_expr(self, expr)
}
fn visit_ty(&mut self, ty: &Ty) {
match ty.node {
TyKind::BareFn(ref bfty) => {
self.check_decl_no_pat(&bfty.decl, |span, _| {
let mut err = struct_span_err!(self.session, span, E0561,
"patterns aren't allowed in function pointer types");
err.span_note(span, "this is a recent error, see \
issue #35203 for more details");
err.emit();
});
}
_ => {}
}
visit::walk_ty(self, ty)
}
fn visit_path(&mut self, path: &Path, id: NodeId) {
if path.global && path.segments.len() > 0 {
let ident = path.segments[0].identifier;
@ -135,6 +163,25 @@ impl<'a> Visitor for AstValidator<'a> {
visit::walk_item(self, item)
}
fn visit_foreign_item(&mut self, fi: &ForeignItem) {
match fi.node {
ForeignItemKind::Fn(ref decl, _) => {
self.check_decl_no_pat(decl, |span, is_recent| {
let mut err = struct_span_err!(self.session, span, E0130,
"patterns aren't allowed in foreign function declarations");
if is_recent {
err.span_note(span, "this is a recent error, see \
issue #35203 for more details");
}
err.emit();
});
}
ForeignItemKind::Static(..) => {}
}
visit::walk_foreign_item(self, fi)
}
fn visit_variant_data(&mut self, vdata: &VariantData, _: Ident,
_: &Generics, _: NodeId, span: Span) {
if vdata.fields().is_empty() {

View File

@ -49,6 +49,39 @@ match 5u32 {
```
"##,
E0130: r##"
You declared a pattern as an argument in a foreign function declaration.
Erroneous code example:
```compile_fail
extern {
fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign
// function declarations
}
```
Please replace the pattern argument with a regular one. Example:
```
struct SomeStruct {
a: u32,
b: u32,
}
extern {
fn foo(s: SomeStruct); // ok!
}
```
Or:
```
extern {
fn foo(a: (u32, u32)); // ok!
}
```
"##,
E0161: r##"
A value was moved. However, its size was not known at compile time, and only
values of a known size can be moved.
@ -187,4 +220,5 @@ pub impl Foo for Bar {
register_diagnostics! {
E0472, // asm! is unsupported on this target
E0561, // patterns aren't allowed in function pointer types
}

View File

@ -1512,7 +1512,7 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
C_integral(llty, min, true), debug_loc);
with_cond(bcx, is_min, |bcx| {
let msg = InternedString::new(
"attempted to negate with overflow");
"attempt to negate with overflow");
controlflow::trans_fail(bcx, expr_info(expr), msg)
})
} else {

View File

@ -261,7 +261,23 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => {
let cond = self.trans_operand(&bcx, cond).immediate();
let const_cond = common::const_to_opt_uint(cond).map(|c| c == 1);
let mut const_cond = common::const_to_opt_uint(cond).map(|c| c == 1);
// This case can currently arise only from functions marked
// with #[rustc_inherit_overflow_checks] and inlined from
// another crate (mostly core::num generic/#[inline] fns),
// while the current crate doesn't use overflow checks.
// NOTE: Unlike binops, negation doesn't have its own
// checked operation, just a comparison with the minimum
// value, so we have to check for the assert message.
if !bcx.ccx().check_overflow() {
use rustc_const_math::ConstMathErr::Overflow;
use rustc_const_math::Op::Neg;
if let mir::AssertMessage::Math(Overflow(Neg)) = *msg {
const_cond = Some(expected);
}
}
// Don't translate the panic block if success if known.
if const_cond == Some(expected) {

View File

@ -60,8 +60,6 @@ There are some shortcomings in this design:
use astconv::{AstConv, ast_region_to_region, Bounds, PartitionedBounds, partition_bounds};
use lint;
use hir::def::Def;
use hir::def_id::DefId;
use constrained_type_params as ctp;
use middle::lang_items::SizedTraitLangItem;
use middle::const_val::ConstVal;
@ -74,7 +72,6 @@ use rustc::ty::{VariantKind};
use rustc::ty::util::IntTypeExt;
use rscope::*;
use rustc::dep_graph::DepNode;
use rustc::hir::map as hir_map;
use util::common::{ErrorReported, MemoizationMap};
use util::nodemap::{NodeMap, FnvHashMap};
use {CrateCtxt, write_ty_to_tcx};
@ -91,9 +88,9 @@ use syntax::parse::token::keywords;
use syntax::ptr::P;
use syntax_pos::Span;
use rustc::hir::{self, PatKind};
use rustc::hir::intravisit;
use rustc::hir::print as pprust;
use rustc::hir::{self, intravisit, map as hir_map, print as pprust};
use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
///////////////////////////////////////////////////////////////////////////
// Main entry point
@ -2145,14 +2142,6 @@ fn compute_type_scheme_of_foreign_fn_decl<'a, 'tcx>(
abi: abi::Abi)
-> ty::TypeScheme<'tcx>
{
for i in &decl.inputs {
match i.pat.node {
PatKind::Binding(..) | PatKind::Wild => {}
_ => span_err!(ccx.tcx.sess, i.pat.span, E0130,
"patterns aren't allowed in foreign function declarations")
}
}
let ty_generics = ty_generics_for_fn(ccx, ast_generics, &ty::Generics::empty());
let rb = BindingRscope::new();

View File

@ -1800,39 +1800,6 @@ Please also verify that this wasn't because of a name-clash and rename the type
parameter if so.
"##,
E0130: r##"
You declared a pattern as an argument in a foreign function declaration.
Erroneous code example:
```compile_fail
extern {
fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign
// function declarations
}
```
Please replace the pattern argument with a regular one. Example:
```
struct SomeStruct {
a: u32,
b: u32,
}
extern {
fn foo(s: SomeStruct); // ok!
}
```
Or:
```
extern {
fn foo(a: (u32, u32)); // ok!
}
```
"##,
E0131: r##"
It is not possible to define `main` with type parameters, or even with function
parameters. When `main` is present, it must take no arguments and return `()`.

View File

@ -0,0 +1,32 @@
// Copyright 2016 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.
struct Foo(u8);
impl Foo {
fn bar(&self) -> bool { self.0 > 5 }
fn bar() {} //~ ERROR E0201
}
trait Baz {
type Quux;
fn baz(&self) -> bool;
}
impl Baz for Foo {
type Quux = u32;
fn baz(&self) -> bool { true }
fn baz(&self) -> bool { self.0 > 5 } //~ ERROR E0201
type Quux = u32; //~ ERROR E0201
}
fn main() {
}

View File

@ -0,0 +1,23 @@
// Copyright 2016 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.
struct Foo {
foo: Vec<u32>,
}
impl Copy for Foo { } //~ ERROR E0204
#[derive(Copy)] //~ ERROR E0204
struct Foo2<'a> {
ty: &'a mut bool,
}
fn main() {
}

View File

@ -0,0 +1,25 @@
// Copyright 2016 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.
enum Foo {
Bar(Vec<u32>),
Baz,
}
impl Copy for Foo { } //~ ERROR E0205
#[derive(Copy)] //~ ERROR E0205
enum Foo2<'a> {
Bar(&'a mut bool),
Baz,
}
fn main() {
}

View File

@ -0,0 +1,22 @@
// Copyright 2016 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.
type Foo = i32;
impl Copy for Foo { } //~ ERROR E0206
//~^ ERROR E0117
#[derive(Copy, Clone)]
struct Bar;
impl Copy for &'static Bar { } //~ ERROR E0206
fn main() {
}

View File

@ -0,0 +1,20 @@
// Copyright 2016 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.
struct Foo;
impl<T: Default> Foo { //~ ERROR E0207
fn get(&self) -> T {
<T as Default>::default()
}
}
fn main() {
}

View File

@ -0,0 +1,13 @@
// Copyright 2016 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.
fn main() {
let v: Vec(&str) = vec!["foo"]; //~ ERROR E0214
}

View File

@ -0,0 +1,19 @@
// Copyright 2016 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.
trait Trait {
type Bar;
}
type Foo = Trait<F=i32>; //~ ERROR E0220
//~^ ERROR E0191
fn main() {
}

View File

@ -0,0 +1,26 @@
// Copyright 2016 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.
trait T1 {}
trait T2 {}
trait Foo {
type A: T1;
}
trait Bar : Foo {
type A: T2;
fn do_something() {
let _: Self::A; //~ ERROR E0221
}
}
fn main() {
}

View File

@ -0,0 +1,15 @@
// Copyright 2016 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.
trait MyTrait { type X; }
fn main() {
let foo: MyTrait::X; //~ ERROR E0223
}

View File

@ -0,0 +1,13 @@
// Copyright 2016 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.
fn main() {
let _: Box<std::io::Read + std::io::Write>; //~ ERROR E0225
}

View File

@ -0,0 +1,26 @@
// Copyright 2016 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.
pub trait Foo {
type A;
fn boo(&self) -> <Self as Foo>::A;
}
struct Bar;
impl Foo for isize {
type A = usize;
fn boo(&self) -> usize { 42 }
}
fn baz<I>(x: &<I as Foo<A=Bar>>::A) {} //~ ERROR E0229
fn main() {
}

View File

@ -0,0 +1,17 @@
// Copyright 2016 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(on_unimplemented)]
#[rustc_on_unimplemented] //~ ERROR E0232
trait Bar {}
fn main() {
}

View File

@ -0,0 +1,15 @@
// Copyright 2016 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.
struct Foo<T> { x: T }
struct Bar { x: Foo } //~ ERROR E0243
fn main() {
}

View File

@ -0,0 +1,15 @@
// Copyright 2016 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.
struct Foo { x: bool }
struct Bar<S, T> { x: Foo<S, T> } //~ ERROR E0244
fn main() {
}

View File

@ -0,0 +1,18 @@
// Copyright 2016 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.
enum Foo {
Bar(u32),
}
fn do_something(x: Foo::Bar) { } //~ ERROR E0248
fn main() {
}

View File

@ -0,0 +1,23 @@
// Copyright 2016 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.
use foo::baz;
use bar::baz; //~ ERROR E0252
mod foo {
pub struct baz;
}
mod bar {
pub mod baz {}
}
fn main() {
}

View File

@ -0,0 +1,16 @@
// Copyright 2016 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.
const A: [u32; "hello"] = []; //~ ERROR E0306
const B: [u32; true] = []; //~ ERROR E0306
const C: [u32; 0.0] = []; //~ ERROR E0306
fn main() {
}

View File

@ -0,0 +1,20 @@
// Copyright 2016 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.
use std::rc::Rc;
struct Foo;
impl Foo {
fn x(self: Rc<Foo>) {} //~ ERROR E0308
}
fn main() {
}

View File

@ -0,0 +1,11 @@
// Copyright 2016 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.
fn main() -> i32 { 0 } //~ ERROR E0308

View File

@ -0,0 +1,17 @@
// Copyright 2016 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.
fn main() {
let x = 1u8;
match x {
0u8...3i8 => (), //~ ERROR E0308
_ => ()
}
}

View File

@ -0,0 +1,18 @@
// Copyright 2016 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(intrinsics)]
extern "rust-intrinsic" {
fn size_of<T>(); //~ ERROR E0308
}
fn main() {
}

View File

@ -11,10 +11,10 @@
#![feature(const_indexing)]
#![deny(const_err)]
pub const A: i8 = -std::i8::MIN; //~ ERROR attempted to negate with overflow
pub const B: u8 = 200u8 + 200u8; //~ ERROR attempted to add with overflow
pub const C: u8 = 200u8 * 4; //~ ERROR attempted to multiply with overflow
pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR attempted to subtract with overflow
pub const A: i8 = -std::i8::MIN; //~ ERROR attempt to negate with overflow
pub const B: u8 = 200u8 + 200u8; //~ ERROR attempt to add with overflow
pub const C: u8 = 200u8 * 4; //~ ERROR attempt to multiply with overflow
pub const D: u8 = 42u8 - (42u8 + 1); //~ ERROR attempt to subtract with overflow
pub const E: u8 = [5u8][1];
//~^ ERROR index out of bounds: the len is 1 but the index is 1

View File

@ -10,7 +10,7 @@
#![deny(const_err)]
pub const A: i8 = -std::i8::MIN; //~ ERROR attempted to negate with overflow
pub const A: i8 = -std::i8::MIN; //~ ERROR attempt to negate with overflow
pub const B: i8 = A;
pub const C: u8 = A as u8;
pub const D: i8 = 50 - A;

View File

@ -30,18 +30,18 @@ const FOO: u8 = [5u8][1];
fn main() {
let a = -std::i8::MIN;
//~^ WARN this expression will panic at run-time
//~| attempted to negate with overflow
//~| attempt to negate with overflow
let b = 200u8 + 200u8 + 200u8;
//~^ WARN this expression will panic at run-time
//~| attempted to add with overflow
//~| attempt to add with overflow
//~^^^ WARN this expression will panic at run-time
//~| attempted to add with overflow
//~| attempt to add with overflow
let c = 200u8 * 4;
//~^ WARN this expression will panic at run-time
//~| attempted to multiply with overflow
//~| attempt to multiply with overflow
let d = 42u8 - (42u8 + 1);
//~^ WARN this expression will panic at run-time
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
let _e = [5u8][1];
//~^ WARN this expression will panic at run-time
//~| index out of bounds: the len is 1 but the index is 1

View File

@ -18,14 +18,14 @@ fn black_box<T>(_: T) {
fn main() {
let a = -std::i8::MIN;
//~^ ERROR attempted to negate with overflow
//~^ ERROR attempt to negate with overflow
let b = 200u8 + 200u8 + 200u8;
//~^ ERROR attempted to add with overflow
//~| ERROR attempted to add with overflow
//~^ ERROR attempt to add with overflow
//~| ERROR attempt to add with overflow
let c = 200u8 * 4;
//~^ ERROR attempted to multiply with overflow
//~^ ERROR attempt to multiply with overflow
let d = 42u8 - (42u8 + 1);
//~^ ERROR attempted to subtract with overflow
//~^ ERROR attempt to subtract with overflow
let _e = [5u8][1];
black_box(a);
black_box(b);

View File

@ -20,11 +20,11 @@ use std::{u8, u16, u32, u64, usize};
const NEG_128: i8 = -128;
const NEG_NEG_128: i8 = -NEG_128;
//~^ ERROR constant evaluation error
//~| attempted to negate with overflow
//~| attempt to negate with overflow
//~| ERROR constant evaluation error
//~| attempted to negate with overflow
//~| attempt to negate with overflow
//~| ERROR constant evaluation error
//~| attempted to negate with overflow
//~| attempt to negate with overflow
fn main() {
match -128i8 {

View File

@ -17,7 +17,7 @@
// self-hosted and a cross-compiled setup; therefore resorting to
// error-pattern for now.
// error-pattern: attempted to add with overflow
// error-pattern: attempt to add with overflow
#![allow(unused_imports)]

View File

@ -23,7 +23,7 @@ use std::{u8, u16, u32, u64, usize};
const A_I8_T
: [u32; (i8::MAX as i8 + 1i8) as usize]
//~^ ERROR error evaluating count: attempted to add with overflow
//~^ ERROR error evaluating count: attempt to add with overflow
= [0; (i8::MAX as usize) + 1];
fn main() {

View File

@ -22,113 +22,113 @@ use std::{u8, u16, u32, u64, usize};
const VALS_I8: (i8, i8, i8, i8) =
(-i8::MIN,
//~^ ERROR constant evaluation error
//~| attempted to negate with overflow
//~| attempt to negate with overflow
i8::MIN - 1,
//~^ ERROR constant evaluation error
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
i8::MAX + 1,
//~^ ERROR constant evaluation error
//~| attempted to add with overflow
//~| attempt to add with overflow
i8::MIN * 2,
//~^ ERROR constant evaluation error
//~| attempted to multiply with overflow
//~| attempt to multiply with overflow
);
const VALS_I16: (i16, i16, i16, i16) =
(-i16::MIN,
//~^ ERROR constant evaluation error
//~| attempted to negate with overflow
//~| attempt to negate with overflow
i16::MIN - 1,
//~^ ERROR constant evaluation error
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
i16::MAX + 1,
//~^ ERROR constant evaluation error
//~| attempted to add with overflow
//~| attempt to add with overflow
i16::MIN * 2,
//~^ ERROR constant evaluation error
//~| attempted to multiply with overflow
//~| attempt to multiply with overflow
);
const VALS_I32: (i32, i32, i32, i32) =
(-i32::MIN,
//~^ ERROR constant evaluation error
//~| attempted to negate with overflow
//~| attempt to negate with overflow
i32::MIN - 1,
//~^ ERROR constant evaluation error
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
i32::MAX + 1,
//~^ ERROR constant evaluation error
//~| attempted to add with overflow
//~| attempt to add with overflow
i32::MIN * 2,
//~^ ERROR constant evaluation error
//~| attempted to multiply with overflow
//~| attempt to multiply with overflow
);
const VALS_I64: (i64, i64, i64, i64) =
(-i64::MIN,
//~^ ERROR constant evaluation error
//~| attempted to negate with overflow
//~| attempt to negate with overflow
i64::MIN - 1,
//~^ ERROR constant evaluation error
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
i64::MAX + 1,
//~^ ERROR constant evaluation error
//~| attempted to add with overflow
//~| attempt to add with overflow
i64::MAX * 2,
//~^ ERROR constant evaluation error
//~| attempted to multiply with overflow
//~| attempt to multiply with overflow
);
const VALS_U8: (u8, u8, u8, u8) =
(-(u8::MIN as i8) as u8,
u8::MIN - 1,
//~^ ERROR constant evaluation error
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
u8::MAX + 1,
//~^ ERROR constant evaluation error
//~| attempted to add with overflow
//~| attempt to add with overflow
u8::MAX * 2,
//~^ ERROR constant evaluation error
//~| attempted to multiply with overflow
//~| attempt to multiply with overflow
);
const VALS_U16: (u16, u16, u16, u16) =
(-(u16::MIN as i16) as u16,
u16::MIN - 1,
//~^ ERROR constant evaluation error
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
u16::MAX + 1,
//~^ ERROR constant evaluation error
//~| attempted to add with overflow
//~| attempt to add with overflow
u16::MAX * 2,
//~^ ERROR constant evaluation error
//~| attempted to multiply with overflow
//~| attempt to multiply with overflow
);
const VALS_U32: (u32, u32, u32, u32) =
(-(u32::MIN as i32) as u32,
u32::MIN - 1,
//~^ ERROR constant evaluation error
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
u32::MAX + 1,
//~^ ERROR constant evaluation error
//~| attempted to add with overflow
//~| attempt to add with overflow
u32::MAX * 2,
//~^ ERROR constant evaluation error
//~| attempted to multiply with overflow
//~| attempt to multiply with overflow
);
const VALS_U64: (u64, u64, u64, u64) =
(-(u64::MIN as i64) as u64,
u64::MIN - 1,
//~^ ERROR constant evaluation error
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
u64::MAX + 1,
//~^ ERROR constant evaluation error
//~| attempted to add with overflow
//~| attempt to add with overflow
u64::MAX * 2,
//~^ ERROR constant evaluation error
//~| attempted to multiply with overflow
//~| attempt to multiply with overflow
);
fn main() {

View File

@ -16,7 +16,7 @@ const ONE: usize = 1;
const TWO: usize = 2;
const LEN: usize = ONE - TWO;
//~^ ERROR E0080
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
fn main() {
let a: [i8; LEN] = unimplemented!();

View File

@ -17,5 +17,5 @@ const TWO: usize = 2;
fn main() {
let a: [i8; ONE - TWO] = unimplemented!();
//~^ ERROR constant evaluation error [E0080]
//~| attempted to subtract with overflow
//~| attempt to subtract with overflow
}

View File

@ -12,7 +12,7 @@
const TUP: (usize,) = 5 << 64;
//~^ ERROR E0080
//~| attempted to shift left with overflow
//~| attempt to shift left with overflow
const ARR: [i32; TUP.0] = [];
fn main() {

View File

@ -0,0 +1,81 @@
// Copyright 2016 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.
#![deny(deprecated)]
#![allow(warnings)]
#[deprecated]
fn issue_35128() {
format_args!("foo");
}
#[deprecated]
fn issue_35128_minimal() {
static FOO: &'static str = "foo";
let _ = FOO;
}
#[deprecated]
mod silent {
type DeprecatedType = u8;
struct DeprecatedStruct;
fn deprecated_fn() {}
trait DeprecatedTrait {}
static DEPRECATED_STATIC: u8 = 0;
const DEPRECATED_CONST: u8 = 1;
struct Foo(DeprecatedType);
impl DeprecatedTrait for Foo {}
impl Foo {
fn bar<T: DeprecatedTrait>() {
deprecated_fn();
}
}
fn foo() -> u8 {
DEPRECATED_STATIC +
DEPRECATED_CONST
}
}
#[deprecated]
mod loud {
#[deprecated]
type DeprecatedType = u8;
#[deprecated]
struct DeprecatedStruct;
#[deprecated]
fn deprecated_fn() {}
#[deprecated]
trait DeprecatedTrait {}
#[deprecated]
static DEPRECATED_STATIC: u8 = 0;
#[deprecated]
const DEPRECATED_CONST: u8 = 1;
struct Foo(DeprecatedType); //~ ERROR use of deprecated item
impl DeprecatedTrait for Foo {} //~ ERROR use of deprecated item
impl Foo {
fn bar<T: DeprecatedTrait>() { //~ ERROR use of deprecated item
deprecated_fn(); //~ ERROR use of deprecated item
}
}
fn foo() -> u8 {
DEPRECATED_STATIC + //~ ERROR use of deprecated item
DEPRECATED_CONST //~ ERROR use of deprecated item
}
}
fn main() {}

View File

@ -266,14 +266,14 @@ mod this_crate {
#[deprecated(since = "1.0.0", note = "text")]
fn test_fn_body() {
fn fn_in_body() {}
fn_in_body(); //~ ERROR use of deprecated item: text
fn_in_body();
}
impl MethodTester {
#[deprecated(since = "1.0.0", note = "text")]
fn test_method_body(&self) {
fn fn_in_body() {}
fn_in_body(); //~ ERROR use of deprecated item: text
fn_in_body();
}
}

View File

@ -10,10 +10,10 @@
enum test {
div_zero = 1/0, //~ ERROR E0080
//~| attempted to divide by zero
//~| attempt to divide by zero
rem_zero = 1%0,
//~^ ERROR E0080
//~| attempted to calculate the remainder with a divisor of zero
//~| attempt to calculate the remainder with a divisor of zero
}
fn main() {}

View File

@ -15,43 +15,43 @@ use std::thread;
fn main() {
assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
//~^ ERROR attempted to divide with overflow
//~^ ERROR attempt to divide with overflow
assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
//~^ ERROR attempted to divide with overflow
//~^ ERROR attempt to divide with overflow
assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
//~^ ERROR attempted to divide with overflow
//~^ ERROR attempt to divide with overflow
assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
//~^ ERROR attempted to divide with overflow
//~^ ERROR attempt to divide with overflow
assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
//~^ ERROR attempted to divide with overflow
//~^ ERROR attempt to divide with overflow
assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
//~^ ERROR attempted to divide by zero
//~^ ERROR attempt to divide by zero
assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
//~^ ERROR attempted to divide by zero
//~^ ERROR attempt to divide by zero
assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
//~^ ERROR attempted to divide by zero
//~^ ERROR attempt to divide by zero
assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
//~^ ERROR attempted to divide by zero
//~^ ERROR attempt to divide by zero
assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
//~^ ERROR attempted to divide by zero
//~^ ERROR attempt to divide by zero
assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with overflow
//~^ ERROR attempt to calculate the remainder with overflow
assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with overflow
//~^ ERROR attempt to calculate the remainder with overflow
assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with overflow
//~^ ERROR attempt to calculate the remainder with overflow
assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with overflow
//~^ ERROR attempt to calculate the remainder with overflow
assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with overflow
//~^ ERROR attempt to calculate the remainder with overflow
assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with a divisor of zero
//~^ ERROR attempt to calculate the remainder with a divisor of zero
assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with a divisor of zero
//~^ ERROR attempt to calculate the remainder with a divisor of zero
assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with a divisor of zero
//~^ ERROR attempt to calculate the remainder with a divisor of zero
assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with a divisor of zero
//~^ ERROR attempt to calculate the remainder with a divisor of zero
assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
//~^ ERROR attempted to calculate the remainder with a divisor of zero
//~^ ERROR attempt to calculate the remainder with a divisor of zero
}

View File

@ -53,7 +53,7 @@ fn main() {
let n = n << 8; //~ ERROR: bitshift exceeds the type's number of bits
let n = 1u8 << -8; //~ ERROR: bitshift exceeds the type's number of bits
//~^ WARN: attempted to shift by a negative amount
//~^ WARN: attempt to shift by a negative amount
let n = 1u8 << (4+3);
let n = 1u8 << (4+4); //~ ERROR: bitshift exceeds the type's number of bits

View File

@ -15,7 +15,7 @@
#[allow(unused_variables)]
fn main() {
let x2: i8 = --128; //~ error: literal out of range for i8
//~^ error: attempted to negate with overflow
//~^ error: attempt to negate with overflow
let x = -3.40282348e+38_f32; //~ error: literal out of range for f32
let x = 3.40282348e+38_f32; //~ error: literal out of range for f32

View File

@ -0,0 +1,30 @@
// Copyright 2016 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.
extern {
fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations
//~^ NOTE this is a recent error
fn f2(&arg: u8); //~ ERROR patterns aren't allowed in foreign function declarations
fn f3(arg @ _: u8); //~ ERROR patterns aren't allowed in foreign function declarations
//~^ NOTE this is a recent error
fn g1(arg: u8); // OK
fn g2(_: u8); // OK
// fn g3(u8); // Not yet
}
type A1 = fn(mut arg: u8); //~ ERROR patterns aren't allowed in function pointer types
//~^ NOTE this is a recent error
type A2 = fn(&arg: u8); //~ ERROR patterns aren't allowed in function pointer types
//~^ NOTE this is a recent error
type B1 = fn(arg: u8); // OK
type B2 = fn(_: u8); // OK
type B3 = fn(u8); // OK
fn main() {}

View File

@ -0,0 +1,41 @@
// Copyright 2016 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.
struct Baz {
x: usize,
y: f32,
z: bool,
}
fn bar(a: usize) -> Baz {
Baz { x: a, y: 0.0, z: false }
}
fn main() {}
// END RUST SOURCE
// START rustc.node13.Deaggregator.before.mir
// bb0: {
// var0 = arg0; // scope 0 at main.rs:8:8: 8:9
// tmp0 = var0; // scope 1 at main.rs:9:14: 9:15
// return = Baz { x: tmp0, y: const F32(0), z: const false }; // scope ...
// goto -> bb1; // scope 1 at main.rs:8:1: 10:2
// }
// END rustc.node13.Deaggregator.before.mir
// START rustc.node13.Deaggregator.after.mir
// bb0: {
// var0 = arg0; // scope 0 at main.rs:8:8: 8:9
// tmp0 = var0; // scope 1 at main.rs:9:14: 9:15
// (return.0: usize) = tmp0; // scope 1 at main.rs:9:5: 9:34
// (return.1: f32) = const F32(0); // scope 1 at main.rs:9:5: 9:34
// (return.2: bool) = const false; // scope 1 at main.rs:9:5: 9:34
// goto -> bb1; // scope 1 at main.rs:8:1: 10:2
// }
// END rustc.node13.Deaggregator.after.mir

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:attempted to divide by zero
// error-pattern:attempt to divide by zero
fn main() {
let y = 0;

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:attempted to calculate the remainder with a divisor of zero
// error-pattern:attempt to calculate the remainder with a divisor of zero
fn main() {
let y = 0;

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to add with overflow'
// error-pattern:thread 'main' panicked at 'attempt to add with overflow'
// compile-flags: -C debug-assertions

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift left with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
// compile-flags: -C debug-assertions
#![warn(exceeding_bitshifts)]

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift left with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
// compile-flags: -C debug-assertions
#![warn(exceeding_bitshifts)]

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift left with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
// compile-flags: -C debug-assertions
#![warn(exceeding_bitshifts)]

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift left with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift left with overflow'
// compile-flags: -C debug-assertions
// This function is checking that our automatic truncation does not

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to multiply with overflow'
// error-pattern:thread 'main' panicked at 'attempt to multiply with overflow'
// compile-flags: -C debug-assertions
fn main() {

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to negate with overflow'
// error-pattern:thread 'main' panicked at 'attempt to negate with overflow'
// compile-flags: -C debug-assertions
fn main() {

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:thread 'main' panicked at 'attempted to multiply with overflow'
// error-pattern:thread 'main' panicked at 'attempt to multiply with overflow'
// compile-flags: -C debug-assertions
fn main() {

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
#![warn(exceeding_bitshifts)]

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
#![warn(exceeding_bitshifts)]

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
#![warn(exceeding_bitshifts)]

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
// This function is checking that our (type-based) automatic

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
#![warn(exceeding_bitshifts)]

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to shift right with overflow'
// error-pattern:thread 'main' panicked at 'attempt to shift right with overflow'
// compile-flags: -C debug-assertions
#![warn(exceeding_bitshifts)]

View File

@ -10,7 +10,7 @@
// ignore-pretty : (#23623) problems when ending with // comments
// error-pattern:thread 'main' panicked at 'attempted to subtract with overflow'
// error-pattern:thread 'main' panicked at 'attempt to subtract with overflow'
// compile-flags: -C debug-assertions
fn main() {

View File

@ -0,0 +1,26 @@
// Copyright 2016 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.
// compile-flags: -Z force-overflow-checks=off -Z orbit
// Test that with MIR trans, overflow checks can be
// turned off, even when they're from core::ops::*.
use std::ops::*;
fn main() {
assert_eq!(i8::neg(-0x80), -0x80);
assert_eq!(u8::add(0xff, 1), 0_u8);
assert_eq!(u8::sub(0, 1), 0xff_u8);
assert_eq!(u8::mul(0xff, 2), 0xfe_u8);
assert_eq!(u8::shl(1, 9), 2_u8);
assert_eq!(u8::shr(2, 9), 1_u8);
}

View File

@ -1340,6 +1340,8 @@ actual:\n\
MirOpt => {
args.extend(["-Z",
"dump-mir=all",
"-Z",
"mir-opt-level=3",
"-Z"]
.iter()
.map(|s| s.to_string()));