Auto merge of #30410 - Manishearth:rollup, r=Manishearth

- Successful merges: #30320, #30368, #30372, #30376, #30388, #30392
- Failed merges: #30354, #30389
This commit is contained in:
bors 2015-12-16 12:16:43 +00:00
commit 785a8a6681
64 changed files with 457 additions and 272 deletions

View File

@ -26,12 +26,17 @@ use Bound;
/// A set based on a B-Tree.
///
/// See BTreeMap's documentation for a detailed discussion of this collection's performance
/// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance
/// benefits and drawbacks.
///
/// It is a logic error for an item to be modified in such a way that the item's ordering relative
/// to any other item, as determined by the `Ord` trait, changes while it is in the set. This is
/// normally only possible through `Cell`, `RefCell`, global state, I/O, or unsafe code.
/// to any other item, as determined by the [`Ord`] trait, changes while it is in the set. This is
/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
///
/// [`BTreeMap`]: ../struct.BTreeMap.html
/// [`Ord`]: ../../core/cmp/trait.Ord.html
/// [`Cell`]: ../../std/cell/struct.Cell.html
/// [`RefCell`]: ../../std/cell/struct.RefCell.html
#[derive(Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct BTreeSet<T> {

View File

@ -99,8 +99,9 @@ pub fn check_crate<'ast>(sess: &Session,
ast_map: ast_map,
discriminant_map: RefCell::new(NodeMap()),
};
sess.abort_if_new_errors(|| {
krate.visit_all_items(&mut visitor);
sess.abort_if_errors();
});
}
struct CheckItemRecursionVisitor<'a, 'ast: 'a> {

View File

@ -52,6 +52,7 @@ pub enum Def {
DefStruct(DefId),
DefLabel(ast::NodeId),
DefMethod(DefId),
DefErr,
}
/// The result of resolving a path.
@ -124,7 +125,7 @@ impl Def {
DefVariant(..) | DefTy(..) | DefAssociatedTy(..) |
DefTyParam(..) | DefUse(..) | DefStruct(..) | DefTrait(..) |
DefMethod(..) | DefConst(..) | DefAssociatedConst(..) |
DefPrimTy(..) | DefLabel(..) | DefSelfTy(..) => {
DefPrimTy(..) | DefLabel(..) | DefSelfTy(..) | DefErr => {
panic!("attempted .def_id() on invalid {:?}", self)
}
}
@ -142,7 +143,8 @@ impl Def {
DefLabel(..) |
DefPrimTy(..) |
DefSelfTy(..) => {
DefSelfTy(..) |
DefErr => {
panic!("attempted .def_id() on invalid def: {:?}", self)
}
}

View File

@ -18,6 +18,7 @@ pub use self::RegionResolutionError::*;
pub use self::VarValue::*;
use super::{RegionVariableOrigin, SubregionOrigin, TypeTrace, MiscVariable};
use super::unify_key;
use rustc_data_structures::graph::{self, Direction, NodeIndex};
use rustc_data_structures::unify::{self, UnificationTable};
@ -345,10 +346,13 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
}
pub fn new_region_var(&self, origin: RegionVariableOrigin) -> RegionVid {
let id = self.num_vars();
let vid = RegionVid { index: self.num_vars() };
self.var_origins.borrow_mut().push(origin.clone());
let vid = self.unification_table.borrow_mut().new_key(());
assert_eq!(vid.index, id);
let u_vid = self.unification_table.borrow_mut().new_key(
unify_key::RegionVidKey { min_vid: vid }
);
assert_eq!(vid, u_vid);
if self.in_snapshot() {
self.undo_log.borrow_mut().push(AddVar(vid));
}
@ -581,7 +585,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
}
pub fn opportunistic_resolve_var(&self, rid: RegionVid) -> ty::Region {
ty::ReVar(self.unification_table.borrow_mut().find(rid))
ty::ReVar(self.unification_table.borrow_mut().find_value(rid).min_vid)
}
fn combine_map(&self, t: CombineMapType) -> &RefCell<CombineMap> {

View File

@ -10,7 +10,7 @@
use syntax::ast;
use middle::ty::{self, IntVarValue, Ty};
use rustc_data_structures::unify::UnifyKey;
use rustc_data_structures::unify::{Combine, UnifyKey};
pub trait ToType<'tcx> {
fn to_type(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx>;
@ -23,8 +23,28 @@ impl UnifyKey for ty::IntVid {
fn tag(_: Option<ty::IntVid>) -> &'static str { "IntVid" }
}
#[derive(PartialEq, Copy, Clone, Debug)]
pub struct RegionVidKey {
/// The minimum region vid in the unification set. This is needed
/// to have a canonical name for a type to prevent infinite
/// recursion.
pub min_vid: ty::RegionVid
}
impl Combine for RegionVidKey {
fn combine(&self, other: &RegionVidKey) -> RegionVidKey {
let min_vid = if self.min_vid.index < other.min_vid.index {
self.min_vid
} else {
other.min_vid
};
RegionVidKey { min_vid: min_vid }
}
}
impl UnifyKey for ty::RegionVid {
type Value = ();
type Value = RegionVidKey;
fn index(&self) -> u32 { self.index }
fn from_index(i: u32) -> ty::RegionVid { ty::RegionVid { index: i } }
fn tag(_: Option<ty::RegionVid>) -> &'static str { "RegionVid" }

View File

@ -609,6 +609,8 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
note: NoteNone
}))
}
def::DefErr => panic!("DefErr in memory categorization")
}
}
@ -1196,7 +1198,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
(*op)(self, cmt.clone(), pat);
let opt_def = if let Some(path_res) = self.tcx().def_map.borrow().get(&pat.id) {
if path_res.depth != 0 {
if path_res.depth != 0 || path_res.base_def == def::DefErr {
// Since patterns can be associated constants
// which are resolved during typeck, we might have
// some unresolved patterns reaching this stage
@ -1261,7 +1263,7 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
_ => {
self.tcx().sess.span_bug(
pat.span,
"enum pattern didn't resolve to enum or struct");
&format!("enum pattern didn't resolve to enum or struct {:?}", opt_def));
}
}
}

View File

@ -95,6 +95,7 @@ static ROOT_SCOPE: ScopeChain<'static> = RootScope;
pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegionMap {
let mut named_region_map = NodeMap();
sess.abort_if_new_errors(|| {
krate.visit_all_items(&mut LifetimeContext {
sess: sess,
named_region_map: &mut named_region_map,
@ -103,7 +104,7 @@ pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegio
trait_ref_hack: false,
labels_in_fn: vec![],
});
sess.abort_if_errors();
});
named_region_map
}

View File

@ -2100,9 +2100,8 @@ impl<'tcx> ctxt<'tcx> {
}) => {
true
}
Some(&def::PathResolution { base_def: def::DefErr, .. })=> true,
Some(..) => false,
None => self.sess.span_bug(expr.span, &format!(
"no def for path {}", expr.id))
}

View File

@ -156,6 +156,15 @@ impl Session {
_ => {}
}
}
pub fn abort_if_new_errors<F>(&self, mut f: F)
where F: FnMut()
{
let count = self.err_count();
f();
if self.err_count() > count {
self.abort_if_errors();
}
}
pub fn span_warn(&self, sp: Span, msg: &str) {
if self.can_print_warnings {
self.diagnostic().span_warn(sp, msg)

View File

@ -33,6 +33,8 @@ use rustc_front::hir::{Expr, FnDecl, Block, Pat};
use rustc_front::intravisit;
use rustc_front::intravisit::Visitor;
use self::restrictions::RestrictionResult;
mod lifetime;
mod restrictions;
mod gather_moves;
@ -354,12 +356,12 @@ impl<'a, 'tcx> GatherLoanCtxt<'a, 'tcx> {
// Create the loan record (if needed).
let loan = match restr {
restrictions::Safe => {
RestrictionResult::Safe => {
// No restrictions---no loan record necessary
return;
}
restrictions::SafeIf(loan_path, restricted_paths) => {
RestrictionResult::SafeIf(loan_path, restricted_paths) => {
let loan_scope = match loan_region {
ty::ReScope(scope) => scope,

View File

@ -10,8 +10,6 @@
//! Computes the restrictions that result from a borrow.
pub use self::RestrictionResult::*;
use borrowck::*;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
@ -69,19 +67,19 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
// are inherently non-aliasable, they can only be
// accessed later through the borrow itself and hence
// must inherently comply with its terms.
Safe
RestrictionResult::Safe
}
Categorization::Local(local_id) => {
// R-Variable, locally declared
let lp = new_lp(LpVar(local_id));
SafeIf(lp.clone(), vec![lp])
RestrictionResult::SafeIf(lp.clone(), vec![lp])
}
Categorization::Upvar(mc::Upvar { id, .. }) => {
// R-Variable, captured into closure
let lp = new_lp(LpUpvar(id));
SafeIf(lp.clone(), vec![lp])
RestrictionResult::SafeIf(lp.clone(), vec![lp])
}
Categorization::Downcast(cmt_base, _) => {
@ -106,7 +104,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
}
Categorization::StaticItem => {
Safe
RestrictionResult::Safe
}
Categorization::Deref(cmt_base, _, pk) => {
@ -133,11 +131,11 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
cmt: cmt_base,
code: err_borrowed_pointer_too_short(
self.loan_region, lt)});
return Safe;
return RestrictionResult::Safe;
}
match bk {
ty::ImmBorrow => Safe,
ty::ImmBorrow => RestrictionResult::Safe,
ty::MutBorrow | ty::UniqueImmBorrow => {
// R-Deref-Mut-Borrowed
//
@ -150,7 +148,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
}
}
// Borrowck is not relevant for raw pointers
mc::UnsafePtr(..) => Safe
mc::UnsafePtr(..) => RestrictionResult::Safe
}
}
}
@ -161,12 +159,12 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
cmt: &mc::cmt<'tcx>,
elem: LoanPathElem) -> RestrictionResult<'tcx> {
match result {
Safe => Safe,
SafeIf(base_lp, mut base_vec) => {
RestrictionResult::Safe => RestrictionResult::Safe,
RestrictionResult::SafeIf(base_lp, mut base_vec) => {
let v = LpExtend(base_lp, cmt.mutbl, elem);
let lp = Rc::new(LoanPath::new(v, cmt.ty));
base_vec.push(lp.clone());
SafeIf(lp, base_vec)
RestrictionResult::SafeIf(lp, base_vec)
}
}
}

View File

@ -37,6 +37,16 @@ pub trait UnifyKey : Copy + Clone + Debug + PartialEq {
fn tag(k: Option<Self>) -> &'static str;
}
/// This trait is implemented for unify values that can be
/// combined. This relation should be a monoid.
pub trait Combine {
fn combine(&self, other: &Self) -> Self;
}
impl Combine for () {
fn combine(&self, _other: &()) {}
}
/// Value of a unification key. We implement Tarjan's union-find
/// algorithm: when two keys are unified, one of them is converted
/// into a "redirect" pointing at the other. These redirects form a
@ -243,8 +253,8 @@ impl<K:UnifyKey> sv::SnapshotVecDelegate for Delegate<K> {
///////////////////////////////////////////////////////////////////////////
// Base union-find algorithm, where we are just making sets
impl<'tcx,K> UnificationTable<K>
where K : UnifyKey<Value=()>,
impl<'tcx,K:UnifyKey> UnificationTable<K>
where K::Value: Combine
{
pub fn union(&mut self, a_id: K, b_id: K) {
let node_a = self.get(a_id);
@ -252,7 +262,8 @@ impl<'tcx,K> UnificationTable<K>
let a_id = node_a.key();
let b_id = node_b.key();
if a_id != b_id {
self.unify(node_a, node_b, ());
let new_value = node_a.value.combine(&node_b.value);
self.unify(node_a, node_b, new_value);
}
}
@ -260,6 +271,10 @@ impl<'tcx,K> UnificationTable<K>
self.get(id).key()
}
pub fn find_value(&mut self, id: K) -> K::Value {
self.get(id).value
}
pub fn unioned(&mut self, a_id: K, b_id: K) -> bool {
self.find(a_id) == self.find(b_id)
}

View File

@ -407,7 +407,8 @@ impl tr for def::Def {
def::DefUpvar(did1, nid1, index, nid2)
}
def::DefStruct(did) => def::DefStruct(did.tr(dcx)),
def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid))
def::DefLabel(nid) => def::DefLabel(dcx.tr_id(nid)),
def::DefErr => def::DefErr,
}
}
}

View File

@ -709,7 +709,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
DefUse(..) |
DefUpvar(..) |
DefLabel(..) |
DefSelfTy(..) => {
DefSelfTy(..) |
DefErr => {
panic!("didn't expect `{:?}`", def);
}
}

View File

@ -566,6 +566,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
Ok(def) => self.record_def(tref.trait_ref.ref_id, def),
Err(_) => {
// error already reported
self.record_def(tref.trait_ref.ref_id, err_path_resolution())
}
}
intravisit::walk_poly_trait_ref(self, tref, m);
@ -2005,6 +2006,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
prefix.span,
ResolutionError::FailedToResolve(
&path_names_to_string(prefix, 0)));
self.record_def(item.id, err_path_resolution());
}
}
}
@ -2164,6 +2166,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
resolve_error(self,
eq_pred.span,
ResolutionError::UndeclaredAssociatedType);
self.record_def(eq_pred.id, err_path_resolution());
}
}
}
@ -2194,6 +2197,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
self.record_def(trait_ref.ref_id, path_res);
new_val = Some((path_res.base_def.def_id(), trait_ref.clone()));
new_id = Some(path_res.base_def.def_id());
} else {
self.record_def(trait_ref.ref_id, err_path_resolution());
}
intravisit::walk_trait_ref(self, trait_ref);
}
@ -2463,6 +2468,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
self.record_def(ty.id, def);
}
None => {
self.record_def(ty.id, err_path_resolution());
// Keep reporting some errors even if they're ignored above.
self.resolve_path(ty.id, path, 0, TypeNS, true);
@ -2545,6 +2552,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
renamed)
);
self.record_def(pattern.id, err_path_resolution());
}
FoundConst(def, lp, _) if const_ok => {
debug!("(resolving pattern) resolving `{}` to constant", renamed);
@ -2564,6 +2572,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::OnlyIrrefutablePatternsAllowedHere(def.def_id(),
name)
);
self.record_def(pattern.id, err_path_resolution());
}
BareIdentifierPatternUnresolved => {
debug!("(resolving pattern) binding `{}`", renamed);
@ -2647,6 +2656,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
resolve_error(&self,
path.span,
ResolutionError::StaticVariableReference);
self.record_def(pattern.id, err_path_resolution());
}
_ => {
// If anything ends up here entirely resolved,
@ -2665,6 +2675,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.name
.as_str())
);
self.record_def(pattern.id, err_path_resolution());
} else {
let const_name = path.segments
.last()
@ -2684,6 +2695,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::UnresolvedEnumVariantStructOrConst(
&path.segments.last().unwrap().identifier.name.as_str())
);
self.record_def(pattern.id, err_path_resolution());
}
intravisit::walk_path(self, path);
}
@ -2726,6 +2738,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&path.segments.last().unwrap().identifier.name.as_str()
)
);
self.record_def(pattern.id, err_path_resolution());
}
}
} else {
@ -2737,6 +2750,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.identifier
.name
.as_str()));
self.record_def(pattern.id, err_path_resolution());
}
intravisit::walk_pat(self, pattern);
}
@ -2754,6 +2768,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::DoesNotNameAStruct(
&*path_names_to_string(path, 0))
);
self.record_def(pattern.id, err_path_resolution());
}
}
intravisit::walk_path(self, path);
@ -3430,6 +3445,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} else {
self.session.span_help(expr.span, &msg);
}
self.record_def(expr.id, err_path_resolution());
} else {
// Write the result into the def map.
debug!("(resolving expr) resolved `{}`",
@ -3454,6 +3470,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let type_res = self.with_no_errors(|this| {
this.resolve_path(expr.id, path, 0, TypeNS, false)
});
self.record_def(expr.id, err_path_resolution());
match type_res.map(|r| r.base_def) {
Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => {
resolve_error(
@ -3540,6 +3558,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ResolutionError::DoesNotNameAStruct(
&*path_names_to_string(path, 0))
);
self.record_def(expr.id, err_path_resolution());
}
}
@ -3562,6 +3581,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
ExprBreak(Some(label)) | ExprAgain(Some(label)) => {
match self.search_label(label.node.name) {
None => {
self.record_def(expr.id, err_path_resolution());
resolve_error(self,
label.span,
ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
@ -3811,6 +3831,14 @@ fn module_to_string(module: &Module) -> String {
names_to_string(&names.into_iter().rev().collect::<Vec<ast::Name>>())
}
fn err_path_resolution() -> PathResolution {
PathResolution {
base_def: DefErr,
last_private: LastMod(AllPublic),
depth: 0,
}
}
pub struct CrateMap {
pub def_map: RefCell<DefMap>,
@ -3836,7 +3864,6 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, None);
resolver.resolve_crate(krate);
session.abort_if_errors();
check_unused::check_crate(&mut resolver, krate);

View File

@ -276,7 +276,8 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
def::DefTyParam(..) |
def::DefUse(_) |
def::DefMethod(..) |
def::DefPrimTy(_) => {
def::DefPrimTy(_) |
def::DefErr => {
self.sess.span_bug(span,
&format!("lookup_def_kind for unexpected item: {:?}", def));
}

View File

@ -216,7 +216,7 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &hir::Expr)
def::DefMod(..) | def::DefForeignMod(..) | def::DefTrait(..) |
def::DefTy(..) | def::DefPrimTy(..) | def::DefAssociatedTy(..) |
def::DefUse(..) | def::DefLabel(..) | def::DefTyParam(..) |
def::DefSelfTy(..) => {
def::DefSelfTy(..) | def::DefErr => {
bcx.tcx().sess.span_bug(
ref_expr.span,
&format!("cannot translate def {:?} \

View File

@ -719,6 +719,9 @@ fn trait_def_id<'tcx>(this: &AstConv<'tcx>, trait_ref: &hir::TraitRef) -> DefId
let path = &trait_ref.path;
match ::lookup_full_def(this.tcx(), path.span, trait_ref.ref_id) {
def::DefTrait(trait_def_id) => trait_def_id,
def::DefErr => {
this.tcx().sess.fatal("cannot continue compilation due to previous error");
}
_ => {
span_fatal!(this.tcx().sess, path.span, E0245, "`{}` is not a trait",
path);
@ -1533,6 +1536,9 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
def::DefPrimTy(prim_ty) => {
prim_ty_to_ty(tcx, base_segments, prim_ty)
}
def::DefErr => {
return this.tcx().types.err;
}
_ => {
let id_node = tcx.map.as_local_node_id(def.def_id()).unwrap();
span_err!(tcx.sess, span, E0248,

View File

@ -142,7 +142,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
return;
}
}
let const_did = tcx.def_map.borrow().get(&pat.id).unwrap().def_id();
if let Some(pat_def) = tcx.def_map.borrow().get(&pat.id) {
let const_did = pat_def.def_id();
let const_scheme = tcx.lookup_item_type(const_did);
assert!(const_scheme.generics.is_empty());
let const_ty = pcx.fcx.instantiate_type_scheme(pat.span,
@ -156,6 +157,9 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
// exist a LUB, but for the cases that can occur, subtype
// is good enough.
demand::suptype(fcx, pat.span, expected, const_ty);
} else {
fcx.write_error(pat.id);
}
}
hir::PatIdent(bm, ref path, ref sub) if pat_is_binding(&tcx.def_map.borrow(), pat) => {
let typ = fcx.local_ty(pat.span, pat.id);
@ -186,7 +190,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
// if there are multiple arms, make sure they all agree on
// what the type of the binding `x` ought to be
let canon_id = *pcx.map.get(&path.node.name).unwrap();
if let Some(&canon_id) = pcx.map.get(&path.node.name) {
if canon_id != pat.id {
let ct = fcx.local_ty(pat.span, canon_id);
demand::eqtype(fcx, pat.span, ct, typ);
@ -196,6 +200,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
check_pat(pcx, &**p, expected);
}
}
}
hir::PatIdent(_, ref path, _) => {
let path = hir_util::ident_to_path(path.span, path.node);
check_pat_enum(pcx, pat, &path, Some(&[]), expected, false);
@ -208,6 +213,10 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
hir::PatQPath(ref qself, ref path) => {
let self_ty = fcx.to_ty(&qself.ty);
let path_res = if let Some(&d) = tcx.def_map.borrow().get(&pat.id) {
if d.base_def == def::DefErr {
fcx.write_error(pat.id);
return;
}
d
} else if qself.position == 0 {
// This is just a sentinel for finish_resolving_def_to_ty.
@ -218,8 +227,9 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
depth: path.segments.len()
}
} else {
tcx.sess.span_bug(pat.span,
&format!("unbound path {:?}", pat))
debug!("unbound path {:?}", pat);
fcx.write_error(pat.id);
return;
};
if let Some((opt_ty, segments, def)) =
resolve_ty_and_def_ufcs(fcx, path_res, Some(self_ty),
@ -597,7 +607,20 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
let fcx = pcx.fcx;
let tcx = pcx.fcx.ccx.tcx;
let path_res = *tcx.def_map.borrow().get(&pat.id).unwrap();
let path_res = match tcx.def_map.borrow().get(&pat.id) {
Some(&path_res) if path_res.base_def != def::DefErr => path_res,
_ => {
fcx.write_error(pat.id);
if let Some(subpats) = subpats {
for pat in subpats {
check_pat(pcx, &**pat, tcx.types.err);
}
}
return;
}
};
let (opt_ty, segments, def) = match resolve_ty_and_def_ufcs(fcx, path_res,
None, path,
@ -636,7 +659,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
let report_bad_struct_kind = |is_warning| {
bad_struct_kind_err(tcx.sess, pat.span, path, is_warning);
if is_warning {
return
return;
}
fcx.write_error(pat.id);

View File

@ -26,6 +26,7 @@ use super::write_call;
use CrateCtxt;
use middle::cstore::LOCAL_CRATE;
use middle::def;
use middle::def_id::DefId;
use middle::infer;
use middle::ty::{self, LvaluePreference, Ty};
@ -234,7 +235,7 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
if let hir::ExprCall(ref expr, _) = call_expr.node {
let tcx = fcx.tcx();
if let Some(pr) = tcx.def_map.borrow().get(&expr.id) {
if pr.depth == 0 {
if pr.depth == 0 && pr.base_def != def::DefErr {
if let Some(span) = tcx.map.span_if_local(pr.def_id()) {
tcx.sess.span_note(span, "defined here")
}

View File

@ -17,6 +17,7 @@ use middle::region;
use middle::subst::{self, Subst};
use middle::traits;
use middle::ty::{self, Ty};
use util::nodemap::FnvHashSet;
use syntax::ast;
use syntax::codemap::{self, Span};
@ -279,7 +280,7 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
rcx: rcx,
span: span,
parent_scope: parent_scope,
breadcrumbs: Vec::new(),
breadcrumbs: FnvHashSet()
},
TypeContext::Root,
typ,
@ -340,7 +341,7 @@ enum TypeContext {
struct DropckContext<'a, 'b: 'a, 'tcx: 'b> {
rcx: &'a mut Rcx<'b, 'tcx>,
/// types that have already been traversed
breadcrumbs: Vec<Ty<'tcx>>,
breadcrumbs: FnvHashSet<Ty<'tcx>>,
/// span for error reporting
span: Span,
/// the scope reachable dtorck types must outlive
@ -355,8 +356,6 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
depth: usize) -> Result<(), Error<'tcx>>
{
let tcx = cx.rcx.tcx();
let ty = cx.rcx.infcx().resolve_type_and_region_vars_if_possible(&ty);
// Issue #22443: Watch out for overflow. While we are careful to
// handle regular types properly, non-regular ones cause problems.
let recursion_limit = tcx.sess.recursion_limit.get();
@ -367,19 +366,17 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'tcx>(
return Err(Error::Overflow(context, ty))
}
for breadcrumb in &mut cx.breadcrumbs {
*breadcrumb =
cx.rcx.infcx().resolve_type_and_region_vars_if_possible(breadcrumb);
if *breadcrumb == ty {
// canoncialize the regions in `ty` before inserting - infinitely many
// region variables can refer to the same region.
let ty = cx.rcx.infcx().resolve_type_and_region_vars_if_possible(&ty);
if !cx.breadcrumbs.insert(ty) {
debug!("iterate_over_potentially_unsafe_regions_in_type \
{}ty: {} scope: {:?} - cached",
(0..depth).map(|_| ' ').collect::<String>(),
ty, cx.parent_scope);
return Ok(()); // we already visited this type
}
}
cx.breadcrumbs.push(ty);
debug!("iterate_over_potentially_unsafe_regions_in_type \
{}ty: {} scope: {:?}",
(0..depth).map(|_| ' ').collect::<String>(),

View File

@ -385,6 +385,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> {
}
pub fn check_wf_old(ccx: &CrateCtxt) {
// If types are not well-formed, it leads to all manner of errors
// downstream, so stop reporting errors at this point.
ccx.tcx.sess.abort_if_new_errors(|| {
// FIXME(#25759). The new code below is much more reliable but (for now)
// only generates warnings. So as to ensure that we continue
// getting errors where we used to get errors, we run the old wf
@ -393,38 +396,35 @@ pub fn check_wf_old(ccx: &CrateCtxt) {
let krate = ccx.tcx.map.krate();
let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx);
krate.visit_all_items(&mut visit);
// If types are not well-formed, it leads to all manner of errors
// downstream, so stop reporting errors at this point.
ccx.tcx.sess.abort_if_errors();
});
}
pub fn check_wf_new(ccx: &CrateCtxt) {
ccx.tcx.sess.abort_if_new_errors(|| {
let krate = ccx.tcx.map.krate();
let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(ccx);
krate.visit_all_items(&mut visit);
// If types are not well-formed, it leads to all manner of errors
// downstream, so stop reporting errors at this point.
ccx.tcx.sess.abort_if_errors();
});
}
pub fn check_item_types(ccx: &CrateCtxt) {
ccx.tcx.sess.abort_if_new_errors(|| {
let krate = ccx.tcx.map.krate();
let mut visit = CheckItemTypesVisitor { ccx: ccx };
krate.visit_all_items(&mut visit);
ccx.tcx.sess.abort_if_errors();
});
}
pub fn check_item_bodies(ccx: &CrateCtxt) {
ccx.tcx.sess.abort_if_new_errors(|| {
let krate = ccx.tcx.map.krate();
let mut visit = CheckItemBodiesVisitor { ccx: ccx };
krate.visit_all_items(&mut visit);
ccx.tcx.sess.abort_if_errors();
});
}
pub fn check_drop_impls(ccx: &CrateCtxt) {
ccx.tcx.sess.abort_if_new_errors(|| {
let drop_trait = match ccx.tcx.lang_items.drop_trait() {
Some(id) => ccx.tcx.lookup_trait_def(id), None => { return }
};
@ -438,8 +438,7 @@ pub fn check_drop_impls(ccx: &CrateCtxt) {
}
}
});
ccx.tcx.sess.abort_if_errors();
});
}
fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
@ -891,14 +890,9 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
for impl_item in impl_items {
let ty_impl_item = ccx.tcx.impl_or_trait_item(ccx.tcx.map.local_def_id(impl_item.id));
let ty_trait_item = trait_items.iter()
.find(|ac| ac.name() == ty_impl_item.name())
.unwrap_or_else(|| {
// This is checked by resolve
tcx.sess.span_bug(impl_item.span,
&format!("impl-item `{}` is not a member of `{:?}`",
ty_impl_item.name(),
impl_trait_ref));
});
.find(|ac| ac.name() == ty_impl_item.name());
if let Some(ty_trait_item) = ty_trait_item {
match impl_item.node {
hir::ImplItemKind::Const(..) => {
let impl_const = match ty_impl_item {
@ -964,6 +958,7 @@ fn check_impl_items_against_trait<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
}
}
}
}
// Check for missing items from trait
let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
@ -3193,6 +3188,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
// Find the relevant variant
let def = lookup_full_def(tcx, path.span, expr.id);
if def == def::DefErr {
check_struct_fields_on_error(fcx, expr.id, fields, base_expr);
return;
}
let (adt, variant) = match fcx.def_struct_variant(def, path.span) {
Some((adt, variant)) => (adt, variant),
None => {
@ -3371,6 +3370,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
if let Some((opt_ty, segments, def)) =
resolve_ty_and_def_ufcs(fcx, path_res, opt_self_ty, path,
expr.span, expr.id) {
if def != def::DefErr {
let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx,
expr.span,
def);
@ -3382,6 +3382,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
def,
expr.span,
id);
} else {
fcx.write_ty(id, fcx.tcx().types.err);
}
}
// We always require that the type provided as the value for
@ -4326,7 +4329,8 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
def::DefForeignMod(..) |
def::DefUse(..) |
def::DefLabel(..) |
def::DefSelfTy(..) => {
def::DefSelfTy(..) |
def::DefErr => {
fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
}
}
@ -4496,7 +4500,8 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
def::DefLocal(..) |
def::DefUse(..) |
def::DefLabel(..) |
def::DefUpvar(..) => {
def::DefUpvar(..) |
def::DefErr => {
segment_spaces = vec![None; segments.len()];
}
}

View File

@ -122,10 +122,12 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
} else {
let tcx = self.tcx();
if let hir::ExprAssignOp(..) = e.node {
if let hir::ExprAssignOp(_, ref lhs, ref rhs) = e.node {
if
!tcx.sess.features.borrow().augmented_assignments &&
!self.fcx.expr_ty(e).references_error()
!self.fcx.expr_ty(e).references_error() &&
!self.fcx.expr_ty(lhs).references_error() &&
!self.fcx.expr_ty(rhs).references_error()
{
tcx.sess.span_err(
e.span,

View File

@ -205,6 +205,9 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
"f64",
item.span);
}
ty::TyError => {
return;
}
_ => {
span_err!(self.tcx.sess, item.span, E0118,
"no base type found for inherent implementation; \

View File

@ -331,18 +331,21 @@ pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) {
tcx: tcx
};
// this ensures that later parts of type checking can assume that items
// have valid types and not error
tcx.sess.abort_if_new_errors(|| {
time(time_passes, "type collecting", ||
collect::collect_item_types(tcx));
// this ensures that later parts of type checking can assume that items
// have valid types and not error
tcx.sess.abort_if_errors();
});
time(time_passes, "variance inference", ||
variance::infer_variance(tcx));
tcx.sess.abort_if_new_errors(|| {
time(time_passes, "coherence checking", ||
coherence::check_coherence(&ccx));
});
time(time_passes, "wf checking (old)", ||
check::check_wf_old(&ccx));

View File

@ -261,7 +261,7 @@ pub fn main_args(args: &[String]) -> isize {
match (should_test, markdown_input) {
(true, true) => {
return markdown::test(input, libs, externs, test_args)
return markdown::test(input, cfgs, libs, externs, test_args)
}
(true, false) => {
return test::run(input, cfgs, libs, externs, test_args, crate_name)

View File

@ -142,13 +142,13 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
}
/// Run any tests/code examples in the markdown file `input`.
pub fn test(input: &str, libs: SearchPaths, externs: core::Externs,
pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: core::Externs,
mut test_args: Vec<String>) -> isize {
let input_str = load_or_return!(input, 1, 2);
let mut opts = TestOptions::default();
opts.no_crate_inject = true;
let mut collector = Collector::new(input.to_string(), libs, externs,
let mut collector = Collector::new(input.to_string(), cfgs, libs, externs,
true, opts);
find_testable_code(&input_str, &mut collector);
test_args.insert(0, "rustdoctest".to_string());

View File

@ -85,7 +85,7 @@ pub fn run(input: &str,
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let mut cfg = config::build_configuration(&sess);
cfg.extend(config::parse_cfgspecs(cfgs));
cfg.extend(config::parse_cfgspecs(cfgs.clone()));
let krate = driver::phase_1_parse_input(&sess, cfg, &input);
let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate,
"rustdoc-test", None)
@ -122,6 +122,7 @@ pub fn run(input: &str,
let (krate, _) = passes::unindent_comments(krate);
let mut collector = Collector::new(krate.name.to_string(),
cfgs,
libs,
externs,
false,
@ -168,7 +169,7 @@ fn scrape_test_config(krate: &::rustc_front::hir::Crate) -> TestOptions {
return opts;
}
fn runtest(test: &str, cratename: &str, libs: SearchPaths,
fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
externs: core::Externs,
should_panic: bool, no_run: bool, as_test_harness: bool,
opts: &TestOptions) {
@ -239,7 +240,8 @@ fn runtest(test: &str, cratename: &str, libs: SearchPaths,
let outdir = TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir");
let out = Some(outdir.path().to_path_buf());
let cfg = config::build_configuration(&sess);
let mut cfg = config::build_configuration(&sess);
cfg.extend(config::parse_cfgspecs(cfgs));
let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
let mut control = driver::CompileController::basic();
if no_run {
@ -349,6 +351,7 @@ fn partition_source(s: &str) -> (String, String) {
pub struct Collector {
pub tests: Vec<testing::TestDescAndFn>,
names: Vec<String>,
cfgs: Vec<String>,
libs: SearchPaths,
externs: core::Externs,
cnt: usize,
@ -359,11 +362,12 @@ pub struct Collector {
}
impl Collector {
pub fn new(cratename: String, libs: SearchPaths, externs: core::Externs,
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: core::Externs,
use_headers: bool, opts: TestOptions) -> Collector {
Collector {
tests: Vec::new(),
names: Vec::new(),
cfgs: cfgs,
libs: libs,
externs: externs,
cnt: 0,
@ -384,6 +388,7 @@ impl Collector {
format!("{}_{}", self.names.join("::"), self.cnt)
};
self.cnt += 1;
let cfgs = self.cfgs.clone();
let libs = self.libs.clone();
let externs = self.externs.clone();
let cratename = self.cratename.to_string();
@ -399,6 +404,7 @@ impl Collector {
testfn: testing::DynTestFn(Box::new(move|| {
runtest(&test,
&cratename,
cfgs,
libs,
externs,
should_panic,

View File

@ -79,8 +79,8 @@ pub use self::ParseResult::*;
use self::TokenTreeOrTokenTreeVec::*;
use ast;
use ast::{TokenTree, Name};
use codemap::{BytePos, mk_sp, Span};
use ast::{TokenTree, Name, Ident};
use codemap::{BytePos, mk_sp, Span, Spanned};
use codemap;
use parse::lexer::*; //resolve bug?
use parse::ParseSess;
@ -526,7 +526,10 @@ pub fn parse_nt(p: &mut Parser, sp: Span, name: &str) -> Nonterminal {
"ty" => token::NtTy(panictry!(p.parse_ty())),
// this could be handled like a token, since it is one
"ident" => match p.token {
token::Ident(sn,b) => { panictry!(p.bump()); token::NtIdent(Box::new(sn),b) }
token::Ident(sn,b) => {
panictry!(p.bump());
token::NtIdent(Box::new(Spanned::<Ident>{node: sn, span: p.span}),b)
}
_ => {
let token_str = pprust::token_to_string(&p.token);
panic!(p.fatal(&format!("expected ident, found {}",

View File

@ -293,8 +293,8 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
// (a) idents can be in lots of places, so it'd be a pain
// (b) we actually can, since it's a token.
MatchedNonterminal(NtIdent(ref sn, b)) => {
r.cur_span = sp;
r.cur_tok = token::Ident(**sn, b);
r.cur_span = sn.span;
r.cur_tok = token::Ident(sn.node, b);
return ret_val;
}
MatchedNonterminal(ref other_whole_nt) => {

View File

@ -663,7 +663,8 @@ pub fn noop_fold_interpolated<T: Folder>(nt: token::Nonterminal, fld: &mut T)
token::NtExpr(expr) => token::NtExpr(fld.fold_expr(expr)),
token::NtTy(ty) => token::NtTy(fld.fold_ty(ty)),
token::NtIdent(id, is_mod_name) =>
token::NtIdent(Box::new(fld.fold_ident(*id)), is_mod_name),
token::NtIdent(Box::new(Spanned::<Ident>{node: fld.fold_ident(id.node), .. *id}),
is_mod_name),
token::NtMeta(meta_item) => token::NtMeta(fld.fold_meta_item(meta_item)),
token::NtPath(path) => token::NtPath(Box::new(fld.fold_path(*path))),
token::NtTT(tt) => token::NtTT(P(fld.fold_tt(&tt))),

View File

@ -377,7 +377,7 @@ pub enum Nonterminal {
NtPat(P<ast::Pat>),
NtExpr(P<ast::Expr>),
NtTy(P<ast::Ty>),
NtIdent(Box<ast::Ident>, IdentStyle),
NtIdent(Box<ast::SpannedIdent>, IdentStyle),
/// Stuff inside brackets for attributes
NtMeta(P<ast::MetaItem>),
NtPath(Box<ast::Path>),

View File

@ -295,7 +295,7 @@ pub fn token_to_string(tok: &Token) -> String {
token::NtBlock(ref e) => block_to_string(&**e),
token::NtStmt(ref e) => stmt_to_string(&**e),
token::NtPat(ref e) => pat_to_string(&**e),
token::NtIdent(ref e, _) => ident_to_string(**e),
token::NtIdent(ref e, _) => ident_to_string(e.node),
token::NtTT(ref e) => tt_to_string(&**e),
token::NtArm(ref e) => arm_to_string(&*e),
token::NtImplItem(ref e) => impl_item_to_string(&**e),

View File

@ -23,7 +23,8 @@ fn main() {
let ps = syntax::parse::ParseSess::new();
let mut cx = syntax::ext::base::ExtCtxt::new(
&ps, vec![],
syntax::ext::expand::ExpansionConfig::default("qquote".to_string()));
syntax::ext::expand::ExpansionConfig::default("qquote".to_string()),
&mut Vec::new());
cx.bt_push(syntax::codemap::ExpnInfo {
call_site: DUMMY_SP,
callee: syntax::codemap::NameAndSpan {

View File

@ -32,13 +32,13 @@ impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
impl<'a, B: ?Sized> IntoCow<'a, B> for <B as ToOwned>::Owned where B: ToOwned {
//~^ ERROR E0119
fn into_cow(self) -> Cow<'a, B> {
Cow
Cow(PhantomData)
}
}
impl<'a, B: ?Sized> IntoCow<'a, B> for &'a B where B: ToOwned {
fn into_cow(self) -> Cow<'a, B> {
Cow
Cow(PhantomData)
}
}

View File

@ -9,14 +9,12 @@
// except according to those terms.
// error-pattern: unresolved
enum color { rgb(isize, isize, isize), rgba(isize, isize, isize, isize), }
fn main() {
let red: color = rgb(255, 0, 0);
let red: color = color::rgb(255, 0, 0);
match red {
rgb(r, g, b) => { println!("rgb"); }
hsl(h, s, l) => { println!("hsl"); }
color::rgb(r, g, b) => { println!("rgb"); }
color::hsl(h, s, l) => { println!("hsl"); } //~ ERROR no associated
}
}

View File

@ -13,7 +13,9 @@
// If the trait is not object-safe, we give a more tailored message
// because we're such schnuckels:
trait NotObjectSafe { fn eq(&self, other: Self); }
impl NotObjectSafe for NotObjectSafe { } //~ ERROR E0372
trait NotObjectSafe { fn eq(&self, other: &Self); }
impl NotObjectSafe for NotObjectSafe { //~ ERROR E0372
fn eq(&self, other: &Self) { panic!(); }
}
fn main() { }

View File

@ -28,8 +28,6 @@ impl Copy for MyType {}
impl Copy for &'static mut MyType {}
//~^ ERROR E0206
//~| ERROR E0277
//~| ERROR E0277
impl Clone for MyType { fn clone(&self) -> Self { *self } }
impl Copy for (MyType, MyType) {}
@ -42,8 +40,6 @@ impl Copy for &'static NotSync {}
impl Copy for [MyType] {}
//~^ ERROR E0206
//~| ERROR E0117
//~| ERROR E0277
//~| ERROR E0277
impl Copy for &'static [NotSync] {}
//~^ ERROR E0206

View File

@ -30,7 +30,6 @@ impl Sized for (MyType, MyType) {} //~ ERROR E0117
impl Sized for &'static NotSync {} //~ ERROR E0322
impl Sized for [MyType] {} //~ ERROR E0117
//~^ ERROR E0277
impl Sized for &'static [NotSync] {} //~ ERROR E0117

View File

@ -33,6 +33,7 @@ trait Qux<T,T> {}
impl<T,T> Qux<T,T> for Option<T> {}
//~^ ERROR the name `T` is already used
//~^^ ERROR the type parameter `T` is not constrained
fn main() {
}

View File

@ -10,7 +10,7 @@
// see #9186
enum Bar<T> { What }
enum Bar<T> { What } //~ ERROR parameter `T` is never used
fn foo<T>() {
static a: Bar<T> = Bar::What;

View File

@ -9,8 +9,8 @@
// except according to those terms.
trait Trait {
fn outer(self) {
fn inner(_: Self) {
fn outer(&self) {
fn inner(_: &Self) {
//~^ ERROR can't use type parameters from outer function
//~^^ ERROR use of `Self` outside of an impl or trait
}

View File

@ -11,7 +11,7 @@
trait Foo {
fn bar(&self);
fn baz(&self) { }
fn bah(_: Option<Self>) { }
fn bah(_: Option<&Self>) { }
}
struct BarTy {

View File

@ -14,7 +14,7 @@ trait From<Src> {
fn from(src: Src) -> <Self as From<Src>>::Output;
}
trait To {
trait To: Sized {
fn to<Dst: From<Self>>(self) ->
<Dst as From<Self>>::Dst
//~^ ERROR use of undeclared associated type `From::Dst`

View File

@ -62,7 +62,7 @@ fn usize<'usize>(usize: &'usize usize) -> &'usize usize { usize }
fn main() {
let bool = true;
match bool {
str @ true => if str { i32 as i64 } else { 0 },
str @ true => if str { i32 as i64 } else { i64 },
false => i64,
}
};
}

View File

@ -13,5 +13,6 @@ pub trait ToNbt<T> {
}
impl ToNbt<Self> {} //~ ERROR use of `Self` outside of an impl or trait
//~^ WARNING the trait `ToNbt` cannot be made into an object
fn main() {}

View File

@ -9,7 +9,7 @@
// except according to those terms.
trait Groom {
fn shave();
fn shave(other: usize);
}
pub struct cat {
@ -30,7 +30,7 @@ impl MaybeDog {
}
impl Groom for cat {
fn shave(&self, other: usize) {
fn shave(other: usize) {
whiskers -= other;
//~^ ERROR: unresolved name `whiskers`. Did you mean `self.whiskers`?
shave(4);

View File

@ -11,6 +11,7 @@
// Make sure that label for continue and break is spanned correctly
fn main() {
loop {
continue
'b //~ ERROR use of undeclared label
;
@ -18,3 +19,4 @@ fn main() {
'c //~ ERROR use of undeclared label
;
}
}

View File

@ -13,13 +13,13 @@ trait siphash {
fn reset(&self);
}
fn siphash(k0 : u64, k1 : u64) -> siphash {
fn siphash(k0 : u64, k1 : u64) {
struct SipState {
v0: u64,
v1: u64,
}
fn mk_result(st : SipState) -> u64 {
fn mk_result(st : &SipState) -> u64 {
let v0 = st.v0;
let v1 = st.v1;

View File

@ -12,7 +12,7 @@ trait SipHash {
fn reset(&self);
}
fn siphash(k0 : u64) -> SipHash {
fn siphash(k0 : u64) {
struct SipState {
v0: u64,
}

View File

@ -15,6 +15,8 @@ fn foo<T>() {
}
impl<T> Drop for foo<T> {
//~^ ERROR wrong number of type arguments
//~^^ ERROR the type parameter `T` is not constrained
fn drop(&mut self) {}
}
}

View File

@ -16,6 +16,7 @@ fn main() {
Bar = foo
//~^ ERROR attempt to use a non-constant value in a constant
//~| ERROR unresolved name `foo`
//~^^^ ERROR constant evaluation error: non-constant path in constant expression
}
println!("{}", Stuff::Bar);

View File

@ -30,5 +30,7 @@ impl ToString_ for Point {
fn main() {
let p = Point::new(0.0, 0.0);
//~^ ERROR no associated item named `new` found for type `Point` in the current scope
println!("{}", p.to_string());
//~^ ERROR the type of this value must be known in this context
}

View File

@ -9,12 +9,10 @@
// except according to those terms.
// error-pattern:unresolved enum variant
fn main() {
let z = match 3 {
x(1) => x(1)
x(1) => x(1) //~ ERROR unresolved enum variant
//~^ ERROR unresolved name `x`
};
assert_eq!(z,3);
assert!(z == 3);
}

View File

@ -13,4 +13,5 @@ struct A { foo: isize }
fn main() {
let A { foo, foo } = A { foo: 3 };
//~^ ERROR: identifier `foo` is bound more than once in the same pattern
//~^^ ERROR: field `foo` bound multiple times
}

View File

@ -0,0 +1,23 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <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.
macro_rules! foo {
($id: ident) => {
$id
}
}
// Testing that the error span points to the parameter 'x' in the callsite,
// not to the macro variable '$id'
fn main() {
foo!(
x //~ ERROR unresolved name `x`
);
}

View File

@ -13,5 +13,5 @@
mod mod_file_aux;
fn main() {
assert_eq!(mod_file_aux::bar(), 10); //~ ERROR unresolved name
assert!(mod_file_aux::bar() == 10); //~ ERROR unresolved name
}

View File

@ -16,7 +16,6 @@ struct IWantToCopyThis {
impl Copy for IWantToCopyThis {}
//~^ ERROR the trait `Copy` may not be implemented for this type
//~| ERROR E0277
enum CantCopyThisEither {
A,
@ -29,6 +28,5 @@ enum IWantToCopyThisToo {
impl Copy for IWantToCopyThisToo {}
//~^ ERROR the trait `Copy` may not be implemented for this type
//~| ERROR E0277
fn main() {}

View File

@ -16,6 +16,7 @@ fn matcher1(x: opts) {
match x {
opts::a(ref i) | opts::b(i) => {}
//~^ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1
//~^^ ERROR mismatched types
opts::c(_) => {}
}
}
@ -24,6 +25,7 @@ fn matcher2(x: opts) {
match x {
opts::a(ref i) | opts::b(i) => {}
//~^ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1
//~^^ ERROR mismatched types
opts::c(_) => {}
}
}
@ -32,6 +34,7 @@ fn matcher4(x: opts) {
match x {
opts::a(ref mut i) | opts::b(ref i) => {}
//~^ ERROR variable `i` is bound with different mode in pattern #2 than in pattern #1
//~^^ ERROR mismatched types
opts::c(_) => {}
}
}

View File

@ -15,6 +15,7 @@
trait TraitA<A> {
fn outer(self) {
enum Foo<B> {
//~^ ERROR parameter `B` is never used
Variance(A)
//~^ ERROR can't use type parameters from outer function
//~^^ ERROR use of undeclared type name `A`
@ -27,6 +28,7 @@ trait TraitB<A> {
struct Foo<B>(A);
//~^ ERROR can't use type parameters from outer function
//~^^ ERROR use of undeclared type name `A`
//~^^^ ERROR parameter `B` is never used
}
}
@ -35,6 +37,7 @@ trait TraitC<A> {
struct Foo<B> { a: A }
//~^ ERROR can't use type parameters from outer function
//~^^ ERROR use of undeclared type name `A`
//~^^^ ERROR parameter `B` is never used
}
}

View File

@ -14,7 +14,7 @@
pub fn main() {
let asdf_fdsa = "<.<".to_string();
assert_eq!(concat_idents!(asd, f_f, dsa), "<.<".to_string());
assert!(concat_idents!(asd, f_f, dsa) == "<.<".to_string());
//~^ ERROR: unresolved name `asdf_fdsa`
assert_eq!(stringify!(use_mention_distinction), "use_mention_distinction");

View File

@ -18,7 +18,7 @@ extern crate trait_safety_lib as lib;
struct Bar;
impl lib::Foo for Bar { //~ ERROR requires an `unsafe impl` declaration
fn foo(&self) -> isize {
*self as isize
panic!();
}
}

View File

@ -12,11 +12,11 @@
// impls cannot be unsafe.
trait SafeTrait {
fn foo(self) { }
fn foo(&self) { }
}
unsafe trait UnsafeTrait {
fn foo(self) { }
fn foo(&self) { }
}
unsafe impl UnsafeTrait for u8 { } // OK

View File

@ -0,0 +1,16 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <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:--test --cfg feature="bar"
/// ```rust
/// assert_eq!(cfg!(feature = "bar"), true);
/// ```
pub fn foo() {}