From 18b4fe0e3eb9c68a966fce2fec12d892db00014a Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Fri, 11 Dec 2015 20:59:11 +1300 Subject: [PATCH 1/8] Make name resolution errors non-fatal --- src/librustc/middle/check_static_recursion.rs | 5 +- src/librustc/middle/def.rs | 6 +- src/librustc/middle/mem_categorization.rs | 6 +- src/librustc/middle/resolve_lifetime.rs | 17 +- src/librustc/middle/ty/mod.rs | 3 +- src/librustc/session/mod.rs | 9 + src/librustc_metadata/astencode.rs | 3 +- src/librustc_resolve/build_reduced_graph.rs | 3 +- src/librustc_resolve/lib.rs | 29 ++- src/librustc_trans/save/dump_csv.rs | 3 +- src/librustc_trans/trans/callee.rs | 2 +- src/librustc_typeck/astconv.rs | 6 + src/librustc_typeck/check/_match.rs | 73 ++++-- src/librustc_typeck/check/callee.rs | 3 +- src/librustc_typeck/check/mod.rs | 231 +++++++++--------- src/librustc_typeck/check/writeback.rs | 6 +- src/librustc_typeck/coherence/orphan.rs | 3 + src/librustc_typeck/lib.rs | 15 +- src/test/compile-fail-fulldeps/qquote.rs | 3 +- .../associated-types-coherence-failure.rs | 4 +- src/test/compile-fail/bogus-tag.rs | 8 +- ...erence-impl-trait-for-trait-object-safe.rs | 6 +- src/test/compile-fail/coherence-impls-copy.rs | 4 - .../compile-fail/coherence-impls-sized.rs | 1 - .../compile-fail/duplicate-type-parameter.rs | 1 + .../inner-static-type-parameter.rs | 2 +- src/test/compile-fail/issue-12796.rs | 4 +- src/test/compile-fail/issue-14254.rs | 2 +- src/test/compile-fail/issue-19883.rs | 2 +- src/test/compile-fail/issue-20427.rs | 4 +- src/test/compile-fail/issue-23305.rs | 1 + src/test/compile-fail/issue-2356.rs | 4 +- src/test/compile-fail/issue-28109.rs | 14 +- src/test/compile-fail/issue-3021-d.rs | 4 +- src/test/compile-fail/issue-3021.rs | 2 +- src/test/compile-fail/issue-3214.rs | 2 + src/test/compile-fail/issue-3521.rs | 1 + src/test/compile-fail/issue-3973.rs | 2 + src/test/compile-fail/issue-5927.rs | 8 +- src/test/compile-fail/issue-9725.rs | 1 + .../compile-fail/mod_file_correct_spans.rs | 2 +- src/test/compile-fail/opt-in-copy.rs | 2 - .../resolve-inconsistent-binding-mode.rs | 3 + .../resolve-type-param-in-item-in-trait.rs | 3 + .../compile-fail/syntax-extension-minor.rs | 2 +- .../trait-safety-trait-impl-cc.rs | 2 +- .../compile-fail/trait-safety-trait-impl.rs | 4 +- 47 files changed, 308 insertions(+), 213 deletions(-) diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs index 85a3117196acf..0882f3f1137ec 100644 --- a/src/librustc/middle/check_static_recursion.rs +++ b/src/librustc/middle/check_static_recursion.rs @@ -99,8 +99,9 @@ pub fn check_crate<'ast>(sess: &Session, ast_map: ast_map, discriminant_map: RefCell::new(NodeMap()), }; - krate.visit_all_items(&mut visitor); - sess.abort_if_errors(); + sess.abort_if_new_errors(|| { + krate.visit_all_items(&mut visitor); + }); } struct CheckItemRecursionVisitor<'a, 'ast: 'a> { diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index b1d2418795753..809c6084b769f 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -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) } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 70ef112efbaab..f869cac9236f6 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -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)); } } } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index b37b30703101a..15d1546d2d548 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -95,15 +95,16 @@ static ROOT_SCOPE: ScopeChain<'static> = RootScope; pub fn krate(sess: &Session, krate: &hir::Crate, def_map: &DefMap) -> NamedRegionMap { let mut named_region_map = NodeMap(); - krate.visit_all_items(&mut LifetimeContext { - sess: sess, - named_region_map: &mut named_region_map, - scope: &ROOT_SCOPE, - def_map: def_map, - trait_ref_hack: false, - labels_in_fn: vec![], + sess.abort_if_new_errors(|| { + krate.visit_all_items(&mut LifetimeContext { + sess: sess, + named_region_map: &mut named_region_map, + scope: &ROOT_SCOPE, + def_map: def_map, + trait_ref_hack: false, + labels_in_fn: vec![], + }); }); - sess.abort_if_errors(); named_region_map } diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index 7477c4dead031..5161a28ca31e8 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -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)) } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 7bf96b41dce7f..b7bfc2f8db53e 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -156,6 +156,15 @@ impl Session { _ => {} } } + pub fn abort_if_new_errors(&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) diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 4c47d3ab99063..d43ffb0fc3f3e 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -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, } } } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 0deef91a0f6b0..8b5b6ff781e07 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -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); } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c32acb7bb269f..4d5978f556078 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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::>()) } +fn err_path_resolution() -> PathResolution { + PathResolution { + base_def: DefErr, + last_private: LastMod(AllPublic), + depth: 0, + } +} + pub struct CrateMap { pub def_map: RefCell, @@ -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); diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index 2964d87ec1c09..b3e7ed7ed5e8e 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -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)); } diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 4aa7c0ff587f0..a22c12588e5f7 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -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 {:?} \ diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b83f0a5be6f04..752dd6e57f64f 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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, diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 38c714fa8f292..efcc08c69f824 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -142,20 +142,24 @@ 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(); - 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, - &Substs::empty(), - &const_scheme.ty); - fcx.write_ty(pat.id, const_ty); - - // FIXME(#20489) -- we should limit the types here to scalars or something! - - // As with PatLit, what we really want here is that there - // exist a LUB, but for the cases that can occur, subtype - // is good enough. - demand::suptype(fcx, pat.span, expected, const_ty); + 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, + &Substs::empty(), + &const_scheme.ty); + fcx.write_ty(pat.id, const_ty); + + // FIXME(#20489) -- we should limit the types here to scalars or something! + + // As with PatLit, what we really want here is that there + // 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,14 +190,15 @@ 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 canon_id != pat.id { - let ct = fcx.local_ty(pat.span, canon_id); - demand::eqtype(fcx, pat.span, ct, typ); - } + 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); + } - if let Some(ref p) = *sub { - check_pat(pcx, &**p, expected); + if let Some(ref p) = *sub { + check_pat(pcx, &**p, expected); + } } } hir::PatIdent(_, ref path, _) => { @@ -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); diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 6a23be682e9d3..1e20cd3985467 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -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") } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a50213202b82c..e43c806dc41e6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -385,61 +385,60 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckItemBodiesVisitor<'a, 'tcx> { } pub fn check_wf_old(ccx: &CrateCtxt) { - // 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 - // code first and abort if it encounters any errors. If no abort - // comes, we run the new code and issue warnings. - 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(); + 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 + // code first and abort if it encounters any errors. If no abort + // comes, we run the new code and issue warnings. + let krate = ccx.tcx.map.krate(); + let mut visit = wf::CheckTypeWellFormedVisitor::new(ccx); + krate.visit_all_items(&mut visit); + }); } pub fn check_wf_new(ccx: &CrateCtxt) { - 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(); + 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); + }); } pub fn check_item_types(ccx: &CrateCtxt) { - let krate = ccx.tcx.map.krate(); - let mut visit = CheckItemTypesVisitor { ccx: ccx }; - krate.visit_all_items(&mut visit); - ccx.tcx.sess.abort_if_errors(); + 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); + }); } pub fn check_item_bodies(ccx: &CrateCtxt) { - let krate = ccx.tcx.map.krate(); - let mut visit = CheckItemBodiesVisitor { ccx: ccx }; - krate.visit_all_items(&mut visit); - - ccx.tcx.sess.abort_if_errors(); + 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); + }); } pub fn check_drop_impls(ccx: &CrateCtxt) { - let drop_trait = match ccx.tcx.lang_items.drop_trait() { - Some(id) => ccx.tcx.lookup_trait_def(id), None => { return } - }; - drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| { - if drop_impl_did.is_local() { - match dropck::check_drop_impl(ccx.tcx, drop_impl_did) { - Ok(()) => {} - Err(()) => { - assert!(ccx.tcx.sess.has_errors()); + 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 } + }; + drop_trait.for_each_impl(ccx.tcx, |drop_impl_did| { + if drop_impl_did.is_local() { + match dropck::check_drop_impl(ccx.tcx, drop_impl_did) { + Ok(()) => {} + Err(()) => { + assert!(ccx.tcx.sess.has_errors()); + } } } - } + }); }); - - ccx.tcx.sess.abort_if_errors(); } fn check_bare_fn<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, @@ -891,75 +890,71 @@ 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)); - }); - match impl_item.node { - hir::ImplItemKind::Const(..) => { - let impl_const = match ty_impl_item { - ty::ConstTraitItem(ref cti) => cti, - _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const") - }; + .find(|ac| ac.name() == ty_impl_item.name()); - // Find associated const definition. - if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item { - compare_const_impl(ccx.tcx, - &impl_const, - impl_item.span, - trait_const, - &*impl_trait_ref); - } else { - span_err!(tcx.sess, impl_item.span, E0323, - "item `{}` is an associated const, \ - which doesn't match its trait `{:?}`", - impl_const.name, - impl_trait_ref) + if let Some(ty_trait_item) = ty_trait_item { + match impl_item.node { + hir::ImplItemKind::Const(..) => { + let impl_const = match ty_impl_item { + ty::ConstTraitItem(ref cti) => cti, + _ => tcx.sess.span_bug(impl_item.span, "non-const impl-item for const") + }; + + // Find associated const definition. + if let &ty::ConstTraitItem(ref trait_const) = ty_trait_item { + compare_const_impl(ccx.tcx, + &impl_const, + impl_item.span, + trait_const, + &*impl_trait_ref); + } else { + span_err!(tcx.sess, impl_item.span, E0323, + "item `{}` is an associated const, \ + which doesn't match its trait `{:?}`", + impl_const.name, + impl_trait_ref) + } } - } - hir::ImplItemKind::Method(ref sig, ref body) => { - check_trait_fn_not_const(ccx, impl_item.span, sig.constness); + hir::ImplItemKind::Method(ref sig, ref body) => { + check_trait_fn_not_const(ccx, impl_item.span, sig.constness); - let impl_method = match ty_impl_item { - ty::MethodTraitItem(ref mti) => mti, - _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method") - }; + let impl_method = match ty_impl_item { + ty::MethodTraitItem(ref mti) => mti, + _ => tcx.sess.span_bug(impl_item.span, "non-method impl-item for method") + }; - if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item { - compare_impl_method(ccx.tcx, - &impl_method, - impl_item.span, - body.id, - &trait_method, - &impl_trait_ref); - } else { - span_err!(tcx.sess, impl_item.span, E0324, - "item `{}` is an associated method, \ - which doesn't match its trait `{:?}`", - impl_method.name, - impl_trait_ref) + if let &ty::MethodTraitItem(ref trait_method) = ty_trait_item { + compare_impl_method(ccx.tcx, + &impl_method, + impl_item.span, + body.id, + &trait_method, + &impl_trait_ref); + } else { + span_err!(tcx.sess, impl_item.span, E0324, + "item `{}` is an associated method, \ + which doesn't match its trait `{:?}`", + impl_method.name, + impl_trait_ref) + } } - } - hir::ImplItemKind::Type(_) => { - let impl_type = match ty_impl_item { - ty::TypeTraitItem(ref tti) => tti, - _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type") - }; + hir::ImplItemKind::Type(_) => { + let impl_type = match ty_impl_item { + ty::TypeTraitItem(ref tti) => tti, + _ => tcx.sess.span_bug(impl_item.span, "non-type impl-item for type") + }; - if let &ty::TypeTraitItem(ref at) = ty_trait_item { - if let Some(_) = at.ty { - overridden_associated_type = Some(impl_item); + if let &ty::TypeTraitItem(ref at) = ty_trait_item { + if let Some(_) = at.ty { + overridden_associated_type = Some(impl_item); + } + } else { + span_err!(tcx.sess, impl_item.span, E0325, + "item `{}` is an associated type, \ + which doesn't match its trait `{:?}`", + impl_type.name, + impl_trait_ref) } - } else { - span_err!(tcx.sess, impl_item.span, E0325, - "item `{}` is an associated type, \ - which doesn't match its trait `{:?}`", - impl_type.name, - impl_trait_ref) } } } @@ -3192,6 +3187,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 => { @@ -3370,17 +3369,21 @@ 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) { - let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, - expr.span, - def); - instantiate_path(fcx, - segments, - scheme, - &predicates, - opt_ty, - def, - expr.span, - id); + if def != def::DefErr { + let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, + expr.span, + def); + instantiate_path(fcx, + segments, + scheme, + &predicates, + opt_ty, + def, + expr.span, + id); + } else { + fcx.write_ty(id, fcx.tcx().types.err); + } } // We always require that the type provided as the value for @@ -4325,7 +4328,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)); } } @@ -4495,7 +4499,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()]; } } diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 984f227cebe79..c24a416a0109c 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -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, diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index e6e31ba0819c5..b436a5ee524ac 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -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; \ diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 495b8995ceea2..02c1f3973c61a 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -331,18 +331,21 @@ pub fn check_crate(tcx: &ty::ctxt, trait_map: ty::TraitMap) { tcx: tcx }; - 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(); + tcx.sess.abort_if_new_errors(|| { + time(time_passes, "type collecting", || + collect::collect_item_types(tcx)); + + }); time(time_passes, "variance inference", || variance::infer_variance(tcx)); - time(time_passes, "coherence checking", || - coherence::check_coherence(&ccx)); + 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)); diff --git a/src/test/compile-fail-fulldeps/qquote.rs b/src/test/compile-fail-fulldeps/qquote.rs index 7ffbbe69c3d6b..3e153a21e5d38 100644 --- a/src/test/compile-fail-fulldeps/qquote.rs +++ b/src/test/compile-fail-fulldeps/qquote.rs @@ -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 { diff --git a/src/test/compile-fail/associated-types-coherence-failure.rs b/src/test/compile-fail/associated-types-coherence-failure.rs index 915cb077787ea..6d68da54112f2 100644 --- a/src/test/compile-fail/associated-types-coherence-failure.rs +++ b/src/test/compile-fail/associated-types-coherence-failure.rs @@ -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 ::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) } } diff --git a/src/test/compile-fail/bogus-tag.rs b/src/test/compile-fail/bogus-tag.rs index 704d856f106b2..a1021500be3d7 100644 --- a/src/test/compile-fail/bogus-tag.rs +++ b/src/test/compile-fail/bogus-tag.rs @@ -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 } } diff --git a/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs b/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs index ce6baeb204c93..b08e4bad1e9c9 100644 --- a/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs +++ b/src/test/compile-fail/coherence-impl-trait-for-trait-object-safe.rs @@ -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() { } diff --git a/src/test/compile-fail/coherence-impls-copy.rs b/src/test/compile-fail/coherence-impls-copy.rs index 1be606c3546fd..9c210c132a313 100644 --- a/src/test/compile-fail/coherence-impls-copy.rs +++ b/src/test/compile-fail/coherence-impls-copy.rs @@ -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 diff --git a/src/test/compile-fail/coherence-impls-sized.rs b/src/test/compile-fail/coherence-impls-sized.rs index 2ac4bb0492b1f..167067cb5fc0a 100644 --- a/src/test/compile-fail/coherence-impls-sized.rs +++ b/src/test/compile-fail/coherence-impls-sized.rs @@ -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 diff --git a/src/test/compile-fail/duplicate-type-parameter.rs b/src/test/compile-fail/duplicate-type-parameter.rs index 42b67337c64e5..3b0f8ee5bda7a 100644 --- a/src/test/compile-fail/duplicate-type-parameter.rs +++ b/src/test/compile-fail/duplicate-type-parameter.rs @@ -33,6 +33,7 @@ trait Qux {} impl Qux for Option {} //~^ ERROR the name `T` is already used +//~^^ ERROR the type parameter `T` is not constrained fn main() { } diff --git a/src/test/compile-fail/inner-static-type-parameter.rs b/src/test/compile-fail/inner-static-type-parameter.rs index cf2a70deee513..56b681378cc9d 100644 --- a/src/test/compile-fail/inner-static-type-parameter.rs +++ b/src/test/compile-fail/inner-static-type-parameter.rs @@ -10,7 +10,7 @@ // see #9186 -enum Bar { What } +enum Bar { What } //~ ERROR parameter `T` is never used fn foo() { static a: Bar = Bar::What; diff --git a/src/test/compile-fail/issue-12796.rs b/src/test/compile-fail/issue-12796.rs index 2249741cdaac5..33fbdce4ee25a 100644 --- a/src/test/compile-fail/issue-12796.rs +++ b/src/test/compile-fail/issue-12796.rs @@ -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 } diff --git a/src/test/compile-fail/issue-14254.rs b/src/test/compile-fail/issue-14254.rs index ce5fa1f1fe1a5..5f8ccd0b0634e 100644 --- a/src/test/compile-fail/issue-14254.rs +++ b/src/test/compile-fail/issue-14254.rs @@ -11,7 +11,7 @@ trait Foo { fn bar(&self); fn baz(&self) { } - fn bah(_: Option) { } + fn bah(_: Option<&Self>) { } } struct BarTy { diff --git a/src/test/compile-fail/issue-19883.rs b/src/test/compile-fail/issue-19883.rs index c6ff82364b3e7..7ec3093a6e058 100644 --- a/src/test/compile-fail/issue-19883.rs +++ b/src/test/compile-fail/issue-19883.rs @@ -14,7 +14,7 @@ trait From { fn from(src: Src) -> >::Output; } -trait To { +trait To: Sized { fn to>(self) -> >::Dst //~^ ERROR use of undeclared associated type `From::Dst` diff --git a/src/test/compile-fail/issue-20427.rs b/src/test/compile-fail/issue-20427.rs index a4b25ab9e56b3..99dd22a888cb5 100644 --- a/src/test/compile-fail/issue-20427.rs +++ b/src/test/compile-fail/issue-20427.rs @@ -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, - } + }; } diff --git a/src/test/compile-fail/issue-23305.rs b/src/test/compile-fail/issue-23305.rs index 4b1010781ff3b..68f053c357bed 100644 --- a/src/test/compile-fail/issue-23305.rs +++ b/src/test/compile-fail/issue-23305.rs @@ -13,5 +13,6 @@ pub trait ToNbt { } impl ToNbt {} //~ ERROR use of `Self` outside of an impl or trait +//~^ WARNING the trait `ToNbt` cannot be made into an object fn main() {} diff --git a/src/test/compile-fail/issue-2356.rs b/src/test/compile-fail/issue-2356.rs index 48cc27e228940..6b81afe13c671 100644 --- a/src/test/compile-fail/issue-2356.rs +++ b/src/test/compile-fail/issue-2356.rs @@ -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); diff --git a/src/test/compile-fail/issue-28109.rs b/src/test/compile-fail/issue-28109.rs index 73163caa455fc..0d372d300154a 100644 --- a/src/test/compile-fail/issue-28109.rs +++ b/src/test/compile-fail/issue-28109.rs @@ -11,10 +11,12 @@ // Make sure that label for continue and break is spanned correctly fn main() { - continue - 'b //~ ERROR use of undeclared label - ; - break - 'c //~ ERROR use of undeclared label - ; + loop { + continue + 'b //~ ERROR use of undeclared label + ; + break + 'c //~ ERROR use of undeclared label + ; + } } diff --git a/src/test/compile-fail/issue-3021-d.rs b/src/test/compile-fail/issue-3021-d.rs index 594f68e1812af..ecc8ac34ecf2b 100644 --- a/src/test/compile-fail/issue-3021-d.rs +++ b/src/test/compile-fail/issue-3021-d.rs @@ -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; diff --git a/src/test/compile-fail/issue-3021.rs b/src/test/compile-fail/issue-3021.rs index 719eef1b63d5d..7cf772b072879 100644 --- a/src/test/compile-fail/issue-3021.rs +++ b/src/test/compile-fail/issue-3021.rs @@ -12,7 +12,7 @@ trait SipHash { fn reset(&self); } -fn siphash(k0 : u64) -> SipHash { +fn siphash(k0 : u64) { struct SipState { v0: u64, } diff --git a/src/test/compile-fail/issue-3214.rs b/src/test/compile-fail/issue-3214.rs index be49ca1fe06a7..27b7fb7527503 100644 --- a/src/test/compile-fail/issue-3214.rs +++ b/src/test/compile-fail/issue-3214.rs @@ -15,6 +15,8 @@ fn foo() { } impl Drop for foo { + //~^ ERROR wrong number of type arguments + //~^^ ERROR the type parameter `T` is not constrained fn drop(&mut self) {} } } diff --git a/src/test/compile-fail/issue-3521.rs b/src/test/compile-fail/issue-3521.rs index f06aa45ac38fd..34cd8cae2de32 100644 --- a/src/test/compile-fail/issue-3521.rs +++ b/src/test/compile-fail/issue-3521.rs @@ -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); diff --git a/src/test/compile-fail/issue-3973.rs b/src/test/compile-fail/issue-3973.rs index 2652fb5dfc2fd..1fda423e9ee8d 100644 --- a/src/test/compile-fail/issue-3973.rs +++ b/src/test/compile-fail/issue-3973.rs @@ -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 } diff --git a/src/test/compile-fail/issue-5927.rs b/src/test/compile-fail/issue-5927.rs index 0359248b36a49..e5f091d873df9 100644 --- a/src/test/compile-fail/issue-5927.rs +++ b/src/test/compile-fail/issue-5927.rs @@ -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); } diff --git a/src/test/compile-fail/issue-9725.rs b/src/test/compile-fail/issue-9725.rs index 1a3c926ba384b..f53122d19c1bd 100644 --- a/src/test/compile-fail/issue-9725.rs +++ b/src/test/compile-fail/issue-9725.rs @@ -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 } diff --git a/src/test/compile-fail/mod_file_correct_spans.rs b/src/test/compile-fail/mod_file_correct_spans.rs index 3b794da10536e..f8ea5dda18336 100644 --- a/src/test/compile-fail/mod_file_correct_spans.rs +++ b/src/test/compile-fail/mod_file_correct_spans.rs @@ -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 } diff --git a/src/test/compile-fail/opt-in-copy.rs b/src/test/compile-fail/opt-in-copy.rs index be321b6290354..bc18b52a0c1c9 100644 --- a/src/test/compile-fail/opt-in-copy.rs +++ b/src/test/compile-fail/opt-in-copy.rs @@ -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() {} diff --git a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs index cdb812790480c..284c08ef09b28 100644 --- a/src/test/compile-fail/resolve-inconsistent-binding-mode.rs +++ b/src/test/compile-fail/resolve-inconsistent-binding-mode.rs @@ -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(_) => {} } } diff --git a/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs b/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs index 341fe173a03f4..88f09233d107e 100644 --- a/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs +++ b/src/test/compile-fail/resolve-type-param-in-item-in-trait.rs @@ -15,6 +15,7 @@ trait TraitA { fn outer(self) { enum Foo { + //~^ 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 { struct Foo(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 { struct Foo { a: A } //~^ ERROR can't use type parameters from outer function //~^^ ERROR use of undeclared type name `A` + //~^^^ ERROR parameter `B` is never used } } diff --git a/src/test/compile-fail/syntax-extension-minor.rs b/src/test/compile-fail/syntax-extension-minor.rs index 506aed6b2ee1d..38a6834a9c460 100644 --- a/src/test/compile-fail/syntax-extension-minor.rs +++ b/src/test/compile-fail/syntax-extension-minor.rs @@ -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"); diff --git a/src/test/compile-fail/trait-safety-trait-impl-cc.rs b/src/test/compile-fail/trait-safety-trait-impl-cc.rs index 6050b549b656f..f30c8f521bdc7 100644 --- a/src/test/compile-fail/trait-safety-trait-impl-cc.rs +++ b/src/test/compile-fail/trait-safety-trait-impl-cc.rs @@ -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!(); } } diff --git a/src/test/compile-fail/trait-safety-trait-impl.rs b/src/test/compile-fail/trait-safety-trait-impl.rs index 1bd6d76360768..e846b660c2a17 100644 --- a/src/test/compile-fail/trait-safety-trait-impl.rs +++ b/src/test/compile-fail/trait-safety-trait-impl.rs @@ -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 From 9a2549ea9c2b0d85f2874b04d02308d499e6c0ca Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 12 Dec 2015 03:29:35 +0000 Subject: [PATCH 2/8] Remove unused imports --- src/compiletest/runtest.rs | 2 -- src/libcollections/btree/node.rs | 2 +- src/libcollections/string.rs | 2 +- src/libcollections/vec.rs | 2 +- src/libcore/slice.rs | 1 - src/librustc/lint/context.rs | 2 +- src/librustc/middle/infer/combine.rs | 1 - src/librustc/middle/infer/mod.rs | 5 ++--- src/librustc/middle/infer/region_inference/mod.rs | 2 +- src/librustc/middle/stability.rs | 2 +- src/librustc/middle/ty/mod.rs | 3 +-- src/librustc/util/ppaux.rs | 7 ++----- src/librustc_borrowck/borrowck/gather_loans/mod.rs | 2 +- src/librustc_borrowck/borrowck/mod.rs | 2 +- src/librustc_metadata/tls_context.rs | 2 +- src/librustc_privacy/lib.rs | 2 +- src/librustc_resolve/build_reduced_graph.rs | 4 ++-- src/librustc_resolve/lib.rs | 2 +- src/librustc_trans/save/dump_csv.rs | 3 +-- src/librustc_trans/trans/closure.rs | 2 +- src/librustc_trans/trans/debuginfo/gdb.rs | 1 - src/librustc_trans/trans/intrinsic.rs | 4 +--- src/librustc_trans/trans/meth.rs | 1 - src/librustc_typeck/check/mod.rs | 3 +-- src/librustc_typeck/check/regionck.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 1 - src/librustc_typeck/coherence/orphan.rs | 1 - src/librustc_typeck/coherence/overlap.rs | 2 +- src/librustc_typeck/coherence/unsafety.rs | 1 - src/librustc_typeck/lib.rs | 1 - src/libstd/collections/hash/map.rs | 1 - src/libstd/collections/hash/set.rs | 1 - src/libstd/sys/unix/fs.rs | 2 +- src/libsyntax/ast.rs | 2 +- src/libsyntax/attr.rs | 2 +- src/libsyntax/ext/cfg.rs | 1 - src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/ext/quote.rs | 4 ++-- src/libsyntax/ext/tt/macro_parser.rs | 2 +- src/libsyntax/ext/tt/transcribe.rs | 2 +- src/libsyntax/parse/parser.rs | 6 +++--- src/libtest/lib.rs | 2 -- 42 files changed, 35 insertions(+), 59 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 1b1f5115b6033..459b43b4ffe5d 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -8,8 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use self::TargetLocation::*; - use common::Config; use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind}; use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc}; diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 26479b3f559b9..198025536f0b0 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -23,7 +23,7 @@ use core::marker::PhantomData; use core::ops::{Deref, DerefMut, Index, IndexMut}; use core::ptr::Unique; use core::{slice, mem, ptr, cmp}; -use alloc::heap::{self, EMPTY}; +use alloc::heap; use borrow::Borrow; diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 8c0b52f71f820..05a4075f50024 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -23,7 +23,7 @@ use core::fmt; use core::hash; use core::iter::FromIterator; use core::mem; -use core::ops::{self, Deref, Add, Index}; +use core::ops::{self, Add}; use core::ptr; use core::slice; use core::str::pattern::Pattern; diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index ddad7533a081f..ab8dee31ee32b 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -68,7 +68,7 @@ use core::hash::{self, Hash}; use core::intrinsics::{arith_offset, assume, needs_drop}; use core::iter::FromIterator; use core::mem; -use core::ops::{Index, IndexMut, Deref}; +use core::ops::{Index, IndexMut}; use core::ops; use core::ptr; use core::slice; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index b17fac4d77162..635b296a645cb 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -48,7 +48,6 @@ use result::Result; use result::Result::{Ok, Err}; use ptr; use mem; -use mem::size_of; use marker::{Send, Sync, self}; use num::wrapping::OverflowingOps; use raw::Repr; diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 1ed873f0508d5..d7ac096b40735 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -26,7 +26,7 @@ use self::TargetLint::*; use middle::privacy::AccessLevels; -use middle::ty::{self, Ty}; +use middle::ty; use session::{early_error, Session}; use lint::{Level, LevelSource, Lint, LintId, LintArray, LintPass}; use lint::{EarlyLintPass, EarlyLintPassObject, LateLintPass, LateLintPassObject}; diff --git a/src/librustc/middle/infer/combine.rs b/src/librustc/middle/infer/combine.rs index 03554a59655b1..2a25ed2c6e144 100644 --- a/src/librustc/middle/infer/combine.rs +++ b/src/librustc/middle/infer/combine.rs @@ -41,7 +41,6 @@ use super::{InferCtxt}; use super::{MiscVariable, TypeTrace}; use super::type_variable::{RelationDir, BiTo, EqTo, SubtypeOf, SupertypeOf}; -use middle::ty::{TyVar}; use middle::ty::{IntType, UintType}; use middle::ty::{self, Ty}; use middle::ty::error::TypeError; diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index b39ddfe95c83a..6876b33036c72 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -27,10 +27,9 @@ use middle::region::CodeExtent; use middle::subst; use middle::subst::Substs; use middle::subst::Subst; -use middle::traits::{self, FulfillmentContext, Normalized, - SelectionContext, ObligationCause}; +use middle::traits; use middle::ty::adjustment; -use middle::ty::{TyVid, IntVid, FloatVid, RegionVid}; +use middle::ty::{TyVid, IntVid, FloatVid}; use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric}; use middle::ty::fold::{TypeFolder, TypeFoldable}; diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index f6068f1b64498..50b8cac5278c5 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -22,7 +22,7 @@ use super::{RegionVariableOrigin, SubregionOrigin, TypeTrace, MiscVariable}; use rustc_data_structures::graph::{self, Direction, NodeIndex}; use middle::free_region::FreeRegionMap; use middle::ty::{self, Ty}; -use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid}; +use middle::ty::{BoundRegion, Region, RegionVid}; use middle::ty::{ReEmpty, ReStatic, ReFree, ReEarlyBound}; use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh}; use middle::ty::error::TypeError; diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 0d92c3da83c8b..dc7ed2add32d2 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -29,7 +29,7 @@ use syntax::attr::{self, Stability, AttrMetaMethods}; use util::nodemap::{DefIdMap, FnvHashSet, FnvHashMap}; use rustc_front::hir; -use rustc_front::hir::{Block, Crate, Item, Generics, StructField, Variant}; +use rustc_front::hir::{Crate, Item, Generics, StructField, Variant}; use rustc_front::intravisit::{self, Visitor}; use std::mem::replace; diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index 7477c4dead031..b5f39747db15b 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -26,7 +26,7 @@ use middle::cstore::{self, CrateStore, LOCAL_CRATE}; use middle::def::{self, ExportMap}; use middle::def_id::DefId; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; -use middle::subst::{self, ParamSpace, Subst, Substs, VecPerParamSpace}; +use middle::subst::{self, Subst, Substs, VecPerParamSpace}; use middle::traits; use middle::ty; use middle::ty::fold::TypeFolder; @@ -51,7 +51,6 @@ use syntax::parse::token::{InternedString, special_idents}; use rustc_front::hir; use rustc_front::hir::{ItemImpl, ItemTrait}; -use rustc_front::hir::{MutImmutable, MutMutable, Visibility}; pub use self::sty::{Binder, DebruijnIndex}; pub use self::sty::{BuiltinBound, BuiltinBounds, ExistentialBounds}; diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 9db34eef91fd1..ab6d0ee74fca5 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -11,16 +11,13 @@ use middle::def_id::DefId; use middle::subst::{self, Subst}; -use middle::ty::{BoundRegion, BrAnon, BrNamed}; -use middle::ty::{ReEarlyBound, BrFresh, ctxt}; -use middle::ty::{ReFree, ReScope, ReStatic, Region, ReEmpty}; -use middle::ty::{ReSkolemized, ReVar, BrEnv}; +use middle::ty::{BrAnon, BrEnv, BrFresh, BrNamed}; use middle::ty::{TyBool, TyChar, TyStruct, TyEnum}; use middle::ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyBareFn}; use middle::ty::{TyParam, TyRawPtr, TyRef, TyTuple}; use middle::ty::TyClosure; use middle::ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer}; -use middle::ty::{self, TypeAndMut, Ty, HasTypeFlags}; +use middle::ty::{self, Ty, HasTypeFlags}; use middle::ty::fold::TypeFoldable; use std::fmt; diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 47f29a26db145..6fbbf45a38ea4 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -29,7 +29,7 @@ use syntax::ast; use syntax::codemap::Span; use syntax::ast::NodeId; use rustc_front::hir; -use rustc_front::hir::{Expr, FnDecl, Block, Pat}; +use rustc_front::hir::Expr; use rustc_front::intravisit; use rustc_front::intravisit::Visitor; diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index b727f10d276ac..d6c698dbe4225 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -38,7 +38,7 @@ use rustc::middle::ty::{self, Ty}; use std::fmt; use std::mem; use std::rc::Rc; -use syntax::ast::{self, NodeId}; +use syntax::ast; use syntax::codemap::Span; use rustc_front::hir; diff --git a/src/librustc_metadata/tls_context.rs b/src/librustc_metadata/tls_context.rs index e368ff3822a1d..eb82d2df94d15 100644 --- a/src/librustc_metadata/tls_context.rs +++ b/src/librustc_metadata/tls_context.rs @@ -16,7 +16,7 @@ use rbml::reader::Decoder as RbmlDecoder; use rustc::middle::cstore::tls; use rustc::middle::def_id::DefId; use rustc::middle::subst::Substs; -use rustc::middle::ty::{self, Ty}; +use rustc::middle::ty; use decoder::{self, Cmd}; use encoder; diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 9f70598198eb9..aee2ed81981a7 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -45,7 +45,7 @@ use rustc::middle::privacy::ImportUse::*; use rustc::middle::privacy::LastPrivate::*; use rustc::middle::privacy::PrivateDep::*; use rustc::middle::privacy::ExternalExports; -use rustc::middle::ty::{self, Ty}; +use rustc::middle::ty; use rustc::util::nodemap::NodeMap; use rustc::front::map as ast_map; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 0deef91a0f6b0..4ffbfa0e01e90 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -38,12 +38,12 @@ use syntax::parse::token::special_idents; use syntax::codemap::{Span, DUMMY_SP}; use rustc_front::hir; -use rustc_front::hir::{Block, Crate, DeclItem}; +use rustc_front::hir::{Block, DeclItem}; use rustc_front::hir::{ForeignItem, ForeignItemFn, ForeignItemStatic}; use rustc_front::hir::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn}; use rustc_front::hir::{ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl}; use rustc_front::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse}; -use rustc_front::hir::{NamedField, PathListIdent, PathListMod, Public}; +use rustc_front::hir::{NamedField, PathListIdent, PathListMod}; use rustc_front::hir::StmtDecl; use rustc_front::hir::UnnamedField; use rustc_front::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple}; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c32acb7bb269f..693a38c9e79cc 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -64,7 +64,7 @@ use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap}; use rustc::util::nodemap::{NodeMap, DefIdSet, FnvHashMap}; use syntax::ast; -use syntax::ast::{CRATE_NODE_ID, Ident, Name, NodeId, CrateNum, TyIs, TyI8, TyI16, TyI32, TyI64}; +use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, TyIs, TyI8, TyI16, TyI32, TyI64}; use syntax::ast::{TyUs, TyU8, TyU16, TyU32, TyU64, TyF64, TyF32}; use syntax::attr::AttrMetaMethods; use syntax::parse::token::{self, special_names, special_idents}; diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index 2964d87ec1c09..9494dee7230b2 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -34,10 +34,9 @@ use session::Session; use middle::def; use middle::def_id::DefId; -use middle::ty::{self, Ty}; +use middle::ty; use std::fs::File; -use std::path::Path; use syntax::ast::{self, NodeId}; use syntax::codemap::*; diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index c125ba30a51e8..e089a6e059ccd 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -20,7 +20,7 @@ use trans::build::*; use trans::callee::{self, ArgVals, Callee, TraitItem, MethodData}; use trans::cleanup::{CleanupMethods, CustomScope, ScopeId}; use trans::common::*; -use trans::datum::{self, Datum, rvalue_scratch_datum, Rvalue, ByValue}; +use trans::datum::{self, Datum, rvalue_scratch_datum, Rvalue}; use trans::debuginfo::{self, DebugLoc}; use trans::declare; use trans::expr; diff --git a/src/librustc_trans/trans/debuginfo/gdb.rs b/src/librustc_trans/trans/debuginfo/gdb.rs index 03b58fb2c474f..4e3fadd0fa911 100644 --- a/src/librustc_trans/trans/debuginfo/gdb.rs +++ b/src/librustc_trans/trans/debuginfo/gdb.rs @@ -11,7 +11,6 @@ // .debug_gdb_scripts binary section. use llvm; -use llvm::ValueRef; use trans::common::{C_bytes, CrateContext, C_i32}; use trans::declare; diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 27f5e31eaaf7c..66f53deffa9f6 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -14,7 +14,7 @@ use arena::TypedArena; use intrinsics::{self, Intrinsic}; use libc; use llvm; -use llvm::{SequentiallyConsistent, Acquire, Release, AtomicXchg, ValueRef, TypeKind}; +use llvm::{ValueRef, TypeKind}; use middle::infer; use middle::subst; use middle::subst::FnSpace; @@ -32,10 +32,8 @@ use trans::debuginfo::DebugLoc; use trans::declare; use trans::expr; use trans::glue; -use trans::type_of::*; use trans::type_of; use trans::machine; -use trans::machine::llsize_of; use trans::type_::Type; use middle::ty::{self, Ty, HasTypeFlags}; use middle::subst::Substs; diff --git a/src/librustc_trans/trans/meth.rs b/src/librustc_trans/trans/meth.rs index 123bd9f9c3765..049773f0becab 100644 --- a/src/librustc_trans/trans/meth.rs +++ b/src/librustc_trans/trans/meth.rs @@ -28,7 +28,6 @@ use trans::consts; use trans::datum::*; use trans::debuginfo::DebugLoc; use trans::declare; -use trans::expr::SaveIn; use trans::expr; use trans::glue; use trans::machine; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a50213202b82c..7593a9bdbcc48 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -93,7 +93,7 @@ use middle::pat_util::{self, pat_id_map}; use middle::privacy::{AllPublic, LastMod}; use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace}; use middle::traits::{self, report_fulfillment_errors}; -use middle::ty::{FnSig, GenericPredicates, TypeScheme}; +use middle::ty::{GenericPredicates, TypeScheme}; use middle::ty::{Disr, ParamTy, ParameterEnvironment}; use middle::ty::{LvaluePreference, NoPreference, PreferMutLvalue}; use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty}; @@ -127,7 +127,6 @@ use syntax::util::lev_distance::lev_distance; use rustc_front::intravisit::{self, Visitor}; use rustc_front::hir; use rustc_front::hir::Visibility; -use rustc_front::hir::{Item, ItemImpl}; use rustc_front::print::pprust; use rustc_back::slice; diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index f980945dbf220..5f01df3cf9aa3 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -92,7 +92,7 @@ use middle::mem_categorization::Categorization; use middle::region::CodeExtent; use middle::subst::Substs; use middle::traits; -use middle::ty::{self, RegionEscape, ReScope, Ty, MethodCall, HasTypeFlags}; +use middle::ty::{self, RegionEscape, Ty, MethodCall, HasTypeFlags}; use middle::infer::{self, GenericKind, InferCtxt, SubregionOrigin, TypeOrigin, VerifyBound}; use middle::pat_util; use middle::ty::adjustment; diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index cdbfda40813b4..37bbfb4e967f7 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -40,7 +40,6 @@ use syntax::codemap::Span; use syntax::parse::token; use util::nodemap::{DefIdMap, FnvHashMap}; use rustc::front::map as hir_map; -use rustc::front::map::NodeItem; use rustc_front::intravisit; use rustc_front::hir::{Item, ItemImpl,Crate}; use rustc_front::hir; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index e6e31ba0819c5..841836a199b22 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -19,7 +19,6 @@ use syntax::ast; use syntax::codemap::Span; use rustc_front::intravisit; use rustc_front::hir; -use rustc_front::hir::{Item, ItemImpl}; pub fn check(tcx: &ty::ctxt) { let mut orphan = OrphanChecker { tcx: tcx }; diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 693c8716ab58a..084ef8941f6f6 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -15,7 +15,7 @@ use middle::cstore::{CrateStore, LOCAL_CRATE}; use middle::def_id::DefId; use middle::traits; use middle::ty; -use middle::infer::{self, new_infer_ctxt}; +use middle::infer; use syntax::ast; use syntax::codemap::Span; use rustc_front::hir; diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 40b38ad88394b..936d26f920850 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -14,7 +14,6 @@ use middle::ty; use rustc_front::intravisit; use rustc_front::hir; -use rustc_front::hir::{Item, ItemImpl}; pub fn check(tcx: &ty::ctxt) { let mut orphan = UnsafetyChecker { tcx: tcx }; diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 495b8995ceea2..1fcbdfac93705 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -110,7 +110,6 @@ use util::common::time; use rustc_front::hir; use syntax::codemap::Span; -use syntax::print::pprust::*; use syntax::{ast, abi}; use std::cell::RefCell; diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 38c080febf196..9ab440f289e8a 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -24,7 +24,6 @@ use mem::{self, replace}; use ops::{Deref, FnMut, FnOnce, Index}; use option::Option::{self, Some, None}; use rand::{self, Rng}; -use result::Result; use super::table::{ self, diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 08f356463bc96..761709d41e77c 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -13,7 +13,6 @@ use clone::Clone; use cmp::{Eq, PartialEq}; use core::marker::Sized; use default::Default; -use fmt::Debug; use fmt; use hash::Hash; use iter::{Iterator, IntoIterator, ExactSizeIterator, FromIterator, Map, Chain, Extend}; diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 8ea8f0c6c771b..9ac11b442da39 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -14,7 +14,7 @@ use os::unix::prelude::*; use ffi::{CString, CStr, OsString, OsStr}; use fmt; use io::{self, Error, ErrorKind, SeekFrom}; -use libc::{self, c_int, size_t, off_t, c_char, mode_t}; +use libc::{self, c_int, off_t, c_char, mode_t}; use mem; use path::{Path, PathBuf}; use ptr; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f11291fc0f7e7..89ede0f82491d 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -52,7 +52,7 @@ use ast_util; use ext::base; use ext::tt::macro_parser; use owned_slice::OwnedSlice; -use parse::token::{InternedString, str_to_ident}; +use parse::token::InternedString; use parse::token; use parse::lexer; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index e828d8ae24874..a65a3412245ec 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -24,7 +24,7 @@ use config::CfgDiag; use diagnostic::SpanHandler; use feature_gate::{GatedCfg, GatedCfgAttr}; use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration}; -use parse::token::{InternedString, intern_and_get_ident}; +use parse::token::InternedString; use parse::token; use ptr::P; diff --git a/src/libsyntax/ext/cfg.rs b/src/libsyntax/ext/cfg.rs index e100355e4f868..39cd718faa9dd 100644 --- a/src/libsyntax/ext/cfg.rs +++ b/src/libsyntax/ext/cfg.rs @@ -18,7 +18,6 @@ use ext::base::*; use ext::base; use ext::build::AstBuilder; use attr; -use attr::*; use parse::token; use config::CfgDiagReal; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 573f4cfe8fa5d..bbc3e1ffb2904 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{Block, Crate, DeclLocal, ExprMac, PatMac}; +use ast::{Block, Crate, DeclLocal, PatMac}; use ast::{Local, Ident, Mac_, Name}; use ast::{ItemMac, MacStmtWithSemicolon, Mrk, Stmt, StmtDecl, StmtMac}; use ast::{StmtExpr, StmtSemi}; diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 496f6a429a31f..0c3a8b05fba1e 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{self, Arg, Arm, Block, Expr, Item, Pat, Path, Stmt, TokenTree, Ty}; +use ast::{self, Arg, Arm, Block, Expr, Item, Pat, Stmt, TokenTree, Ty}; use codemap::Span; use ext::base::ExtCtxt; use ext::base; @@ -33,7 +33,7 @@ pub mod rt { use ptr::P; use std::rc::Rc; - use ast::{TokenTree, Expr}; + use ast::TokenTree; pub use parse::new_parser_from_tts; pub use codemap::{BytePos, Span, dummy_spanned, DUMMY_SP}; diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 5b8307eb6c6f2..e280fbf2cd469 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -85,7 +85,7 @@ use codemap; use parse::lexer::*; //resolve bug? use parse::ParseSess; use parse::parser::{LifetimeAndTypesWithoutColons, Parser}; -use parse::token::{Eof, DocComment, MatchNt, SubstNt}; +use parse::token::{DocComment, MatchNt, SubstNt}; use parse::token::{Token, Nonterminal}; use parse::token; use print::pprust; diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 0fc31f3fd08af..1545a07d230cc 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -14,7 +14,7 @@ use ast::{TokenTree, Ident, Name}; use codemap::{Span, DUMMY_SP}; use diagnostic::SpanHandler; use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal}; -use parse::token::{Eof, DocComment, Interpolated, MatchNt, SubstNt}; +use parse::token::{DocComment, MatchNt, SubstNt}; use parse::token::{Token, NtIdent, SpecialMacroVar}; use parse::token; use parse::lexer::TokenAndSpan; diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7502a8cbc3546..f6519632c95d8 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -28,12 +28,12 @@ use ast::{ExprLit, ExprLoop, ExprMac, ExprRange}; use ast::{ExprMethodCall, ExprParen, ExprPath}; use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary}; use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl}; -use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRetTy}; +use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, FunctionRetTy}; use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic}; use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst}; use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy, ItemDefaultImpl}; use ast::{ItemExternCrate, ItemUse}; -use ast::{LifetimeDef, Lit, Lit_}; +use ast::{Lit, Lit_}; use ast::{LitBool, LitChar, LitByte, LitByteStr}; use ast::{LitStr, LitInt, Local}; use ast::{MacStmtWithBraces, MacStmtWithSemicolon, MacStmtWithoutBraces}; @@ -50,7 +50,7 @@ use ast::{SelfExplicit, SelfRegion, SelfStatic, SelfValue}; use ast::{Delimited, SequenceRepetition, TokenTree, TraitItem, TraitRef}; use ast::{Ty, Ty_, TypeBinding, TyMac}; use ast::{TyFixedLengthVec, TyBareFn, TyTypeof, TyInfer}; -use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr}; +use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPtr}; use ast::{TyRptr, TyTup, TyU32, TyVec}; use ast::TypeTraitItem; use ast::{UnnamedField, UnsafeBlock}; diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 7ffe567ac83c1..365f67e561628 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -59,11 +59,9 @@ use self::NamePadding::*; use self::OutputLocation::*; use stats::Stats; -use getopts::{OptGroup, optflag, optopt}; use serialize::Encodable; use std::boxed::FnBox; use term::Terminal; -use term::color::{Color, RED, YELLOW, GREEN, CYAN}; use std::any::Any; use std::cmp; From 83dde14a45f9718b9edaf60f2e163747e4488e0f Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Sat, 12 Dec 2015 03:30:53 +0000 Subject: [PATCH 3/8] rustc_resolve: fix a bug in which unused imports can get wrongly marked as used when checking for unused qualifications in resolve_path (fixes #30078) --- src/librustc_resolve/lib.rs | 35 +++++++++++--------- src/test/compile-fail/lint-qualification.rs | 1 + src/test/compile-fail/lint-unused-imports.rs | 5 ++- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 693a38c9e79cc..993e5ffdb5c25 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1462,7 +1462,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_item_in_lexical_scope(&mut self, module_: Rc, name: Name, - namespace: Namespace) + namespace: Namespace, + record_used: bool) -> ResolveResult<(Target, bool)> { debug!("(resolving item in lexical scope) resolving `{}` in namespace {:?} in `{}`", name, @@ -1502,10 +1503,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { debug!("(resolving item in lexical scope) using import resolution"); // track used imports and extern crates as well let id = import_resolution[namespace].id; - self.used_imports.insert((id, namespace)); - self.record_import_use(id, name); - if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() { - self.used_crates.insert(kid); + if record_used { + self.used_imports.insert((id, namespace)); + self.record_import_use(id, name); + if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() { + self.used_crates.insert(kid); + } } return Success((target, false)); } @@ -1582,7 +1585,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { -> ResolveResult> { // If this module is an anonymous module, resolve the item in the // lexical scope. Otherwise, resolve the item from the crate root. - let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS); + let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS, true); match resolve_result { Success((target, _)) => { if let Some(module_def) = target.binding.module() { @@ -2776,7 +2779,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { span: Span) -> BareIdentifierPatternResolution { let module = self.current_module.clone(); - match self.resolve_item_in_lexical_scope(module, name, ValueNS) { + match self.resolve_item_in_lexical_scope(module, name, ValueNS, true) { Success((target, _)) => { debug!("(resolve bare identifier pattern) succeeded in finding {} at {:?}", name, @@ -2884,17 +2887,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } // Try to find a path to an item in a module. - let unqualified_def = self.resolve_identifier(segments.last().unwrap().identifier, - namespace, - check_ribs); - + let last_ident = segments.last().unwrap().identifier; if segments.len() <= 1 { + let unqualified_def = self.resolve_identifier(last_ident, namespace, check_ribs, true); return unqualified_def.and_then(|def| self.adjust_local_def(def, span)) .map(|def| { PathResolution::new(def, LastMod(AllPublic), path_depth) }); } + let unqualified_def = self.resolve_identifier(last_ident, namespace, check_ribs, false); let def = self.resolve_module_relative_path(span, segments, namespace); match (def, unqualified_def) { (Some((ref d, _)), Some(ref ud)) if *d == ud.def => { @@ -2914,7 +2916,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_identifier(&mut self, identifier: hir::Ident, namespace: Namespace, - check_ribs: bool) + check_ribs: bool, + record_used: bool) -> Option { // First, check to see whether the name is a primitive type. if namespace == TypeNS { @@ -2931,7 +2934,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - self.resolve_item_by_name_in_lexical_scope(identifier.unhygienic_name, namespace) + let name = identifier.unhygienic_name; + self.resolve_item_by_name_in_lexical_scope(name, namespace, record_used) .map(LocalDef::from_def) } @@ -3182,11 +3186,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_item_by_name_in_lexical_scope(&mut self, name: Name, - namespace: Namespace) + namespace: Namespace, + record_used: bool) -> Option { // Check the items. let module = self.current_module.clone(); - match self.resolve_item_in_lexical_scope(module, name, namespace) { + match self.resolve_item_in_lexical_scope(module, name, namespace, record_used) { Success((target, _)) => { match target.binding.def() { None => { diff --git a/src/test/compile-fail/lint-qualification.rs b/src/test/compile-fail/lint-qualification.rs index 18a5a8ecc5d52..0ad3d2c5e7317 100644 --- a/src/test/compile-fail/lint-qualification.rs +++ b/src/test/compile-fail/lint-qualification.rs @@ -17,4 +17,5 @@ mod foo { fn main() { use foo::bar; foo::bar(); //~ ERROR: unnecessary qualification + bar(); } diff --git a/src/test/compile-fail/lint-unused-imports.rs b/src/test/compile-fail/lint-unused-imports.rs index 1468ae64d9418..35883293990a3 100644 --- a/src/test/compile-fail/lint-unused-imports.rs +++ b/src/test/compile-fail/lint-unused-imports.rs @@ -50,11 +50,14 @@ mod foo { mod bar { // Don't ignore on 'pub use' because we're not sure if it's used or not pub use std::cmp::PartialEq; + pub struct Square; pub mod c { use foo::Point; use foo::Square; //~ ERROR unused import - pub fn cc(p: Point) -> isize { return 2 * (p.x + p.y); } + pub fn cc(_p: Point) -> super::Square { + super::Square + } } #[allow(unused_imports)] From 08bffdd5c0c0916d9caed05f42419076e1e89359 Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Sat, 12 Dec 2015 19:02:33 +0200 Subject: [PATCH 4/8] fix dropck performance regression Turns out that calling `resolve_type_variables_if_possible` in a O(n^2) loop is a bad idea. Now we just resolve each copy of the region variable to its lowest name each time (we resolve the region variable to its lowest name, rather than to its unify-table name to avoid the risk of the unify-table name changing infinitely many times. That may be not a problem in practice, but I am not sure of it). --- .../middle/infer/region_inference/mod.rs | 12 +++++--- src/librustc/middle/infer/unify_key.rs | 24 +++++++++++++-- src/librustc_data_structures/unify/mod.rs | 21 ++++++++++++-- src/librustc_typeck/check/dropck.rs | 29 +++++++++---------- 4 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 30cf6344e2332..e148aecd241f2 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -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 { diff --git a/src/librustc/middle/infer/unify_key.rs b/src/librustc/middle/infer/unify_key.rs index 85d7d67a0e3ca..c83231930f502 100644 --- a/src/librustc/middle/infer/unify_key.rs +++ b/src/librustc/middle/infer/unify_key.rs @@ -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) -> &'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) -> &'static str { "RegionVid" } diff --git a/src/librustc_data_structures/unify/mod.rs b/src/librustc_data_structures/unify/mod.rs index 4d79b1a64c191..c6da70eef750a 100644 --- a/src/librustc_data_structures/unify/mod.rs +++ b/src/librustc_data_structures/unify/mod.rs @@ -37,6 +37,16 @@ pub trait UnifyKey : Copy + Clone + Debug + PartialEq { fn tag(k: Option) -> &'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 sv::SnapshotVecDelegate for Delegate { /////////////////////////////////////////////////////////////////////////// // Base union-find algorithm, where we are just making sets -impl<'tcx,K> UnificationTable - where K : UnifyKey, +impl<'tcx,K:UnifyKey> UnificationTable + 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 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 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) } diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index 0fbe83674931c..59025346ce3bd 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -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>, + breadcrumbs: FnvHashSet>, /// 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 { - debug!("iterate_over_potentially_unsafe_regions_in_type \ - {}ty: {} scope: {:?} - cached", - (0..depth).map(|_| ' ').collect::(), - ty, cx.parent_scope); - return Ok(()); // we already visited this type - } - } - cx.breadcrumbs.push(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::(), + ty, cx.parent_scope); + return Ok(()); // we already visited this type + } debug!("iterate_over_potentially_unsafe_regions_in_type \ {}ty: {} scope: {:?}", (0..depth).map(|_| ' ').collect::(), From 37b8e22c681a092510e150e5eb5268e749a5a34b Mon Sep 17 00:00:00 2001 From: Ori Avtalion Date: Mon, 14 Dec 2015 00:12:17 +0200 Subject: [PATCH 5/8] Add links in BTreeSet docs --- src/libcollections/btree/set.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index a2c09c36795e4..12d3465e5188d 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -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 { From 2dcd791d46523e75da5c594033383e90c08d4ae3 Mon Sep 17 00:00:00 2001 From: Daniel Campbell Date: Tue, 15 Dec 2015 17:31:54 +1300 Subject: [PATCH 6/8] Generated code spans now point to callsite parameters (where applicable) --- src/libsyntax/ext/tt/macro_parser.rs | 9 +++++--- src/libsyntax/ext/tt/transcribe.rs | 4 ++-- src/libsyntax/fold.rs | 3 ++- src/libsyntax/parse/token.rs | 2 +- src/libsyntax/print/pprust.rs | 2 +- src/test/compile-fail/macro-parameter-span.rs | 23 +++++++++++++++++++ 6 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 src/test/compile-fail/macro-parameter-span.rs diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 5b8307eb6c6f2..16764e5af5cce 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -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::{node: sn, span: p.span}),b) + } _ => { let token_str = pprust::token_to_string(&p.token); panic!(p.fatal(&format!("expected ident, found {}", diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 0fc31f3fd08af..ba781ae3cc212 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -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) => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 73f2c51b24622..944dd44a0b6c4 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -663,7 +663,8 @@ pub fn noop_fold_interpolated(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::{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))), diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 17b7d8dbaece9..b942954c1874a 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -377,7 +377,7 @@ pub enum Nonterminal { NtPat(P), NtExpr(P), NtTy(P), - NtIdent(Box, IdentStyle), + NtIdent(Box, IdentStyle), /// Stuff inside brackets for attributes NtMeta(P), NtPath(Box), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index f710595129672..d3c570de248c0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -296,7 +296,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), diff --git a/src/test/compile-fail/macro-parameter-span.rs b/src/test/compile-fail/macro-parameter-span.rs new file mode 100644 index 0000000000000..2ef697591284d --- /dev/null +++ b/src/test/compile-fail/macro-parameter-span.rs @@ -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 or the MIT license +// , 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` + ); +} From 9a0ab50ac08a01cea1d4170fa90dc851f42971c7 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Tue, 15 Dec 2015 16:15:59 +0100 Subject: [PATCH 7/8] Stop re-exporting RestrictionResult variants. --- .../borrowck/gather_loans/mod.rs | 6 +++-- .../borrowck/gather_loans/restrictions.rs | 22 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs index 47f29a26db145..c07a27043c275 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs @@ -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, diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index cb75180b47466..2a0d8ef276648 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -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) } } } From 88ed7b7b8a286309a349d349c625adcec64d1a27 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Tue, 15 Dec 2015 21:35:11 -0500 Subject: [PATCH 8/8] add tests for #26873 --- src/test/run-pass/issue-26873-multifile.rs | 14 +++++++++ src/test/run-pass/issue-26873-onefile.rs | 31 +++++++++++++++++++ .../run-pass/issue_26873_multifile/A/B.rs | 14 +++++++++ .../run-pass/issue_26873_multifile/A/C.rs | 16 ++++++++++ .../run-pass/issue_26873_multifile/A/mod.rs | 15 +++++++++ .../run-pass/issue_26873_multifile/mod.rs | 14 +++++++++ 6 files changed, 104 insertions(+) create mode 100644 src/test/run-pass/issue-26873-multifile.rs create mode 100644 src/test/run-pass/issue-26873-onefile.rs create mode 100644 src/test/run-pass/issue_26873_multifile/A/B.rs create mode 100644 src/test/run-pass/issue_26873_multifile/A/C.rs create mode 100644 src/test/run-pass/issue_26873_multifile/A/mod.rs create mode 100644 src/test/run-pass/issue_26873_multifile/mod.rs diff --git a/src/test/run-pass/issue-26873-multifile.rs b/src/test/run-pass/issue-26873-multifile.rs new file mode 100644 index 0000000000000..e3da52203ced3 --- /dev/null +++ b/src/test/run-pass/issue-26873-multifile.rs @@ -0,0 +1,14 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod issue_26873_multifile; + +fn main() {} + diff --git a/src/test/run-pass/issue-26873-onefile.rs b/src/test/run-pass/issue-26873-onefile.rs new file mode 100644 index 0000000000000..a9a04fd889455 --- /dev/null +++ b/src/test/run-pass/issue-26873-onefile.rs @@ -0,0 +1,31 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod A { + pub mod B { + use super::*; + + pub struct S; + } + + pub mod C { + use super::*; + use super::B::S; + + pub struct T; + } + + pub use self::C::T; +} + +use A::*; + +fn main() {} + diff --git a/src/test/run-pass/issue_26873_multifile/A/B.rs b/src/test/run-pass/issue_26873_multifile/A/B.rs new file mode 100644 index 0000000000000..8917a98b8cf3f --- /dev/null +++ b/src/test/run-pass/issue_26873_multifile/A/B.rs @@ -0,0 +1,14 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::*; + +pub struct S; + diff --git a/src/test/run-pass/issue_26873_multifile/A/C.rs b/src/test/run-pass/issue_26873_multifile/A/C.rs new file mode 100644 index 0000000000000..64aaf9c279865 --- /dev/null +++ b/src/test/run-pass/issue_26873_multifile/A/C.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::*; + +use super::B::S; + +pub struct T { i: i32 } + diff --git a/src/test/run-pass/issue_26873_multifile/A/mod.rs b/src/test/run-pass/issue_26873_multifile/A/mod.rs new file mode 100644 index 0000000000000..a2aeb1cc43f98 --- /dev/null +++ b/src/test/run-pass/issue_26873_multifile/A/mod.rs @@ -0,0 +1,15 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub mod B; +pub mod C; + +pub use self::C::T; + diff --git a/src/test/run-pass/issue_26873_multifile/mod.rs b/src/test/run-pass/issue_26873_multifile/mod.rs new file mode 100644 index 0000000000000..3643b94e31a85 --- /dev/null +++ b/src/test/run-pass/issue_26873_multifile/mod.rs @@ -0,0 +1,14 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod A; + +use self::A::*; +