Auto merge of #56340 - GuillaumeGomez:rollup, r=GuillaumeGomez

Rollup of 22 pull requests

Successful merges:

 - #55391 (bootstrap: clean up a few clippy findings)
 - #56021 (avoid features_untracked)
 - #56023 (atomic::Ordering: Get rid of misleading parts of intro)
 - #56080 (Reduce the amount of bold text at doc.rlo)
 - #56114 (Enclose type in backticks for "non-exhaustive patterns" error)
 - #56124 (Fix small doc mistake on std::io::read::read_to_end)
 - #56127 (Update an outdated comment in mir building)
 - #56148 (Add rustc-guide as a submodule)
 - #56149 (Make std::os::unix/linux::fs::MetadataExt::a/m/ctime* documentation clearer)
 - #56220 (Suggest appropriate place for lifetime when declared after type arguments)
 - #56223 (Make JSON output from -Zprofile-json valid)
 - #56236 (Remove unsafe `unsafe` inner function.)
 - #56255 (Update outdated code comments in StringReader)
 - #56257 (rustc-guide has moved to rust-lang/)
 - #56273 (Add missing doc link)
 - #56289 (Fix small typo in comment of thread::stack_size)
 - #56294 (Fix a typo in the documentation of std::ffi)
 - #56312 (Deduplicate literal -> constant lowering)
 - #56319 (fix futures creating aliasing mutable and shared ref)
 - #56321 (rustdoc: add bottom margin spacing to nested lists)
 - #56322 (resolve: Fix false-positives from lint `absolute_paths_not_starting_with_crate`)
 - #56330 (Clean up span in non-trailing `..` suggestion)

Failed merges:

r? @ghost
This commit is contained in:
bors 2018-11-29 12:23:05 +00:00
commit 0c1dc62c1e
83 changed files with 418 additions and 316 deletions

3
.gitmodules vendored
View file

@ -62,3 +62,6 @@
url = https://github.com/rust-lang-nursery/clang.git
branch = rust-release-80-v1
[submodule "src/doc/rustc-guide"]
path = src/doc/rustc-guide
url = https://github.com/rust-lang/rustc-guide.git

View file

@ -640,7 +640,7 @@ are:
* **Google!** ([search only in Rust Documentation][gsearchdocs] to find types, traits, etc. quickly)
* Don't be afraid to ask! The Rust community is friendly and helpful.
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
[gdfrustc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
[gsearchdocs]: https://www.google.com/search?q=site:doc.rust-lang.org+your+query+here
[rif]: http://internals.rust-lang.org
@ -648,5 +648,5 @@ are:
[rustforge]: https://forge.rust-lang.org/
[tlgba]: http://tomlee.co/2014/04/a-more-detailed-tour-of-the-rust-compiler/
[ro]: http://www.rustaceans.org/
[rctd]: https://rust-lang-nursery.github.io/rustc-guide/tests/intro.html
[rctd]: https://rust-lang.github.io/rustc-guide/tests/intro.html
[cheatsheet]: https://buildbot2.rust-lang.org/homu/

View file

@ -233,7 +233,7 @@ Also, you may find the [rustdocs for the compiler itself][rustdocs] useful.
[IRC]: https://en.wikipedia.org/wiki/Internet_Relay_Chat
[#rust]: irc://irc.mozilla.org/rust
[#rust-beginners]: irc://irc.mozilla.org/rust-beginners
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html
[rustdocs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/
## License

View file

@ -12,4 +12,4 @@ There is also useful content in the following READMEs, which are gradually being
- https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked
- https://github.com/rust-lang/rust/tree/master/src/librustc/infer/lexical_region_resolve
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/about-this-guide.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/about-this-guide.html

View file

@ -777,10 +777,10 @@ fn cc(&self, target: Interned<String>) -> &Path {
fn cflags(&self, target: Interned<String>, which: GitRepo) -> Vec<String> {
// Filter out -O and /O (the optimization flags) that we picked up from
// cc-rs because the build scripts will determine that for themselves.
let mut base: Vec<String> = self.cc[&target].args().iter()
let mut base = self.cc[&target].args().iter()
.map(|s| s.to_string_lossy().into_owned())
.filter(|s| !s.starts_with("-O") && !s.starts_with("/O"))
.collect::<Vec<_>>();
.collect::<Vec<String>>();
// If we're compiling on macOS then we add a few unconditional flags
// indicating that we want libc++ (more filled out than libstdc++) and

View file

@ -21,6 +21,9 @@ nav {
#search-but:hover, #search-input:focus {
border-color: #55a9ff;
}
h2 {
font-size: 18px;
}
</style>
Welcome to an overview of the documentation provided by the Rust project.

1
src/doc/rustc-guide Submodule

@ -0,0 +1 @@
Subproject commit 3a804956e3c28d7e44e38804207a00013594e1d3

View file

@ -1,6 +1,6 @@
# Contributing to rustc
We'd love to have your help improving `rustc`! To that end, we've written [a
whole book](https://rust-lang-nursery.github.io/rustc-guide/) on its
whole book](https://rust-lang.github.io/rustc-guide/) on its
internals, how it works, and how to get started working on it. To learn
more, you'll want to check that out.
more, you'll want to check that out.

View file

@ -519,7 +519,7 @@ fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter> where
/// element.
///
/// `map()` transforms one iterator into another, by means of its argument:
/// something that implements `FnMut`. It produces a new iterator which
/// something that implements [`FnMut`]. It produces a new iterator which
/// calls this closure on each element of the original iterator.
///
/// If you are good at thinking in types, you can think of `map()` like this:
@ -533,6 +533,7 @@ fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter> where
/// more idiomatic to use [`for`] than `map()`.
///
/// [`for`]: ../../book/ch03-05-control-flow.html#looping-through-a-collection-with-for
/// [`FnMut`]: ../../std/ops/trait.FnMut.html
///
/// # Examples
///

View file

@ -62,18 +62,15 @@ fn next(&mut self) -> Option<Utf8LossyChunk<'a>> {
}
const TAG_CONT_U8: u8 = 128;
fn unsafe_get(xs: &[u8], i: usize) -> u8 {
unsafe { *xs.get_unchecked(i) }
}
fn safe_get(xs: &[u8], i: usize) -> u8 {
if i >= xs.len() { 0 } else { unsafe_get(xs, i) }
*xs.get(i).unwrap_or(&0)
}
let mut i = 0;
while i < self.source.len() {
let i_ = i;
let byte = unsafe_get(self.source, i);
let byte = unsafe { *self.source.get_unchecked(i) };
i += 1;
if byte < 128 {

View file

@ -173,11 +173,11 @@ unsafe impl<T> Sync for AtomicPtr<T> {}
/// Atomic memory orderings
///
/// Memory orderings limit the ways that both the compiler and CPU may reorder
/// instructions around atomic operations. At its most restrictive,
/// "sequentially consistent" atomics allow neither reads nor writes
/// to be moved either before or after the atomic operation; on the other end
/// "relaxed" atomics allow all reorderings.
/// Memory orderings specify the way atomic operations synchronize memory.
/// In its weakest [`Relaxed`][Ordering::Relaxed], only the memory directly touched by the
/// operation is synchronized. On the other hand, a store-load pair of [`SeqCst`][Ordering::SeqCst]
/// operations synchronize other memory while additionally preserving a total order of such
/// operations across all threads.
///
/// Rust's memory orderings are [the same as
/// LLVM's](https://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations).
@ -185,6 +185,8 @@ unsafe impl<T> Sync for AtomicPtr<T> {}
/// For more information see the [nomicon].
///
/// [nomicon]: ../../../nomicon/atomics.html
/// [Ordering::Relaxed]: #variant.Relaxed
/// [Ordering::SeqCst]: #variant.SeqCst
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
@ -234,8 +236,8 @@ pub enum Ordering {
/// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering.
///
/// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up
/// not performing any store and hence it has just `Acquire` ordering. However,
/// `AcqRel` will never perform [`Relaxed`] accesses.
/// not performing any store and hence it has just [`Acquire`] ordering. However,
/// [`AcqRel`][`AcquireRelease`] will never perform [`Relaxed`] accesses.
///
/// This ordering is only applicable for operations that combine both loads and stores.
///

View file

@ -1,3 +1,3 @@
For more information about how rustc works, see the [rustc guide].
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
[rustc guide]: https://rust-lang.github.io/rustc-guide/

View file

@ -1,4 +1,4 @@
To learn more about how dependency tracking works in rustc, see the [rustc
guide].
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/query.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/query.html

View file

@ -195,7 +195,7 @@ pub fn with_ignore<OP,R>(&self, op: OP) -> R
/// - If you need 3+ arguments, use a tuple for the
/// `arg` parameter.
///
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/incremental-compilation.html
/// [rustc guide]: https://rust-lang.github.io/rustc-guide/incremental-compilation.html
pub fn with_task<'gcx, C, A, R>(&self,
key: DepNode,
cx: C,

View file

@ -689,7 +689,7 @@ pub struct WhereEqPredicate {
///
/// For more details, see the [rustc guide].
///
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/hir.html
/// [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Crate {
pub module: Mod,

View file

@ -13,7 +13,7 @@
//! For an overview of what canonicalization is and how it fits into
//! rustc, check out the [chapter in the rustc guide][c].
//!
//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
use infer::canonical::{
Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, Canonicalized,
@ -44,7 +44,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
/// To get a good understanding of what is happening here, check
/// out the [chapter in the rustc guide][c].
///
/// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query
/// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query
pub fn canonicalize_query<V>(
&self,
value: &V,
@ -92,7 +92,7 @@ pub fn canonicalize_query<V>(
/// To get a good understanding of what is happening here, check
/// out the [chapter in the rustc guide][c].
///
/// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
/// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#canonicalizing-the-query-result
pub fn canonicalize_response<V>(&self, value: &V) -> Canonicalized<'gcx, V>
where
V: TypeFoldable<'tcx> + Lift<'gcx>,

View file

@ -29,7 +29,7 @@
//! For a more detailed look at what is happening here, check
//! out the [chapter in the rustc guide][c].
//!
//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
use infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin};
use rustc_data_structures::indexed_vec::IndexVec;

View file

@ -15,7 +15,7 @@
//! For an overview of what canonicaliation is and how it fits into
//! rustc, check out the [chapter in the rustc guide][c].
//!
//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
use infer::canonical::substitute::substitute_value;
use infer::canonical::{
@ -184,7 +184,7 @@ fn make_query_response<T>(
/// To get a good understanding of what is happening here, check
/// out the [chapter in the rustc guide][c].
///
/// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
/// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html#processing-the-canonicalized-query-result
pub fn instantiate_query_response_and_region_obligations<R>(
&self,
cause: &ObligationCause<'tcx>,

View file

@ -14,7 +14,7 @@
//! For an overview of what canonicalization is and how it fits into
//! rustc, check out the [chapter in the rustc guide][c].
//!
//! [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
//! [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
use infer::canonical::{Canonical, CanonicalVarValues};
use ty::fold::TypeFoldable;

View file

@ -329,7 +329,7 @@ fn region_vars_confined_to_snapshot(&self,
/// For more information about how placeholders and HRTBs work, see
/// the [rustc guide].
///
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
/// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html
pub fn replace_bound_vars_with_placeholders<T>(
&self,
binder: &ty::Binder<T>

View file

@ -3,7 +3,7 @@
> WARNING: This README is obsolete and will be removed soon! For
> more info on how the current borrowck works, see the [rustc guide].
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
## Terminology

View file

@ -3,7 +3,7 @@
> WARNING: This README is obsolete and will be removed soon! For
> more info on how the current borrowck works, see the [rustc guide].
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
## Terminology
@ -18,7 +18,7 @@ constraints over the course of a function. Finally, at the end of
processing a function, we process and solve the constraints all at
once.
[ti]: https://rust-lang-nursery.github.io/rustc-guide/type-inference.html
[ti]: https://rust-lang.github.io/rustc-guide/type-inference.html
The constraints are always of one of three possible forms:

View file

@ -30,7 +30,7 @@
//!
//! For more information about how rustc works, see the [rustc guide].
//!
//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/
//!
//! # Note
//!

View file

@ -14,7 +14,7 @@
//! For more information about how MIR-based region-checking works,
//! see the [rustc guide].
//!
//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
use ich::{StableHashingContext, NodeIdHashingMode};
use util::nodemap::{FxHashMap, FxHashSet};

View file

@ -10,7 +10,7 @@
//! MIR datatypes and passes. See the [rustc guide] for more info.
//!
//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/index.html
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/mir/index.html
use hir::def::CtorKind;
use hir::def_id::DefId;

View file

@ -11,8 +11,8 @@
//! See rustc guide chapters on [trait-resolution] and [trait-specialization] for more info on how
//! this works.
//!
//! [trait-resolution]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
//! [trait-specialization]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
//! [trait-resolution]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
//! [trait-specialization]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
use hir::def_id::{DefId, LOCAL_CRATE};
use syntax_pos::DUMMY_SP;

View file

@ -10,7 +10,7 @@
//! Trait Resolution. See [rustc guide] for more info on how this works.
//!
//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html
pub use self::SelectionError::*;
pub use self::FulfillmentErrorCode::*;

View file

@ -53,7 +53,7 @@ fn fully_perform(
/// first canonicalize the key and then invoke the query on the tcx,
/// which produces the resulting query region constraints.
///
/// [c]: https://rust-lang-nursery.github.io/rustc-guide/traits/canonicalization.html
/// [c]: https://rust-lang.github.io/rustc-guide/traits/canonicalization.html
pub trait QueryTypeOp<'gcx: 'tcx, 'tcx>:
fmt::Debug + Sized + TypeFoldable<'tcx> + Lift<'gcx>
{

View file

@ -10,7 +10,7 @@
//! See [rustc guide] for more info on how this works.
//!
//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#selection
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/resolution.html#selection
use self::EvaluationResult::*;
use self::SelectionCandidate::*;
@ -1173,7 +1173,7 @@ fn insert_evaluation_cache(
// candidates. See [rustc guide] for more details.
//
// [rustc guide]:
// https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#candidate-assembly
// https://rust-lang.github.io/rustc-guide/traits/resolution.html#candidate-assembly
fn candidate_from_obligation<'o>(
&mut self,
@ -2720,7 +2720,7 @@ fn collect_predicates_for_types(
// type error. See [rustc guide] for more details.
//
// [rustc guide]:
// https://rust-lang-nursery.github.io/rustc-guide/traits/resolution.html#confirmation
// https://rust-lang.github.io/rustc-guide/traits/resolution.html#confirmation
fn confirm_candidate(
&mut self,

View file

@ -17,7 +17,7 @@
//! See the [rustc guide] for a bit more detail on how specialization
//! fits together with the rest of the trait machinery.
//!
//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/specialization.html
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/specialization.html
use super::{SelectionContext, FulfillmentContext};
use super::util::impl_trait_ref_and_oblig;

View file

@ -66,7 +66,7 @@ pub fn is_min_const_fn(self, def_id: DefId) -> bool {
}
} else {
// users enabling the `const_fn` feature gate can do what they want
!self.sess.features_untracked().const_fn
!self.features().const_fn
}
}
}

View file

@ -876,7 +876,7 @@ pub struct FreeRegionInfo {
/// various **compiler queries** that have been performed. See the
/// [rustc guide] for more details.
///
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ty.html
/// [rustc guide]: https://rust-lang.github.io/rustc-guide/ty.html
#[derive(Copy, Clone)]
pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> {
gcx: &'a GlobalCtxt<'gcx>,

View file

@ -1138,7 +1138,7 @@ pub struct DebruijnIndex {
///
/// [1]: http://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
/// [2]: http://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
/// [rustc guide]: https://rust-lang.github.io/rustc-guide/traits/hrtb.html
#[derive(Clone, PartialEq, Eq, Hash, Copy, RustcEncodable, RustcDecodable, PartialOrd, Ord)]
pub enum RegionKind {
// Region bound in a type or fn declaration which will be

View file

@ -102,7 +102,7 @@ fn json(&self) -> String {
};
json.push_str(&format!(
"{{ \"category\": {}, \"time_ms\": {},
"{{ \"category\": \"{}\", \"time_ms\": {},\
\"query_count\": {}, \"query_hits\": {} }},",
stringify!($name),
self.times.$name / 1_000_000,

View file

@ -3,7 +3,7 @@
> WARNING: This README is more or less obsolete, and will be removed
> soon! The new system is described in the [rustc guide].
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir/borrowck.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/mir/borrowck.html
This pass has the job of enforcing memory safety. This is a subtle
topic. This docs aim to explain both the practice and the theory

View file

@ -4,4 +4,4 @@ that runs towards the end of the compilation process.
For more information about how codegen works, see the [rustc guide].
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/codegen.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/codegen.html

View file

@ -7,4 +7,4 @@ options).
For more information about how the driver works, see the [rustc guide].
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustc-driver.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/rustc-driver.html

View file

@ -85,9 +85,15 @@ fn expr_as_temp(
unpack!(block = this.into(&Place::Local(temp), block, expr));
// In constants, temp_lifetime is None. We should not need to drop
// anything because no values with a destructor can be created in
// a constant at this time, even if the type may need dropping.
// In constants, temp_lifetime is None for temporaries that live for the
// 'static lifetime. Thus we do not drop these temporaries and simply leak them.
// This is equivalent to what `let x = &foo();` does in functions. The temporary
// is lifted to their surrounding scope. In a function that means the temporary lives
// until just before the function returns. In constants that means it outlives the
// constant's initialization value computation. Anything outliving a constant
// must have the `'static` lifetime and live forever.
// Anything with a shorter lifetime (e.g the `&foo()` in `bar(&foo())` or anything
// within a block will keep the regular drops just like runtime code.
if let Some(temp_lifetime) = temp_lifetime {
this.schedule_drop_storage_and_value(
expr_span,

View file

@ -0,0 +1,102 @@
use syntax::ast;
use rustc::ty::{self, Ty, TyCtxt, ParamEnv};
use syntax_pos::symbol::Symbol;
use rustc::mir::interpret::{ConstValue, Scalar};
#[derive(PartialEq)]
crate enum LitToConstError {
UnparseableFloat,
Reported,
}
crate fn lit_to_const<'a, 'gcx, 'tcx>(
lit: &'tcx ast::LitKind,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
ty: Ty<'tcx>,
neg: bool,
) -> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
use syntax::ast::*;
let trunc = |n| {
let param_ty = ParamEnv::reveal_all().and(tcx.lift_to_global(&ty).unwrap());
let width = tcx.layout_of(param_ty).map_err(|_| LitToConstError::Reported)?.size;
trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
let shift = 128 - width.bits();
let result = (n << shift) >> shift;
trace!("trunc result: {}", result);
Ok(ConstValue::Scalar(Scalar::Bits {
bits: result,
size: width.bytes() as u8,
}))
};
use rustc::mir::interpret::*;
let lit = match *lit {
LitKind::Str(ref s, _) => {
let s = s.as_str();
let id = tcx.allocate_bytes(s.as_bytes());
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
},
LitKind::ByteStr(ref data) => {
let id = tcx.allocate_bytes(data);
ConstValue::Scalar(Scalar::Ptr(id.into()))
},
LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
bits: n as u128,
size: 1,
}),
LitKind::Int(n, _) if neg => {
let n = n as i128;
let n = n.overflowing_neg().0;
trunc(n as u128)?
},
LitKind::Int(n, _) => trunc(n)?,
LitKind::Float(n, fty) => {
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
}
LitKind::FloatUnsuffixed(n) => {
let fty = match ty.sty {
ty::Float(fty) => fty,
_ => bug!()
};
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
}
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
};
Ok(ty::Const::from_const_value(tcx, lit, ty))
}
fn parse_float<'tcx>(
num: Symbol,
fty: ast::FloatTy,
neg: bool,
) -> Result<ConstValue<'tcx>, ()> {
let num = num.as_str();
use rustc_apfloat::ieee::{Single, Double};
use rustc_apfloat::Float;
let (bits, size) = match fty {
ast::FloatTy::F32 => {
num.parse::<f32>().map_err(|_| ())?;
let mut f = num.parse::<Single>().unwrap_or_else(|e| {
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
});
if neg {
f = -f;
}
(f.to_bits(), 4)
}
ast::FloatTy::F64 => {
num.parse::<f64>().map_err(|_| ())?;
let mut f = num.parse::<Double>().unwrap_or_else(|e| {
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
});
if neg {
f = -f;
}
(f.to_bits(), 8)
}
};
Ok(ConstValue::Scalar(Scalar::Bits { bits, size }))
}

View file

@ -26,12 +26,12 @@
use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::subst::{Kind, Substs};
use rustc::ty::layout::VariantIdx;
use syntax::ast::{self, LitKind};
use syntax::ast;
use syntax::attr;
use syntax::symbol::Symbol;
use rustc::hir;
use rustc_data_structures::sync::Lrc;
use hair::pattern::parse_float;
use hair::constant::{lit_to_const, LitToConstError};
#[derive(Clone)]
pub struct Cx<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
@ -131,7 +131,6 @@ pub fn false_literal(&mut self) -> &'tcx ty::Const<'tcx> {
ty::Const::from_bool(self.tcx, false)
}
// FIXME: Combine with rustc_mir::hair::pattern::lit_to_const
pub fn const_eval_literal(
&mut self,
lit: &'tcx ast::LitKind,
@ -141,61 +140,19 @@ pub fn const_eval_literal(
) -> &'tcx ty::Const<'tcx> {
trace!("const_eval_literal: {:#?}, {:?}, {:?}, {:?}", lit, ty, sp, neg);
let parse_float = |num, fty| -> ConstValue<'tcx> {
parse_float(num, fty, neg).unwrap_or_else(|_| {
match lit_to_const(lit, self.tcx, ty, neg) {
Ok(c) => c,
Err(LitToConstError::UnparseableFloat) => {
// FIXME(#31407) this is only necessary because float parsing is buggy
self.tcx.sess.span_fatal(sp, "could not evaluate float literal (see issue #31407)");
})
};
let trunc = |n| {
let param_ty = self.param_env.and(self.tcx.lift_to_global(&ty).unwrap());
let width = self.tcx.layout_of(param_ty).unwrap().size;
trace!("trunc {} with size {} and shift {}", n, width.bits(), 128 - width.bits());
let shift = 128 - width.bits();
let result = (n << shift) >> shift;
trace!("trunc result: {}", result);
ConstValue::Scalar(Scalar::Bits {
bits: result,
size: width.bytes() as u8,
})
};
use rustc::mir::interpret::*;
let lit = match *lit {
LitKind::Str(ref s, _) => {
let s = s.as_str();
let id = self.tcx.allocate_bytes(s.as_bytes());
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &self.tcx)
self.tcx.sess.span_err(sp, "could not evaluate float literal (see issue #31407)");
// create a dummy value and continue compiling
Const::from_bits(self.tcx, 0, self.param_env.and(ty))
},
LitKind::ByteStr(ref data) => {
let id = self.tcx.allocate_bytes(data);
ConstValue::Scalar(Scalar::Ptr(id.into()))
},
LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
bits: n as u128,
size: 1,
}),
LitKind::Int(n, _) if neg => {
let n = n as i128;
let n = n.overflowing_neg().0;
trunc(n as u128)
},
LitKind::Int(n, _) => trunc(n),
LitKind::Float(n, fty) => {
parse_float(n, fty)
Err(LitToConstError::Reported) => {
// create a dummy value and continue compiling
Const::from_bits(self.tcx, 0, self.param_env.and(ty))
}
LitKind::FloatUnsuffixed(n) => {
let fty = match ty.sty {
ty::Float(fty) => fty,
_ => bug!()
};
parse_float(n, fty)
}
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
};
ty::Const::from_const_value(self.tcx, lit, ty)
}
}
pub fn pattern_from_hir(&mut self, p: &hir::Pat) -> Pattern<'tcx> {

View file

@ -26,6 +26,7 @@
use self::cx::Cx;
pub mod cx;
mod constant;
pub mod pattern;
pub use self::pattern::{BindingMode, Pattern, PatternKind, FieldPattern};

View file

@ -234,7 +234,7 @@ fn check_match(
if !scrutinee_is_uninhabited {
// We know the type is inhabited, so this must be wrong
let mut err = create_e0004(self.tcx.sess, scrut.span,
format!("non-exhaustive patterns: type {} \
format!("non-exhaustive patterns: type `{}` \
is non-empty",
pat_ty));
span_help!(&mut err, scrut.span,

View file

@ -19,6 +19,7 @@
use const_eval::{const_field, const_variant_index};
use hair::util::UserAnnotatedTyHelpers;
use hair::constant::*;
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
use rustc::mir::{ProjectionElem, UserTypeAnnotation, UserTypeProjection, UserTypeProjections};
@ -37,7 +38,6 @@
use syntax::ast;
use syntax::ptr::P;
use syntax_pos::Span;
use syntax_pos::symbol::Symbol;
#[derive(Clone, Debug)]
pub enum PatternError {
@ -891,12 +891,11 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr) -> PatternKind<'tcx> {
);
*self.const_to_pat(instance, val, expr.hir_id, lit.span).kind
},
Err(e) => {
if e == LitToConstError::UnparseableFloat {
self.errors.push(PatternError::FloatBug);
}
Err(LitToConstError::UnparseableFloat) => {
self.errors.push(PatternError::FloatBug);
PatternKind::Wild
},
Err(LitToConstError::Reported) => PatternKind::Wild,
}
},
hir::ExprKind::Path(ref qpath) => *self.lower_path(qpath, expr.hir_id, expr.span).kind,
@ -914,12 +913,11 @@ fn lower_lit(&mut self, expr: &'tcx hir::Expr) -> PatternKind<'tcx> {
);
*self.const_to_pat(instance, val, expr.hir_id, lit.span).kind
},
Err(e) => {
if e == LitToConstError::UnparseableFloat {
self.errors.push(PatternError::FloatBug);
}
Err(LitToConstError::UnparseableFloat) => {
self.errors.push(PatternError::FloatBug);
PatternKind::Wild
},
Err(LitToConstError::Reported) => PatternKind::Wild,
}
}
_ => span_bug!(expr.span, "not a literal: {:?}", expr),
@ -1294,124 +1292,3 @@ pub fn compare_const_vals<'a, 'tcx>(
fallback()
}
#[derive(PartialEq)]
enum LitToConstError {
UnparseableFloat,
Propagated,
}
// FIXME: Combine with rustc_mir::hair::cx::const_eval_literal
fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
ty: Ty<'tcx>,
neg: bool)
-> Result<&'tcx ty::Const<'tcx>, LitToConstError> {
use syntax::ast::*;
use rustc::mir::interpret::*;
let lit = match *lit {
LitKind::Str(ref s, _) => {
let s = s.as_str();
let id = tcx.allocate_bytes(s.as_bytes());
ConstValue::new_slice(Scalar::Ptr(id.into()), s.len() as u64, &tcx)
},
LitKind::ByteStr(ref data) => {
let id = tcx.allocate_bytes(data);
ConstValue::Scalar(Scalar::Ptr(id.into()))
},
LitKind::Byte(n) => ConstValue::Scalar(Scalar::Bits {
bits: n as u128,
size: 1,
}),
LitKind::Int(n, _) => {
enum Int {
Signed(IntTy),
Unsigned(UintTy),
}
let ity = match ty.sty {
ty::Int(IntTy::Isize) => Int::Signed(tcx.sess.target.isize_ty),
ty::Int(other) => Int::Signed(other),
ty::Uint(UintTy::Usize) => Int::Unsigned(tcx.sess.target.usize_ty),
ty::Uint(other) => Int::Unsigned(other),
ty::Error => { // Avoid ICE (#51963)
return Err(LitToConstError::Propagated);
}
_ => bug!("literal integer type with bad type ({:?})", ty.sty),
};
// This converts from LitKind::Int (which is sign extended) to
// Scalar::Bytes (which is zero extended)
let n = match ity {
// FIXME(oli-obk): are these casts correct?
Int::Signed(IntTy::I8) if neg =>
(n as i8).overflowing_neg().0 as u8 as u128,
Int::Signed(IntTy::I16) if neg =>
(n as i16).overflowing_neg().0 as u16 as u128,
Int::Signed(IntTy::I32) if neg =>
(n as i32).overflowing_neg().0 as u32 as u128,
Int::Signed(IntTy::I64) if neg =>
(n as i64).overflowing_neg().0 as u64 as u128,
Int::Signed(IntTy::I128) if neg =>
(n as i128).overflowing_neg().0 as u128,
Int::Signed(IntTy::I8) | Int::Unsigned(UintTy::U8) => n as u8 as u128,
Int::Signed(IntTy::I16) | Int::Unsigned(UintTy::U16) => n as u16 as u128,
Int::Signed(IntTy::I32) | Int::Unsigned(UintTy::U32) => n as u32 as u128,
Int::Signed(IntTy::I64) | Int::Unsigned(UintTy::U64) => n as u64 as u128,
Int::Signed(IntTy::I128)| Int::Unsigned(UintTy::U128) => n,
_ => bug!(),
};
let size = tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size.bytes() as u8;
ConstValue::Scalar(Scalar::Bits {
bits: n,
size,
})
},
LitKind::Float(n, fty) => {
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
}
LitKind::FloatUnsuffixed(n) => {
let fty = match ty.sty {
ty::Float(fty) => fty,
_ => bug!()
};
parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)?
}
LitKind::Bool(b) => ConstValue::Scalar(Scalar::from_bool(b)),
LitKind::Char(c) => ConstValue::Scalar(Scalar::from_char(c)),
};
Ok(ty::Const::from_const_value(tcx, lit, ty))
}
pub fn parse_float<'tcx>(
num: Symbol,
fty: ast::FloatTy,
neg: bool,
) -> Result<ConstValue<'tcx>, ()> {
let num = num.as_str();
use rustc_apfloat::ieee::{Single, Double};
use rustc_apfloat::Float;
let (bits, size) = match fty {
ast::FloatTy::F32 => {
num.parse::<f32>().map_err(|_| ())?;
let mut f = num.parse::<Single>().unwrap_or_else(|e| {
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
});
if neg {
f = -f;
}
(f.to_bits(), 4)
}
ast::FloatTy::F64 => {
num.parse::<f64>().map_err(|_| ())?;
let mut f = num.parse::<Double>().unwrap_or_else(|e| {
panic!("apfloat::ieee::Single failed to parse `{}`: {:?}", num, e)
});
if neg {
f = -f;
}
(f.to_bits(), 8)
}
};
Ok(ConstValue::Scalar(Scalar::Bits { bits, size }))
}

View file

@ -357,7 +357,7 @@ fn qualify_const(&mut self) -> (Qualif, Lrc<BitSet<Local>>) {
TerminatorKind::FalseUnwind { .. } => None,
TerminatorKind::Return => {
if !self.tcx.sess.features_untracked().const_let {
if !self.tcx.features().const_let {
// Check for unused values. This usually means
// there are extra statements in the AST.
for temp in mir.temps_iter() {
@ -464,7 +464,7 @@ fn visit_local(&mut self,
LocalKind::ReturnPointer => {
self.not_const();
}
LocalKind::Var if !self.tcx.sess.features_untracked().const_let => {
LocalKind::Var if !self.tcx.features().const_let => {
if self.mode != Mode::Fn {
emit_feature_err(&self.tcx.sess.parse_sess, "const_let",
self.span, GateIssue::Language,
@ -558,7 +558,7 @@ fn visit_place(&mut self,
Mode::Fn => {},
_ => {
if let ty::RawPtr(_) = base_ty.sty {
if !this.tcx.sess.features_untracked().const_raw_ptr_deref {
if !this.tcx.features().const_raw_ptr_deref {
emit_feature_err(
&this.tcx.sess.parse_sess, "const_raw_ptr_deref",
this.span, GateIssue::Language,
@ -581,7 +581,7 @@ fn visit_place(&mut self,
match this.mode {
Mode::Fn => this.not_const(),
Mode::ConstFn => {
if !this.tcx.sess.features_untracked().const_fn_union {
if !this.tcx.features().const_fn_union {
emit_feature_err(
&this.tcx.sess.parse_sess, "const_fn_union",
this.span, GateIssue::Language,
@ -807,7 +807,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
if let Mode::Fn = self.mode {
// in normal functions, mark such casts as not promotable
self.add(Qualif::NOT_CONST);
} else if !self.tcx.sess.features_untracked().const_raw_ptr_to_usize_cast {
} else if !self.tcx.features().const_raw_ptr_to_usize_cast {
// in const fn and constants require the feature gate
// FIXME: make it unsafe inside const fn and constants
emit_feature_err(
@ -834,7 +834,7 @@ fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
if let Mode::Fn = self.mode {
// raw pointer operations are not allowed inside promoteds
self.add(Qualif::NOT_CONST);
} else if !self.tcx.sess.features_untracked().const_compare_raw_pointers {
} else if !self.tcx.features().const_compare_raw_pointers {
// require the feature gate inside constants and const fn
// FIXME: make it unsafe to use these operations
emit_feature_err(
@ -933,7 +933,7 @@ fn visit_terminator_kind(&mut self,
if self.mode != Mode::Fn {
is_const_fn = true;
// const eval transmute calls only with the feature gate
if !self.tcx.sess.features_untracked().const_transmute {
if !self.tcx.features().const_transmute {
emit_feature_err(
&self.tcx.sess.parse_sess, "const_transmute",
self.span, GateIssue::Language,
@ -971,7 +971,7 @@ fn visit_terminator_kind(&mut self,
// FIXME: cannot allow this inside `allow_internal_unstable` because
// that would make `panic!` insta stable in constants, since the
// macro is marked with the attr
if self.tcx.sess.features_untracked().const_panic {
if self.tcx.features().const_panic {
is_const_fn = true;
} else {
// don't allow panics in constants without the feature gate
@ -1158,7 +1158,7 @@ fn visit_assign(&mut self,
if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) {
if self.mir.local_kind(index) == LocalKind::Var &&
self.const_fn_arg_vars.insert(index) &&
!self.tcx.sess.features_untracked().const_let {
!self.tcx.features().const_let {
// Direct use of an argument is permitted.
match *rvalue {

View file

@ -3950,7 +3950,7 @@ fn lint_if_path_starts_with_module(
let first_name = match path.get(0) {
// In the 2018 edition this lint is a hard error, so nothing to do
Some(seg) if seg.ident.span.rust_2015() => seg.ident.name,
Some(seg) if seg.ident.span.rust_2015() && self.session.rust_2015() => seg.ident.name,
_ => return,
};

View file

@ -3,4 +3,4 @@ specific to different compilation targets and so forth.
For more information about how rustc works, see the [rustc guide].
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
[rustc guide]: https://rust-lang.github.io/rustc-guide/

View file

@ -1,5 +1,5 @@
For high-level intro to how type checking works in rustc, see the
[type checking] chapter of the [rustc guide].
[type checking]: https://rust-lang-nursery.github.io/rustc-guide/type-checking.html
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/
[type checking]: https://rust-lang.github.io/rustc-guide/type-checking.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/

View file

@ -59,7 +59,7 @@ fn next(&mut self) -> Option<Self::Item> {
if self.steps.len() >= *tcx.sess.recursion_limit.get() {
// We've reached the recursion limit, error gracefully.
let suggested_limit = *tcx.sess.recursion_limit.get() * 2;
let msg = format!("reached the recursion limit while auto-dereferencing {:?}",
let msg = format!("reached the recursion limit while auto-dereferencing `{:?}`",
self.cur_ty);
let error_id = (DiagnosticMessageId::ErrorId(55), Some(self.span), msg);
let fresh = tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
@ -67,7 +67,7 @@ fn next(&mut self) -> Option<Self::Item> {
struct_span_err!(tcx.sess,
self.span,
E0055,
"reached the recursion limit while auto-dereferencing {:?}",
"reached the recursion limit while auto-dereferencing `{:?}`",
self.cur_ty)
.span_label(self.span, "deref recursion limit reached")
.help(&format!(

View file

@ -10,7 +10,7 @@
//! Method lookup: the secret sauce of Rust. See the [rustc guide] chapter.
//!
//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/method-lookup.html
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/method-lookup.html
use check::FnCtxt;
use hir::def::Def;

View file

@ -538,7 +538,7 @@ fn main() {
let foo = Foo;
let ref_foo = &&Foo;
// error, reached the recursion limit while auto-dereferencing &&Foo
// error, reached the recursion limit while auto-dereferencing `&&Foo`
ref_foo.foo();
}
```

View file

@ -11,7 +11,7 @@
//! Module for inferring the variance of type and lifetime parameters. See the [rustc guide]
//! chapter for more info.
//!
//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/variance.html
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/variance.html
use arena;
use rustc::hir;

View file

@ -89,8 +89,8 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>
// See the following for a discussion on dep-graph management.
//
// - https://rust-lang-nursery.github.io/rustc-guide/query.html
// - https://rust-lang-nursery.github.io/rustc-guide/variance.html
// - https://rust-lang.github.io/rustc-guide/query.html
// - https://rust-lang.github.io/rustc-guide/variance.html
tcx.hir.krate().visit_all_item_likes(&mut terms_cx);
terms_cx

View file

@ -1,3 +1,3 @@
For more information about how `librustdoc` works, see the [rustc guide].
[rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/rustdoc.html
[rustc guide]: https://rust-lang.github.io/rustc-guide/rustdoc.html

View file

@ -121,7 +121,7 @@ ol, ul {
padding-left: 25px;
}
ul ul, ol ul, ul ol, ol ol {
margin-bottom: 0;
margin-bottom: .6em;
}
p {

View file

@ -112,12 +112,12 @@
//! ## On Unix
//!
//! On Unix, [`OsStr`] implements the
//! `std::os::unix:ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
//! `std::os::unix::ffi::`[`OsStrExt`][unix.OsStrExt] trait, which
//! augments it with two methods, [`from_bytes`] and [`as_bytes`].
//! These do inexpensive conversions from and to UTF-8 byte slices.
//!
//! Additionally, on Unix [`OsString`] implements the
//! `std::os::unix:ffi::`[`OsStringExt`][unix.OsStringExt] trait,
//! `std::os::unix::ffi::`[`OsStringExt`][unix.OsStringExt] trait,
//! which provides [`from_vec`] and [`into_vec`] methods that consume
//! their arguments, and take or produce vectors of [`u8`].
//!

View file

@ -95,10 +95,10 @@ pub fn get_task_waker<F, R>(f: F) -> R
});
let _reset_waker = SetOnDrop(waker_ptr);
let mut waker_ptr = waker_ptr.expect(
let waker_ptr = waker_ptr.expect(
"TLS LocalWaker not set. This is a rustc bug. \
Please file an issue on https://github.com/rust-lang/rust.");
unsafe { f(waker_ptr.as_mut()) }
unsafe { f(waker_ptr.as_ref()) }
}
#[unstable(feature = "gen_future", issue = "50547")]

View file

@ -431,7 +431,7 @@ fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R,
/// // read up to 10 bytes
/// f.read(&mut buffer)?;
///
/// let mut buffer = vec![0; 10];
/// let mut buffer = Vec::new();
/// // read the whole file
/// f.read_to_end(&mut buffer)?;
///

View file

@ -191,7 +191,7 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_size(&self) -> u64;
/// Returns the last access time.
/// Returns the last access time of the file, in seconds since Unix Epoch.
///
/// # Examples
///
@ -208,7 +208,9 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime(&self) -> i64;
/// Returns the last access time, nano seconds part.
/// Returns the last access time of the file, in nanoseconds since [`st_atime`].
///
/// [`st_atime`]: #tymethod.st_atime
///
/// # Examples
///
@ -225,7 +227,7 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_atime_nsec(&self) -> i64;
/// Returns the last modification time.
/// Returns the last modification time of the file, in seconds since Unix Epoch.
///
/// # Examples
///
@ -242,7 +244,9 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime(&self) -> i64;
/// Returns the last modification time, nano seconds part.
/// Returns the last modification time of the file, in nanoseconds since [`st_mtime`].
///
/// [`st_mtime`]: #tymethod.st_mtime
///
/// # Examples
///
@ -259,7 +263,7 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_mtime_nsec(&self) -> i64;
/// Returns the last status change time.
/// Returns the last status change time of the file, in seconds since Unix Epoch.
///
/// # Examples
///
@ -276,7 +280,9 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext2", since = "1.8.0")]
fn st_ctime(&self) -> i64;
/// Returns the last status change time, nano seconds part.
/// Returns the last status change time of the file, in nanoseconds since [`st_ctime`].
///
/// [`st_ctime`]: #tymethod.st_ctime
///
/// # Examples
///

View file

@ -522,7 +522,7 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn size(&self) -> u64;
/// Returns the time of the last access to the file.
/// Returns the last access time of the file, in seconds since Unix Epoch.
///
/// # Examples
///
@ -539,7 +539,9 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn atime(&self) -> i64;
/// Returns the time of the last access to the file in nanoseconds.
/// Returns the last access time of the file, in nanoseconds since [`atime`].
///
/// [`atime`]: #tymethod.atime
///
/// # Examples
///
@ -556,7 +558,7 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn atime_nsec(&self) -> i64;
/// Returns the time of the last modification of the file.
/// Returns the last modification time of the file, in seconds since Unix Epoch.
///
/// # Examples
///
@ -573,7 +575,9 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn mtime(&self) -> i64;
/// Returns the time of the last modification of the file in nanoseconds.
/// Returns the last modification time of the file, in nanoseconds since [`mtime`].
///
/// [`mtime`]: #tymethod.mtime
///
/// # Examples
///
@ -590,7 +594,7 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn mtime_nsec(&self) -> i64;
/// Returns the time of the last status change of the file.
/// Returns the last status change time of the file, in seconds since Unix Epoch.
///
/// # Examples
///
@ -607,7 +611,9 @@ pub trait MetadataExt {
/// ```
#[stable(feature = "metadata_ext", since = "1.1.0")]
fn ctime(&self) -> i64;
/// Returns the time of the last status change of the file in nanoseconds.
/// Returns the last status change time of the file, in nanoseconds since [`ctime`].
///
/// [`ctime`]: #tymethod.ctime
///
/// # Examples
///

View file

@ -326,7 +326,7 @@ pub fn name(mut self, name: String) -> Builder {
/// Sets the size of the stack (in bytes) for the new thread.
///
/// The actual stack size may be greater than this value if
/// the platform specifies minimal stack size.
/// the platform specifies a minimal stack size.
///
/// For more information about the stack size for threads, see
/// [this module-level documentation][stack-size].

View file

@ -5,5 +5,5 @@ lexer, macro expander, and utilities for traversing ASTs.
For more information about how these things work in rustc, see the
rustc guide:
- [Parsing](https://rust-lang-nursery.github.io/rustc-guide/the-parser.html)
- [Macro Expansion](https://rust-lang-nursery.github.io/rustc-guide/macro-expansion.html)
- [Parsing](https://rust-lang.github.io/rustc-guide/the-parser.html)
- [Macro Expansion](https://rust-lang.github.io/rustc-guide/macro-expansion.html)

View file

@ -60,11 +60,11 @@ pub struct StringReader<'a> {
// cache a direct reference to the source text, so that we don't have to
// retrieve it via `self.source_file.src.as_ref().unwrap()` all the time.
src: Lrc<String>,
/// Stack of open delimiters and their spans. Used for error message.
token: token::Token,
span: Span,
/// The raw source span which *does not* take `override_span` into account
span_src_raw: Span,
/// Stack of open delimiters and their spans. Used for error message.
open_braces: Vec<(token::DelimToken, Span)>,
/// The type and spans for all braces
///
@ -506,8 +506,7 @@ fn translate_crlf_(rdr: &StringReader,
}
}
/// Advance the StringReader by one character. If a newline is
/// discovered, add it to the SourceFile's list of line start offsets.
/// Advance the StringReader by one character.
crate fn bump(&mut self) {
let next_src_index = self.src_index(self.next_pos);
if next_src_index < self.end_src_index {

View file

@ -3952,7 +3952,7 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<source_map::Spanned<ast::Fiel
);
err.emit();
}
self.bump(); // `..` || `...`:w
self.bump(); // `..` || `...`
if self.token == token::CloseDelim(token::Brace) {
etc_span = Some(etc_sp);
@ -3972,7 +3972,7 @@ fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<source_map::Spanned<ast::Fiel
ate_comma = true;
}
etc_span = Some(etc_sp);
etc_span = Some(etc_sp.until(self.span));
if self.token == token::CloseDelim(token::Brace) {
// If the struct looks otherwise well formed, recover and continue.
if let Some(sp) = comma_sp {
@ -5172,8 +5172,12 @@ fn parse_trait_item_assoc_ty(&mut self)
/// Parses (possibly empty) list of lifetime and type parameters, possibly including
/// trailing comma and erroneous trailing attributes.
crate fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> {
let mut lifetimes = Vec::new();
let mut params = Vec::new();
let mut seen_ty_param = false;
let mut seen_ty_param: Option<Span> = None;
let mut last_comma_span = None;
let mut bad_lifetime_pos = vec![];
let mut suggestions = vec![];
loop {
let attrs = self.parse_outer_attributes()?;
if self.check_lifetime() {
@ -5184,25 +5188,42 @@ fn parse_trait_item_assoc_ty(&mut self)
} else {
Vec::new()
};
params.push(ast::GenericParam {
lifetimes.push(ast::GenericParam {
ident: lifetime.ident,
id: lifetime.id,
attrs: attrs.into(),
bounds,
kind: ast::GenericParamKind::Lifetime,
});
if seen_ty_param {
self.span_err(self.prev_span,
"lifetime parameters must be declared prior to type parameters");
if let Some(sp) = seen_ty_param {
let param_span = self.prev_span;
let ate_comma = self.eat(&token::Comma);
let remove_sp = if ate_comma {
param_span.until(self.span)
} else {
last_comma_span.unwrap_or(param_span).to(param_span)
};
bad_lifetime_pos.push(param_span);
if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) {
suggestions.push((remove_sp, String::new()));
suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet)));
}
if ate_comma {
last_comma_span = Some(self.prev_span);
continue
}
}
} else if self.check_ident() {
// Parse type parameter.
params.push(self.parse_ty_param(attrs)?);
seen_ty_param = true;
if seen_ty_param.is_none() {
seen_ty_param = Some(self.prev_span);
}
} else {
// Check for trailing attributes and stop parsing.
if !attrs.is_empty() {
let param_kind = if seen_ty_param { "type" } else { "lifetime" };
let param_kind = if seen_ty_param.is_some() { "type" } else { "lifetime" };
self.span_err(attrs[0].span,
&format!("trailing attribute after {} parameters", param_kind));
}
@ -5212,8 +5233,24 @@ fn parse_trait_item_assoc_ty(&mut self)
if !self.eat(&token::Comma) {
break
}
last_comma_span = Some(self.prev_span);
}
Ok(params)
if !bad_lifetime_pos.is_empty() {
let mut err = self.struct_span_err(
bad_lifetime_pos,
"lifetime parameters must be declared prior to type parameters",
);
if !suggestions.is_empty() {
err.multipart_suggestion_with_applicability(
"move the lifetime parameter prior to the first type parameter",
suggestions,
Applicability::MachineApplicable,
);
}
err.emit();
}
lifetimes.extend(params); // ensure the correct order of lifetimes and type params
Ok(lifetimes)
}
/// Parse a set of optional generic type parameter declarations. Where

View file

@ -1,4 +1,4 @@
# Compiler Test Documentation
Documentation the compiler testing framework has moved to
[the rustc guide](https://rust-lang-nursery.github.io/rustc-guide/tests/intro.html).
[the rustc guide](https://rust-lang.github.io/rustc-guide/tests/intro.html).

View file

@ -1,4 +1,4 @@
error[E0055]: reached the recursion limit while auto-dereferencing I
error[E0055]: reached the recursion limit while auto-dereferencing `I`
--> $DIR/recursion_limit_deref.rs:60:22
|
LL | let x: &Bottom = &t; //~ ERROR mismatched types

View file

@ -1,4 +1,4 @@
error[E0004]: non-exhaustive patterns: type std::option::Option<i32> is non-empty
error[E0004]: non-exhaustive patterns: type `std::option::Option<i32>` is non-empty
--> $DIR/E0004-2.rs:14:11
|
LL | match x { } //~ ERROR E0004

View file

@ -1,4 +1,4 @@
error[E0055]: reached the recursion limit while auto-dereferencing Foo
error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
--> $DIR/E0055.rs:21:13
|
LL | ref_foo.foo();

View file

@ -7,7 +7,7 @@ LL | x = box x;
| cyclic type of infinite size
| help: try using a conversion method: `box x.to_string()`
error[E0055]: reached the recursion limit while auto-dereferencing Foo
error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
--> $DIR/infinite-autoderef.rs:35:5
|
LL | Foo.foo;
@ -15,7 +15,7 @@ LL | Foo.foo;
|
= help: consider adding a `#![recursion_limit="128"]` attribute to your crate
error[E0055]: reached the recursion limit while auto-dereferencing Foo
error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
--> $DIR/infinite-autoderef.rs:35:9
|
LL | Foo.foo;
@ -29,7 +29,7 @@ error[E0609]: no field `foo` on type `Foo`
LL | Foo.foo;
| ^^^ unknown field
error[E0055]: reached the recursion limit while auto-dereferencing Foo
error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
--> $DIR/infinite-autoderef.rs:36:9
|
LL | Foo.bar();

View file

@ -1,4 +1,4 @@
error[E0004]: non-exhaustive patterns: type () is non-empty
error[E0004]: non-exhaustive patterns: type `()` is non-empty
--> $DIR/issue-3096-1.rs:12:11
|
LL | match () { } //~ ERROR non-exhaustive

View file

@ -1,4 +1,4 @@
error[E0004]: non-exhaustive patterns: type *const bottom is non-empty
error[E0004]: non-exhaustive patterns: type `*const bottom` is non-empty
--> $DIR/issue-3096-2.rs:15:11
|
LL | match x { } //~ ERROR non-exhaustive patterns

View file

@ -42,5 +42,5 @@ fn main() {
let t = Top::new();
let x: &Bottom = &t;
//~^ ERROR mismatched types
//~| ERROR reached the recursion limit while auto-dereferencing I
//~| ERROR reached the recursion limit while auto-dereferencing `I`
}

View file

@ -1,4 +1,4 @@
error[E0055]: reached the recursion limit while auto-dereferencing I
error[E0055]: reached the recursion limit while auto-dereferencing `I`
--> $DIR/issue-38940.rs:43:22
|
LL | let x: &Bottom = &t;

View file

@ -8,8 +8,8 @@ LL | let Point { .., y, } = p; //~ ERROR expected `}`, found `,`
| `..` must be at the end and cannot have a trailing comma
help: move the `..` to the end of the field list
|
LL | let Point { y, .. } = p; //~ ERROR expected `}`, found `,`
| -- ^^^^
LL | let Point { y, .. } = p; //~ ERROR expected `}`, found `,`
| -- ^^^^
error: expected `}`, found `,`
--> $DIR/issue-49257.rs:21:19
@ -21,8 +21,8 @@ LL | let Point { .., y } = p; //~ ERROR expected `}`, found `,`
| `..` must be at the end and cannot have a trailing comma
help: move the `..` to the end of the field list
|
LL | let Point { y , .. } = p; //~ ERROR expected `}`, found `,`
| -- ^^^^^^
LL | let Point { y , .. } = p; //~ ERROR expected `}`, found `,`
| -- ^^^^^^
error: expected `}`, found `,`
--> $DIR/issue-49257.rs:22:19

View file

@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
|
LL | enum X<'a, T, 'b> {
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | enum X<'a, 'b, T> {
| ^^^ --
error: aborting due to previous error

View file

@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
|
LL | fn foo<'a, T, 'b>(x: &'a T) {}
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | fn foo<'a, 'b, T>(x: &'a T) {}
| ^^^ --
error: aborting due to previous error

View file

@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
|
LL | impl<'a, T, 'b> X {}
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | impl<'a, 'b, T> X {}
| ^^^ --
error: aborting due to previous error

View file

@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
|
LL | struct X<'a, T, 'b> {
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | struct X<'a, 'b, T> {
| ^^^ --
error: aborting due to previous error

View file

@ -3,6 +3,10 @@ error: lifetime parameters must be declared prior to type parameters
|
LL | trait Foo<'a, T, 'b> {}
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | trait Foo<'a, 'b, T> {}
| ^^^ --
error: aborting due to previous error

View file

@ -9,3 +9,14 @@
// except according to those terms.
pub fn foo() {}
#[macro_export]
macro_rules! macro_2015 {
() => {
use edition_lint_paths as other_name;
use edition_lint_paths::foo as other_foo;
fn check_macro_2015() {
::edition_lint_paths::foo();
}
}
}

View file

@ -0,0 +1,10 @@
// compile-pass
// edition:2018
// compile-flags:--extern edition_lint_paths
// aux-build:edition-lint-paths.rs
#![deny(absolute_paths_not_starting_with_crate)]
edition_lint_paths::macro_2015!(); // OK
fn main() {}

View file

@ -0,0 +1,21 @@
struct A<T, 'a> {
t: &'a T,
}
struct B<T, 'a, U> {
t: &'a T,
u: U,
}
struct C<T, U, 'a> {
t: &'a T,
u: U,
}
struct D<T, U, 'a, 'b, V, 'c> {
t: &'a T,
u: &'b U,
v: &'c V,
}
fn main() {}

View file

@ -0,0 +1,42 @@
error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:1:13
|
LL | struct A<T, 'a> {
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | struct A<'a, T> {
| ^^^ --
error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:5:13
|
LL | struct B<T, 'a, U> {
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | struct B<'a, T, U> {
| ^^^ --
error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:10:16
|
LL | struct C<T, U, 'a> {
| ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | struct C<'a, T, U> {
| ^^^ --
error: lifetime parameters must be declared prior to type parameters
--> $DIR/suggest-move-lifetimes.rs:15:16
|
LL | struct D<T, U, 'a, 'b, V, 'c> {
| ^^ ^^ ^^
help: move the lifetime parameter prior to the first type parameter
|
LL | struct D<'a, 'b, 'c, T, U, V> {
| ^^^ ^^^ ^^^ ---
error: aborting due to 4 previous errors

View file

@ -4,7 +4,7 @@ error[E0004]: non-exhaustive patterns: `Err(_)` not covered
LL | let _ = match x { //~ ERROR non-exhaustive
| ^ pattern `Err(_)` not covered
error[E0004]: non-exhaustive patterns: type &Void is non-empty
error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
--> $DIR/uninhabited-matches-feature-gated.rs:20:19
|
LL | let _ = match x {}; //~ ERROR non-exhaustive
@ -16,7 +16,7 @@ help: ensure that all possible cases are being handled, possibly by adding wildc
LL | let _ = match x {}; //~ ERROR non-exhaustive
| ^
error[E0004]: non-exhaustive patterns: type (Void,) is non-empty
error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
--> $DIR/uninhabited-matches-feature-gated.rs:23:19
|
LL | let _ = match x {}; //~ ERROR non-exhaustive
@ -28,7 +28,7 @@ help: ensure that all possible cases are being handled, possibly by adding wildc
LL | let _ = match x {}; //~ ERROR non-exhaustive
| ^
error[E0004]: non-exhaustive patterns: type [Void; 1] is non-empty
error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
--> $DIR/uninhabited-matches-feature-gated.rs:26:19
|
LL | let _ = match x {}; //~ ERROR non-exhaustive