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
83 changed files with 418 additions and 316 deletions
+3
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
+2 -2
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/
+1 -1
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
+1 -1
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
+2 -2
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
+3
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.
Submodule src/doc/rustc-guide added at 3a804956e3
+2 -2
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.
+2 -1
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
///
+2 -5
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 {
+9 -7
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.
///
+1 -1
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/
+1 -1
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
+1 -1
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,
+1 -1
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,
@@ -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>,
+1 -1
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;
@@ -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>,
+1 -1
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;
+1 -1
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>
@@ -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
@@ -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:
+1 -1
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
//!
+1 -1
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};
+1 -1
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;
+2 -2
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;
+1 -1
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::*;
+1 -1
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>
{
+3 -3
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,
+1 -1
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;
+1 -1
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
}
}
}
+1 -1
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>,
+1 -1
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
+1 -1
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,
+1 -1
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
+1 -1
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
+1 -1
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
+9 -3
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,
+102
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 }))
}
+12 -55
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> {
+1
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};
+1 -1
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,
+7 -130
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 }))
}
+9 -9
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 {
+1 -1
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,
};
+1 -1
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/
+2 -2
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/
+2 -2
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!(
+1 -1
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;
+1 -1
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();
}
```
+1 -1
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;
+2 -2
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
+1 -1
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
+1 -1
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 {
+2 -2
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`].
//!
+2 -2
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")]
+1 -1
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)?;
///
+12 -6
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
///
+12 -6
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
///
+1 -1
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].
+2 -2
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)
+2 -3
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 {
+47 -10
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
+1 -1
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).
@@ -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
+1 -1
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
+1 -1
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();
@@ -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();
+1 -1
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
+1 -1
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
+1 -1
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`
}
+1 -1
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;
+4 -4
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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();
}
}
}
@@ -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() {}
@@ -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() {}
@@ -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
@@ -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