mirror of
https://github.com/rust-lang/rust
synced 2024-10-14 12:33:57 +00:00
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:
commit
0c1dc62c1e
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
1
src/doc/rustc-guide
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 3a804956e3c28d7e44e38804207a00013594e1d3
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
///
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,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,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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
//!
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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>
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
src/librustc_mir/hair/constant.rs
Normal file
102
src/librustc_mir/hair/constant.rs
Normal 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 }))
|
||||
}
|
|
@ -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> {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
use self::cx::Cx;
|
||||
|
||||
pub mod cx;
|
||||
mod constant;
|
||||
|
||||
pub mod pattern;
|
||||
pub use self::pattern::{BindingMode, Pattern, PatternKind, FieldPattern};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 }))
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
```
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,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
|
||||
|
|
|
@ -121,7 +121,7 @@ ol, ul {
|
|||
padding-left: 25px;
|
||||
}
|
||||
ul ul, ol ul, ul ol, ol ol {
|
||||
margin-bottom: 0;
|
||||
margin-bottom: .6em;
|
||||
}
|
||||
|
||||
p {
|
||||
|
|
|
@ -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`].
|
||||
//!
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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)?;
|
||||
///
|
||||
|
|
|
@ -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
|
||||
///
|
||||
|
|
|
@ -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
|
||||
///
|
||||
|
|
|
@ -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].
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,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,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,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,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,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
|
||||
|
|
|
@ -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,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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
src/test/ui/rust-2018/edition-lint-paths-2018.rs
Normal file
10
src/test/ui/rust-2018/edition-lint-paths-2018.rs
Normal 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() {}
|
21
src/test/ui/suggestions/suggest-move-lifetimes.rs
Normal file
21
src/test/ui/suggestions/suggest-move-lifetimes.rs
Normal 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() {}
|
42
src/test/ui/suggestions/suggest-move-lifetimes.stderr
Normal file
42
src/test/ui/suggestions/suggest-move-lifetimes.stderr
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue