1
Fork 0

Auto merge of #40826 - frewsxcv:rollup, r=frewsxcv

Rollup of 7 pull requests

- Successful merges: #40642, #40734, #40740, #40771, #40807, #40820, #40821
- Failed merges:
This commit is contained in:
bors 2017-03-26 14:04:25 +00:00
commit 7846dbe0c8
26 changed files with 236 additions and 142 deletions

View file

@ -6,5 +6,15 @@ The tracking issue for this feature is: [#28237]
------------------------ ------------------------
To get a range that goes from 0 to 10 and includes the value 10, you
can write `0...10`:
```rust
#![feature(inclusive_range_syntax)]
fn main() {
for i in 0...10 {
println!("{}", i);
}
}
```

View file

@ -141,7 +141,7 @@ pub fn fast_path<T: RawFloat>(integral: &[u8], fractional: &[u8], e: i64) -> Opt
/// ///
/// It rounds ``f`` to a float with 64 bit significand and multiplies it by the best approximation /// It rounds ``f`` to a float with 64 bit significand and multiplies it by the best approximation
/// of `10^e` (in the same floating point format). This is often enough to get the correct result. /// of `10^e` (in the same floating point format). This is often enough to get the correct result.
/// However, when the result is close to halfway between two adjecent (ordinary) floats, the /// However, when the result is close to halfway between two adjacent (ordinary) floats, the
/// compound rounding error from multiplying two approximation means the result may be off by a /// compound rounding error from multiplying two approximation means the result may be off by a
/// few bits. When this happens, the iterative Algorithm R fixes things up. /// few bits. When this happens, the iterative Algorithm R fixes things up.
/// ///
@ -392,7 +392,7 @@ fn underflow<T: RawFloat>(x: Big, v: Big, rem: Big) -> T {
// //
// Therefore, when the rounded-off bits are != 0.5 ULP, they decide the rounding // Therefore, when the rounded-off bits are != 0.5 ULP, they decide the rounding
// on their own. When they are equal and the remainder is non-zero, the value still // on their own. When they are equal and the remainder is non-zero, the value still
// needs to be rounded up. Only when the rounded off bits are 1/2 and the remainer // needs to be rounded up. Only when the rounded off bits are 1/2 and the remainder
// is zero, we have a half-to-even situation. // is zero, we have a half-to-even situation.
let bits = x.bit_length(); let bits = x.bit_length();
let lsb = bits - T::sig_bits() as usize; let lsb = bits - T::sig_bits() as usize;

View file

@ -152,8 +152,8 @@ fn partial_insertion_sort<T, F>(v: &mut [T], is_less: &mut F) -> bool
fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F) fn insertion_sort<T, F>(v: &mut [T], is_less: &mut F)
where F: FnMut(&T, &T) -> bool where F: FnMut(&T, &T) -> bool
{ {
for i in 2..v.len()+1 { for i in 1..v.len() {
shift_tail(&mut v[..i], is_less); shift_tail(&mut v[..i+1], is_less);
} }
} }

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use hir::def_id::CrateNum;
use std::fmt::Debug; use std::fmt::Debug;
use std::sync::Arc; use std::sync::Arc;
@ -81,7 +82,7 @@ pub enum DepNode<D: Clone + Debug> {
TypeckItemType(D), TypeckItemType(D),
UnusedTraitCheck, UnusedTraitCheck,
CheckConst(D), CheckConst(D),
Privacy, PrivacyAccessLevels(CrateNum),
IntrinsicCheck(D), IntrinsicCheck(D),
MatchCheck(D), MatchCheck(D),
@ -230,7 +231,7 @@ impl<D: Clone + Debug> DepNode<D> {
CheckEntryFn => Some(CheckEntryFn), CheckEntryFn => Some(CheckEntryFn),
Variance => Some(Variance), Variance => Some(Variance),
UnusedTraitCheck => Some(UnusedTraitCheck), UnusedTraitCheck => Some(UnusedTraitCheck),
Privacy => Some(Privacy), PrivacyAccessLevels(k) => Some(PrivacyAccessLevels(k)),
Reachability => Some(Reachability), Reachability => Some(Reachability),
DeadCheck => Some(DeadCheck), DeadCheck => Some(DeadCheck),
LateLintCheck => Some(LateLintCheck), LateLintCheck => Some(LateLintCheck),

View file

@ -101,11 +101,15 @@ impl<D: Clone + Debug + Eq + Hash> DepGraphEdges<D> {
} }
/// Indicates that the current task `C` reads `v` by adding an /// Indicates that the current task `C` reads `v` by adding an
/// edge from `v` to `C`. If there is no current task, panics. If /// edge from `v` to `C`. If there is no current task, has no
/// you want to suppress this edge, use `ignore`. /// effect. Note that *reading* from tracked state is harmless if
/// you are not in a task; what is bad is *writing* to tracked
/// state (and leaking data that you read into a tracked task).
pub fn read(&mut self, v: DepNode<D>) { pub fn read(&mut self, v: DepNode<D>) {
let source = self.make_node(v); if self.current_node().is_some() {
self.add_edge_from_current_node(|current| (source, current)) let source = self.make_node(v);
self.add_edge_from_current_node(|current| (source, current))
}
} }
/// Indicates that the current task `C` writes `v` by adding an /// Indicates that the current task `C` writes `v` by adding an

View file

@ -80,7 +80,13 @@ impl ShadowGraph {
let mut stack = self.stack.borrow_mut(); let mut stack = self.stack.borrow_mut();
match *message { match *message {
DepMessage::Read(ref n) => self.check_edge(Some(Some(n)), top(&stack)), // It is ok to READ shared state outside of a
// task. That can't do any harm (at least, the only
// way it can do harm is by leaking that data into a
// query or task, which would be a problem
// anyway). What would be bad is WRITING to that
// state.
DepMessage::Read(_) => { }
DepMessage::Write(ref n) => self.check_edge(top(&stack), Some(Some(n))), DepMessage::Write(ref n) => self.check_edge(top(&stack), Some(Some(n))),
DepMessage::PushTask(ref n) => stack.push(Some(n.clone())), DepMessage::PushTask(ref n) => stack.push(Some(n.clone())),
DepMessage::PushIgnore => stack.push(None), DepMessage::PushIgnore => stack.push(None),
@ -116,7 +122,7 @@ impl ShadowGraph {
(None, None) => unreachable!(), (None, None) => unreachable!(),
// nothing on top of the stack // nothing on top of the stack
(None, Some(n)) | (Some(n), None) => bug!("read/write of {:?} but no current task", n), (None, Some(n)) | (Some(n), None) => bug!("write of {:?} but no current task", n),
// this corresponds to an Ignore being top of the stack // this corresponds to an Ignore being top of the stack
(Some(None), _) | (_, Some(None)) => (), (Some(None), _) | (_, Some(None)) => (),

View file

@ -159,6 +159,10 @@ impl Lifetime {
pub fn is_elided(&self) -> bool { pub fn is_elided(&self) -> bool {
self.name == keywords::Invalid.name() self.name == keywords::Invalid.name()
} }
pub fn is_static(&self) -> bool {
self.name == keywords::StaticLifetime.name()
}
} }
/// A lifetime definition, eg `'a: 'b+'c+'d` /// A lifetime definition, eg `'a: 'b+'c+'d`

View file

@ -44,9 +44,10 @@ use std::ops::Deref;
use syntax::attr; use syntax::attr;
use syntax::ast; use syntax::ast;
use syntax::symbol::Symbol; use syntax::symbol::Symbol;
use syntax_pos::{MultiSpan, Span}; use syntax_pos::{DUMMY_SP, MultiSpan, Span};
use errors::{self, Diagnostic, DiagnosticBuilder}; use errors::{self, Diagnostic, DiagnosticBuilder};
use hir; use hir;
use hir::def_id::LOCAL_CRATE;
use hir::intravisit as hir_visit; use hir::intravisit as hir_visit;
use syntax::visit as ast_visit; use syntax::visit as ast_visit;
@ -1231,10 +1232,11 @@ fn check_lint_name_cmdline(sess: &Session, lint_cx: &LintStore,
/// Perform lint checking on a crate. /// Perform lint checking on a crate.
/// ///
/// Consumes the `lint_store` field of the `Session`. /// Consumes the `lint_store` field of the `Session`.
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
access_levels: &AccessLevels) {
let _task = tcx.dep_graph.in_task(DepNode::LateLintCheck); let _task = tcx.dep_graph.in_task(DepNode::LateLintCheck);
let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
let krate = tcx.hir.krate(); let krate = tcx.hir.krate();
// We want to own the lint store, so move it out of the session. // We want to own the lint store, so move it out of the session.

View file

@ -255,8 +255,8 @@ pub trait CrateStore {
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>; fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource; fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>; fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, fn encode_metadata<'a, 'tcx>(&self,
reexports: &def::ExportMap, tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta, link_meta: &LinkMeta,
reachable: &NodeSet) -> Vec<u8>; reachable: &NodeSet) -> Vec<u8>;
fn metadata_encoding_version(&self) -> &[u8]; fn metadata_encoding_version(&self) -> &[u8];
@ -412,10 +412,10 @@ impl CrateStore for DummyCrateStore {
{ vec![] } { vec![] }
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") } fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None } fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, fn encode_metadata<'a, 'tcx>(&self,
reexports: &def::ExportMap, tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta, link_meta: &LinkMeta,
reachable: &NodeSet) -> Vec<u8> { vec![] } reachable: &NodeSet) -> Vec<u8> { vec![] }
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") } fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
} }

View file

@ -21,12 +21,13 @@ use hir::itemlikevisit::ItemLikeVisitor;
use middle::privacy; use middle::privacy;
use ty::{self, TyCtxt}; use ty::{self, TyCtxt};
use hir::def::Def; use hir::def::Def;
use hir::def_id::{DefId}; use hir::def_id::{DefId, LOCAL_CRATE};
use lint; use lint;
use util::nodemap::FxHashSet; use util::nodemap::FxHashSet;
use syntax::{ast, codemap}; use syntax::{ast, codemap};
use syntax::attr; use syntax::attr;
use syntax::codemap::DUMMY_SP;
use syntax_pos; use syntax_pos;
// Any local node that may call something in its body block should be // Any local node that may call something in its body block should be
@ -592,9 +593,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
} }
} }
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
access_levels: &privacy::AccessLevels) {
let _task = tcx.dep_graph.in_task(DepNode::DeadCheck); let _task = tcx.dep_graph.in_task(DepNode::DeadCheck);
let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
let krate = tcx.hir.krate(); let krate = tcx.hir.krate();
let live_symbols = find_live(tcx, access_levels, krate); let live_symbols = find_live(tcx, access_levels, krate);
let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols }; let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols };

View file

@ -27,7 +27,9 @@ use util::nodemap::{NodeSet, FxHashSet};
use syntax::abi::Abi; use syntax::abi::Abi;
use syntax::ast; use syntax::ast;
use syntax::attr; use syntax::attr;
use syntax::codemap::DUMMY_SP;
use hir; use hir;
use hir::def_id::LOCAL_CRATE;
use hir::intravisit::{Visitor, NestedVisitorMap}; use hir::intravisit::{Visitor, NestedVisitorMap};
use hir::itemlikevisit::ItemLikeVisitor; use hir::itemlikevisit::ItemLikeVisitor;
use hir::intravisit; use hir::intravisit;
@ -359,11 +361,11 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
} }
} }
pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet {
access_levels: &privacy::AccessLevels)
-> NodeSet {
let _task = tcx.dep_graph.in_task(DepNode::Reachability); let _task = tcx.dep_graph.in_task(DepNode::Reachability);
let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| { let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
*ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib || *ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib ||
*ty == config::CrateTypeProcMacro *ty == config::CrateTypeProcMacro

View file

@ -29,7 +29,7 @@ use syntax::ast;
use syntax::attr; use syntax::attr;
use syntax::ptr::P; use syntax::ptr::P;
use syntax::symbol::keywords; use syntax::symbol::keywords;
use syntax_pos::Span; use syntax_pos::{mk_sp, Span};
use errors::DiagnosticBuilder; use errors::DiagnosticBuilder;
use util::nodemap::{NodeMap, NodeSet, FxHashSet, FxHashMap, DefIdMap}; use util::nodemap::{NodeMap, NodeSet, FxHashSet, FxHashMap, DefIdMap};
use rustc_back::slice; use rustc_back::slice;
@ -434,7 +434,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
self.resolve_elided_lifetimes(slice::ref_slice(lifetime_ref)); self.resolve_elided_lifetimes(slice::ref_slice(lifetime_ref));
return; return;
} }
if lifetime_ref.name == keywords::StaticLifetime.name() { if lifetime_ref.is_static() {
self.insert_lifetime(lifetime_ref, Region::Static); self.insert_lifetime(lifetime_ref, Region::Static);
return; return;
} }
@ -1434,7 +1434,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
let lifetime_i = &lifetimes[i]; let lifetime_i = &lifetimes[i];
for lifetime in lifetimes { for lifetime in lifetimes {
if lifetime.lifetime.name == keywords::StaticLifetime.name() { if lifetime.lifetime.is_static() {
let lifetime = lifetime.lifetime; let lifetime = lifetime.lifetime;
let mut err = struct_span_err!(self.sess, lifetime.span, E0262, let mut err = struct_span_err!(self.sess, lifetime.span, E0262,
"invalid lifetime parameter name: `{}`", lifetime.name); "invalid lifetime parameter name: `{}`", lifetime.name);
@ -1464,7 +1464,17 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
self.check_lifetime_def_for_shadowing(old_scope, &lifetime_i.lifetime); self.check_lifetime_def_for_shadowing(old_scope, &lifetime_i.lifetime);
for bound in &lifetime_i.bounds { for bound in &lifetime_i.bounds {
self.resolve_lifetime_ref(bound); if !bound.is_static() {
self.resolve_lifetime_ref(bound);
} else {
self.insert_lifetime(bound, Region::Static);
let full_span = mk_sp(lifetime_i.lifetime.span.lo, bound.span.hi);
self.sess.struct_span_warn(full_span,
&format!("unnecessary lifetime parameter `{}`", lifetime_i.lifetime.name))
.help(&format!("you can use the `'static` lifetime directly, in place \
of `{}`", lifetime_i.lifetime.name))
.emit();
}
} }
} }
} }

View file

@ -656,10 +656,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// Given the list of enabled features that were not language features (i.e. that /// Given the list of enabled features that were not language features (i.e. that
/// were expected to be library features), and the list of features used from /// were expected to be library features), and the list of features used from
/// libraries, identify activated features that don't exist and error about them. /// libraries, identify activated features that don't exist and error about them.
pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
access_levels: &AccessLevels) {
let sess = &tcx.sess; let sess = &tcx.sess;
let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
if tcx.stability.borrow().staged_api[&LOCAL_CRATE] && tcx.sess.features.borrow().staged_api { if tcx.stability.borrow().staged_api[&LOCAL_CRATE] && tcx.sess.features.borrow().staged_api {
let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex); let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex);
let krate = tcx.hir.krate(); let krate = tcx.hir.krate();

View file

@ -15,7 +15,7 @@ use session::Session;
use lint; use lint;
use middle; use middle;
use hir::TraitMap; use hir::TraitMap;
use hir::def::Def; use hir::def::{Def, ExportMap};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use hir::map as hir_map; use hir::map as hir_map;
use hir::map::DisambiguatedDefPathData; use hir::map::DisambiguatedDefPathData;
@ -416,6 +416,9 @@ pub struct GlobalCtxt<'tcx> {
/// is relevant; generated by resolve. /// is relevant; generated by resolve.
pub trait_map: TraitMap, pub trait_map: TraitMap,
/// Export map produced by name resolution.
pub export_map: ExportMap,
pub named_region_map: resolve_lifetime::NamedRegionMap, pub named_region_map: resolve_lifetime::NamedRegionMap,
pub region_maps: RegionMaps, pub region_maps: RegionMaps,
@ -698,6 +701,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
region_maps: region_maps, region_maps: region_maps,
variance_computed: Cell::new(false), variance_computed: Cell::new(false),
trait_map: resolutions.trait_map, trait_map: resolutions.trait_map,
export_map: resolutions.export_map,
fulfilled_predicates: RefCell::new(fulfilled_predicates), fulfilled_predicates: RefCell::new(fulfilled_predicates),
hir: hir, hir: hir,
maps: maps::Maps::new(dep_graph, providers), maps: maps::Maps::new(dep_graph, providers),

View file

@ -11,6 +11,7 @@
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig}; use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use middle::const_val::ConstVal; use middle::const_val::ConstVal;
use middle::privacy::AccessLevels;
use mir; use mir;
use ty::{self, Ty, TyCtxt}; use ty::{self, Ty, TyCtxt};
@ -189,6 +190,12 @@ impl<'tcx> QueryDescription for queries::mir_shims<'tcx> {
} }
} }
impl<'tcx> QueryDescription for queries::privacy_access_levels<'tcx> {
fn describe(_: TyCtxt, _: CrateNum) -> String {
format!("privacy access levels")
}
}
macro_rules! define_maps { macro_rules! define_maps {
(<$tcx:tt> (<$tcx:tt>
$($(#[$attr:meta])* $($(#[$attr:meta])*
@ -406,6 +413,9 @@ define_maps! { <'tcx>
/// other items, such as enum variant explicit discriminants. /// other items, such as enum variant explicit discriminants.
pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>, pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>,
/// Performs the privacy check and computes "access levels".
pub privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>,
pub mir_shims: mir_shim(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>> pub mir_shims: mir_shim(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>
} }

View file

@ -17,11 +17,11 @@ pub use self::fold::TypeFoldable;
use dep_graph::{self, DepNode}; use dep_graph::{self, DepNode};
use hir::{map as hir_map, FreevarMap, TraitMap}; use hir::{map as hir_map, FreevarMap, TraitMap};
use middle;
use hir::def::{Def, CtorKind, ExportMap}; use hir::def::{Def, CtorKind, ExportMap};
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use middle::const_val::ConstVal; use middle::const_val::ConstVal;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::privacy::AccessLevels;
use middle::region::{CodeExtent, ROOT_CODE_EXTENT}; use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
use middle::resolve_lifetime::ObjectLifetimeDefault; use middle::resolve_lifetime::ObjectLifetimeDefault;
use mir::Mir; use mir::Mir;
@ -108,10 +108,12 @@ mod sty;
/// The complete set of all analyses described in this module. This is /// The complete set of all analyses described in this module. This is
/// produced by the driver and fed to trans and later passes. /// produced by the driver and fed to trans and later passes.
///
/// NB: These contents are being migrated into queries using the
/// *on-demand* infrastructure.
#[derive(Clone)] #[derive(Clone)]
pub struct CrateAnalysis { pub struct CrateAnalysis {
pub export_map: ExportMap, pub access_levels: Rc<AccessLevels>,
pub access_levels: middle::privacy::AccessLevels,
pub reachable: NodeSet, pub reachable: NodeSet,
pub name: String, pub name: String,
pub glob_map: Option<hir::GlobMap>, pub glob_map: Option<hir::GlobMap>,
@ -122,6 +124,7 @@ pub struct Resolutions {
pub freevars: FreevarMap, pub freevars: FreevarMap,
pub trait_map: TraitMap, pub trait_map: TraitMap,
pub maybe_unused_trait_imports: NodeSet, pub maybe_unused_trait_imports: NodeSet,
pub export_map: ExportMap,
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]

View file

@ -48,6 +48,7 @@ use std::fs;
use std::io::{self, Write}; use std::io::{self, Write};
use std::iter; use std::iter;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::rc::Rc;
use syntax::{ast, diagnostics, visit}; use syntax::{ast, diagnostics, visit};
use syntax::attr; use syntax::attr;
use syntax::ext::base::ExtCtxt; use syntax::ext::base::ExtCtxt;
@ -807,18 +808,18 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
expanded_crate: krate, expanded_crate: krate,
defs: resolver.definitions, defs: resolver.definitions,
analysis: ty::CrateAnalysis { analysis: ty::CrateAnalysis {
export_map: resolver.export_map, access_levels: Rc::new(AccessLevels::default()),
access_levels: AccessLevels::default(),
reachable: NodeSet(), reachable: NodeSet(),
name: crate_name.to_string(), name: crate_name.to_string(),
glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None }, glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
}, },
resolutions: Resolutions { resolutions: Resolutions {
freevars: resolver.freevars, freevars: resolver.freevars,
export_map: resolver.export_map,
trait_map: resolver.trait_map, trait_map: resolver.trait_map,
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports, maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
}, },
hir_forest: hir_forest hir_forest: hir_forest,
}) })
} }
@ -888,6 +889,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
let mut local_providers = ty::maps::Providers::default(); let mut local_providers = ty::maps::Providers::default();
mir::provide(&mut local_providers); mir::provide(&mut local_providers);
rustc_privacy::provide(&mut local_providers);
typeck::provide(&mut local_providers); typeck::provide(&mut local_providers);
ty::provide(&mut local_providers); ty::provide(&mut local_providers);
@ -931,9 +933,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|| consts::check_crate(tcx)); || consts::check_crate(tcx));
analysis.access_levels = analysis.access_levels =
time(time_passes, "privacy checking", || { time(time_passes, "privacy checking", || rustc_privacy::check_crate(tcx));
rustc_privacy::check_crate(tcx, &analysis.export_map)
});
time(time_passes, time(time_passes,
"intrinsic checking", "intrinsic checking",
@ -1000,19 +1000,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
analysis.reachable = analysis.reachable =
time(time_passes, time(time_passes,
"reachability checking", "reachability checking",
|| reachable::find_reachable(tcx, &analysis.access_levels)); || reachable::find_reachable(tcx));
time(time_passes, "death checking", || { time(time_passes, "death checking", || middle::dead::check_crate(tcx));
middle::dead::check_crate(tcx, &analysis.access_levels);
});
time(time_passes, "unused lib feature checking", || { time(time_passes, "unused lib feature checking", || {
stability::check_unused_or_stable_features(tcx, &analysis.access_levels) stability::check_unused_or_stable_features(tcx)
}); });
time(time_passes, time(time_passes, "lint checking", || lint::check_crate(tcx));
"lint checking",
|| lint::check_crate(tcx, &analysis.access_levels));
// The above three passes generate errors w/o aborting // The above three passes generate errors w/o aborting
if sess.err_count() > 0 { if sess.err_count() > 0 {

View file

@ -496,12 +496,12 @@ impl CrateStore for cstore::CStore {
self.do_extern_mod_stmt_cnum(emod_id) self.do_extern_mod_stmt_cnum(emod_id)
} }
fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, fn encode_metadata<'a, 'tcx>(&self,
reexports: &def::ExportMap, tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta, link_meta: &LinkMeta,
reachable: &NodeSet) -> Vec<u8> reachable: &NodeSet) -> Vec<u8>
{ {
encoder::encode_metadata(tcx, self, reexports, link_meta, reachable) encoder::encode_metadata(tcx, self, link_meta, reachable)
} }
fn metadata_encoding_version(&self) -> &[u8] fn metadata_encoding_version(&self) -> &[u8]

View file

@ -13,7 +13,6 @@ use index::Index;
use schema::*; use schema::*;
use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary}; use rustc::middle::cstore::{LinkMeta, LinkagePreference, NativeLibrary};
use rustc::hir::def;
use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId}; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId};
use rustc::hir::map::definitions::DefPathTable; use rustc::hir::map::definitions::DefPathTable;
use rustc::middle::dependency_format::Linkage; use rustc::middle::dependency_format::Linkage;
@ -48,7 +47,6 @@ use super::index_builder::{FromId, IndexBuilder, Untracked};
pub struct EncodeContext<'a, 'tcx: 'a> { pub struct EncodeContext<'a, 'tcx: 'a> {
opaque: opaque::Encoder<'a>, opaque: opaque::Encoder<'a>,
pub tcx: TyCtxt<'a, 'tcx, 'tcx>, pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &'a def::ExportMap,
link_meta: &'a LinkMeta, link_meta: &'a LinkMeta,
cstore: &'a cstore::CStore, cstore: &'a cstore::CStore,
exported_symbols: &'a NodeSet, exported_symbols: &'a NodeSet,
@ -306,7 +304,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let def_id = tcx.hir.local_def_id(id); let def_id = tcx.hir.local_def_id(id);
let data = ModData { let data = ModData {
reexports: match self.reexports.get(&id) { reexports: match tcx.export_map.get(&id) {
Some(exports) if *vis == hir::Public => self.lazy_seq_ref(exports), Some(exports) if *vis == hir::Public => self.lazy_seq_ref(exports),
_ => LazySeq::empty(), _ => LazySeq::empty(),
}, },
@ -1423,7 +1421,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
cstore: &cstore::CStore, cstore: &cstore::CStore,
reexports: &def::ExportMap,
link_meta: &LinkMeta, link_meta: &LinkMeta,
exported_symbols: &NodeSet) exported_symbols: &NodeSet)
-> Vec<u8> { -> Vec<u8> {
@ -1437,7 +1434,6 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let mut ecx = EncodeContext { let mut ecx = EncodeContext {
opaque: opaque::Encoder::new(&mut cursor), opaque: opaque::Encoder::new(&mut cursor),
tcx: tcx, tcx: tcx,
reexports: reexports,
link_meta: link_meta, link_meta: link_meta,
cstore: cstore, cstore: cstore,
exported_symbols: exported_symbols, exported_symbols: exported_symbols,

View file

@ -17,6 +17,7 @@
html_root_url = "https://doc.rust-lang.org/nightly/")] html_root_url = "https://doc.rust-lang.org/nightly/")]
#![deny(warnings)] #![deny(warnings)]
#![cfg_attr(stage0, feature(field_init_shorthand))]
#![feature(rustc_diagnostic_macros)] #![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(staged_api)] #![feature(staged_api)]
@ -25,10 +26,9 @@ extern crate rustc;
#[macro_use] extern crate syntax; #[macro_use] extern crate syntax;
extern crate syntax_pos; extern crate syntax_pos;
use rustc::dep_graph::DepNode;
use rustc::hir::{self, PatKind}; use rustc::hir::{self, PatKind};
use rustc::hir::def::{self, Def}; use rustc::hir::def::Def;
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::itemlikevisit::DeepVisitor; use rustc::hir::itemlikevisit::DeepVisitor;
use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@ -36,12 +36,14 @@ use rustc::lint;
use rustc::middle::privacy::{AccessLevel, AccessLevels}; use rustc::middle::privacy::{AccessLevel, AccessLevels};
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable}; use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
use rustc::ty::fold::TypeVisitor; use rustc::ty::fold::TypeVisitor;
use rustc::ty::maps::Providers;
use rustc::util::nodemap::NodeSet; use rustc::util::nodemap::NodeSet;
use syntax::ast; use syntax::ast;
use syntax_pos::Span; use syntax_pos::{DUMMY_SP, Span};
use std::cmp; use std::cmp;
use std::mem::replace; use std::mem::replace;
use std::rc::Rc;
pub mod diagnostics; pub mod diagnostics;
@ -71,7 +73,6 @@ impl<'a, 'tcx> Visitor<'tcx> for PubRestrictedVisitor<'a, 'tcx> {
struct EmbargoVisitor<'a, 'tcx: 'a> { struct EmbargoVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
export_map: &'a def::ExportMap,
// Accessibility levels for reachable nodes // Accessibility levels for reachable nodes
access_levels: AccessLevels, access_levels: AccessLevels,
@ -324,7 +325,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
// This code is here instead of in visit_item so that the // This code is here instead of in visit_item so that the
// crate module gets processed as well. // crate module gets processed as well.
if self.prev_level.is_some() { if self.prev_level.is_some() {
if let Some(exports) = self.export_map.get(&id) { if let Some(exports) = self.tcx.export_map.get(&id) {
for export in exports { for export in exports {
if let Some(node_id) = self.tcx.hir.as_local_node_id(export.def.def_id()) { if let Some(node_id) = self.tcx.hir.as_local_node_id(export.def.def_id()) {
self.update(node_id, Some(AccessLevel::Exported)); self.update(node_id, Some(AccessLevel::Exported));
@ -1204,10 +1205,23 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
fn visit_pat(&mut self, _: &'tcx hir::Pat) {} fn visit_pat(&mut self, _: &'tcx hir::Pat) {}
} }
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn provide(providers: &mut Providers) {
export_map: &def::ExportMap) *providers = Providers {
-> AccessLevels { privacy_access_levels,
let _task = tcx.dep_graph.in_task(DepNode::Privacy); ..*providers
};
}
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc<AccessLevels> {
tcx.dep_graph.with_ignore(|| { // FIXME
ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE)
})
}
fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
krate: CrateNum)
-> Rc<AccessLevels> {
assert_eq!(krate, LOCAL_CRATE);
let krate = tcx.hir.krate(); let krate = tcx.hir.krate();
@ -1226,7 +1240,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// items which are reachable from external crates based on visibility. // items which are reachable from external crates based on visibility.
let mut visitor = EmbargoVisitor { let mut visitor = EmbargoVisitor {
tcx: tcx, tcx: tcx,
export_map: export_map,
access_levels: Default::default(), access_levels: Default::default(),
prev_level: Some(AccessLevel::Public), prev_level: Some(AccessLevel::Public),
changed: false, changed: false,
@ -1270,7 +1283,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor)); krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
} }
visitor.access_levels Rc::new(visitor.access_levels)
} }
__build_diagnostic_array! { librustc_privacy, DIAGNOSTICS } __build_diagnostic_array! { librustc_privacy, DIAGNOSTICS }

View file

@ -755,7 +755,6 @@ fn write_metadata(cx: &SharedCrateContext,
let cstore = &cx.tcx().sess.cstore; let cstore = &cx.tcx().sess.cstore;
let metadata = cstore.encode_metadata(cx.tcx(), let metadata = cstore.encode_metadata(cx.tcx(),
cx.export_map(),
cx.link_meta(), cx.link_meta(),
exported_symbols); exported_symbols);
if kind == MetadataKind::Uncompressed { if kind == MetadataKind::Uncompressed {
@ -1056,7 +1055,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// particular items that will be processed. // particular items that will be processed.
let krate = tcx.hir.krate(); let krate = tcx.hir.krate();
let ty::CrateAnalysis { export_map, reachable, name, .. } = analysis; let ty::CrateAnalysis { reachable, name, .. } = analysis;
let exported_symbols = find_exported_symbols(tcx, reachable); let exported_symbols = find_exported_symbols(tcx, reachable);
let check_overflow = tcx.sess.overflow_checks(); let check_overflow = tcx.sess.overflow_checks();
@ -1064,7 +1063,6 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let link_meta = link::build_link_meta(incremental_hashes_map, &name); let link_meta = link::build_link_meta(incremental_hashes_map, &name);
let shared_ccx = SharedCrateContext::new(tcx, let shared_ccx = SharedCrateContext::new(tcx,
export_map,
link_meta.clone(), link_meta.clone(),
exported_symbols, exported_symbols,
check_overflow); check_overflow);

View file

@ -14,7 +14,6 @@ use rustc::dep_graph::{DepGraph, DepGraphSafe, DepNode, DepTrackingMap,
DepTrackingMapConfig, WorkProduct}; DepTrackingMapConfig, WorkProduct};
use middle::cstore::LinkMeta; use middle::cstore::LinkMeta;
use rustc::hir; use rustc::hir;
use rustc::hir::def::ExportMap;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::traits; use rustc::traits;
use debuginfo; use debuginfo;
@ -68,7 +67,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
metadata_llmod: ModuleRef, metadata_llmod: ModuleRef,
metadata_llcx: ContextRef, metadata_llcx: ContextRef,
export_map: ExportMap,
exported_symbols: NodeSet, exported_symbols: NodeSet,
link_meta: LinkMeta, link_meta: LinkMeta,
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
@ -402,7 +400,6 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> { impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>, pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
export_map: ExportMap,
link_meta: LinkMeta, link_meta: LinkMeta,
exported_symbols: NodeSet, exported_symbols: NodeSet,
check_overflow: bool) check_overflow: bool)
@ -459,7 +456,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
SharedCrateContext { SharedCrateContext {
metadata_llmod: metadata_llmod, metadata_llmod: metadata_llmod,
metadata_llcx: metadata_llcx, metadata_llcx: metadata_llcx,
export_map: export_map,
exported_symbols: exported_symbols, exported_symbols: exported_symbols,
link_meta: link_meta, link_meta: link_meta,
empty_param_env: tcx.empty_parameter_environment(), empty_param_env: tcx.empty_parameter_environment(),
@ -499,10 +495,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
self.metadata_llcx self.metadata_llcx
} }
pub fn export_map<'a>(&'a self) -> &'a ExportMap {
&self.export_map
}
pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet { pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
&self.exported_symbols &self.exported_symbols
} }
@ -702,10 +694,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) } unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
} }
pub fn export_map<'a>(&'a self) -> &'a ExportMap {
&self.shared.export_map
}
pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet { pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
&self.shared.exported_symbols &self.shared.exported_symbols
} }

View file

@ -13,7 +13,7 @@ use rustc_driver::{driver, target_features, abort_on_err};
use rustc::dep_graph::DepGraph; use rustc::dep_graph::DepGraph;
use rustc::session::{self, config}; use rustc::session::{self, config};
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::hir::def::{Def, ExportMap}; use rustc::hir::def::Def;
use rustc::middle::privacy::AccessLevels; use rustc::middle::privacy::AccessLevels;
use rustc::ty::{self, TyCtxt, GlobalArenas}; use rustc::ty::{self, TyCtxt, GlobalArenas};
use rustc::hir::map as hir_map; use rustc::hir::map as hir_map;
@ -64,7 +64,6 @@ pub struct DocContext<'a, 'tcx: 'a> {
pub ty_substs: RefCell<FxHashMap<Def, clean::Type>>, pub ty_substs: RefCell<FxHashMap<Def, clean::Type>>,
/// Table node id of lifetime parameter definition -> substituted lifetime /// Table node id of lifetime parameter definition -> substituted lifetime
pub lt_substs: RefCell<FxHashMap<ast::NodeId, clean::Lifetime>>, pub lt_substs: RefCell<FxHashMap<ast::NodeId, clean::Lifetime>>,
pub export_map: ExportMap,
} }
impl<'a, 'tcx> DocContext<'a, 'tcx> { impl<'a, 'tcx> DocContext<'a, 'tcx> {
@ -180,13 +179,13 @@ pub fn run_core(search_paths: SearchPaths,
sess.fatal("Compilation failed, aborting rustdoc"); sess.fatal("Compilation failed, aborting rustdoc");
} }
let ty::CrateAnalysis { access_levels, export_map, .. } = analysis; let ty::CrateAnalysis { access_levels, .. } = analysis;
// Convert from a NodeId set to a DefId set since we don't always have easy access // Convert from a NodeId set to a DefId set since we don't always have easy access
// to the map from defid -> nodeid // to the map from defid -> nodeid
let access_levels = AccessLevels { let access_levels = AccessLevels {
map: access_levels.map.into_iter() map: access_levels.map.iter()
.map(|(k, v)| (tcx.hir.local_def_id(k), v)) .map(|(&k, &v)| (tcx.hir.local_def_id(k), v))
.collect() .collect()
}; };
@ -198,7 +197,6 @@ pub fn run_core(search_paths: SearchPaths,
renderinfo: Default::default(), renderinfo: Default::default(),
ty_substs: Default::default(), ty_substs: Default::default(),
lt_substs: Default::default(), lt_substs: Default::default(),
export_map: export_map,
}; };
debug!("crate: {:?}", tcx.hir.krate()); debug!("crate: {:?}", tcx.hir.krate());

View file

@ -198,7 +198,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
self.visit_item(item, None, &mut om); self.visit_item(item, None, &mut om);
} }
self.inside_public_path = orig_inside_public_path; self.inside_public_path = orig_inside_public_path;
if let Some(exports) = self.cx.export_map.get(&id) { if let Some(exports) = self.cx.tcx.export_map.get(&id) {
for export in exports { for export in exports {
if let Def::Macro(def_id, ..) = export.def { if let Def::Macro(def_id, ..) = export.def {
if def_id.krate == LOCAL_CRATE { if def_id.krate == LOCAL_CRATE {

View file

@ -1290,28 +1290,42 @@ pub trait BufRead: Read {
/// If an I/O error is encountered then all bytes read so far will be /// If an I/O error is encountered then all bytes read so far will be
/// present in `buf` and its length will have been adjusted appropriately. /// present in `buf` and its length will have been adjusted appropriately.
/// ///
/// # Examples
///
/// A locked standard input implements `BufRead`. In this example, we'll
/// read from standard input until we see an `a` byte.
///
/// [`fill_buf`]: #tymethod.fill_buf /// [`fill_buf`]: #tymethod.fill_buf
/// [`ErrorKind::Interrupted`]: enum.ErrorKind.html#variant.Interrupted /// [`ErrorKind::Interrupted`]: enum.ErrorKind.html#variant.Interrupted
/// ///
/// # Examples
///
/// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
/// this example, we use [`Cursor`] to read all the bytes in a byte slice
/// in hyphen delimited segments:
///
/// [`Cursor`]: struct.Cursor.html
///
/// ``` /// ```
/// use std::io; /// use std::io::{self, BufRead};
/// use std::io::prelude::*;
/// ///
/// fn foo() -> io::Result<()> { /// let mut cursor = io::Cursor::new(b"lorem-ipsum");
/// let stdin = io::stdin(); /// let mut buf = vec![];
/// let mut stdin = stdin.lock();
/// let mut buffer = Vec::new();
/// ///
/// stdin.read_until(b'a', &mut buffer)?; /// // cursor is at 'l'
/// let num_bytes = cursor.read_until(b'-', &mut buf)
/// .expect("reading from cursor won't fail");
/// assert_eq!(num_bytes, 6);
/// assert_eq!(buf, b"lorem-");
/// buf.clear();
/// ///
/// println!("{:?}", buffer); /// // cursor is at 'i'
/// # Ok(()) /// let num_bytes = cursor.read_until(b'-', &mut buf)
/// # } /// .expect("reading from cursor won't fail");
/// assert_eq!(num_bytes, 5);
/// assert_eq!(buf, b"ipsum");
/// buf.clear();
///
/// // cursor is at EOF
/// let num_bytes = cursor.read_until(b'-', &mut buf)
/// .expect("reading from cursor won't fail");
/// assert_eq!(num_bytes, 0);
/// assert_eq!(buf, b"");
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> { fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize> {
@ -1337,28 +1351,36 @@ pub trait BufRead: Read {
/// ///
/// # Examples /// # Examples
/// ///
/// A locked standard input implements `BufRead`. In this example, we'll /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
/// read all of the lines from standard input. If we were to do this in /// this example, we use [`Cursor`] to read all the lines in a byte slice:
/// an actual project, the [`lines`] method would be easier, of
/// course.
/// ///
/// [`lines`]: #method.lines /// [`Cursor`]: struct.Cursor.html
/// [`read_until`]: #method.read_until
/// ///
/// ``` /// ```
/// use std::io; /// use std::io::{self, BufRead};
/// use std::io::prelude::*;
/// ///
/// let stdin = io::stdin(); /// let mut cursor = io::Cursor::new(b"foo\nbar");
/// let mut stdin = stdin.lock(); /// let mut buf = String::new();
/// let mut buffer = String::new();
/// ///
/// while stdin.read_line(&mut buffer).unwrap() > 0 { /// // cursor is at 'f'
/// // work with buffer /// let num_bytes = cursor.read_line(&mut buf)
/// println!("{:?}", buffer); /// .expect("reading from cursor won't fail");
/// assert_eq!(num_bytes, 4);
/// assert_eq!(buf, "foo\n");
/// buf.clear();
/// ///
/// buffer.clear(); /// // cursor is at 'b'
/// } /// let num_bytes = cursor.read_line(&mut buf)
/// .expect("reading from cursor won't fail");
/// assert_eq!(num_bytes, 3);
/// assert_eq!(buf, "bar");
/// buf.clear();
///
/// // cursor is at EOF
/// let num_bytes = cursor.read_line(&mut buf)
/// .expect("reading from cursor won't fail");
/// assert_eq!(num_bytes, 0);
/// assert_eq!(buf, "");
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn read_line(&mut self, buf: &mut String) -> Result<usize> { fn read_line(&mut self, buf: &mut String) -> Result<usize> {
@ -1378,24 +1400,28 @@ pub trait BufRead: Read {
/// This function will yield errors whenever [`read_until`] would have /// This function will yield errors whenever [`read_until`] would have
/// also yielded an error. /// also yielded an error.
/// ///
/// # Examples
///
/// A locked standard input implements `BufRead`. In this example, we'll
/// read some input from standard input, splitting on commas.
///
/// [`io::Result`]: type.Result.html /// [`io::Result`]: type.Result.html
/// [`Vec<u8>`]: ../vec/struct.Vec.html /// [`Vec<u8>`]: ../vec/struct.Vec.html
/// [`read_until`]: #method.read_until /// [`read_until`]: #method.read_until
/// ///
/// # Examples
///
/// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
/// this example, we use [`Cursor`] to iterate over all hyphen delimited
/// segments in a byte slice
///
/// [`Cursor`]: struct.Cursor.html
///
/// ``` /// ```
/// use std::io; /// use std::io::{self, BufRead};
/// use std::io::prelude::*;
/// ///
/// let stdin = io::stdin(); /// let cursor = io::Cursor::new(b"lorem-ipsum-dolor");
/// ///
/// for content in stdin.lock().split(b',') { /// let mut split_iter = cursor.split(b'-').map(|l| l.unwrap());
/// println!("{:?}", content.unwrap()); /// assert_eq!(split_iter.next(), Some(b"lorem".to_vec()));
/// } /// assert_eq!(split_iter.next(), Some(b"ipsum".to_vec()));
/// assert_eq!(split_iter.next(), Some(b"dolor".to_vec()));
/// assert_eq!(split_iter.next(), None);
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn split(self, byte: u8) -> Split<Self> where Self: Sized { fn split(self, byte: u8) -> Split<Self> where Self: Sized {
@ -1413,17 +1439,22 @@ pub trait BufRead: Read {
/// ///
/// # Examples /// # Examples
/// ///
/// A locked standard input implements `BufRead`: /// [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In
/// this example, we use [`Cursor`] to iterate over all the lines in a byte
/// slice.
///
/// [`Cursor`]: struct.Cursor.html
/// ///
/// ``` /// ```
/// use std::io; /// use std::io::{self, BufRead};
/// use std::io::prelude::*;
/// ///
/// let stdin = io::stdin(); /// let cursor = io::Cursor::new(b"lorem\nipsum\r\ndolor");
/// ///
/// for line in stdin.lock().lines() { /// let mut lines_iter = cursor.lines().map(|l| l.unwrap());
/// println!("{}", line.unwrap()); /// assert_eq!(lines_iter.next(), Some(String::from("lorem")));
/// } /// assert_eq!(lines_iter.next(), Some(String::from("ipsum")));
/// assert_eq!(lines_iter.next(), Some(String::from("dolor")));
/// assert_eq!(lines_iter.next(), None);
/// ``` /// ```
/// ///
/// # Errors /// # Errors

View file

@ -0,0 +1,16 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn f<'a: 'static>(_: &'a i32) {} //~WARN unnecessary lifetime parameter `'a`
fn main() {
let x = 0;
f(&x); //~ERROR does not live long enough
}