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`:
```sh
$ git clone https://github.com/rust-lang/rust.git
$ cd rust
git clone https://github.com/rust-lang/rust.git
cd 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.
```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
@ -68,7 +68,7 @@ by running `./x.py --help` or reading the [rustc dev guide][rustcguidebuild].
4. Build and install:
```sh
$ ./x.py build && ./x.py install
./x.py build && ./x.py install
```
When complete, `./x.py install` will place several programs into
@ -106,7 +106,7 @@ build.
```sh
# 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,
# 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'
# packages from the 'msys2' subsystem. The build has historically been known
# to fail with these packages.
$ pacman -S git \
pacman -S git \
make \
diffutils \
tar \
@ -127,7 +127,7 @@ build.
4. Navigate to Rust's source code (or clone it), then build it:
```sh
$ ./x.py build && ./x.py install
./x.py build && ./x.py install
```
#### MSVC
@ -145,7 +145,7 @@ With these dependencies installed, you can build the compiler in a `cmd.exe`
shell with:
```sh
> python x.py build
python x.py build
```
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.
```batch
> CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
> python x.py build
CALL "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
python x.py build
```
#### 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`).
```sh
$ ./configure
$ make && sudo make install
./configure
make && sudo make install
```
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:
```sh
$ ./x.py doc
./x.py doc
```
The generated documentation will appear under `doc` in the `build` directory for

View File

@ -1931,7 +1931,7 @@ pub enum TyKind {
impl TyKind {
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 {
@ -2227,7 +2227,7 @@ pub enum Async {
impl Async {
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.
@ -2508,7 +2508,7 @@ pub enum VisibilityKind {
impl VisibilityKind {
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();
}
if !bounds
.iter()
.any(|b| if let GenericBound::Trait(..) = *b { true } else { false })
{
if !bounds.iter().any(|b| matches!(b, GenericBound::Trait(..))) {
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 {
pub fn is_unstable(&self) -> bool {
if let StabilityLevel::Unstable { .. } = *self { true } else { false }
matches!(self, StabilityLevel::Unstable { .. })
}
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()) {
(false, false) => cx.span_bug(
self.span,

View File

@ -15,6 +15,7 @@ use rustc_session::{
};
use rustc_span::symbol::Symbol;
use rustc_target::abi::LayoutOf;
use rustc_target::spec::Target;
pub use rustc_data_structures::sync::MetadataRef;
@ -54,6 +55,12 @@ pub trait CodegenBackend {
fn print_passes(&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 provide(&self, _providers: &mut Providers);
fn provide_extern(&self, _providers: &mut Providers);

View File

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

View File

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

View File

@ -65,6 +65,10 @@ pub fn create_session(
lint_caps: FxHashMap<lint::LintId, lint::Level>,
descriptions: Registry,
) -> (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(
sopts,
input_path,
@ -72,9 +76,10 @@ pub fn create_session(
diagnostic_output,
lint_caps,
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));
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 mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!();
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 {
filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()),
codegen_name => get_builtin_codegen_backend(codegen_name),
@ -235,9 +240,7 @@ pub fn get_codegen_backend(sess: &Session) -> Box<dyn CodegenBackend> {
LOAD = backend;
}
});
let backend = unsafe { LOAD() };
backend.init(sess);
backend
unsafe { LOAD() }
}
// 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)| {
if let hir::GenericBound::Outlives(lifetime) = bound {
let is_inferred = match tcx.named_region(lifetime.hir_id) {
Some(Region::Static) if infer_static => inferred_outlives
.iter()
.any(|r| if let ty::ReStatic = r { true } else { false }),
Some(Region::Static) if infer_static => {
inferred_outlives.iter().any(|r| matches!(r, ty::ReStatic))
}
Some(Region::EarlyBound(index, ..)) => inferred_outlives.iter().any(|r| {
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();
for param in hir_generics.params {
let has_lifetime_bounds = param.bounds.iter().any(|bound| {
if let hir::GenericBound::Outlives(_) = bound { true } else { false }
});
let has_lifetime_bounds = param
.bounds
.iter()
.any(|bound| matches!(bound, hir::GenericBound::Outlives(_)));
if !has_lifetime_bounds {
continue;
}
@ -2349,13 +2350,6 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
/// Determine if this expression is a "dangerous initialization".
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 {
// Find calls to `mem::{uninitialized,zeroed}` methods.
if let hir::ExprKind::Path(ref qpath) = path_expr.kind {
@ -2365,7 +2359,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue {
return Some(InitKind::Zeroed);
} else if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, def_id) {
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]) {
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`;
/// 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
///
/// ```rust,ignore (no context or def id available)

View File

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

View File

@ -17,7 +17,7 @@ use rustc_target::spec::PanicStrategy;
impl<'tcx> TyCtxt<'tcx> {
/// Returns the `DefId` for a given `LangItem`.
/// 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| {
if let Some(span) = span {
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();
match Some(id) {
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)
}
}

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
/// an `AllocId` from a query.
pub fn reserve_alloc_id(&self) -> AllocId {
pub fn reserve_alloc_id(self) -> AllocId {
self.alloc_map.lock().reserve()
}
/// 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
/// 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();
match alloc {
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
/// 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))
}
/// Generates an `AllocId` for a function. Depending on the function type,
/// 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
// by the linker (we set the "unnamed_addr" attribute for LLVM) and functions can be
// duplicated across crates.
@ -507,7 +507,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Statics with identical content will still point to the same `Allocation`, i.e.,
/// their data will be deduplicated through `Allocation` interning -- but they
/// 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();
self.set_alloc_id_memory(id, mem);
id
@ -519,7 +519,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// This function exists to allow const eval to detect the difference between evaluation-
/// local dangling pointers and allocations in constants/statics.
#[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()
}
@ -529,7 +529,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// 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
/// 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) {
Some(alloc) => alloc,
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
/// 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)) {
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
/// 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));
}
}

View File

@ -1077,6 +1077,25 @@ pub struct VarDebugInfo<'tcx> {
// BasicBlock
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 {
derive [HashStable]
DEBUG_FORMAT = "bb{}",
@ -1093,6 +1112,7 @@ impl BasicBlock {
///////////////////////////////////////////////////////////////////////////
// BasicBlockData and Terminator
/// See [`BasicBlock`] for documentation on what basic blocks are at a high level.
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable)]
pub struct BasicBlockData<'tcx> {
/// 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.
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 {
ty::ReFree(ref free_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.
pub fn return_type_impl_or_dyn_traits(
&self,
self,
scope_def_id: LocalDefId,
) -> Vec<&'tcx hir::Ty<'tcx>> {
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
@ -1479,7 +1479,7 @@ impl<'tcx> TyCtxt<'tcx> {
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`.
let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id);
match self.hir().get(hir_id) {
@ -1497,7 +1497,7 @@ impl<'tcx> TyCtxt<'tcx> {
let ret_ty = self.type_of(scope_def_id);
match ret_ty.kind() {
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());
if output.is_impl_trait() {
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.
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 =
self.associated_item(suitable_region_binding_scope.to_def_id()).container.id();
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.
/// 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")
}
/// 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.lifetimes.re_static,
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")`).
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) {
DefKind::Generator => match self.generator_kind(def_id).unwrap() {
rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"),

View File

@ -546,7 +546,7 @@ impl<T> Trait<T> for X {
}
fn suggest_constraint(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
msg: &str,
body_owner_def_id: DefId,
@ -554,14 +554,14 @@ impl<T> Trait<T> for X {
ty: Ty<'tcx>,
) -> bool {
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(hir_generics) = item.generics() {
// Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
// This will also work for `impl Trait`.
let def_id = if let ty::Param(param_ty) = proj_ty.self_ty().kind() {
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 {
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
/// fn that returns the type.
fn expected_projection(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
proj_ty: &ty::ProjectionTy<'tcx>,
values: &ExpectedFound<Ty<'tcx>>,
@ -734,7 +734,7 @@ fn foo(&self) -> Self::T { String::new() }
}
fn point_at_methods_that_satisfy_associated_type(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
assoc_container_id: DefId,
current_method_ident: Option<Symbol>,
@ -789,7 +789,7 @@ fn foo(&self) -> Self::T { String::new() }
}
fn point_at_associated_type(
&self,
self,
db: &mut DiagnosticBuilder<'_>,
body_owner_def_id: DefId,
found: Ty<'tcx>,

View File

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

View File

@ -170,9 +170,7 @@ impl<'tcx> TyCtxt<'tcx> {
});
hasher.finish()
}
}
impl<'tcx> TyCtxt<'tcx> {
pub fn has_error_field(self, ty: Ty<'tcx>) -> bool {
if let ty::Adt(def, substs) = *ty.kind() {
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.
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()
}
/// 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)
}
/// 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)
}
/// 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.
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.
// 3) Suggest unifying 'a with 'b if we have both 'a: 'b and 'b: 'a
if outlived.iter().any(|(_, outlived_name)| {
if let RegionNameSource::Static = outlived_name.source { true } else { false }
}) {
if outlived
.iter()
.any(|(_, outlived_name)| matches!(outlived_name.source, RegionNameSource::Static))
{
suggested.push(SuggestedConstraint::Static(fr_name));
} else {
// 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 {
pub fn is_promotable(&self) -> bool {
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) {
for blk in self.basic_blocks.iter_mut() {
blk.statements
.retain(|stmt| if let StatementKind::Nop = stmt.kind { false } else { true })
blk.statements.retain(|stmt| !matches!(stmt.kind, StatementKind::Nop))
}
}
}

View File

@ -96,8 +96,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
);
}
StmtKind::Let { remainder_scope, init_scope, pattern, initializer, lint_level } => {
let ignores_expr_result =
if let PatKind::Wild = *pattern.kind { true } else { false };
let ignores_expr_result = matches!(*pattern.kind, PatKind::Wild);
this.block_context.push(BlockFrame::Statement { ignores_expr_result });
// 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)
.chain(&candidate.bindings)
.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
// place they refer to can't be modified by the guard.

View File

@ -12,11 +12,11 @@
use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_span::def_id::{DefId, LOCAL_CRATE};
use rustc_span::symbol::{sym, Symbol};
struct DiagnosticItemCollector<'tcx> {
@ -100,6 +100,18 @@ fn collect<'tcx>(tcx: TyCtxt<'tcx>) -> FxHashMap<Symbol, DefId> {
// Collect diagnostic items in this crate.
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
}

View File

@ -395,7 +395,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
// so prefixes are prepended with crate root segment if necessary.
// 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.
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() {
Some(seg) if !seg.ident.is_path_segment_keyword() && seg.ident.span.rust_2015() => {
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 parent_rib = self.ribs[ns]
.iter()
.rfind(|r| if let ItemRibKind(_) = r.kind { true } else { false })
.rfind(|r| matches!(r.kind, ItemRibKind(_)))
.expect("associated item outside of an item");
seen_bindings
.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
}
pub fn build_target_config(opts: &Options, error_format: ErrorOutputType) -> Config {
let target = Target::search(&opts.target_triple).unwrap_or_else(|e| {
pub fn build_target_config(opts: &Options, target_override: Option<Target>) -> Config {
let target_result = target_override.map_or_else(|| Target::search(&opts.target_triple), Ok);
let target = target_result.unwrap_or_else(|e| {
early_error(
error_format,
opts.error_format,
&format!(
"Error loading target specification: {}. \
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,
"64" => 64,
w => early_error(
error_format,
opts.error_format,
&format!(
"target specification was invalid: \
unrecognized target-pointer-width {}",

View File

@ -1234,6 +1234,7 @@ pub fn build_session(
diagnostics_output: DiagnosticOutput,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>,
target_override: Option<Target>,
) -> Session {
// 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
@ -1253,7 +1254,7 @@ pub fn build_session(
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 = Target::search(&host_triple).unwrap_or_else(|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
// `let u = &raw const Box::new((1,)).0`, which creates an
// immediately dangling raw pointer.
self.typeck_results.borrow().adjustments().get(base.hir_id).map_or(false, |x| {
x.iter().any(|adj| if let Adjust::Deref(_) = adj.kind { true } else { false })
})
self.typeck_results
.borrow()
.adjustments()
.get(base.hir_id)
.map_or(false, |x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
});
if !is_named {
self.tcx.sess.emit_err(AddressOfTemporaryTaken { span: oprnd.span })

View File

@ -230,6 +230,14 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
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
//! [sssp]: https://en.wikipedia.org/wiki/Shortest_path_problem
//! [dir_graph]: https://en.wikipedia.org/wiki/Directed_graph
//! [`BinaryHeap`]: struct.BinaryHeap.html
//!
//! ```
//! use std::cmp::Ordering;
@ -240,10 +239,10 @@ use super::SpecExtend;
/// The value for `push` is an expected cost; the method documentation gives a
/// more detailed analysis.
///
/// [push]: #method.push
/// [pop]: #method.pop
/// [peek]: #method.peek
/// [peek\_mut]: #method.peek_mut
/// [push]: BinaryHeap::push
/// [pop]: BinaryHeap::pop
/// [peek]: BinaryHeap::peek
/// [peek\_mut]: BinaryHeap::peek_mut
#[stable(feature = "rust1", since = "1.0.0")]
pub struct BinaryHeap<T> {
data: Vec<T>,
@ -255,8 +254,7 @@ pub struct BinaryHeap<T> {
/// This `struct` is created by the [`peek_mut`] method on [`BinaryHeap`]. See
/// its documentation for more.
///
/// [`peek_mut`]: struct.BinaryHeap.html#method.peek_mut
/// [`BinaryHeap`]: struct.BinaryHeap.html
/// [`peek_mut`]: BinaryHeap::peek_mut
#[stable(feature = "binary_heap_peek_mut", since = "1.12.0")]
pub struct PeekMut<'a, T: 'a + Ord> {
heap: &'a mut BinaryHeap<T>,
@ -802,7 +800,7 @@ impl<T> BinaryHeap<T> {
/// heap.push(4);
/// ```
///
/// [`reserve`]: #method.reserve
/// [`reserve`]: BinaryHeap::reserve
#[stable(feature = "rust1", since = "1.0.0")]
pub fn reserve_exact(&mut self, additional: usize) {
self.data.reserve_exact(additional);
@ -1057,11 +1055,10 @@ impl<T> Drop for Hole<'_, T> {
/// 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.
///
/// [`iter`]: struct.BinaryHeap.html#method.iter
/// [`BinaryHeap`]: struct.BinaryHeap.html
/// [`iter`]: BinaryHeap::iter
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, T: 'a> {
iter: slice::Iter<'a, T>,
@ -1122,11 +1119,10 @@ impl<T> FusedIterator for Iter<'_, T> {}
/// 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.
///
/// [`into_iter`]: struct.BinaryHeap.html#method.into_iter
/// [`BinaryHeap`]: struct.BinaryHeap.html
/// [`into_iter`]: BinaryHeap::into_iter
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
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`.
///
/// This `struct` is created by the [`drain`] method on [`BinaryHeap`]. See its
/// This `struct` is created by [`BinaryHeap::drain()`]. See its
/// documentation for more.
///
/// [`drain`]: struct.BinaryHeap.html#method.drain
/// [`BinaryHeap`]: struct.BinaryHeap.html
/// [`drain`]: BinaryHeap::drain
#[stable(feature = "drain", since = "1.6.0")]
#[derive(Debug)]
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`.
///
/// 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.
///
/// [`drain_sorted`]: struct.BinaryHeap.html#method.drain_sorted
/// [`BinaryHeap`]: struct.BinaryHeap.html
/// [`drain_sorted`]: BinaryHeap::drain_sorted
#[unstable(feature = "binary_heap_drain_sorted", issue = "59278")]
#[derive(Debug)]
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
/// normally only possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
///
/// [`Ord`]: core::cmp::Ord
/// [`Cell`]: core::cell::Cell
/// [`RefCell`]: core::cell::RefCell
///
@ -93,9 +92,10 @@ use UnderflowResult::*;
/// }
/// ```
///
/// `BTreeMap` also implements an [`Entry API`](#method.entry), which allows
/// for more complex methods of getting, setting, updating and removing keys and
/// their values:
/// `BTreeMap` also implements an [`Entry API`], which allows for more complex
/// methods of getting, setting, updating and removing keys and their values:
///
/// [`Entry API`]: BTreeMap::entry
///
/// ```
/// 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`.
/// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct VacantEntry<'a, K: 'a, V: 'a> {
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`.
/// It is part of the [`Entry`] enum.
///
/// [`Entry`]: enum.Entry.html
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
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
/// documentation] for more.
///
/// [module-level documentation]: index.html#insert-and-complex-keys
/// [module-level documentation]: crate::collections#insert-and-complex-keys
///
/// # Examples
///
@ -1719,7 +1715,7 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
/// Allow Debug implementations to predict the next element.
pub(super) fn peek(&self) -> Option<(&K, &V)> {
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.
@ -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
/// destruction of the `Entry` value, see [`into_mut`].
///
/// [`into_mut`]: #method.into_mut
/// [`into_mut`]: OccupiedEntry::into_mut
///
/// # 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`].
///
/// [`get_mut`]: #method.get_mut
/// [`get_mut`]: OccupiedEntry::get_mut
///
/// # 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();
loop {
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() {
Ok(parent_edge) => parent_edge.forget_node_type(),
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();
loop {
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() {
Ok(parent_edge) => parent_edge.forget_node_type(),
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.
fn insert(mut self, key: K, val: V) -> (InsertResult<'a, K, V, marker::Leaf>, *mut V) {
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) };
(InsertResult::Fit(kv), ptr)
(InsertResult::Fit(kv), val_ptr)
} else {
let (middle_kv_idx, insertion) = splitpoint(self.idx);
let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) };
let (mut left, k, v, mut right) = middle.split();
let ptr = match insertion {
let val_ptr = match insertion {
InsertionPlace::Left(insert_idx) => unsafe {
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)
},
};
(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`]
/// (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)]
#[stable(feature = "rust1", since = "1.0.0")]
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
/// now-contiguous element sequence.
///
/// [`push_back`]: #method.push_back
/// [`pop_front`]: #method.pop_front
/// [`extend`]: #method.extend
/// [`append`]: #method.append
/// [`make_contiguous`]: #method.make_contiguous
/// [`push_back`]: VecDeque::push_back
/// [`pop_front`]: VecDeque::pop_front
/// [`extend`]: VecDeque::extend
/// [`append`]: VecDeque::append
/// [`make_contiguous`]: VecDeque::make_contiguous
#[cfg_attr(not(test), rustc_diagnostic_item = "vecdeque_type")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct VecDeque<T> {
@ -640,7 +640,7 @@ impl<T> VecDeque<T> {
/// assert!(buf.capacity() >= 11);
/// ```
///
/// [`reserve`]: #method.reserve
/// [`reserve`]: VecDeque::reserve
#[stable(feature = "rust1", since = "1.0.0")]
pub fn reserve_exact(&mut self, additional: usize) {
self.reserve(additional);
@ -987,8 +987,10 @@ impl<T> VecDeque<T> {
/// Returns a pair of slices which contain, in order, the contents of the
/// `VecDeque`.
///
/// If [`make_contiguous`](#method.make_contiguous) was previously called, all elements
/// of the `VecDeque` will be in the first slice and the second slice will be empty.
/// If [`make_contiguous`] was previously called, all elements of the
/// `VecDeque` will be in the first slice and the second slice will be empty.
///
/// [`make_contiguous`]: VecDeque::make_contiguous
///
/// # Examples
///
@ -1020,8 +1022,10 @@ impl<T> VecDeque<T> {
/// Returns a pair of slices which contain, in order, the contents of the
/// `VecDeque`.
///
/// If [`make_contiguous`](#method.make_contiguous) was previously called, all elements
/// of the `VecDeque` will be in the first slice and the second slice will be empty.
/// If [`make_contiguous`] was previously called, all elements of the
/// `VecDeque` will be in the first slice and the second slice will be empty.
///
/// [`make_contiguous`]: VecDeque::make_contiguous
///
/// # 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.
/// As it returns a mutable slice, this can be used to sort or binary search a deque.
/// This method does not allocate and does not change the order of the
/// 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
/// [`as_mut_slices`](#method.as_mut_slices) methods will return the entire contents of the
/// Once the internal storage is contiguous, the [`as_slices`] and
/// [`as_mut_slices`] methods will return the entire contents of the
/// `VecDeque` in a single slice.
///
/// [`as_slices`]: VecDeque::as_slices
/// [`as_mut_slices`]: VecDeque::as_mut_slices
///
/// # Examples
///
/// 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
/// documentation for more.
///
/// [`iter`]: struct.VecDeque.html#method.iter
/// [`VecDeque`]: struct.VecDeque.html
/// [`iter`]: VecDeque::iter
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, T: 'a> {
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
/// documentation for more.
///
/// [`iter_mut`]: struct.VecDeque.html#method.iter_mut
/// [`VecDeque`]: struct.VecDeque.html
/// [`iter_mut`]: VecDeque::iter_mut
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, T: 'a> {
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`]
/// (provided by the `IntoIterator` trait). See its documentation for more.
///
/// [`into_iter`]: struct.VecDeque.html#method.into_iter
/// [`VecDeque`]: struct.VecDeque.html
/// [`into_iter`]: VecDeque::into_iter
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
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
/// documentation for more.
///
/// [`drain`]: struct.VecDeque.html#method.drain
/// [`VecDeque`]: struct.VecDeque.html
/// [`drain`]: VecDeque::drain
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, T: 'a> {
pub(crate) after_tail: usize,

View File

@ -74,6 +74,7 @@
#![deny(unsafe_op_in_unsafe_fn)]
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(test))]
#![cfg_attr(test, feature(new_uninit))]
#![feature(allocator_api)]
#![feature(array_chunks)]
#![feature(array_windows)]
@ -81,7 +82,6 @@
#![feature(arbitrary_self_types)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(btree_drain_filter)]
#![feature(cfg_sanitize)]
#![feature(cfg_target_has_atomic)]
#![feature(coerce_unsized)]
@ -89,10 +89,8 @@
#![feature(const_generics)]
#![feature(const_in_array_repeat_expressions)]
#![feature(cow_is_borrowed)]
#![feature(deque_range)]
#![feature(dispatch_from_dyn)]
#![feature(core_intrinsics)]
#![feature(container_error_extra)]
#![feature(dropck_eyepatch)]
#![feature(exact_size_is_empty)]
#![feature(exclusive_range_pattern)]
@ -104,13 +102,9 @@
#![feature(int_bits_const)]
#![feature(lang_items)]
#![feature(layout_for_ptr)]
#![feature(libc)]
#![feature(map_first_last)]
#![feature(map_into_keys_values)]
#![feature(maybe_uninit_ref)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(new_uninit)]
#![feature(nll)]
#![feature(nonnull_slice_from_raw_parts)]
#![feature(optin_builtin_traits)]
@ -125,10 +119,8 @@
#![feature(slice_ptr_get)]
#![feature(slice_ptr_len)]
#![feature(staged_api)]
#![feature(std_internals)]
#![feature(str_internals)]
#![feature(trusted_len)]
#![feature(try_reserve)]
#![feature(unboxed_closures)]
#![feature(unicode_internals)]
#![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
// checks that prevent its use within `const fn`.
#[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;
/// Returns `true` if the actual type given as `T` requires drop

View File

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

View File

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

View File

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

View File

@ -1173,6 +1173,16 @@ where
/// See its documentation for more.
///
/// [`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")]
pub struct Iter<'a, K: 'a> {
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.
///
/// [`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")]
pub struct IntoIter<K> {
base: base::IntoIter<K>,
@ -1195,6 +1215,16 @@ pub struct IntoIter<K> {
/// See its documentation for more.
///
/// [`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")]
pub struct Drain<'a, K: 'a> {
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`].
///
/// [`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")]
pub struct DrainFilter<'a, K, F>
where
@ -1219,6 +1261,17 @@ where
/// See its documentation for more.
///
/// [`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")]
pub struct Intersection<'a, T: 'a, S: 'a> {
// iterator of the first set
@ -1233,6 +1286,17 @@ pub struct Intersection<'a, T: 'a, S: 'a> {
/// See its documentation for more.
///
/// [`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")]
pub struct Difference<'a, T: 'a, S: 'a> {
// iterator of the first set
@ -1247,6 +1311,17 @@ pub struct Difference<'a, T: 'a, S: 'a> {
/// [`HashSet`]. See its documentation for more.
///
/// [`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")]
pub struct SymmetricDifference<'a, T: 'a, S: 'a> {
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.
///
/// [`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")]
pub struct Union<'a, T: 'a, S: 'a> {
iter: Chain<Iter<'a, T>, Difference<'a, T, S>>,

View File

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

View File

@ -667,7 +667,7 @@ impl UnixStream {
/// 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> {
self.0.peek(buf)
}
@ -1708,7 +1708,7 @@ impl UnixDatagram {
/// 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> {
self.0.peek(buf)
}
@ -1740,7 +1740,7 @@ impl UnixDatagram {
/// 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)> {
self.recv_from_flags(buf, libc::MSG_PEEK)
}

View File

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

View File

@ -18,7 +18,6 @@ use build_helper::{output, t};
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::cache::{Interned, INTERNER};
use crate::channel;
use crate::compile;
use crate::config::TargetSelection;
use crate::tool::{self, Tool};
@ -569,7 +568,7 @@ impl Step for Rustc {
&page_dst,
&[
("<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) {
let mut parts = channel::CFG_RELEASE_NUM.split('.');
let mut parts = builder.version.split('.');
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_VER_MAJOR", parts.next().unwrap())
.env("CFG_VER_MINOR", parts.next().unwrap())

View File

@ -433,7 +433,7 @@ impl Step for Std {
.arg("-Z")
.arg("unstable-options")
.arg("--resource-suffix")
.arg(crate::channel::CFG_RELEASE_NUM)
.arg(&builder.version)
.arg("--index-page")
.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);
index.arg("html");
index.arg(out.join("error-index.html"));
index.arg(crate::channel::CFG_RELEASE_NUM);
index.arg(&builder.version);
builder.run(&mut index);
}

View File

@ -218,6 +218,9 @@ pub struct Build {
/// User-specified configuration from `config.toml`.
config: Config,
// Version information
version: String,
// Properties derived from the above configuration
src: PathBuf,
out: PathBuf,
@ -380,6 +383,10 @@ impl Build {
.unwrap()
.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 {
initial_rustc: config.initial_rustc.clone(),
initial_cargo: config.initial_cargo.clone(),
@ -395,6 +402,7 @@ impl Build {
targets: config.targets.clone(),
config,
version: version.to_string(),
src,
out,
@ -433,8 +441,7 @@ impl Build {
.next()
.unwrap()
.trim();
let my_version = channel::CFG_RELEASE_NUM;
if local_release.split('.').take(2).eq(my_version.split('.').take(2)) {
if local_release.split('.').take(2).eq(version.split('.').take(2)) {
build.verbose(&format!("auto-detected local-rebuild {}", local_release));
build.local_rebuild = true;
}
@ -785,7 +792,7 @@ impl Build {
match which {
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))
}
GitRepo::Llvm => Some(String::from("/rustc/llvm")),
@ -1016,7 +1023,7 @@ impl Build {
/// Returns the value of `release` above for Rust itself.
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
@ -1036,7 +1043,7 @@ impl Build {
/// Returns the value of `package_vers` above for Rust itself.
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
@ -1070,7 +1077,7 @@ impl Build {
}
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 {
@ -1087,7 +1094,7 @@ impl Build {
/// Note that this is a descriptive string which includes the commit date,
/// sha, version, etc.
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.

View File

@ -19,7 +19,6 @@ use std::process::Command;
use build_helper::{output, t};
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::channel;
use crate::config::TargetSelection;
use crate::util::{self, exe};
use crate::GitRepo;
@ -296,7 +295,7 @@ impl Step for Llvm {
// release number on the dev channel.
cfg.define("LLVM_VERSION_SUFFIX", "-rust-dev");
} 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);
}

View File

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

View File

@ -7,7 +7,6 @@ use std::process::{exit, Command};
use build_helper::t;
use crate::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step};
use crate::channel;
use crate::channel::GitInfo;
use crate::compile;
use crate::config::TargetSelection;
@ -255,7 +254,7 @@ pub fn prepare_tool_cargo(
cargo.env("CFG_RELEASE", builder.rust_release());
cargo.env("CFG_RELEASE_CHANNEL", &builder.config.channel);
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);
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