Auto merge of #76975 - RalfJung:rollup-s2wiuqr, r=RalfJung

Rollup of 15 pull requests

Successful merges:

 - #76732 (Add docs for `BasicBlock`)
 - #76832 (Let backends define custom targets)
 - #76866 (Remove unused feature gates from library/ crates)
 - #76875 (Move to intra-doc links in library/alloc/src/collections/binary_heap.rs)
 - #76876 (Move to intra-doc links in collections/btree/map.rs and collections/linked_list.rs)
 - #76877 (Move to intra-doc links in collections/vec_deque.rs and collections/vec_deque/drain.rs)
 - #76878 (Move the version number to a plaintext file)
 - #76883 (README.md: Remove prompts from code blocks)
 - #76887 (Add missing examples on HashSet iter types)
 - #76890 (use matches!() macro for simple if let conditions)
 - #76891 (don't take `TyCtxt` by reference)
 - #76910 (transmute: use diagnostic item)
 - #76924 (Add tracking issue for feature(unix_socket_peek))
 - #76926 (BTreeMap: code readability tweaks)
 - #76940 (Don't allow implementing trait directly on type-alias-impl-trait)

Failed merges:

r? `@ghost`
This commit is contained in:
bors 2020-09-20 15:12:40 +00:00
commit 81e02708f1
56 changed files with 359 additions and 213 deletions

View File

@ -44,8 +44,8 @@ by running `./x.py --help` or reading the [rustc dev guide][rustcguidebuild].
2. Clone the [source] with `git`: 2. Clone the [source] with `git`:
```sh ```sh
$ git clone https://github.com/rust-lang/rust.git git clone https://github.com/rust-lang/rust.git
$ cd rust cd rust
``` ```
[source]: https://github.com/rust-lang/rust [source]: https://github.com/rust-lang/rust
@ -57,7 +57,7 @@ by running `./x.py --help` or reading the [rustc dev guide][rustcguidebuild].
Copy the default `config.toml.example` to `config.toml` to get started. Copy the default `config.toml.example` to `config.toml` to get started.
```sh ```sh
$ cp config.toml.example config.toml cp config.toml.example config.toml
``` ```
If you plan to use `x.py install` to create an installation, it is recommended If you plan to use `x.py install` to create an installation, it is recommended
@ -68,7 +68,7 @@ by running `./x.py --help` or reading the [rustc dev guide][rustcguidebuild].
4. Build and install: 4. Build and install:
```sh ```sh
$ ./x.py build && ./x.py install ./x.py build && ./x.py install
``` ```
When complete, `./x.py install` will place several programs into When complete, `./x.py install` will place several programs into
@ -106,7 +106,7 @@ build.
```sh ```sh
# Update package mirrors (may be needed if you have a fresh install of MSYS2) # Update package mirrors (may be needed if you have a fresh install of MSYS2)
$ pacman -Sy pacman-mirrors pacman -Sy pacman-mirrors
# Install build tools needed for Rust. If you're building a 32-bit compiler, # Install build tools needed for Rust. If you're building a 32-bit compiler,
# then replace "x86_64" below with "i686". If you've already got git, python, # then replace "x86_64" below with "i686". If you've already got git, python,
@ -114,7 +114,7 @@ build.
# that it is important that you do **not** use the 'python2', 'cmake' and 'ninja' # that it is important that you do **not** use the 'python2', 'cmake' and 'ninja'
# packages from the 'msys2' subsystem. The build has historically been known # packages from the 'msys2' subsystem. The build has historically been known
# to fail with these packages. # to fail with these packages.
$ pacman -S git \ pacman -S git \
make \ make \
diffutils \ diffutils \
tar \ tar \
@ -127,7 +127,7 @@ build.
4. Navigate to Rust's source code (or clone it), then build it: 4. Navigate to Rust's source code (or clone it), then build it:
```sh ```sh
$ ./x.py build && ./x.py install ./x.py build && ./x.py install
``` ```
#### MSVC #### MSVC
@ -145,7 +145,7 @@ With these dependencies installed, you can build the compiler in a `cmd.exe`
shell with: shell with:
```sh ```sh
> python x.py build python x.py build
``` ```
Currently, building Rust only works with some known versions of Visual Studio. If Currently, building Rust only works with some known versions of Visual Studio. If
@ -154,8 +154,8 @@ you may need to force rustbuild to use an older version. This can be done
by manually calling the appropriate vcvars file before running the bootstrap. by manually calling the appropriate vcvars file before running the bootstrap.
```batch ```batch
> CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat" CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
> python x.py build python x.py build
``` ```
#### Specifying an ABI #### Specifying an ABI
@ -181,8 +181,8 @@ While it's not the recommended build system, this project also provides a
configure script and makefile (the latter of which just invokes `x.py`). configure script and makefile (the latter of which just invokes `x.py`).
```sh ```sh
$ ./configure ./configure
$ make && sudo make install make && sudo make install
``` ```
When using the configure script, the generated `config.mk` file may override the When using the configure script, the generated `config.mk` file may override the
@ -194,7 +194,7 @@ When using the configure script, the generated `config.mk` file may override the
If youd like to build the documentation, its almost the same: If youd like to build the documentation, its almost the same:
```sh ```sh
$ ./x.py doc ./x.py doc
``` ```
The generated documentation will appear under `doc` in the `build` directory for The generated documentation will appear under `doc` in the `build` directory for

View File

@ -1931,7 +1931,7 @@ pub enum TyKind {
impl TyKind { impl TyKind {
pub fn is_implicit_self(&self) -> bool { pub fn is_implicit_self(&self) -> bool {
if let TyKind::ImplicitSelf = *self { true } else { false } matches!(self, TyKind::ImplicitSelf)
} }
pub fn is_unit(&self) -> bool { pub fn is_unit(&self) -> bool {
@ -2227,7 +2227,7 @@ pub enum Async {
impl Async { impl Async {
pub fn is_async(self) -> bool { pub fn is_async(self) -> bool {
if let Async::Yes { .. } = self { true } else { false } matches!(self, Async::Yes { .. })
} }
/// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item. /// In this case this is an `async` return, the `NodeId` for the generated `impl Trait` item.
@ -2508,7 +2508,7 @@ pub enum VisibilityKind {
impl VisibilityKind { impl VisibilityKind {
pub fn is_pub(&self) -> bool { pub fn is_pub(&self) -> bool {
if let VisibilityKind::Public = *self { true } else { false } matches!(self, VisibilityKind::Public)
} }
} }

View File

@ -868,10 +868,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.emit(); .emit();
} }
if !bounds if !bounds.iter().any(|b| matches!(b, GenericBound::Trait(..))) {
.iter()
.any(|b| if let GenericBound::Trait(..) = *b { true } else { false })
{
self.err_handler().span_err(ty.span, "at least one trait must be specified"); self.err_handler().span_err(ty.span, "at least one trait must be specified");
} }

View File

@ -160,10 +160,10 @@ pub enum StabilityLevel {
impl StabilityLevel { impl StabilityLevel {
pub fn is_unstable(&self) -> bool { pub fn is_unstable(&self) -> bool {
if let StabilityLevel::Unstable { .. } = *self { true } else { false } matches!(self, StabilityLevel::Unstable { .. })
} }
pub fn is_stable(&self) -> bool { pub fn is_stable(&self) -> bool {
if let StabilityLevel::Stable { .. } = *self { true } else { false } matches!(self, StabilityLevel::Stable { .. })
} }
} }

View File

@ -1529,7 +1529,7 @@ impl<'a> TraitDef<'a> {
} }
} }
let is_tuple = if let ast::VariantData::Tuple(..) = struct_def { true } else { false }; let is_tuple = matches!(struct_def, ast::VariantData::Tuple(..));
match (just_spans.is_empty(), named_idents.is_empty()) { match (just_spans.is_empty(), named_idents.is_empty()) {
(false, false) => cx.span_bug( (false, false) => cx.span_bug(
self.span, self.span,

View File

@ -15,6 +15,7 @@ use rustc_session::{
}; };
use rustc_span::symbol::Symbol; use rustc_span::symbol::Symbol;
use rustc_target::abi::LayoutOf; use rustc_target::abi::LayoutOf;
use rustc_target::spec::Target;
pub use rustc_data_structures::sync::MetadataRef; pub use rustc_data_structures::sync::MetadataRef;
@ -54,6 +55,12 @@ pub trait CodegenBackend {
fn print_passes(&self) {} fn print_passes(&self) {}
fn print_version(&self) {} fn print_version(&self) {}
/// If this plugin provides additional builtin targets, provide the one enabled by the options here.
/// Be careful: this is called *before* init() is called.
fn target_override(&self, _opts: &config::Options) -> Option<Target> {
None
}
fn metadata_loader(&self) -> Box<MetadataLoaderDyn>; fn metadata_loader(&self) -> Box<MetadataLoaderDyn>;
fn provide(&self, _providers: &mut Providers); fn provide(&self, _providers: &mut Providers);
fn provide_extern(&self, _providers: &mut Providers); fn provide_extern(&self, _providers: &mut Providers);

View File

@ -118,17 +118,15 @@ pub struct Annotation {
impl Annotation { impl Annotation {
/// Whether this annotation is a vertical line placeholder. /// Whether this annotation is a vertical line placeholder.
pub fn is_line(&self) -> bool { pub fn is_line(&self) -> bool {
if let AnnotationType::MultilineLine(_) = self.annotation_type { true } else { false } matches!(self.annotation_type, AnnotationType::MultilineLine(_))
} }
pub fn is_multiline(&self) -> bool { pub fn is_multiline(&self) -> bool {
match self.annotation_type { matches!(self.annotation_type,
AnnotationType::Multiline(_) AnnotationType::Multiline(_)
| AnnotationType::MultilineStart(_) | AnnotationType::MultilineStart(_)
| AnnotationType::MultilineLine(_) | AnnotationType::MultilineLine(_)
| AnnotationType::MultilineEnd(_) => true, | AnnotationType::MultilineEnd(_))
_ => false,
}
} }
pub fn len(&self) -> usize { pub fn len(&self) -> usize {

View File

@ -40,6 +40,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
DiagnosticOutput::Default, DiagnosticOutput::Default,
Default::default(), Default::default(),
None, None,
None,
); );
(sess, cfg) (sess, cfg)
} }

View File

@ -65,6 +65,10 @@ pub fn create_session(
lint_caps: FxHashMap<lint::LintId, lint::Level>, lint_caps: FxHashMap<lint::LintId, lint::Level>,
descriptions: Registry, descriptions: Registry,
) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>) { ) -> (Lrc<Session>, Lrc<Box<dyn CodegenBackend>>) {
let codegen_backend = get_codegen_backend(&sopts);
// target_override is documented to be called before init(), so this is okay
let target_override = codegen_backend.target_override(&sopts);
let mut sess = session::build_session( let mut sess = session::build_session(
sopts, sopts,
input_path, input_path,
@ -72,9 +76,10 @@ pub fn create_session(
diagnostic_output, diagnostic_output,
lint_caps, lint_caps,
file_loader, file_loader,
target_override,
); );
let codegen_backend = get_codegen_backend(&sess); codegen_backend.init(&sess);
let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg)); let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
add_configuration(&mut cfg, &mut sess, &*codegen_backend); add_configuration(&mut cfg, &mut sess, &*codegen_backend);
@ -219,13 +224,13 @@ fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
} }
} }
pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> { pub fn get_codegen_backend(sopts: &config::Options) -> Box<dyn CodegenBackend> {
static INIT: Once = Once::new(); static INIT: Once = Once::new();
static mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!(); static mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!();
INIT.call_once(|| { INIT.call_once(|| {
let codegen_name = sess.opts.debugging_opts.codegen_backend.as_deref().unwrap_or("llvm"); let codegen_name = sopts.debugging_opts.codegen_backend.as_deref().unwrap_or("llvm");
let backend = match codegen_name { let backend = match codegen_name {
filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()), filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
codegen_name => get_builtin_codegen_backend(codegen_name), codegen_name => get_builtin_codegen_backend(codegen_name),
@ -235,9 +240,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
LOAD = backend; LOAD = backend;
} }
}); });
let backend = unsafe { LOAD() }; unsafe { LOAD() }
backend.init(sess);
backend
} }
// This is used for rustdoc, but it uses similar machinery to codegen backend // This is used for rustdoc, but it uses similar machinery to codegen backend

View File

@ -1984,9 +1984,9 @@ impl ExplicitOutlivesRequirements {
.filter_map(|(i, bound)| { .filter_map(|(i, bound)| {
if let hir::GenericBound::Outlives(lifetime) = bound { if let hir::GenericBound::Outlives(lifetime) = bound {
let is_inferred = match tcx.named_region(lifetime.hir_id) { let is_inferred = match tcx.named_region(lifetime.hir_id) {
Some(Region::Static) if infer_static => inferred_outlives Some(Region::Static) if infer_static => {
.iter() inferred_outlives.iter().any(|r| matches!(r, ty::ReStatic))
.any(|r| if let ty::ReStatic = r { true } else { false }), }
Some(Region::EarlyBound(index, ..)) => inferred_outlives.iter().any(|r| { Some(Region::EarlyBound(index, ..)) => inferred_outlives.iter().any(|r| {
if let ty::ReEarlyBound(ebr) = r { ebr.index == index } else { false } if let ty::ReEarlyBound(ebr) = r { ebr.index == index } else { false }
}), }),
@ -2078,9 +2078,10 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
let mut lint_spans = Vec::new(); let mut lint_spans = Vec::new();
for param in hir_generics.params { for param in hir_generics.params {
let has_lifetime_bounds = param.bounds.iter().any(|bound| { let has_lifetime_bounds = param
if let hir::GenericBound::Outlives(_) = bound { true } else { false } .bounds
}); .iter()
.any(|bound| matches!(bound, hir::GenericBound::Outlives(_)));
if !has_lifetime_bounds { if !has_lifetime_bounds {
continue; continue;
} }
@ -2349,13 +2350,6 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
/// Determine if this expression is a "dangerous initialization". /// Determine if this expression is a "dangerous initialization".
fn is_dangerous_init(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<InitKind> { fn is_dangerous_init(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<InitKind> {
// `transmute` is inside an anonymous module (the `extern` block?);
// `Invalid` represents the empty string and matches that.
// FIXME(#66075): use diagnostic items. Somehow, that does not seem to work
// on intrinsics right now.
const TRANSMUTE_PATH: &[Symbol] =
&[sym::core, sym::intrinsics, kw::Invalid, sym::transmute];
if let hir::ExprKind::Call(ref path_expr, ref args) = expr.kind { if let hir::ExprKind::Call(ref path_expr, ref args) = expr.kind {
// Find calls to `mem::{uninitialized,zeroed}` methods. // Find calls to `mem::{uninitialized,zeroed}` methods.
if let hir::ExprKind::Path(ref qpath) = path_expr.kind { if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
@ -2365,7 +2359,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
return Some(InitKind::Zeroed); return Some(InitKind::Zeroed);
} else if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, def_id) { } else if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, def_id) {
return Some(InitKind::Uninit); return Some(InitKind::Uninit);
} else if cx.match_def_path(def_id, TRANSMUTE_PATH) { } else if cx.tcx.is_diagnostic_item(sym::transmute, def_id) {
if is_zero(&args[0]) { if is_zero(&args[0]) {
return Some(InitKind::Zeroed); return Some(InitKind::Zeroed);
} }

View File

@ -720,6 +720,10 @@ impl<'tcx> LateContext<'tcx> {
/// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`; /// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`;
/// inherent `impl` blocks are matched with the name of the type. /// inherent `impl` blocks are matched with the name of the type.
/// ///
/// Instead of using this method, it is often preferable to instead use
/// `rustc_diagnostic_item` or a `lang_item`. This is less prone to errors
/// as paths get invalidated if the target definition moves.
///
/// # Examples /// # Examples
/// ///
/// ```rust,ignore (no context or def id available) /// ```rust,ignore (no context or def id available)

View File

@ -69,7 +69,7 @@ pub enum LibSource {
impl LibSource { impl LibSource {
pub fn is_some(&self) -> bool { pub fn is_some(&self) -> bool {
if let LibSource::Some(_) = *self { true } else { false } matches!(self, LibSource::Some(_))
} }
pub fn option(&self) -> Option<PathBuf> { pub fn option(&self) -> Option<PathBuf> {

View File

@ -17,7 +17,7 @@ use rustc_target::spec::PanicStrategy;
impl<'tcx> TyCtxt<'tcx> { impl<'tcx> TyCtxt<'tcx> {
/// Returns the `DefId` for a given `LangItem`. /// Returns the `DefId` for a given `LangItem`.
/// If not found, fatally aborts compilation. /// If not found, fatally aborts compilation.
pub fn require_lang_item(&self, lang_item: LangItem, span: Option<Span>) -> DefId { pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId {
self.lang_items().require(lang_item).unwrap_or_else(|msg| { self.lang_items().require(lang_item).unwrap_or_else(|msg| {
if let Some(span) = span { if let Some(span) = span {
self.sess.span_fatal(span, &msg) self.sess.span_fatal(span, &msg)
@ -27,7 +27,7 @@ impl<'tcx> TyCtxt<'tcx> {
}) })
} }
pub fn fn_trait_kind_from_lang_item(&self, id: DefId) -> Option<ty::ClosureKind> { pub fn fn_trait_kind_from_lang_item(self, id: DefId) -> Option<ty::ClosureKind> {
let items = self.lang_items(); let items = self.lang_items();
match Some(id) { match Some(id) {
x if x == items.fn_trait() => Some(ty::ClosureKind::Fn), x if x == items.fn_trait() => Some(ty::ClosureKind::Fn),
@ -37,7 +37,7 @@ impl<'tcx> TyCtxt<'tcx> {
} }
} }
pub fn is_weak_lang_item(&self, item_def_id: DefId) -> bool { pub fn is_weak_lang_item(self, item_def_id: DefId) -> bool {
self.lang_items().is_weak_lang_item(item_def_id) self.lang_items().is_weak_lang_item(item_def_id)
} }
} }

View File

@ -447,14 +447,14 @@ impl<'tcx> TyCtxt<'tcx> {
/// ///
/// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such /// Make sure to call `set_alloc_id_memory` or `set_alloc_id_same_memory` before returning such
/// an `AllocId` from a query. /// an `AllocId` from a query.
pub fn reserve_alloc_id(&self) -> AllocId { pub fn reserve_alloc_id(self) -> AllocId {
self.alloc_map.lock().reserve() self.alloc_map.lock().reserve()
} }
/// Reserves a new ID *if* this allocation has not been dedup-reserved before. /// Reserves a new ID *if* this allocation has not been dedup-reserved before.
/// Should only be used for function pointers and statics, we don't want /// Should only be used for function pointers and statics, we don't want
/// to dedup IDs for "real" memory! /// to dedup IDs for "real" memory!
fn reserve_and_set_dedup(&self, alloc: GlobalAlloc<'tcx>) -> AllocId { fn reserve_and_set_dedup(self, alloc: GlobalAlloc<'tcx>) -> AllocId {
let mut alloc_map = self.alloc_map.lock(); let mut alloc_map = self.alloc_map.lock();
match alloc { match alloc {
GlobalAlloc::Function(..) | GlobalAlloc::Static(..) => {} GlobalAlloc::Function(..) | GlobalAlloc::Static(..) => {}
@ -472,13 +472,13 @@ impl<'tcx> TyCtxt<'tcx> {
/// Generates an `AllocId` for a static or return a cached one in case this function has been /// Generates an `AllocId` for a static or return a cached one in case this function has been
/// called on the same static before. /// called on the same static before.
pub fn create_static_alloc(&self, static_id: DefId) -> AllocId { pub fn create_static_alloc(self, static_id: DefId) -> AllocId {
self.reserve_and_set_dedup(GlobalAlloc::Static(static_id)) self.reserve_and_set_dedup(GlobalAlloc::Static(static_id))
} }
/// Generates an `AllocId` for a function. Depending on the function type, /// Generates an `AllocId` for a function. Depending on the function type,
/// this might get deduplicated or assigned a new ID each time. /// this might get deduplicated or assigned a new ID each time.
pub fn create_fn_alloc(&self, instance: Instance<'tcx>) -> AllocId { pub fn create_fn_alloc(self, instance: Instance<'tcx>) -> AllocId {
// Functions cannot be identified by pointers, as asm-equal functions can get deduplicated // Functions cannot be identified by pointers, as asm-equal functions can get deduplicated
// by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be // by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
// duplicated across crates. // duplicated across crates.
@ -507,7 +507,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Statics with identical content will still point to the same `Allocation`, i.e., /// Statics with identical content will still point to the same `Allocation`, i.e.,
/// their data will be deduplicated through `Allocation` interning -- but they /// their data will be deduplicated through `Allocation` interning -- but they
/// are different places in memory and as such need different IDs. /// are different places in memory and as such need different IDs.
pub fn create_memory_alloc(&self, mem: &'tcx Allocation) -> AllocId { pub fn create_memory_alloc(self, mem: &'tcx Allocation) -> AllocId {
let id = self.reserve_alloc_id(); let id = self.reserve_alloc_id();
self.set_alloc_id_memory(id, mem); self.set_alloc_id_memory(id, mem);
id id
@ -519,7 +519,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// This function exists to allow const eval to detect the difference between evaluation- /// This function exists to allow const eval to detect the difference between evaluation-
/// local dangling pointers and allocations in constants/statics. /// local dangling pointers and allocations in constants/statics.
#[inline] #[inline]
pub fn get_global_alloc(&self, id: AllocId) -> Option<GlobalAlloc<'tcx>> { pub fn get_global_alloc(self, id: AllocId) -> Option<GlobalAlloc<'tcx>> {
self.alloc_map.lock().alloc_map.get(&id).cloned() self.alloc_map.lock().alloc_map.get(&id).cloned()
} }
@ -529,7 +529,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// constants (as all constants must pass interning and validation that check for dangling /// constants (as all constants must pass interning and validation that check for dangling
/// ids), this function is frequently used throughout rustc, but should not be used within /// ids), this function is frequently used throughout rustc, but should not be used within
/// the miri engine. /// the miri engine.
pub fn global_alloc(&self, id: AllocId) -> GlobalAlloc<'tcx> { pub fn global_alloc(self, id: AllocId) -> GlobalAlloc<'tcx> {
match self.get_global_alloc(id) { match self.get_global_alloc(id) {
Some(alloc) => alloc, Some(alloc) => alloc,
None => bug!("could not find allocation for {}", id), None => bug!("could not find allocation for {}", id),
@ -538,7 +538,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. Trying to
/// call this function twice, even with the same `Allocation` will ICE the compiler. /// call this function twice, even with the same `Allocation` will ICE the compiler.
pub fn set_alloc_id_memory(&self, id: AllocId, mem: &'tcx Allocation) { pub fn set_alloc_id_memory(self, id: AllocId, mem: &'tcx Allocation) {
if let Some(old) = self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Memory(mem)) { if let Some(old) = self.alloc_map.lock().alloc_map.insert(id, GlobalAlloc::Memory(mem)) {
bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old); bug!("tried to set allocation ID {}, but it was already existing as {:#?}", id, old);
} }
@ -546,7 +546,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called /// Freezes an `AllocId` created with `reserve` by pointing it at an `Allocation`. May be called
/// twice for the same `(AllocId, Allocation)` pair. /// twice for the same `(AllocId, Allocation)` pair.
fn set_alloc_id_same_memory(&self, id: AllocId, mem: &'tcx Allocation) { fn set_alloc_id_same_memory(self, id: AllocId, mem: &'tcx Allocation) {
self.alloc_map.lock().alloc_map.insert_same(id, GlobalAlloc::Memory(mem)); self.alloc_map.lock().alloc_map.insert_same(id, GlobalAlloc::Memory(mem));
} }
} }

View File

@ -1077,6 +1077,25 @@ pub struct VarDebugInfo<'tcx> {
// BasicBlock // BasicBlock
rustc_index::newtype_index! { rustc_index::newtype_index! {
/// A node in the MIR [control-flow graph][CFG].
///
/// There are no branches (e.g., `if`s, function calls, etc.) within a basic block, which makes
/// it easier to do [data-flow analyses] and optimizations. Instead, branches are represented
/// as an edge in a graph between basic blocks.
///
/// Basic blocks consist of a series of [statements][Statement], ending with a
/// [terminator][Terminator]. Basic blocks can have multiple predecessors and successors,
/// however there is a MIR pass ([`CriticalCallEdges`]) that removes *critical edges*, which
/// are edges that go from a multi-successor node to a multi-predecessor node. This pass is
/// needed because some analyses require that there are no critical edges in the CFG.
///
/// Read more about basic blocks in the [rustc-dev-guide][guide-mir].
///
/// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg
/// [data-flow analyses]:
/// https://rustc-dev-guide.rust-lang.org/appendix/background.html#what-is-a-dataflow-analysis
/// [`CriticalCallEdges`]: ../../rustc_mir/transform/add_call_guards/enum.AddCallGuards.html#variant.CriticalCallEdges
/// [guide-mir]: https://rustc-dev-guide.rust-lang.org/mir/
pub struct BasicBlock { pub struct BasicBlock {
derive [HashStable] derive [HashStable]
DEBUG_FORMAT = "bb{}", DEBUG_FORMAT = "bb{}",
@ -1093,6 +1112,7 @@ impl BasicBlock {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// BasicBlockData and Terminator // BasicBlockData and Terminator
/// See [`BasicBlock`] for documentation on what basic blocks are at a high level.
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)] #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
pub struct BasicBlockData<'tcx> { pub struct BasicBlockData<'tcx> {
/// List of statements in this block. /// List of statements in this block.

View File

@ -1403,7 +1403,7 @@ impl<'tcx> TyCtxt<'tcx> {
} }
// Returns the `DefId` and the `BoundRegion` corresponding to the given region. // Returns the `DefId` and the `BoundRegion` corresponding to the given region.
pub fn is_suitable_region(&self, region: Region<'tcx>) -> Option<FreeRegionInfo> { pub fn is_suitable_region(self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
let (suitable_region_binding_scope, bound_region) = match *region { let (suitable_region_binding_scope, bound_region) = match *region {
ty::ReFree(ref free_region) => { ty::ReFree(ref free_region) => {
(free_region.scope.expect_local(), free_region.bound_region) (free_region.scope.expect_local(), free_region.bound_region)
@ -1433,7 +1433,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type. /// Given a `DefId` for an `fn`, return all the `dyn` and `impl` traits in its return type.
pub fn return_type_impl_or_dyn_traits( pub fn return_type_impl_or_dyn_traits(
&self, self,
scope_def_id: LocalDefId, scope_def_id: LocalDefId,
) -> Vec<&'tcx hir::Ty<'tcx>> { ) -> Vec<&'tcx hir::Ty<'tcx>> {
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
@ -1479,7 +1479,7 @@ impl<'tcx> TyCtxt<'tcx> {
v.0 v.0
} }
pub fn return_type_impl_trait(&self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> { pub fn return_type_impl_trait(self, scope_def_id: LocalDefId) -> Option<(Ty<'tcx>, Span)> {
// HACK: `type_of_def_id()` will fail on these (#55796), so return `None`. // HACK: `type_of_def_id()` will fail on these (#55796), so return `None`.
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
match self.hir().get(hir_id) { match self.hir().get(hir_id) {
@ -1497,7 +1497,7 @@ impl<'tcx> TyCtxt<'tcx> {
let ret_ty = self.type_of(scope_def_id); let ret_ty = self.type_of(scope_def_id);
match ret_ty.kind() { match ret_ty.kind() {
ty::FnDef(_, _) => { ty::FnDef(_, _) => {
let sig = ret_ty.fn_sig(*self); let sig = ret_ty.fn_sig(self);
let output = self.erase_late_bound_regions(&sig.output()); let output = self.erase_late_bound_regions(&sig.output());
if output.is_impl_trait() { if output.is_impl_trait() {
let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap(); let fn_decl = self.hir().fn_decl_by_hir_id(hir_id).unwrap();
@ -1511,7 +1511,7 @@ impl<'tcx> TyCtxt<'tcx> {
} }
// Checks if the bound region is in Impl Item. // Checks if the bound region is in Impl Item.
pub fn is_bound_region_in_impl_item(&self, suitable_region_binding_scope: LocalDefId) -> bool { pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
let container_id = let container_id =
self.associated_item(suitable_region_binding_scope.to_def_id()).container.id(); self.associated_item(suitable_region_binding_scope.to_def_id()).container.id();
if self.impl_trait_ref(container_id).is_some() { if self.impl_trait_ref(container_id).is_some() {
@ -1528,21 +1528,21 @@ impl<'tcx> TyCtxt<'tcx> {
/// Determines whether identifiers in the assembly have strict naming rules. /// Determines whether identifiers in the assembly have strict naming rules.
/// Currently, only NVPTX* targets need it. /// Currently, only NVPTX* targets need it.
pub fn has_strict_asm_symbol_naming(&self) -> bool { pub fn has_strict_asm_symbol_naming(self) -> bool {
self.sess.target.target.arch.contains("nvptx") self.sess.target.target.arch.contains("nvptx")
} }
/// Returns `&'static core::panic::Location<'static>`. /// Returns `&'static core::panic::Location<'static>`.
pub fn caller_location_ty(&self) -> Ty<'tcx> { pub fn caller_location_ty(self) -> Ty<'tcx> {
self.mk_imm_ref( self.mk_imm_ref(
self.lifetimes.re_static, self.lifetimes.re_static,
self.type_of(self.require_lang_item(LangItem::PanicLocation, None)) self.type_of(self.require_lang_item(LangItem::PanicLocation, None))
.subst(*self, self.mk_substs([self.lifetimes.re_static.into()].iter())), .subst(self, self.mk_substs([self.lifetimes.re_static.into()].iter())),
) )
} }
/// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`). /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`).
pub fn article_and_description(&self, def_id: DefId) -> (&'static str, &'static str) { pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) {
match self.def_kind(def_id) { match self.def_kind(def_id) {
DefKind::Generator => match self.generator_kind(def_id).unwrap() { DefKind::Generator => match self.generator_kind(def_id).unwrap() {
rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"), rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"),

View File

@ -546,7 +546,7 @@ impl<T> Trait<T> for X {
} }
fn suggest_constraint( fn suggest_constraint(
&self, self,
db: &mut DiagnosticBuilder<'_>, db: &mut DiagnosticBuilder<'_>,
msg: &str, msg: &str,
body_owner_def_id: DefId, body_owner_def_id: DefId,
@ -554,14 +554,14 @@ impl<T> Trait<T> for X {
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> bool { ) -> bool {
let assoc = self.associated_item(proj_ty.item_def_id); let assoc = self.associated_item(proj_ty.item_def_id);
let trait_ref = proj_ty.trait_ref(*self); let trait_ref = proj_ty.trait_ref(self);
if let Some(item) = self.hir().get_if_local(body_owner_def_id) { if let Some(item) = self.hir().get_if_local(body_owner_def_id) {
if let Some(hir_generics) = item.generics() { if let Some(hir_generics) = item.generics() {
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`. // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
// This will also work for `impl Trait`. // This will also work for `impl Trait`.
let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() { let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
let generics = self.generics_of(body_owner_def_id); let generics = self.generics_of(body_owner_def_id);
generics.type_param(&param_ty, *self).def_id generics.type_param(param_ty, self).def_id
} else { } else {
return false; return false;
}; };
@ -629,7 +629,7 @@ impl<T> Trait<T> for X {
/// and the `impl`, we provide a generic `help` to constrain the assoc type or call an assoc /// and the `impl`, we provide a generic `help` to constrain the assoc type or call an assoc
/// fn that returns the type. /// fn that returns the type.
fn expected_projection( fn expected_projection(
&self, self,
db: &mut DiagnosticBuilder<'_>, db: &mut DiagnosticBuilder<'_>,
proj_ty: &ty::ProjectionTy<'tcx>, proj_ty: &ty::ProjectionTy<'tcx>,
values: &ExpectedFound<Ty<'tcx>>, values: &ExpectedFound<Ty<'tcx>>,
@ -734,7 +734,7 @@ fn foo(&self) -> Self::T { String::new() }
} }
fn point_at_methods_that_satisfy_associated_type( fn point_at_methods_that_satisfy_associated_type(
&self, self,
db: &mut DiagnosticBuilder<'_>, db: &mut DiagnosticBuilder<'_>,
assoc_container_id: DefId, assoc_container_id: DefId,
current_method_ident: Option<Symbol>, current_method_ident: Option<Symbol>,
@ -789,7 +789,7 @@ fn foo(&self) -> Self::T { String::new() }
} }
fn point_at_associated_type( fn point_at_associated_type(
&self, self,
db: &mut DiagnosticBuilder<'_>, db: &mut DiagnosticBuilder<'_>,
body_owner_def_id: DefId, body_owner_def_id: DefId,
found: Ty<'tcx>, found: Ty<'tcx>,

View File

@ -623,7 +623,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Replaces any late-bound regions bound in `value` with /// Replaces any late-bound regions bound in `value` with
/// free variants attached to `all_outlive_scope`. /// free variants attached to `all_outlive_scope`.
pub fn liberate_late_bound_regions<T>( pub fn liberate_late_bound_regions<T>(
&self, self,
all_outlive_scope: DefId, all_outlive_scope: DefId,
value: &ty::Binder<T>, value: &ty::Binder<T>,
) -> T ) -> T
@ -644,7 +644,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// variables and equate `value` with something else, those /// variables and equate `value` with something else, those
/// variables will also be equated. /// variables will also be equated.
pub fn collect_constrained_late_bound_regions<T>( pub fn collect_constrained_late_bound_regions<T>(
&self, self,
value: &Binder<T>, value: &Binder<T>,
) -> FxHashSet<ty::BoundRegion> ) -> FxHashSet<ty::BoundRegion>
where where
@ -655,7 +655,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Returns a set of all late-bound regions that appear in `value` anywhere. /// Returns a set of all late-bound regions that appear in `value` anywhere.
pub fn collect_referenced_late_bound_regions<T>( pub fn collect_referenced_late_bound_regions<T>(
&self, self,
value: &Binder<T>, value: &Binder<T>,
) -> FxHashSet<ty::BoundRegion> ) -> FxHashSet<ty::BoundRegion>
where where
@ -665,7 +665,7 @@ impl<'tcx> TyCtxt<'tcx> {
} }
fn collect_late_bound_regions<T>( fn collect_late_bound_regions<T>(
&self, self,
value: &Binder<T>, value: &Binder<T>,
just_constraint: bool, just_constraint: bool,
) -> FxHashSet<ty::BoundRegion> ) -> FxHashSet<ty::BoundRegion>

View File

@ -170,9 +170,7 @@ impl<'tcx> TyCtxt<'tcx> {
}); });
hasher.finish() hasher.finish()
} }
}
impl<'tcx> TyCtxt<'tcx> {
pub fn has_error_field(self, ty: Ty<'tcx>) -> bool { pub fn has_error_field(self, ty: Ty<'tcx>) -> bool {
if let ty::Adt(def, substs) = *ty.kind() { if let ty::Adt(def, substs) = *ty.kind() {
for field in def.all_fields() { for field in def.all_fields() {
@ -526,22 +524,22 @@ impl<'tcx> TyCtxt<'tcx> {
} }
/// Returns `true` if the node pointed to by `def_id` is a `static` item. /// Returns `true` if the node pointed to by `def_id` is a `static` item.
pub fn is_static(&self, def_id: DefId) -> bool { pub fn is_static(self, def_id: DefId) -> bool {
self.static_mutability(def_id).is_some() self.static_mutability(def_id).is_some()
} }
/// Returns `true` if this is a `static` item with the `#[thread_local]` attribute. /// Returns `true` if this is a `static` item with the `#[thread_local]` attribute.
pub fn is_thread_local_static(&self, def_id: DefId) -> bool { pub fn is_thread_local_static(self, def_id: DefId) -> bool {
self.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) self.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::THREAD_LOCAL)
} }
/// Returns `true` if the node pointed to by `def_id` is a mutable `static` item. /// Returns `true` if the node pointed to by `def_id` is a mutable `static` item.
pub fn is_mutable_static(&self, def_id: DefId) -> bool { pub fn is_mutable_static(self, def_id: DefId) -> bool {
self.static_mutability(def_id) == Some(hir::Mutability::Mut) self.static_mutability(def_id) == Some(hir::Mutability::Mut)
} }
/// Get the type of the pointer to the static that we use in MIR. /// Get the type of the pointer to the static that we use in MIR.
pub fn static_ptr_ty(&self, def_id: DefId) -> Ty<'tcx> { pub fn static_ptr_ty(self, def_id: DefId) -> Ty<'tcx> {
// Make sure that any constants in the static's type are evaluated. // Make sure that any constants in the static's type are evaluated.
let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id)); let static_ty = self.normalize_erasing_regions(ty::ParamEnv::empty(), self.type_of(def_id));

View File

@ -115,9 +115,10 @@ impl OutlivesSuggestionBuilder {
// should just replace 'a with 'static. // should just replace 'a with 'static.
// 3) Suggest unifying 'a with 'b if we have both 'a: 'b and 'b: 'a // 3) Suggest unifying 'a with 'b if we have both 'a: 'b and 'b: 'a
if outlived.iter().any(|(_, outlived_name)| { if outlived
if let RegionNameSource::Static = outlived_name.source { true } else { false } .iter()
}) { .any(|(_, outlived_name)| matches!(outlived_name.source, RegionNameSource::Static))
{
suggested.push(SuggestedConstraint::Static(fr_name)); suggested.push(SuggestedConstraint::Static(fr_name));
} else { } else {
// We want to isolate out all lifetimes that should be unified and print out // We want to isolate out all lifetimes that should be unified and print out

View File

@ -92,7 +92,7 @@ pub enum TempState {
impl TempState { impl TempState {
pub fn is_promotable(&self) -> bool { pub fn is_promotable(&self) -> bool {
debug!("is_promotable: self={:?}", self); debug!("is_promotable: self={:?}", self);
if let TempState::Defined { .. } = *self { true } else { false } matches!(self, TempState::Defined { .. } )
} }
} }

View File

@ -281,8 +281,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> {
fn strip_nops(&mut self) { fn strip_nops(&mut self) {
for blk in self.basic_blocks.iter_mut() { for blk in self.basic_blocks.iter_mut() {
blk.statements blk.statements.retain(|stmt| !matches!(stmt.kind, StatementKind::Nop))
.retain(|stmt| if let StatementKind::Nop = stmt.kind { false } else { true })
} }
} }
} }

View File

@ -96,8 +96,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
); );
} }
StmtKind::Let { remainder_scope, init_scope, pattern, initializer, lint_level } => { StmtKind::Let { remainder_scope, init_scope, pattern, initializer, lint_level } => {
let ignores_expr_result = let ignores_expr_result = matches!(*pattern.kind, PatKind::Wild);
if let PatKind::Wild = *pattern.kind { true } else { false };
this.block_context.push(BlockFrame::Statement { ignores_expr_result }); this.block_context.push(BlockFrame::Statement { ignores_expr_result });
// Enter the remainder scope, i.e., the bindings' destruction scope. // Enter the remainder scope, i.e., the bindings' destruction scope.

View File

@ -1793,7 +1793,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
.flat_map(|(bindings, _)| bindings) .flat_map(|(bindings, _)| bindings)
.chain(&candidate.bindings) .chain(&candidate.bindings)
.filter(|binding| { .filter(|binding| {
if let BindingMode::ByValue = binding.binding_mode { true } else { false } matches!(binding.binding_mode, BindingMode::ByValue )
}); });
// Read all of the by reference bindings to ensure that the // Read all of the by reference bindings to ensure that the
// place they refer to can't be modified by the guard. // place they refer to can't be modified by the guard.

View File

@ -12,11 +12,11 @@
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::Session; use rustc_session::Session;
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::{sym, Symbol}; use rustc_span::symbol::{sym, Symbol};
struct DiagnosticItemCollector<'tcx> { struct DiagnosticItemCollector<'tcx> {
@ -100,6 +100,18 @@ fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> FxHashMap<Symbol, DefId> {
// Collect diagnostic items in this crate. // Collect diagnostic items in this crate.
tcx.hir().krate().visit_all_item_likes(&mut collector); tcx.hir().krate().visit_all_item_likes(&mut collector);
// FIXME(visit_all_item_likes): Foreign items are not visited
// here, so we have to manually look at them for now.
for foreign_module in tcx.foreign_modules(LOCAL_CRATE) {
for &foreign_item in foreign_module.foreign_items.iter() {
match tcx.hir().get(tcx.hir().local_def_id_to_hir_id(foreign_item.expect_local())) {
hir::Node::ForeignItem(item) => {
collector.observe_item(item.attrs, item.hir_id);
}
item => bug!("unexpected foreign item {:?}", item),
}
}
}
collector.items collector.items
} }

View File

@ -395,7 +395,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
// so prefixes are prepended with crate root segment if necessary. // so prefixes are prepended with crate root segment if necessary.
// The root is prepended lazily, when the first non-empty prefix or terminating glob // The root is prepended lazily, when the first non-empty prefix or terminating glob
// appears, so imports in braced groups can have roots prepended independently. // appears, so imports in braced groups can have roots prepended independently.
let is_glob = if let ast::UseTreeKind::Glob = use_tree.kind { true } else { false }; let is_glob = matches!(use_tree.kind, ast::UseTreeKind::Glob);
let crate_root = match prefix_iter.peek() { let crate_root = match prefix_iter.peek() {
Some(seg) if !seg.ident.is_path_segment_keyword() && seg.ident.span.rust_2015() => { Some(seg) if !seg.ident.is_path_segment_keyword() && seg.ident.span.rust_2015() => {
Some(seg.ident.span.ctxt()) Some(seg.ident.span.ctxt())

View File

@ -1034,7 +1034,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
let mut add_bindings_for_ns = |ns| { let mut add_bindings_for_ns = |ns| {
let parent_rib = self.ribs[ns] let parent_rib = self.ribs[ns]
.iter() .iter()
.rfind(|r| if let ItemRibKind(_) = r.kind { true } else { false }) .rfind(|r| matches!(r.kind, ItemRibKind(_)))
.expect("associated item outside of an item"); .expect("associated item outside of an item");
seen_bindings seen_bindings
.extend(parent_rib.bindings.iter().map(|(ident, _)| (*ident, ident.span))); .extend(parent_rib.bindings.iter().map(|(ident, _)| (*ident, ident.span)));

View File

@ -818,10 +818,11 @@ pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateCo
user_cfg user_cfg
} }
pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Config { pub fn build_target_config(opts: &Options, target_override: Option<Target>) -> Config {
let target = Target::search(&opts.target_triple).unwrap_or_else(|e| { let target_result = target_override.map_or_else(|| Target::search(&opts.target_triple), Ok);
let target = target_result.unwrap_or_else(|e| {
early_error( early_error(
error_format, opts.error_format,
&format!( &format!(
"Error loading target specification: {}. \ "Error loading target specification: {}. \
Use `--print target-list` for a list of built-in targets", Use `--print target-list` for a list of built-in targets",
@ -835,7 +836,7 @@ pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Con
"32" => 32, "32" => 32,
"64" => 64, "64" => 64,
w => early_error( w => early_error(
error_format, opts.error_format,
&format!( &format!(
"target specification was invalid: \ "target specification was invalid: \
unrecognized target-pointer-width {}", unrecognized target-pointer-width {}",

View File

@ -1234,6 +1234,7 @@ pub fn build_session(
diagnostics_output: DiagnosticOutput, diagnostics_output: DiagnosticOutput,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>, driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>, file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
target_override: Option<Target>,
) -> Session { ) -> Session {
// FIXME: This is not general enough to make the warning lint completely override // FIXME: This is not general enough to make the warning lint completely override
// normal diagnostic warnings, since the warning lint can also be denied and changed // normal diagnostic warnings, since the warning lint can also be denied and changed
@ -1253,7 +1254,7 @@ pub fn build_session(
DiagnosticOutput::Raw(write) => Some(write), DiagnosticOutput::Raw(write) => Some(write),
}; };
let target_cfg = config::build_target_config(&sopts, sopts.error_format); let target_cfg = config::build_target_config(&sopts, target_override);
let host_triple = TargetTriple::from_triple(config::host_triple()); let host_triple = TargetTriple::from_triple(config::host_triple());
let host = Target::search(&host_triple).unwrap_or_else(|e| { let host = Target::search(&host_triple).unwrap_or_else(|e| {
early_error(sopts.error_format, &format!("Error loading host specification: {}", e)) early_error(sopts.error_format, &format!("Error loading host specification: {}", e))

View File

@ -439,9 +439,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// This is maybe too permissive, since it allows // This is maybe too permissive, since it allows
// `let u = &raw const Box::new((1,)).0`, which creates an // `let u = &raw const Box::new((1,)).0`, which creates an
// immediately dangling raw pointer. // immediately dangling raw pointer.
self.typeck_results.borrow().adjustments().get(base.hir_id).map_or(false, |x| { self.typeck_results
x.iter().any(|adj| if let Adjust::Deref(_) = adj.kind { true } else { false }) .borrow()
}) .adjustments()
.get(base.hir_id)
.map_or(false, |x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
}); });
if !is_named { if !is_named {
self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span }) self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span })

View File

@ -230,6 +230,14 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
return; return;
} }
} }
if let ty::Opaque(def_id, _) = *trait_ref.self_ty().kind() {
self.tcx
.sess
.struct_span_err(sp, "cannot implement trait on type alias impl trait")
.span_note(self.tcx.def_span(def_id), "type alias impl trait defined here")
.emit();
}
} }
} }

View File

@ -15,7 +15,6 @@
//! [dijkstra]: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm //! [dijkstra]: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
//! [sssp]: https://en.wikipedia.org/wiki/Shortest_path_problem //! [sssp]: https://en.wikipedia.org/wiki/Shortest_path_problem
//! [dir_graph]: https://en.wikipedia.org/wiki/Directed_graph //! [dir_graph]: https://en.wikipedia.org/wiki/Directed_graph
//! [`BinaryHeap`]: struct.BinaryHeap.html
//! //!
//! ``` //! ```
//! use std::cmp::Ordering; //! use std::cmp::Ordering;
@ -240,10 +239,10 @@ use super::SpecExtend;
/// The value for `push` is an expected cost; the method documentation gives a /// The value for `push` is an expected cost; the method documentation gives a
/// more detailed analysis. /// more detailed analysis.
/// ///
/// [push]: #method.push /// [push]: BinaryHeap::push
/// [pop]: #method.pop /// [pop]: BinaryHeap::pop
/// [peek]: #method.peek /// [peek]: BinaryHeap::peek
/// [peek\_mut]: #method.peek_mut /// [peek\_mut]: BinaryHeap::peek_mut
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct BinaryHeap<T> { pub struct BinaryHeap<T> {
data: Vec<T>, data: Vec<T>,
@ -255,8 +254,7 @@ pub struct BinaryHeap<T> {
/// This `struct` is created by the [`peek_mut`] method on [`BinaryHeap`]. See /// This `struct` is created by the [`peek_mut`] method on [`BinaryHeap`]. See
/// its documentation for more. /// its documentation for more.
/// ///
/// [`peek_mut`]: struct.BinaryHeap.html#method.peek_mut /// [`peek_mut`]: BinaryHeap::peek_mut
/// [`BinaryHeap`]: struct.BinaryHeap.html
#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")] #[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
pub struct PeekMut<'a, T: 'a + Ord> { pub struct PeekMut<'a, T: 'a + Ord> {
heap: &'a mut BinaryHeap<T>, heap: &'a mut BinaryHeap<T>,
@ -802,7 +800,7 @@ impl<T> BinaryHeap<T> {
/// heap.push(4); /// heap.push(4);
/// ``` /// ```
/// ///
/// [`reserve`]: #method.reserve /// [`reserve`]: BinaryHeap::reserve
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn reserve_exact(&mut self, additional: usize) { pub fn reserve_exact(&mut self, additional: usize) {
self.data.reserve_exact(additional); self.data.reserve_exact(additional);
@ -1057,11 +1055,10 @@ impl<T> Drop for Hole<'_, T> {
/// An iterator over the elements of a `BinaryHeap`. /// An iterator over the elements of a `BinaryHeap`.
/// ///
/// This `struct` is created by the [`iter`] method on [`BinaryHeap`]. See its /// This `struct` is created by [`BinaryHeap::iter()`]. See its
/// documentation for more. /// documentation for more.
/// ///
/// [`iter`]: struct.BinaryHeap.html#method.iter /// [`iter`]: BinaryHeap::iter
/// [`BinaryHeap`]: struct.BinaryHeap.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, T: 'a> { pub struct Iter<'a, T: 'a> {
iter: slice::Iter<'a, T>, iter: slice::Iter<'a, T>,
@ -1122,11 +1119,10 @@ impl<T> FusedIterator for Iter<'_, T> {}
/// An owning iterator over the elements of a `BinaryHeap`. /// An owning iterator over the elements of a `BinaryHeap`.
/// ///
/// This `struct` is created by the [`into_iter`] method on [`BinaryHeap`] /// This `struct` is created by [`BinaryHeap::into_iter()`]
/// (provided by the `IntoIterator` trait). See its documentation for more. /// (provided by the `IntoIterator` trait). See its documentation for more.
/// ///
/// [`into_iter`]: struct.BinaryHeap.html#method.into_iter /// [`into_iter`]: BinaryHeap::into_iter
/// [`BinaryHeap`]: struct.BinaryHeap.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)] #[derive(Clone)]
pub struct IntoIter<T> { pub struct IntoIter<T> {
@ -1227,11 +1223,10 @@ unsafe impl<T: Ord> TrustedLen for IntoIterSorted<T> {}
/// A draining iterator over the elements of a `BinaryHeap`. /// A draining iterator over the elements of a `BinaryHeap`.
/// ///
/// This `struct` is created by the [`drain`] method on [`BinaryHeap`]. See its /// This `struct` is created by [`BinaryHeap::drain()`]. See its
/// documentation for more. /// documentation for more.
/// ///
/// [`drain`]: struct.BinaryHeap.html#method.drain /// [`drain`]: BinaryHeap::drain
/// [`BinaryHeap`]: struct.BinaryHeap.html
#[stable(feature = "drain", since = "1.6.0")] #[stable(feature = "drain", since = "1.6.0")]
#[derive(Debug)] #[derive(Debug)]
pub struct Drain<'a, T: 'a> { pub struct Drain<'a, T: 'a> {
@ -1273,11 +1268,10 @@ impl<T> FusedIterator for Drain<'_, T> {}
/// A draining iterator over the elements of a `BinaryHeap`. /// A draining iterator over the elements of a `BinaryHeap`.
/// ///
/// This `struct` is created by the [`drain_sorted`] method on [`BinaryHeap`]. See its /// This `struct` is created by [`BinaryHeap::drain_sorted()`]. See its
/// documentation for more. /// documentation for more.
/// ///
/// [`drain_sorted`]: struct.BinaryHeap.html#method.drain_sorted /// [`drain_sorted`]: BinaryHeap::drain_sorted
/// [`BinaryHeap`]: struct.BinaryHeap.html
#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")] #[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
#[derive(Debug)] #[derive(Debug)]
pub struct DrainSorted<'a, T: Ord> { pub struct DrainSorted<'a, T: Ord> {

View File

@ -47,7 +47,6 @@ use UnderflowResult::*;
/// any other key, as determined by the [`Ord`] trait, changes while it is in the map. This is /// any other key, as determined by the [`Ord`] trait, changes while it is in the map. This is
/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code. /// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
/// ///
/// [`Ord`]: core::cmp::Ord
/// [`Cell`]: core::cell::Cell /// [`Cell`]: core::cell::Cell
/// [`RefCell`]: core::cell::RefCell /// [`RefCell`]: core::cell::RefCell
/// ///
@ -93,9 +92,10 @@ use UnderflowResult::*;
/// } /// }
/// ``` /// ```
/// ///
/// `BTreeMap` also implements an [`Entry API`](#method.entry), which allows /// `BTreeMap` also implements an [`Entry API`], which allows for more complex
/// for more complex methods of getting, setting, updating and removing keys and /// methods of getting, setting, updating and removing keys and their values:
/// their values: ///
/// [`Entry API`]: BTreeMap::entry
/// ///
/// ``` /// ```
/// use std::collections::BTreeMap; /// use std::collections::BTreeMap;
@ -453,8 +453,6 @@ impl<K: Debug + Ord, V: Debug> Debug for Entry<'_, K, V> {
/// A view into a vacant entry in a `BTreeMap`. /// A view into a vacant entry in a `BTreeMap`.
/// It is part of the [`Entry`] enum. /// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct VacantEntry<'a, K: 'a, V: 'a> { pub struct VacantEntry<'a, K: 'a, V: 'a> {
key: K, key: K,
@ -474,8 +472,6 @@ impl<K: Debug + Ord, V> Debug for VacantEntry<'_, K, V> {
/// A view into an occupied entry in a `BTreeMap`. /// A view into an occupied entry in a `BTreeMap`.
/// It is part of the [`Entry`] enum. /// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct OccupiedEntry<'a, K: 'a, V: 'a> { pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>, handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>,
@ -815,7 +811,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// types that can be `==` without being identical. See the [module-level /// types that can be `==` without being identical. See the [module-level
/// documentation] for more. /// documentation] for more.
/// ///
/// [module-level documentation]: index.html#insert-and-complex-keys /// [module-level documentation]: crate::collections#insert-and-complex-keys
/// ///
/// # Examples /// # Examples
/// ///
@ -1719,7 +1715,7 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
/// Allow Debug implementations to predict the next element. /// Allow Debug implementations to predict the next element.
pub(super) fn peek(&self) -> Option<(&K, &V)> { pub(super) fn peek(&self) -> Option<(&K, &V)> {
let edge = self.cur_leaf_edge.as_ref()?; let edge = self.cur_leaf_edge.as_ref()?;
edge.reborrow().next_kv().ok().map(|kv| kv.into_kv()) edge.reborrow().next_kv().ok().map(Handle::into_kv)
} }
/// Implementation of a typical `DrainFilter::next` method, given the predicate. /// Implementation of a typical `DrainFilter::next` method, given the predicate.
@ -2554,7 +2550,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
/// If you need a reference to the `OccupiedEntry` that may outlive the /// If you need a reference to the `OccupiedEntry` that may outlive the
/// destruction of the `Entry` value, see [`into_mut`]. /// destruction of the `Entry` value, see [`into_mut`].
/// ///
/// [`into_mut`]: #method.into_mut /// [`into_mut`]: OccupiedEntry::into_mut
/// ///
/// # Examples /// # Examples
/// ///
@ -2584,7 +2580,7 @@ impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
/// ///
/// If you need multiple references to the `OccupiedEntry`, see [`get_mut`]. /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
/// ///
/// [`get_mut`]: #method.get_mut /// [`get_mut`]: OccupiedEntry::get_mut
/// ///
/// # Examples /// # Examples
/// ///

View File

@ -218,7 +218,7 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::E
let mut edge = self.forget_node_type(); let mut edge = self.forget_node_type();
loop { loop {
edge = match edge.right_kv() { edge = match edge.right_kv() {
Ok(internal_kv) => return Ok(internal_kv), Ok(kv) => return Ok(kv),
Err(last_edge) => match last_edge.into_node().ascend() { Err(last_edge) => match last_edge.into_node().ascend() {
Ok(parent_edge) => parent_edge.forget_node_type(), Ok(parent_edge) => parent_edge.forget_node_type(),
Err(root) => return Err(root), Err(root) => return Err(root),
@ -239,7 +239,7 @@ impl<BorrowType, K, V> Handle<NodeRef<BorrowType, K, V, marker::Leaf>, marker::E
let mut edge = self.forget_node_type(); let mut edge = self.forget_node_type();
loop { loop {
edge = match edge.left_kv() { edge = match edge.left_kv() {
Ok(internal_kv) => return Ok(internal_kv), Ok(kv) => return Ok(kv),
Err(last_edge) => match last_edge.into_node().ascend() { Err(last_edge) => match last_edge.into_node().ascend() {
Ok(parent_edge) => parent_edge.forget_node_type(), Ok(parent_edge) => parent_edge.forget_node_type(),
Err(root) => return Err(root), Err(root) => return Err(root),

View File

@ -929,14 +929,14 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
/// The returned pointer points to the inserted value. /// The returned pointer points to the inserted value.
fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) { fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) {
if self.node.len() < CAPACITY { if self.node.len() < CAPACITY {
let ptr = self.insert_fit(key, val); let val_ptr = self.insert_fit(key, val);
let kv = unsafe { Handle::new_kv(self.node, self.idx) }; let kv = unsafe { Handle::new_kv(self.node, self.idx) };
(InsertResult::Fit(kv), ptr) (InsertResult::Fit(kv), val_ptr)
} else { } else {
let (middle_kv_idx, insertion) = splitpoint(self.idx); let (middle_kv_idx, insertion) = splitpoint(self.idx);
let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) }; let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
let (mut left, k, v, mut right) = middle.split(); let (mut left, k, v, mut right) = middle.split();
let ptr = match insertion { let val_ptr = match insertion {
InsertionPlace::Left(insert_idx) => unsafe { InsertionPlace::Left(insert_idx) => unsafe {
Handle::new_edge(left.reborrow_mut(), insert_idx).insert_fit(key, val) Handle::new_edge(left.reborrow_mut(), insert_idx).insert_fit(key, val)
}, },
@ -948,7 +948,7 @@ impl<'a, K: 'a, V: 'a> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, mark
.insert_fit(key, val) .insert_fit(key, val)
}, },
}; };
(InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right }), ptr) (InsertResult::Split(SplitResult { left: left.forget_type(), k, v, right }), val_ptr)
} }
} }
} }

View File

@ -102,7 +102,7 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
/// This `struct` is created by the [`into_iter`] method on [`LinkedList`] /// This `struct` is created by the [`into_iter`] method on [`LinkedList`]
/// (provided by the `IntoIterator` trait). See its documentation for more. /// (provided by the `IntoIterator` trait). See its documentation for more.
/// ///
/// [`into_iter`]: struct.LinkedList.html#method.into_iter /// [`into_iter`]: LinkedList::into_iter
#[derive(Clone)] #[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> { pub struct IntoIter<T> {

View File

@ -48,11 +48,11 @@ const MAXIMUM_ZST_CAPACITY: usize = 1 << (core::mem::size_of::<usize>() * 8 - 1)
/// so that its elements do not wrap, and returns a mutable slice to the /// so that its elements do not wrap, and returns a mutable slice to the
/// now-contiguous element sequence. /// now-contiguous element sequence.
/// ///
/// [`push_back`]: #method.push_back /// [`push_back`]: VecDeque::push_back
/// [`pop_front`]: #method.pop_front /// [`pop_front`]: VecDeque::pop_front
/// [`extend`]: #method.extend /// [`extend`]: VecDeque::extend
/// [`append`]: #method.append /// [`append`]: VecDeque::append
/// [`make_contiguous`]: #method.make_contiguous /// [`make_contiguous`]: VecDeque::make_contiguous
#[cfg_attr(not(test), rustc_diagnostic_item = "vecdeque_type")] #[cfg_attr(not(test), rustc_diagnostic_item = "vecdeque_type")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct VecDeque<T> { pub struct VecDeque<T> {
@ -640,7 +640,7 @@ impl<T> VecDeque<T> {
/// assert!(buf.capacity() >= 11); /// assert!(buf.capacity() >= 11);
/// ``` /// ```
/// ///
/// [`reserve`]: #method.reserve /// [`reserve`]: VecDeque::reserve
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn reserve_exact(&mut self, additional: usize) { pub fn reserve_exact(&mut self, additional: usize) {
self.reserve(additional); self.reserve(additional);
@ -987,8 +987,10 @@ impl<T> VecDeque<T> {
/// Returns a pair of slices which contain, in order, the contents of the /// Returns a pair of slices which contain, in order, the contents of the
/// `VecDeque`. /// `VecDeque`.
/// ///
/// If [`make_contiguous`](#method.make_contiguous) was previously called, all elements /// If [`make_contiguous`] was previously called, all elements of the
/// of the `VecDeque` will be in the first slice and the second slice will be empty. /// `VecDeque` will be in the first slice and the second slice will be empty.
///
/// [`make_contiguous`]: VecDeque::make_contiguous
/// ///
/// # Examples /// # Examples
/// ///
@ -1020,8 +1022,10 @@ impl<T> VecDeque<T> {
/// Returns a pair of slices which contain, in order, the contents of the /// Returns a pair of slices which contain, in order, the contents of the
/// `VecDeque`. /// `VecDeque`.
/// ///
/// If [`make_contiguous`](#method.make_contiguous) was previously called, all elements /// If [`make_contiguous`] was previously called, all elements of the
/// of the `VecDeque` will be in the first slice and the second slice will be empty. /// `VecDeque` will be in the first slice and the second slice will be empty.
///
/// [`make_contiguous`]: VecDeque::make_contiguous
/// ///
/// # Examples /// # Examples
/// ///
@ -2160,15 +2164,20 @@ impl<T> VecDeque<T> {
} }
} }
/// Rearranges the internal storage of this deque so it is one contiguous slice, which is then returned. /// Rearranges the internal storage of this deque so it is one contiguous
/// slice, which is then returned.
/// ///
/// This method does not allocate and does not change the order of the inserted elements. /// This method does not allocate and does not change the order of the
/// As it returns a mutable slice, this can be used to sort or binary search a deque. /// inserted elements. As it returns a mutable slice, this can be used to
/// sort or binary search a deque.
/// ///
/// Once the internal storage is contiguous, the [`as_slices`](#method.as_slices) and /// Once the internal storage is contiguous, the [`as_slices`] and
/// [`as_mut_slices`](#method.as_mut_slices) methods will return the entire contents of the /// [`as_mut_slices`] methods will return the entire contents of the
/// `VecDeque` in a single slice. /// `VecDeque` in a single slice.
/// ///
/// [`as_slices`]: VecDeque::as_slices
/// [`as_mut_slices`]: VecDeque::as_mut_slices
///
/// # Examples /// # Examples
/// ///
/// Sorting the content of a deque. /// Sorting the content of a deque.
@ -2495,8 +2504,7 @@ fn count(tail: usize, head: usize, size: usize) -> usize {
/// This `struct` is created by the [`iter`] method on [`VecDeque`]. See its /// This `struct` is created by the [`iter`] method on [`VecDeque`]. See its
/// documentation for more. /// documentation for more.
/// ///
/// [`iter`]: struct.VecDeque.html#method.iter /// [`iter`]: VecDeque::iter
/// [`VecDeque`]: struct.VecDeque.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, T: 'a> { pub struct Iter<'a, T: 'a> {
ring: &'a [T], ring: &'a [T],
@ -2650,8 +2658,7 @@ impl<T> FusedIterator for Iter<'_, T> {}
/// This `struct` is created by the [`iter_mut`] method on [`VecDeque`]. See its /// This `struct` is created by the [`iter_mut`] method on [`VecDeque`]. See its
/// documentation for more. /// documentation for more.
/// ///
/// [`iter_mut`]: struct.VecDeque.html#method.iter_mut /// [`iter_mut`]: VecDeque::iter_mut
/// [`VecDeque`]: struct.VecDeque.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, T: 'a> { pub struct IterMut<'a, T: 'a> {
ring: &'a mut [T], ring: &'a mut [T],
@ -2756,8 +2763,7 @@ impl<T> FusedIterator for IterMut<'_, T> {}
/// This `struct` is created by the [`into_iter`] method on [`VecDeque`] /// This `struct` is created by the [`into_iter`] method on [`VecDeque`]
/// (provided by the `IntoIterator` trait). See its documentation for more. /// (provided by the `IntoIterator` trait). See its documentation for more.
/// ///
/// [`into_iter`]: struct.VecDeque.html#method.into_iter /// [`into_iter`]: VecDeque::into_iter
/// [`VecDeque`]: struct.VecDeque.html
#[derive(Clone)] #[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> { pub struct IntoIter<T> {

View File

@ -9,8 +9,7 @@ use super::{count, Iter, VecDeque};
/// This `struct` is created by the [`drain`] method on [`VecDeque`]. See its /// This `struct` is created by the [`drain`] method on [`VecDeque`]. See its
/// documentation for more. /// documentation for more.
/// ///
/// [`drain`]: struct.VecDeque.html#method.drain /// [`drain`]: VecDeque::drain
/// [`VecDeque`]: struct.VecDeque.html
#[stable(feature = "drain", since = "1.6.0")] #[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, T: 'a> { pub struct Drain<'a, T: 'a> {
pub(crate) after_tail: usize, pub(crate) after_tail: usize,

View File

@ -74,6 +74,7 @@
#![deny(unsafe_op_in_unsafe_fn)] #![deny(unsafe_op_in_unsafe_fn)]
#![cfg_attr(not(test), feature(generator_trait))] #![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(test))] #![cfg_attr(test, feature(test))]
#![cfg_attr(test, feature(new_uninit))]
#![feature(allocator_api)] #![feature(allocator_api)]
#![feature(array_chunks)] #![feature(array_chunks)]
#![feature(array_windows)] #![feature(array_windows)]
@ -81,7 +82,6 @@
#![feature(arbitrary_self_types)] #![feature(arbitrary_self_types)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(btree_drain_filter)]
#![feature(cfg_sanitize)] #![feature(cfg_sanitize)]
#![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)] #![feature(coerce_unsized)]
@ -89,10 +89,8 @@
#![feature(const_generics)] #![feature(const_generics)]
#![feature(const_in_array_repeat_expressions)] #![feature(const_in_array_repeat_expressions)]
#![feature(cow_is_borrowed)] #![feature(cow_is_borrowed)]
#![feature(deque_range)]
#![feature(dispatch_from_dyn)] #![feature(dispatch_from_dyn)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(container_error_extra)]
#![feature(dropck_eyepatch)] #![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)] #![feature(exact_size_is_empty)]
#![feature(exclusive_range_pattern)] #![feature(exclusive_range_pattern)]
@ -104,13 +102,9 @@
#![feature(int_bits_const)] #![feature(int_bits_const)]
#![feature(lang_items)] #![feature(lang_items)]
#![feature(layout_for_ptr)] #![feature(layout_for_ptr)]
#![feature(libc)]
#![feature(map_first_last)]
#![feature(map_into_keys_values)]
#![feature(maybe_uninit_ref)] #![feature(maybe_uninit_ref)]
#![feature(negative_impls)] #![feature(negative_impls)]
#![feature(never_type)] #![feature(never_type)]
#![feature(new_uninit)]
#![feature(nll)] #![feature(nll)]
#![feature(nonnull_slice_from_raw_parts)] #![feature(nonnull_slice_from_raw_parts)]
#![feature(optin_builtin_traits)] #![feature(optin_builtin_traits)]
@ -125,10 +119,8 @@
#![feature(slice_ptr_get)] #![feature(slice_ptr_get)]
#![feature(slice_ptr_len)] #![feature(slice_ptr_len)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(std_internals)]
#![feature(str_internals)] #![feature(str_internals)]
#![feature(trusted_len)] #![feature(trusted_len)]
#![feature(try_reserve)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(unicode_internals)] #![feature(unicode_internals)]
#![feature(unsafe_block_in_unsafe_fn)] #![feature(unsafe_block_in_unsafe_fn)]

View File

@ -1071,6 +1071,7 @@ extern "rust-intrinsic" {
// NOTE: While this makes the intrinsic const stable, we have some custom code in const fn // NOTE: While this makes the intrinsic const stable, we have some custom code in const fn
// checks that prevent its use within `const fn`. // checks that prevent its use within `const fn`.
#[rustc_const_stable(feature = "const_transmute", since = "1.46.0")] #[rustc_const_stable(feature = "const_transmute", since = "1.46.0")]
#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "transmute")]
pub fn transmute<T, U>(e: T) -> U; pub fn transmute<T, U>(e: T) -> U;
/// Returns `true` if the actual type given as `T` requires drop /// Returns `true` if the actual type given as `T` requires drop

View File

@ -66,9 +66,7 @@
#![feature(allow_internal_unstable)] #![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)] #![feature(arbitrary_self_types)]
#![feature(asm)] #![feature(asm)]
#![feature(bound_cloned)]
#![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_alloc_layout)] #![feature(const_alloc_layout)]
#![feature(const_discriminant)] #![feature(const_discriminant)]
#![feature(const_checked_int_methods)] #![feature(const_checked_int_methods)]
@ -103,8 +101,6 @@
#![feature(extern_types)] #![feature(extern_types)]
#![feature(fundamental)] #![feature(fundamental)]
#![feature(intrinsics)] #![feature(intrinsics)]
#![feature(try_find)]
#![feature(is_sorted)]
#![feature(lang_items)] #![feature(lang_items)]
#![feature(link_llvm_intrinsics)] #![feature(link_llvm_intrinsics)]
#![feature(llvm_asm)] #![feature(llvm_asm)]
@ -116,7 +112,6 @@
#![feature(optin_builtin_traits)] #![feature(optin_builtin_traits)]
#![feature(or_patterns)] #![feature(or_patterns)]
#![feature(prelude_import)] #![feature(prelude_import)]
#![feature(ptr_as_uninit)]
#![feature(repr_simd, platform_intrinsics)] #![feature(repr_simd, platform_intrinsics)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#![feature(simd_ffi)] #![feature(simd_ffi)]
@ -147,8 +142,6 @@
#![feature(const_fn_transmute)] #![feature(const_fn_transmute)]
#![feature(abi_unadjusted)] #![feature(abi_unadjusted)]
#![feature(adx_target_feature)] #![feature(adx_target_feature)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_extra)]
#![feature(external_doc)] #![feature(external_doc)]
#![feature(associated_type_bounds)] #![feature(associated_type_bounds)]
#![feature(const_caller_location)] #![feature(const_caller_location)]

View File

@ -12,7 +12,6 @@
#![panic_runtime] #![panic_runtime]
#![allow(unused_features)] #![allow(unused_features)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(libc)]
#![feature(nll)] #![feature(nll)]
#![feature(panic_runtime)] #![feature(panic_runtime)]
#![feature(staged_api)] #![feature(staged_api)]

View File

@ -20,7 +20,6 @@
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(int_bits_const)] #![feature(int_bits_const)]
#![feature(lang_items)] #![feature(lang_items)]
#![feature(libc)]
#![feature(nll)] #![feature(nll)]
#![feature(panic_unwind)] #![feature(panic_unwind)]
#![feature(staged_api)] #![feature(staged_api)]

View File

@ -1173,6 +1173,16 @@ where
/// See its documentation for more. /// See its documentation for more.
/// ///
/// [`iter`]: HashSet::iter /// [`iter`]: HashSet::iter
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
///
/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
///
/// let mut iter = a.iter();
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, K: 'a> { pub struct Iter<'a, K: 'a> {
base: base::Iter<'a, K>, base: base::Iter<'a, K>,
@ -1184,6 +1194,16 @@ pub struct Iter<'a, K: 'a> {
/// (provided by the `IntoIterator` trait). See its documentation for more. /// (provided by the `IntoIterator` trait). See its documentation for more.
/// ///
/// [`into_iter`]: IntoIterator::into_iter /// [`into_iter`]: IntoIterator::into_iter
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
///
/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
///
/// let mut iter = a.into_iter();
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<K> { pub struct IntoIter<K> {
base: base::IntoIter<K>, base: base::IntoIter<K>,
@ -1195,6 +1215,16 @@ pub struct IntoIter<K> {
/// See its documentation for more. /// See its documentation for more.
/// ///
/// [`drain`]: HashSet::drain /// [`drain`]: HashSet::drain
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
///
/// let mut a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
///
/// let mut drain = a.drain();
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Drain<'a, K: 'a> { pub struct Drain<'a, K: 'a> {
base: base::Drain<'a, K>, base: base::Drain<'a, K>,
@ -1205,6 +1235,18 @@ pub struct Drain<'a, K: 'a> {
/// This `struct` is created by the [`drain_filter`] method on [`HashSet`]. /// This `struct` is created by the [`drain_filter`] method on [`HashSet`].
/// ///
/// [`drain_filter`]: HashSet::drain_filter /// [`drain_filter`]: HashSet::drain_filter
///
/// # Examples
///
/// ```
/// #![feature(hash_drain_filter)]
///
/// use std::collections::HashSet;
///
/// let mut a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
///
/// let mut drain_filtered = a.drain_filter(|v| v % 2 == 0);
/// ```
#[unstable(feature = "hash_drain_filter", issue = "59618")] #[unstable(feature = "hash_drain_filter", issue = "59618")]
pub struct DrainFilter<'a, K, F> pub struct DrainFilter<'a, K, F>
where where
@ -1219,6 +1261,17 @@ where
/// See its documentation for more. /// See its documentation for more.
/// ///
/// [`intersection`]: HashSet::intersection /// [`intersection`]: HashSet::intersection
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
///
/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
/// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
///
/// let mut intersection = a.intersection(&b);
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Intersection<'a, T: 'a, S: 'a> { pub struct Intersection<'a, T: 'a, S: 'a> {
// iterator of the first set // iterator of the first set
@ -1233,6 +1286,17 @@ pub struct Intersection<'a, T: 'a, S: 'a> {
/// See its documentation for more. /// See its documentation for more.
/// ///
/// [`difference`]: HashSet::difference /// [`difference`]: HashSet::difference
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
///
/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
/// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
///
/// let mut difference = a.difference(&b);
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Difference<'a, T: 'a, S: 'a> { pub struct Difference<'a, T: 'a, S: 'a> {
// iterator of the first set // iterator of the first set
@ -1247,6 +1311,17 @@ pub struct Difference<'a, T: 'a, S: 'a> {
/// [`HashSet`]. See its documentation for more. /// [`HashSet`]. See its documentation for more.
/// ///
/// [`symmetric_difference`]: HashSet::symmetric_difference /// [`symmetric_difference`]: HashSet::symmetric_difference
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
///
/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
/// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
///
/// let mut intersection = a.symmetric_difference(&b);
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct SymmetricDifference<'a, T: 'a, S: 'a> { pub struct SymmetricDifference<'a, T: 'a, S: 'a> {
iter: Chain<Difference<'a, T, S>, Difference<'a, T, S>>, iter: Chain<Difference<'a, T, S>, Difference<'a, T, S>>,
@ -1258,6 +1333,17 @@ pub struct SymmetricDifference<'a, T: 'a, S: 'a> {
/// See its documentation for more. /// See its documentation for more.
/// ///
/// [`union`]: HashSet::union /// [`union`]: HashSet::union
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
///
/// let a: HashSet<u32> = vec![1, 2, 3].into_iter().collect();
/// let b: HashSet<_> = [4, 2, 3, 4].iter().cloned().collect();
///
/// let mut union_iter = a.union(&b);
/// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Union<'a, T: 'a, S: 'a> { pub struct Union<'a, T: 'a, S: 'a> {
iter: Chain<Iter<'a, T>, Difference<'a, T, S>>, iter: Chain<Iter<'a, T>, Difference<'a, T, S>>,

View File

@ -228,7 +228,6 @@
#![feature(atomic_mut_ptr)] #![feature(atomic_mut_ptr)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(c_variadic)] #![feature(c_variadic)]
#![feature(can_vector)]
#![feature(cfg_accessible)] #![feature(cfg_accessible)]
#![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic)]
#![feature(cfg_target_thread_local)] #![feature(cfg_target_thread_local)]
@ -261,14 +260,12 @@
#![feature(gen_future)] #![feature(gen_future)]
#![feature(generator_trait)] #![feature(generator_trait)]
#![feature(global_asm)] #![feature(global_asm)]
#![feature(hash_raw_entry)]
#![feature(hashmap_internals)] #![feature(hashmap_internals)]
#![feature(int_error_internals)] #![feature(int_error_internals)]
#![feature(int_error_matching)] #![feature(int_error_matching)]
#![feature(integer_atomics)] #![feature(integer_atomics)]
#![feature(into_future)] #![feature(into_future)]
#![feature(lang_items)] #![feature(lang_items)]
#![feature(libc)]
#![feature(link_args)] #![feature(link_args)]
#![feature(linkage)] #![feature(linkage)]
#![feature(llvm_asm)] #![feature(llvm_asm)]

View File

@ -667,7 +667,7 @@ impl UnixStream {
/// Ok(()) /// Ok(())
/// } /// }
/// ``` /// ```
#[unstable(feature = "unix_socket_peek", issue = "none")] #[unstable(feature = "unix_socket_peek", issue = "76923")]
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
self.0.peek(buf) self.0.peek(buf)
} }
@ -1708,7 +1708,7 @@ impl UnixDatagram {
/// Ok(()) /// Ok(())
/// } /// }
/// ``` /// ```
#[unstable(feature = "unix_socket_peek", issue = "none")] #[unstable(feature = "unix_socket_peek", issue = "76923")]
pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
self.0.peek(buf) self.0.peek(buf)
} }
@ -1740,7 +1740,7 @@ impl UnixDatagram {
/// Ok(()) /// Ok(())
/// } /// }
/// ``` /// ```
#[unstable(feature = "unix_socket_peek", issue = "none")] #[unstable(feature = "unix_socket_peek", issue = "76923")]
pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
self.recv_from_flags(buf, libc::MSG_PEEK) self.recv_from_flags(buf, libc::MSG_PEEK)
} }

View File

@ -12,9 +12,6 @@ use build_helper::output;
use crate::Build; use crate::Build;
// The version number
pub const CFG_RELEASE_NUM: &str = "1.48.0";
pub struct GitInfo { pub struct GitInfo {
inner: Option<Info>, inner: Option<Info>,
} }

View File

@ -18,7 +18,6 @@ use build_helper::{output, t};
use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::cache::{Interned, INTERNER}; use crate::cache::{Interned, INTERNER};
use crate::channel;
use crate::compile; use crate::compile;
use crate::config::TargetSelection; use crate::config::TargetSelection;
use crate::tool::{self, Tool}; use crate::tool::{self, Tool};
@ -569,7 +568,7 @@ impl Step for Rustc {
&page_dst, &page_dst,
&[ &[
("<INSERT DATE HERE>", &month_year), ("<INSERT DATE HERE>", &month_year),
("<INSERT VERSION HERE>", channel::CFG_RELEASE_NUM), ("<INSERT VERSION HERE>", &builder.version),
], ],
); );
} }
@ -2301,9 +2300,9 @@ impl Step for Extended {
} }
fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) { fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) {
let mut parts = channel::CFG_RELEASE_NUM.split('.'); let mut parts = builder.version.split('.');
cmd.env("CFG_RELEASE_INFO", builder.rust_version()) cmd.env("CFG_RELEASE_INFO", builder.rust_version())
.env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM) .env("CFG_RELEASE_NUM", &builder.version)
.env("CFG_RELEASE", builder.rust_release()) .env("CFG_RELEASE", builder.rust_release())
.env("CFG_VER_MAJOR", parts.next().unwrap()) .env("CFG_VER_MAJOR", parts.next().unwrap())
.env("CFG_VER_MINOR", parts.next().unwrap()) .env("CFG_VER_MINOR", parts.next().unwrap())

View File

@ -433,7 +433,7 @@ impl Step for Std {
.arg("-Z") .arg("-Z")
.arg("unstable-options") .arg("unstable-options")
.arg("--resource-suffix") .arg("--resource-suffix")
.arg(crate::channel::CFG_RELEASE_NUM) .arg(&builder.version)
.arg("--index-page") .arg("--index-page")
.arg(&builder.src.join("src/doc/index.md")); .arg(&builder.src.join("src/doc/index.md"));
@ -659,7 +659,7 @@ impl Step for ErrorIndex {
let mut index = tool::ErrorIndex::command(builder, self.compiler); let mut index = tool::ErrorIndex::command(builder, self.compiler);
index.arg("html"); index.arg("html");
index.arg(out.join("error-index.html")); index.arg(out.join("error-index.html"));
index.arg(crate::channel::CFG_RELEASE_NUM); index.arg(&builder.version);
builder.run(&mut index); builder.run(&mut index);
} }

View File

@ -218,6 +218,9 @@ pub struct Build {
/// User-specified configuration from `config.toml`. /// User-specified configuration from `config.toml`.
config: Config, config: Config,
// Version information
version: String,
// Properties derived from the above configuration // Properties derived from the above configuration
src: PathBuf, src: PathBuf,
out: PathBuf, out: PathBuf,
@ -380,6 +383,10 @@ impl Build {
.unwrap() .unwrap()
.to_path_buf(); .to_path_buf();
let version = std::fs::read_to_string(src.join("src").join("version"))
.expect("failed to read src/version");
let version = version.trim();
let mut build = Build { let mut build = Build {
initial_rustc: config.initial_rustc.clone(), initial_rustc: config.initial_rustc.clone(),
initial_cargo: config.initial_cargo.clone(), initial_cargo: config.initial_cargo.clone(),
@ -395,6 +402,7 @@ impl Build {
targets: config.targets.clone(), targets: config.targets.clone(),
config, config,
version: version.to_string(),
src, src,
out, out,
@ -433,8 +441,7 @@ impl Build {
.next() .next()
.unwrap() .unwrap()
.trim(); .trim();
let my_version = channel::CFG_RELEASE_NUM; if local_release.split('.').take(2).eq(version.split('.').take(2)) {
if local_release.split('.').take(2).eq(my_version.split('.').take(2)) {
build.verbose(&format!("auto-detected local-rebuild {}", local_release)); build.verbose(&format!("auto-detected local-rebuild {}", local_release));
build.local_rebuild = true; build.local_rebuild = true;
} }
@ -785,7 +792,7 @@ impl Build {
match which { match which {
GitRepo::Rustc => { GitRepo::Rustc => {
let sha = self.rust_sha().unwrap_or(channel::CFG_RELEASE_NUM); let sha = self.rust_sha().unwrap_or(&self.version);
Some(format!("/rustc/{}", sha)) Some(format!("/rustc/{}", sha))
} }
GitRepo::Llvm => Some(String::from("/rustc/llvm")), GitRepo::Llvm => Some(String::from("/rustc/llvm")),
@ -1016,7 +1023,7 @@ impl Build {
/// Returns the value of `release` above for Rust itself. /// Returns the value of `release` above for Rust itself.
fn rust_release(&self) -> String { fn rust_release(&self) -> String {
self.release(channel::CFG_RELEASE_NUM) self.release(&self.version)
} }
/// Returns the "package version" for a component given the `num` release /// Returns the "package version" for a component given the `num` release
@ -1036,7 +1043,7 @@ impl Build {
/// Returns the value of `package_vers` above for Rust itself. /// Returns the value of `package_vers` above for Rust itself.
fn rust_package_vers(&self) -> String { fn rust_package_vers(&self) -> String {
self.package_vers(channel::CFG_RELEASE_NUM) self.package_vers(&self.version)
} }
/// Returns the value of `package_vers` above for Cargo /// Returns the value of `package_vers` above for Cargo
@ -1070,7 +1077,7 @@ impl Build {
} }
fn llvm_tools_package_vers(&self) -> String { fn llvm_tools_package_vers(&self) -> String {
self.package_vers(channel::CFG_RELEASE_NUM) self.package_vers(&self.version)
} }
fn llvm_tools_vers(&self) -> String { fn llvm_tools_vers(&self) -> String {
@ -1087,7 +1094,7 @@ impl Build {
/// Note that this is a descriptive string which includes the commit date, /// Note that this is a descriptive string which includes the commit date,
/// sha, version, etc. /// sha, version, etc.
fn rust_version(&self) -> String { fn rust_version(&self) -> String {
self.rust_info.version(self, channel::CFG_RELEASE_NUM) self.rust_info.version(self, &self.version)
} }
/// Returns the full commit hash. /// Returns the full commit hash.

View File

@ -19,7 +19,6 @@ use std::process::Command;
use build_helper::{output, t}; use build_helper::{output, t};
use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::channel;
use crate::config::TargetSelection; use crate::config::TargetSelection;
use crate::util::{self, exe}; use crate::util::{self, exe};
use crate::GitRepo; use crate::GitRepo;
@ -296,7 +295,7 @@ impl Step for Llvm {
// release number on the dev channel. // release number on the dev channel.
cfg.define("LLVM_VERSION_SUFFIX", "-rust-dev"); cfg.define("LLVM_VERSION_SUFFIX", "-rust-dev");
} else { } else {
let suffix = format!("-rust-{}-{}", channel::CFG_RELEASE_NUM, builder.config.channel); let suffix = format!("-rust-{}-{}", builder.version, builder.config.channel);
cfg.define("LLVM_VERSION_SUFFIX", suffix); cfg.define("LLVM_VERSION_SUFFIX", suffix);
} }

View File

@ -636,7 +636,7 @@ impl Step for RustdocJSStd {
.arg("--crate-name") .arg("--crate-name")
.arg("std") .arg("std")
.arg("--resource-suffix") .arg("--resource-suffix")
.arg(crate::channel::CFG_RELEASE_NUM) .arg(&builder.version)
.arg("--doc-folder") .arg("--doc-folder")
.arg(builder.doc_out(self.target)) .arg(builder.doc_out(self.target))
.arg("--test-folder") .arg("--test-folder")

View File

@ -7,7 +7,6 @@ use std::process::{exit, Command};
use build_helper::t; use build_helper::t;
use crate::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; use crate::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step};
use crate::channel;
use crate::channel::GitInfo; use crate::channel::GitInfo;
use crate::compile; use crate::compile;
use crate::config::TargetSelection; use crate::config::TargetSelection;
@ -255,7 +254,7 @@ pub fn prepare_tool_cargo(
cargo.env("CFG_RELEASE", builder.rust_release()); cargo.env("CFG_RELEASE", builder.rust_release());
cargo.env("CFG_RELEASE_CHANNEL", &builder.config.channel); cargo.env("CFG_RELEASE_CHANNEL", &builder.config.channel);
cargo.env("CFG_VERSION", builder.rust_version()); cargo.env("CFG_VERSION", builder.rust_version());
cargo.env("CFG_RELEASE_NUM", channel::CFG_RELEASE_NUM); cargo.env("CFG_RELEASE_NUM", &builder.version);
let info = GitInfo::new(builder.config.ignore_git, &dir); let info = GitInfo::new(builder.config.ignore_git, &dir);
if let Some(sha) = info.sha() { if let Some(sha) = info.sha() {

View File

@ -0,0 +1,23 @@
// Regression test for issue #76202
// Tests that we don't ICE when we have a trait impl on a TAIT.
#![feature(type_alias_impl_trait)]
trait Dummy {}
impl Dummy for () {}
type F = impl Dummy;
fn f() -> F {}
trait Test {
fn test(self);
}
impl Test for F { //~ ERROR cannot implement trait
fn test(self) {}
}
fn main() {
let x: F = f();
x.test();
}

View File

@ -0,0 +1,14 @@
error: cannot implement trait on type alias impl trait
--> $DIR/issue-76202-trait-impl-for-tait.rs:16:1
|
LL | impl Test for F {
| ^^^^^^^^^^^^^^^
|
note: type alias impl trait defined here
--> $DIR/issue-76202-trait-impl-for-tait.rs:9:10
|
LL | type F = impl Dummy;
| ^^^^^^^^^^
error: aborting due to previous error

1
src/version Normal file
View File

@ -0,0 +1 @@
1.48.0