<ins> //! Test codegen when setting deployment targets on Apple platforms. //! //! This is important since its a compatibility hazard. The linker will //! generate load commands differently based on what minimum OS it can assume. //! //! See https://github.com/rust-lang/rust/pull/105123. //@ only-apple use run_make_support::{apple_os, cmd, run_in_tmpdir, rustc, target}; /// Run vtool to check the `minos` field in LC_BUILD_VERSION. /// /// On lower deployment targets, LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS and similar /// are used instead of LC_BUILD_VERSION - these have a `version` field, so also check that. #[track_caller] fn minos(file: &str, version: &str) { cmd("vtool") .arg("-show-build") .arg(file) .run() .assert_stdout_contains_regex(format!("(minos|version) {version}")); } fn main() { // These versions should generally be higher than the default versions let (env_var, example_version, higher_example_version) = match apple_os() { "macos" => ("MACOSX_DEPLOYMENT_TARGET", "12.0", "13.0"), // armv7s-apple-ios and i386-apple-ios only supports iOS 10.0 "ios" if target() == "armv7s-apple-ios" || target() == "i386-apple-ios" => { ("IPHONEOS_DEPLOYMENT_TARGET", "10.0", "10.0") } "ios" => ("IPHONEOS_DEPLOYMENT_TARGET", "15.0", "16.0"), "watchos" => ("WATCHOS_DEPLOYMENT_TARGET", "7.0", "9.0"), "tvos" => ("TVOS_DEPLOYMENT_TARGET", "14.0", "15.0"), "visionos" => ("XROS_DEPLOYMENT_TARGET", "1.1", "1.2"), _ => unreachable!(), }; let default_version = rustc().target(target()).env_remove(env_var).print("deployment-target").run().stdout_utf8(); let default_version = default_version.strip_prefix("deployment_target=").unwrap().trim(); // Test that version makes it to the object file. run_in_tmpdir(|| { let rustc = || { let mut rustc = rustc(); rustc.target(target()); rustc.crate_type("lib"); rustc.emit("obj"); rustc.input("foo.rs"); rustc.output("foo.o"); rustc }; rustc().env(env_var, example_version).run(); minos("foo.o", example_version); // FIXME(madsmtm): Doesn't work on Mac Catalyst and the simulator. if !target().contains("macabi") && !target().contains("sim") { rustc().env_remove(env_var).run(); minos("foo.o", default_version); } }); // Test that version makes it to the linker when linking dylibs. run_in_tmpdir(|| { // Certain watchOS targets don't support dynamic linking, so we disable the test on those. if apple_os() == "watchos" { return; } let rustc = || { let mut rustc = rustc(); rustc.target(target()); rustc.crate_type("dylib"); rustc.input("foo.rs"); rustc.output("libfoo.dylib"); rustc }; rustc().env(env_var, example_version).run(); minos("libfoo.dylib", example_version); // FIXME(madsmtm): Deployment target is not currently passed properly to linker // rustc().env_remove(env_var).run(); // minos("libfoo.dylib", default_version); // Test with ld64 instead rustc().arg("-Clinker-flavor=ld").env(env_var, example_version).run(); minos("libfoo.dylib", example_version); rustc().arg("-Clinker-flavor=ld").env_remove(env_var).run(); minos("libfoo.dylib", default_version); }); // Test that version makes it to the linker when linking executables. run_in_tmpdir(|| { let rustc = || { let mut rustc = rustc(); rustc.target(target()); rustc.crate_type("bin"); rustc.input("foo.rs"); rustc.output("foo"); rustc }; // FIXME(madsmtm): Doesn't work on watchOS for some reason? if !target().contains("watchos") { rustc().env(env_var, example_version).run(); minos("foo", example_version); // FIXME(madsmtm): Deployment target is not currently passed properly to linker // rustc().env_remove(env_var).run(); // minos("foo", default_version); } // Test with ld64 instead rustc().arg("-Clinker-flavor=ld").env(env_var, example_version).run(); minos("foo", example_version); rustc().arg("-Clinker-flavor=ld").env_remove(env_var).run(); minos("foo", default_version); }); // Test that changing the deployment target busts the incremental cache. run_in_tmpdir(|| { let rustc = || { let mut rustc = rustc(); rustc.target(target()); rustc.incremental("incremental"); rustc.crate_type("lib"); rustc.emit("obj"); rustc.input("foo.rs"); rustc.output("foo.o"); rustc }; // FIXME(madsmtm): Incremental cache is not yet busted // https://github.com/rust-lang/rust/issues/118204 let higher_example_version = example_version; let default_version = example_version; rustc().env(env_var, example_version).run(); minos("foo.o", example_version); rustc().env(env_var, higher_example_version).run(); minos("foo.o", higher_example_version); // FIXME(madsmtm): Doesn't work on Mac Catalyst and the simulator. if !target().contains("macabi") && !target().contains("sim") { rustc().env_remove(env_var).run(); minos("foo.o", default_version); } }); } </ins>


<del> # only-macos # # Check that a set deployment target actually makes it to the linker. # This is important since its a compatibility hazard. The linker will # generate load commands differently based on what minimum OS it can assume. include ../tools.mk ifeq ($(strip $(shell uname -m)),arm64) GREP_PATTERN = "minos 11.0" else GREP_PATTERN = "version 10.13" endif OUT_FILE=$(TMPDIR)/with_deployment_target.dylib all: env MACOSX_DEPLOYMENT_TARGET=10.13 $(RUSTC) with_deployment_target.rs -o $(OUT_FILE) # XXX: The check is for either the x86_64 minimum OR the aarch64 minimum (M1 starts at macOS 11). # They also use different load commands, so we let that change with each too. The aarch64 check # isn't as robust as the x86 one, but testing both seems unneeded. vtool -show-build $(OUT_FILE) | $(CGREP) -e $(GREP_PATTERN) </del>


<del> #![crate_type = "cdylib"] #[allow(dead_code)] fn something_and_nothing() {} </del>


)*) } <del> step_impl_unsigned!(usize u8 u16 u32); step_impl_signed!([isize: usize] [i8: u8] [i16: u16] [i32: u32]); </del> <ins> step_impl_unsigned!(usize u8 u16); #[cfg(not(target_pointer_witdth = "16"))] step_impl_unsigned!(u32); #[cfg(target_pointer_witdth = "16")] step_impl_no_between!(u32); step_impl_signed!([isize: usize] [i8: u8] [i16: u16]); #[cfg(not(target_pointer_witdth = "16"))] step_impl_signed!([i32: u32]); #[cfg(target_pointer_witdth = "16")] step_impl_no_between!(i32); </ins> #[cfg(target_pointer_width = "64")] step_impl_unsigned!(u64); #[cfg(target_pointer_width = "64")]


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(step_trait)] use std::iter::Step; #[cfg(target_pointer_width = "16")] fn main() { assert!(Step::steps_between(&0u32, &::std::u32::MAX).is_none()); } #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] fn main() { assert!(Step::steps_between(&0u32, &::std::u32::MAX).is_some()); } </ins>


cfg.file("../rustllvm/PassWrapper.cpp") .file("../rustllvm/RustWrapper.cpp") .file("../rustllvm/ArchiveWrapper.cpp") <ins> .file("../rustllvm/Linker.cpp") </ins> .cpp(true) .cpp_link_stdlib(None) // we handle this below .compile("rustllvm");


#[allow(missing_copy_implementations)] pub enum OperandBundleDef_opaque {} pub type OperandBundleDefRef = *mut OperandBundleDef_opaque; <ins> #[allow(missing_copy_implementations)] pub enum Linker_opaque {} pub type LinkerRef = *mut Linker_opaque; </ins> pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void); pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint);


pub fn LLVMRustPrintPasses(); pub fn LLVMRustSetNormalizedTarget(M: ModuleRef, triple: *const c_char); pub fn LLVMRustAddAlwaysInlinePass(P: PassManagerBuilderRef, AddLifetimes: bool); <del> pub fn LLVMRustLinkInExternalBitcode(M: ModuleRef, bc: *const c_char, len: size_t) -> bool; </del> pub fn LLVMRustRunRestrictionPass(M: ModuleRef, syms: *const *const c_char, len: size_t); pub fn LLVMRustMarkAllFunctionsNounwind(M: ModuleRef);


CU2: *mut *mut c_void); pub fn LLVMRustThinLTOPatchDICompileUnit(M: ModuleRef, CU: *mut c_void); pub fn LLVMRustThinLTORemoveAvailableExternally(M: ModuleRef); <ins> pub fn LLVMRustLinkerNew(M: ModuleRef) -> LinkerRef; pub fn LLVMRustLinkerAdd(linker: LinkerRef, bytecode: *const c_char, bytecode_len: usize) -> bool; pub fn LLVMRustLinkerFree(linker: LinkerRef); </ins> }


// know much about the memory management here so we err on the side of being // save and persist everything with the original module. let mut serialized_bitcode = Vec::new(); <ins> let mut linker = Linker::new(llmod); </ins> for (bc_decoded, name) in serialized_modules { info!("linking {:?}", name); <del> time(cgcx.time_passes, &format!("ll link {:?}", name), || unsafe { </del> <ins> time(cgcx.time_passes, &format!("ll link {:?}", name), || { </ins> let data = bc_decoded.data(); <del> if llvm::LLVMRustLinkInExternalBitcode(llmod, data.as_ptr() as *const libc::c_char, data.len() as libc::size_t) { Ok(()) } else { </del> <ins> linker.add(&data).map_err(|()| { </ins> let msg = format!("failed to load bc of {:?}", name); <del> Err(write::llvm_err(&diag_handler, msg)) } </del> <ins> write::llvm_err(&diag_handler, msg) }) </ins> })?; timeline.record(&format!("link {:?}", name)); serialized_bitcode.push(bc_decoded); } <ins> drop(linker); </ins> cgcx.save_temp_bitcode(&module, "lto.input"); // Internalize everything that *isn't* in our whitelist to help strip out


}]) } <ins> struct Linker(llvm::LinkerRef); impl Linker { fn new(llmod: ModuleRef) -> Linker { unsafe { Linker(llvm::LLVMRustLinkerNew(llmod)) } } fn add(&mut self, bytecode: &[u8]) -> Result<(), ()> { unsafe { if llvm::LLVMRustLinkerAdd(self.0, bytecode.as_ptr() as *const libc::c_char, bytecode.len()) { Ok(()) } else { Err(()) } } } } impl Drop for Linker { fn drop(&mut self) { unsafe { llvm::LLVMRustLinkerFree(self.0); } } } </ins> /// Prepare "thin" LTO to get run on these modules. /// /// The general structure of ThinLTO is quite different from the structure of


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #include "llvm/Linker/Linker.h" #include "rustllvm.h" using namespace llvm; struct RustLinker { Linker L; LLVMContext &Ctx; RustLinker(Module &M) : L(M), Ctx(M.getContext()) {} }; extern "C" RustLinker* LLVMRustLinkerNew(LLVMModuleRef DstRef) { Module *Dst = unwrap(DstRef); auto Ret = llvm::make_unique<RustLinker>(*Dst); return Ret.release(); } extern "C" void LLVMRustLinkerFree(RustLinker *L) { delete L; } extern "C" bool LLVMRustLinkerAdd(RustLinker *L, char *BC, size_t Len) { std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBufferCopy(StringRef(BC, Len)); #if LLVM_VERSION_GE(4, 0) Expected<std::unique_ptr<Module>> SrcOrError = llvm::getLazyBitcodeModule(Buf->getMemBufferRef(), L->Ctx); if (!SrcOrError) { LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str()); return false; } auto Src = std::move(*SrcOrError); #else ErrorOr<std::unique_ptr<Module>> Src = llvm::getLazyBitcodeModule(std::move(Buf), L->Ctx); if (!Src) { LLVMRustSetLastError(Src.getError().message().c_str()); return false; } #endif #if LLVM_VERSION_GE(4, 0) if (L->L.linkInModule(std::move(Src))) { #else if (L->L.linkInModule(std::move(Src.get()))) { #endif LLVMRustSetLastError(""); return false; } return true; } </ins>


} } <del> extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef DstRef, char *BC, size_t Len) { Module *Dst = unwrap(DstRef); std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBufferCopy(StringRef(BC, Len)); #if LLVM_VERSION_GE(4, 0) Expected<std::unique_ptr<Module>> SrcOrError = llvm::getLazyBitcodeModule(Buf->getMemBufferRef(), Dst->getContext()); if (!SrcOrError) { LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str()); return false; } auto Src = std::move(*SrcOrError); #else ErrorOr<std::unique_ptr<Module>> Src = llvm::getLazyBitcodeModule(std::move(Buf), Dst->getContext()); if (!Src) { LLVMRustSetLastError(Src.getError().message().c_str()); return false; } #endif std::string Err; raw_string_ostream Stream(Err); DiagnosticPrinterRawOStream DP(Stream); #if LLVM_VERSION_GE(4, 0) if (Linker::linkModules(*Dst, std::move(Src))) { #else if (Linker::linkModules(*Dst, std::move(Src.get()))) { #endif LLVMRustSetLastError(Err.c_str()); return false; } return true; } </del> // Note that the two following functions look quite similar to the // LLVMGetSectionName function. Sadly, it appears that this function only // returns a char* pointer, which isn't guaranteed to be null-terminated. The


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // run-pass // revisions: lxl nll #![cfg_attr(nll, feature(nll))] struct Foo { x: u32 } impl Foo { fn twiddle(&mut self) -> &mut Self { self } fn twaddle(&mut self) -> &mut Self { self } fn emit(&mut self) { self.x += 1; } } fn main() { let mut foo = Foo { x: 0 }; match 22 { 22 => &mut foo, 44 => foo.twiddle(), _ => foo.twaddle(), }.emit(); } </ins>


FileType(self.0.file_type()) } <del> /// Returns whether this metadata is for a directory. </del> <ins> /// Returns whether this metadata is for a directory. The /// result is mutually exclusive to the result of /// [`is_file`], and will be false for symlink metadata /// obtained from [`symlink_metadata`]. /// /// [`is_file`]: struct.Metadata.html#method.is_file /// [`symlink_metadata`]: fn.symlink_metadata.html </ins> /// /// # Examples ///


#[stable(feature = "rust1", since = "1.0.0")] pub fn is_dir(&self) -> bool { self.file_type().is_dir() } <del> /// Returns whether this metadata is for a regular file. </del> <ins> /// Returns whether this metadata is for a regular file. The /// result is mutually exclusive to the result of /// [`is_dir`], and will be false for symlink metadata /// obtained from [`symlink_metadata`]. /// /// [`is_dir`]: struct.Metadata.html#method.is_dir /// [`symlink_metadata`]: fn.symlink_metadata.html </ins> /// /// # Examples ///


} impl FileType { <del> /// Test whether this file type represents a directory. </del> <ins> /// Test whether this file type represents a directory. The /// result is mutually exclusive to the results of /// [`is_file`] and [`is_symlink`]; only zero or one of these /// tests may pass. /// /// [`is_file`]: struct.FileType.html#method.is_file /// [`is_symlink`]: struct.FileType.html#method.is_symlink </ins> /// /// # Examples ///


pub fn is_dir(&self) -> bool { self.0.is_dir() } /// Test whether this file type represents a regular file. <ins> /// The result is  mutually exclusive to the results of /// [`is_dir`] and [`is_symlink`]; only zero or one of these /// tests may pass. /// /// [`is_dir`]: struct.FileType.html#method.is_dir /// [`is_symlink`]: struct.FileType.html#method.is_symlink </ins> /// /// # Examples ///


pub fn is_file(&self) -> bool { self.0.is_file() } /// Test whether this file type represents a symbolic link. <ins> /// The result is mutually exclusive to the results of /// [`is_dir`] and [`is_file`]; only zero or one of these /// tests may pass. </ins> /// /// The underlying [`Metadata`] struct needs to be retrieved /// with the [`fs::symlink_metadata`] function and not the


/// [`Metadata`]: struct.Metadata.html /// [`fs::metadata`]: fn.metadata.html /// [`fs::symlink_metadata`]: fn.symlink_metadata.html <ins> /// [`is_dir`]: struct.FileType.html#method.is_dir /// [`is_file`]: struct.FileType.html#method.is_file </ins> /// [`is_symlink`]: struct.FileType.html#method.is_symlink /// /// # Examples


#[lang="return_to_mut"] #[inline(always)] pub unsafe fn return_to_mut(a: *u8) { <del> let a: *mut BoxRepr = transmute(a); (*a).header.ref_count &= !FROZEN_BIT; </del> <ins> // Sometimes the box is null, if it is conditionally frozen. // See e.g. #4904. if !a.is_null() { let a: *mut BoxRepr = transmute(a); (*a).header.ref_count &= !FROZEN_BIT; } </ins> } #[lang="check_not_borrowed"]


/// # Examples /// /// ``` <del> /// #![feature(path_ancestors)] /// </del> /// use std::path::Path; /// /// let path = Path::new("/foo/bar");


/// [`ancestors`]: struct.Path.html#method.ancestors /// [`Path`]: struct.Path.html #[derive(Copy, Clone, Debug)] <del> #[unstable(feature = "path_ancestors", issue = "48581")] </del> <ins> #[stable(feature = "path_ancestors", since = "1.28.0")] </ins> pub struct Ancestors<'a> { next: Option<&'a Path>, } <del> #[unstable(feature = "path_ancestors", issue = "48581")] </del> <ins> #[stable(feature = "path_ancestors", since = "1.28.0")] </ins> impl<'a> Iterator for Ancestors<'a> { type Item = &'a Path;


} } <del> #[unstable(feature = "path_ancestors", issue = "48581")] </del> <ins> #[stable(feature = "path_ancestors", since = "1.28.0")] </ins> impl<'a> FusedIterator for Ancestors<'a> {} ////////////////////////////////////////////////////////////////////////////////


/// # Examples /// /// ``` <del> /// #![feature(path_ancestors)] /// </del> /// use std::path::Path; /// /// let mut ancestors = Path::new("/foo/bar").ancestors();


/// /// [`None`]: ../../std/option/enum.Option.html#variant.None /// [`parent`]: struct.Path.html#method.parent <del> #[unstable(feature = "path_ancestors", issue = "48581")] </del> <ins> #[stable(feature = "path_ancestors", since = "1.28.0")] </ins> pub fn ancestors(&self) -> Ancestors { Ancestors { next: Some(&self),


use ich::{self, CachingCodemapView, Fingerprint}; use middle::cstore::CrateStore; use ty::{TyCtxt, fast_reject}; <ins> use mir::interpret::AllocId; </ins> use session::Session; use std::cmp::Ord;


// CachingCodemapView, so we initialize it lazily. raw_codemap: &'a CodeMap, caching_codemap: Option<CachingCodemapView<'a>>, <ins> pub(super) alloc_id_recursion_tracker: FxHashSet<AllocId>, </ins> } #[derive(PartialEq, Eq, Clone, Copy)]


hash_spans: hash_spans_initial, hash_bodies: true, node_id_hashing_mode: NodeIdHashingMode::HashDefPath, <ins> alloc_id_recursion_tracker: Default::default(), </ins> } }


}); enum AllocDiscriminant { <del> Static, Constant, </del> <ins> Alloc, ExternStatic, </ins> Function, } impl_stable_hash_for!(enum self::AllocDiscriminant { <del> Static, Constant, </del> <ins> Alloc, ExternStatic, </ins> Function });


) { ty::tls::with_opt(|tcx| { let tcx = tcx.expect("can't hash AllocIds during hir lowering"); <del> if let Some(def_id) = tcx.interpret_interner.get_corresponding_static_def_id(*self) { AllocDiscriminant::Static.hash_stable(hcx, hasher); // statics are unique via their DefId def_id.hash_stable(hcx, hasher); } else if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) { // not a static, can't be recursive, hash the allocation AllocDiscriminant::Constant.hash_stable(hcx, hasher); alloc.hash_stable(hcx, hasher); </del> <ins> if let Some(alloc) = tcx.interpret_interner.get_alloc(*self) { AllocDiscriminant::Alloc.hash_stable(hcx, hasher); if !hcx.alloc_id_recursion_tracker.insert(*self) { tcx .interpret_interner .get_corresponding_static_def_id(*self) .hash_stable(hcx, hasher); alloc.hash_stable(hcx, hasher); assert!(hcx.alloc_id_recursion_tracker.remove(self)); } </ins> } else if let Some(inst) = tcx.interpret_interner.get_fn(*self) { AllocDiscriminant::Function.hash_stable(hcx, hasher); inst.hash_stable(hcx, hasher); <ins> } else if let Some(def_id) = tcx.interpret_interner .get_corresponding_static_def_id(*self) { AllocDiscriminant::ExternStatic.hash_stable(hcx, hasher); def_id.hash_stable(hcx, hasher); </ins> } else { bug!("no allocation for {}", self); }


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // https://github.com/rust-lang/rust/issues/49081 // revisions:rpass1 rpass2 #[cfg(rpass1)] pub static A: &str = "hello"; #[cfg(rpass2)] pub static A: &str = "xxxxx"; #[cfg(rpass1)] fn main() { assert_eq!(A, "hello"); } #[cfg(rpass2)] fn main() { assert_eq!(A, "xxxxx"); } </ins>


/// [`Release`]: http://llvm.org/docs/Atomics.html#release #[stable(feature = "rust1", since = "1.0.0")] Acquire, <del> /// When coupled with a load, uses [`Acquire`] ordering, and with a store /// [`Release`] ordering. </del> <ins> /// Has the effects of both [`Acquire`] and [`Release`] together. /// /// This ordering is only applicable for operations that combine both loads and stores. /// /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering. </ins> /// /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire /// [`Release`]: http://llvm.org/docs/Atomics.html#release


} if let PatKind::Binding(_, _, name, None) = fieldpat.node.pat.node { if name.node == fieldpat.node.name { <ins> if let Some(_) = fieldpat.span.ctxt().outer().expn_info() { // Don't lint if this is a macro expansion: macro authors // shouldn't have to worry about this kind of style issue // (Issue #49588) return; } </ins> let mut err = cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, &format!("the `{}:` in this pattern is redundant",


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![deny(non_shorthand_field_patterns)] pub struct Value<A> { pub value: A } #[macro_export] macro_rules! pat { ($a:pat) => { Value { value: $a } }; } fn main() { let pat!(value) = Value { value: () }; } </ins>


} // unsigned to signed (only positive bound) <ins> #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] </ins> macro_rules! try_from_upper_bounded { ($($target:ty),*) => {$( impl PrivateTryFromUsize for $target {


// all span information. // // As a result, some AST nodes are annotated with the token <del> // stream they came from. Attempt to extract these lossless // token streams before we fall back to the stringification. </del> <ins> // stream they came from. Here we attempt to extract these // lossless token streams before we fall back to the // stringification. // // During early phases of the compiler, though, the AST could // get modified directly (e.g. attributes added or removed) and // the internal cache of tokens my not be invalidated or // updated. Consequently if the "lossless" token stream // disagrees with our actuall stringification (which has // historically been much more battle-tested) then we go with // the lossy stream anyway (losing span information). </ins> let mut tokens = None; match nt.0 {


_ => {} } <del> tokens.unwrap_or_else(|| { nt.1.force(|| { // FIXME(jseyfried): Avoid this pretty-print + reparse hack let source = pprust::token_to_string(self); parse_stream_from_source_str(FileName::MacroExpansion, source, sess, Some(span)) }) }) </del> <ins> let tokens_for_real = nt.1.force(|| { // FIXME(#43081): Avoid this pretty-print + reparse hack let source = pprust::token_to_string(self); parse_stream_from_source_str(FileName::MacroExpansion, source, sess, Some(span)) }); if let Some(tokens) = tokens { if tokens.eq_unspanned(&tokens_for_real) { return tokens } } return tokens_for_real </ins> } }


(&TokenTree::Token(_, ref tk), &TokenTree::Token(_, ref tk2)) => tk == tk2, (&TokenTree::Delimited(_, ref dl), &TokenTree::Delimited(_, ref dl2)) => { dl.delim == dl2.delim && <del> dl.stream().trees().zip(dl2.stream().trees()).all(|(tt, tt2)| tt.eq_unspanned(&tt2)) </del> <ins> dl.stream().eq_unspanned(&dl2.stream()) </ins> } (_, _) => false, }


/// Compares two TokenStreams, checking equality without regarding span information. pub fn eq_unspanned(&self, other: &TokenStream) -> bool { <del> for (t1, t2) in self.trees().zip(other.trees()) { </del> <ins> let mut t1 = self.trees(); let mut t2 = other.trees(); for (t1, t2) in t1.by_ref().zip(t2.by_ref()) { </ins> if !t1.eq_unspanned(&t2) { return false; } } <del> true </del> <ins> t1.next().is_none() && t2.next().is_none() </ins> } /// Precondition: `self` consists of a single token tree.


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // no-prefer-dynamic #![crate_type = "proc-macro"] #![feature(proc_macro)] extern crate proc_macro; use proc_macro::*; #[proc_macro_attribute] pub fn assert1(_a: TokenStream, b: TokenStream) -> TokenStream { assert_eq(b.clone(), "pub fn foo() {}".parse().unwrap()); b } #[proc_macro_derive(Foo, attributes(foo))] pub fn assert2(a: TokenStream) -> TokenStream { assert_eq(a, "pub struct MyStructc { _a: i32, }".parse().unwrap()); TokenStream::empty() } fn assert_eq(a: TokenStream, b: TokenStream) { let mut a = a.into_iter(); let mut b = b.into_iter(); for (a, b) in a.by_ref().zip(&mut b) { match (a, b) { (TokenTree::Group(a), TokenTree::Group(b)) => { assert_eq!(a.delimiter(), b.delimiter()); assert_eq(a.stream(), b.stream()); } (TokenTree::Op(a), TokenTree::Op(b)) => { assert_eq!(a.op(), b.op()); assert_eq!(a.spacing(), b.spacing()); } (TokenTree::Literal(a), TokenTree::Literal(b)) => { assert_eq!(a.to_string(), b.to_string()); } (TokenTree::Term(a), TokenTree::Term(b)) => { assert_eq!(a.to_string(), b.to_string()); } (a, b) => panic!("{:?} != {:?}", a, b), } } assert!(a.next().is_none()); assert!(b.next().is_none()); } </ins>


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // aux-build:modify-ast.rs #![feature(proc_macro)] extern crate modify_ast; use modify_ast::*; #[derive(Foo)] pub struct MyStructc { #[cfg_attr(my_cfg, foo)] _a: i32, } macro_rules! a { ($i:item) => ($i) } a! { #[assert1] pub fn foo() {} } fn main() { let _a = MyStructc { _a: 0 }; foo(); } </ins>


} #[test] <ins> fn test_str_slice_rangetoinclusive_ok() { let s = "abcαβγ"; assert_eq!(&s[..=2], "abc"); assert_eq!(&s[..=4], "abcα"); } #[test] #[should_panic] fn test_str_slice_rangetoinclusive_notok() { let s = "abcαβγ"; &s[..=3]; } #[test] fn test_str_slicemut_rangetoinclusive_ok() { let mut s = "abcαβγ".to_owned(); let s: &mut str = &mut s; assert_eq!(&mut s[..=2], "abc"); assert_eq!(&mut s[..=4], "abcα"); } #[test] #[should_panic] fn test_str_slicemut_rangetoinclusive_notok() { let mut s = "abcαβγ".to_owned(); let s: &mut str = &mut s; &mut s[..=3]; } #[test] </ins> fn test_is_char_boundary() { let s = "ศไทย中华Việt Nam β-release 🐱123"; assert!(s.is_char_boundary(0));


fn index(self, slice: &str) -> &Self::Output { assert!(self.end != usize::max_value(), "attempted to index str up to maximum usize"); <del> let end = self.end + 1; self.get(slice).unwrap_or_else(|| super::slice_error_fail(slice, 0, end)) </del> <ins> (..self.end+1).index(slice) </ins> } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { assert!(self.end != usize::max_value(), "attempted to index str up to maximum usize"); <del> if slice.is_char_boundary(self.end) { unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, 0, self.end + 1) } </del> <ins> (..self.end+1).index_mut(slice) </ins> } }


continue; } <del> let result = select.select(&Obligation::new(dummy_cause.clone(), new_env, pred)); </del> <ins> // Call infcx.resolve_type_vars_if_possible to see if we can // get rid of any inference variables. let obligation = infcx.resolve_type_vars_if_possible( &Obligation::new(dummy_cause.clone(), new_env, pred) ); let result = select.select(&obligation); </ins> match &result { &Ok(Some(ref vtable)) => {


} &Ok(None) => {} &Err(SelectionError::Unimplemented) => { <del> if self.is_of_param(pred.skip_binder().trait_ref.substs) { </del> <ins> if self.is_param_no_infer(pred.skip_binder().trait_ref.substs) { </ins> already_visited.remove(&pred); self.add_user_pred( &mut user_computed_preds,


finished_map } <del> pub fn is_of_param(&self, substs: &Substs<'_>) -> bool { if substs.is_noop() { return false; } </del> <ins> fn is_param_no_infer(&self, substs: &Substs<'_>) -> bool { return self.is_of_param(substs.type_at(0)) && !substs.types().any(|t| t.has_infer_types()); } </ins> <del> return match substs.type_at(0).sty { </del> <ins> pub fn is_of_param(&self, ty: Ty<'_>) -> bool { return match ty.sty { </ins> ty::Param(_) => true, <del> ty::Projection(p) => self.is_of_param(p.substs), </del> <ins> ty::Projection(p) => self.is_of_param(p.self_ty()), </ins> _ => false, }; } <ins> fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool { match p.ty().skip_binder().sty { ty::Projection(proj) if proj == p.skip_binder().projection_ty => { true }, _ => false } } </ins> pub fn evaluate_nested_obligations< 'b, 'c,


) -> bool { let dummy_cause = ObligationCause::misc(DUMMY_SP, ast::DUMMY_NODE_ID); <del> for (obligation, predicate) in nested .filter(|o| o.recursion_depth == 1) </del> <ins> for (obligation, mut predicate) in nested </ins> .map(|o| (o.clone(), o.predicate.clone())) { let is_new_pred = fresh_preds.insert(self.clean_pred(select.infcx(), predicate.clone())); <ins> // Resolve any inference variables that we can, to help selection succeed predicate = select.infcx().resolve_type_vars_if_possible(&predicate); // We only add a predicate as a user-displayable bound if // it involves a generic parameter, and doesn't contain // any inference variables. // // Displaying a bound involving a concrete type (instead of a generic // parameter) would be pointless, since it's always true // (e.g. u8: Copy) // Displaying an inference variable is impossible, since they're // an internal compiler detail without a defined visual representation // // We check this by calling is_of_param on the relevant types // from the various possible predicates </ins> match &predicate { &ty::Predicate::Trait(ref p) => { <del> let substs = &p.skip_binder().trait_ref.substs; </del> <ins> if self.is_param_no_infer(p.skip_binder().trait_ref.substs) && !only_projections && is_new_pred { </ins> <del> if self.is_of_param(substs) && !only_projections && is_new_pred { </del> self.add_user_pred(computed_preds, predicate); } predicates.push_back(p.clone()); } &ty::Predicate::Projection(p) => { <del> // If the projection isn't all type vars, then // we don't want to add it as a bound if self.is_of_param(p.skip_binder().projection_ty.substs) && is_new_pred { self.add_user_pred(computed_preds, predicate); } else { </del> <ins> debug!("evaluate_nested_obligations: examining projection predicate {:?}", predicate); // As described above, we only want to display // bounds which include a generic parameter but don't include // an inference variable. // Additionally, we check if we've seen this predicate before, // to avoid rendering duplicate bounds to the user. if self.is_param_no_infer(p.skip_binder().projection_ty.substs) && !p.ty().skip_binder().is_ty_infer() && is_new_pred { debug!("evaluate_nested_obligations: adding projection predicate to computed_preds: {:?}", predicate); // Under unusual circumstances, we can end up with a self-refeential // projection predicate. For example: // <T as MyType>::Value == <T as MyType>::Value // Not only is displaying this to the user pointless, // having it in the ParamEnv will cause an issue if we try to call // poly_project_and_unify_type on the predicate, since this kind of // predicate will normally never end up in a ParamEnv. // // For these reasons, we ignore these weird predicates, // ensuring that we're able to properly synthesize an auto trait impl if self.is_self_referential_projection(p) { debug!("evaluate_nested_obligations: encountered a projection predicate equating a type with itself! Skipping"); } else { self.add_user_pred(computed_preds, predicate); } } // We can only call poly_project_and_unify_type when our predicate's // Ty is an inference variable - otherwise, there won't be anything to // unify if p.ty().skip_binder().is_ty_infer() { debug!("Projecting and unifying projection predicate {:?}", predicate); </ins> match poly_project_and_unify_type(select, &obligation.with(p.clone())) { Err(e) => { debug!(


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. pub trait Signal { type Item; } pub trait Signal2 { type Item2; } impl<B, C> Signal2 for B where B: Signal<Item = C> { type Item2 = C; } // @has issue_50159/struct.Switch.html // @has - '//code' 'impl<B> Send for Switch<B> where <B as Signal>::Item: Send' // @has - '//code' 'impl<B> Sync for Switch<B> where <B as Signal>::Item: Sync' // @count - '//*[@id="implementations-list"]/*[@class="impl"]' 0 // @count - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]' 2 pub struct Switch<B: Signal> { pub inner: <B as Signal2>::Item2, } </ins>


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // Some unusual code minimized from // https://github.com/sile/handy_async/tree/7b619b762c06544fc67792c8ff8ebc24a88fdb98 pub trait Pattern { type Value; } pub struct Constrain<A, B = A, C = A>(A, B, C); impl<A, B, C> Pattern for Constrain<A, B, C> where A: Pattern, B: Pattern<Value = A::Value>, C: Pattern<Value = A::Value>, { type Value = A::Value; } pub struct Wrapper<T>(T); impl<T> Pattern for Wrapper<T> { type Value = T; } // @has self_referential/struct.WriteAndThen.html // @has - '//*[@id="synthetic-implementations-list"]/*[@class="impl"]//*/code' "impl<P1> Send for  // WriteAndThen<P1>  where  <P1 as Pattern>::Value: Send" pub struct WriteAndThen<P1>(pub P1::Value,pub <Constrain<P1, Wrapper<P1::Value>> as Pattern>::Value) where P1: Pattern; </ins>


} } <del> /// Replaces the value at a mutable location with a new one, returning the old value, without /// deinitializing either one. </del> <ins> /// Moves `src` into the referenced `dest`, returning the previous `dest` value. /// /// Neither value is dropped. </ins> /// /// # Examples ///


} } <del> /// Replaces the value at `dest` with `src`, returning the old /// value, without dropping either. </del> <ins> /// Moves `src` into the pointed `dest`, returning the previous `dest` value. /// /// Neither value is dropped. </ins> /// /// # Safety ///


use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; use crate::{path_names_to_string, KNOWN_TOOLS}; <del> use crate::{CrateLint, LegacyScope, Module, ModuleOrUniformRoot}; </del> <ins> use crate::{BindingError, CrateLint, LegacyScope, Module, ModuleOrUniformRoot}; </ins> use crate::{PathResult, ParentScope, ResolutionError, Resolver, Scope, ScopeSet, Segment}; type Res = def::Res<ast::NodeId>;


err } ResolutionError::VariableNotBoundInPattern(binding_error) => { <del> let target_sp = binding_error.target.iter().cloned().collect::<Vec<_>>(); </del> <ins> let BindingError { name, target, origin, could_be_path } = binding_error; let target_sp = target.iter().copied().collect::<Vec<_>>(); let origin_sp = origin.iter().copied().collect::<Vec<_>>(); </ins> let msp = MultiSpan::from_spans(target_sp.clone()); <del> let msg = format!("variable `{}` is not bound in all patterns", binding_error.name); </del> <ins> let msg = format!("variable `{}` is not bound in all patterns", name); </ins> let mut err = self.session.struct_span_err_with_code( msp, &msg, DiagnosticId::Error("E0408".into()), ); for sp in target_sp { <del> err.span_label(sp, format!("pattern doesn't bind `{}`", binding_error.name)); </del> <ins> err.span_label(sp, format!("pattern doesn't bind `{}`", name)); </ins> } <del> let origin_sp = binding_error.origin.iter().cloned(); </del> for sp in origin_sp { err.span_label(sp, "variable not in all patterns"); } <ins> if *could_be_path { let help_msg = format!( "if you meant to match on a variant or a `const` item, consider  making the path in the pattern qualified: `?::{}`", name, ); err.span_help(span, &help_msg); } </ins> err } ResolutionError::VariableBoundWithDifferentMode(variable_name,


// Checks that all of the arms in an or-pattern have exactly the // same set of bindings, with the same binding modes for each. fn check_consistent_bindings(&mut self, pats: &[P<Pat>]) { <del> if pats.is_empty() { return; } </del> let mut missing_vars = FxHashMap::default(); let mut inconsistent_vars = FxHashMap::default(); <del> for (i, p) in pats.iter().enumerate() { let map_i = self.binding_mode_map(&p); for (j, q) in pats.iter().enumerate() { if i == j { continue; } let map_j = self.binding_mode_map(&q); for (&key, &binding_i) in &map_i { if map_j.is_empty() {                   // Account for missing bindings when let binding_error = missing_vars    // `map_j` has none. .entry(key.name) .or_insert(BindingError { name: key.name, origin: BTreeSet::new(), target: BTreeSet::new(), }); binding_error.origin.insert(binding_i.span); binding_error.target.insert(q.span); } for (&key_j, &binding_j) in &map_j { match map_i.get(&key_j) { None => {  // missing binding let binding_error = missing_vars .entry(key_j.name) .or_insert(BindingError { name: key_j.name, origin: BTreeSet::new(), target: BTreeSet::new(), }); binding_error.origin.insert(binding_j.span); binding_error.target.insert(p.span); } Some(binding_i) => {  // check consistent binding if binding_i.binding_mode != binding_j.binding_mode { inconsistent_vars .entry(key.name) .or_insert((binding_j.span, binding_i.span)); } </del> <ins> for pat_outer in pats.iter() { let map_outer = self.binding_mode_map(&pat_outer); for pat_inner in pats.iter().filter(|pat| pat.id != pat_outer.id) { let map_inner = self.binding_mode_map(&pat_inner); for (&key_inner, &binding_inner) in map_inner.iter() { match map_outer.get(&key_inner) { None => {  // missing binding let binding_error = missing_vars .entry(key_inner.name) .or_insert(BindingError { name: key_inner.name, origin: BTreeSet::new(), target: BTreeSet::new(), could_be_path: key_inner.name.as_str().starts_with(char::is_uppercase) }); binding_error.origin.insert(binding_inner.span); binding_error.target.insert(pat_outer.span); } Some(binding_outer) => {  // check consistent binding if binding_outer.binding_mode != binding_inner.binding_mode { inconsistent_vars .entry(key_inner.name) .or_insert((binding_inner.span, binding_outer.span)); </ins> } } } } } } <del> let mut missing_vars = missing_vars.iter().collect::<Vec<_>>(); </del> <ins> let mut missing_vars = missing_vars.iter_mut().collect::<Vec<_>>(); </ins> missing_vars.sort(); <del> for (_, v) in missing_vars { </del> <ins> for (name, mut v) in missing_vars { if inconsistent_vars.contains_key(name) { v.could_be_path = false; } </ins> self.r.report_error( <del> *v.origin.iter().next().unwrap(), ResolutionError::VariableNotBoundInPattern(v) ); </del> <ins> *v.origin.iter().next().unwrap(), ResolutionError::VariableNotBoundInPattern(v)); </ins> } let mut inconsistent_vars = inconsistent_vars.iter().collect::<Vec<_>>(); inconsistent_vars.sort(); for (name, v) in inconsistent_vars {


self.resolve_pattern(pat, source, &mut bindings_list); } // This has to happen *after* we determine which pat_idents are variants <del> self.check_consistent_bindings(pats); </del> <ins> if pats.len() > 1 { self.check_consistent_bindings(pats); } </ins> } fn resolve_block(&mut self, block: &Block) {


name: Name, origin: BTreeSet<Span>, target: BTreeSet<Span>, <ins> could_be_path: bool </ins> } impl PartialOrd for BindingError {


<ins> #![allow(non_camel_case_types)] enum E { A, B, c } mod m { const CONST1: usize = 10; const Const2: usize = 20; } </ins> fn main() { let y = 1; match y { a | b => {} //~  ERROR variable `a` is not bound in all patterns <del> //~^ ERROR variable `b` is not bound in all patterns </del> <ins> //~| ERROR variable `b` is not bound in all patterns } let x = (E::A, E::B); match x { (A, B) | (ref B, c) | (c, A) => () //~^ ERROR variable `A` is not bound in all patterns //~| ERROR variable `B` is not bound in all patterns //~| ERROR variable `B` is bound in inconsistent ways //~| ERROR mismatched types //~| ERROR variable `c` is not bound in all patterns //~| HELP consider making the path in the pattern qualified: `?::A` } let z = (10, 20); match z { (CONST1, _) | (_, Const2) => () //~^ ERROR variable `CONST1` is not bound in all patterns //~| HELP consider making the path in the pattern qualified: `?::CONST1` //~| ERROR variable `Const2` is not bound in all patterns //~| HELP consider making the path in the pattern qualified: `?::Const2` </ins> } }


error[E0408]: variable `a` is not bound in all patterns <del> --> $DIR/resolve-inconsistent-names.rs:4:12 </del> <ins> --> $DIR/resolve-inconsistent-names.rs:13:12 </ins> | LL |        a | b => {} |        -   ^ pattern doesn't bind `a`


|        variable not in all patterns error[E0408]: variable `b` is not bound in all patterns <del> --> $DIR/resolve-inconsistent-names.rs:4:8 </del> <ins> --> $DIR/resolve-inconsistent-names.rs:13:8 </ins> | LL |        a | b => {} |        ^   - variable not in all patterns |        | |        pattern doesn't bind `b` <del> error: aborting due to 2 previous errors </del> <ins> error[E0408]: variable `A` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:19:18 | LL |         (A, B) | (ref B, c) | (c, A) => () |          -       ^^^^^^^^^^       - variable not in all patterns |          |       | |          |       pattern doesn't bind `A` |          variable not in all patterns | help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::A` --> $DIR/resolve-inconsistent-names.rs:19:10 | LL |         (A, B) | (ref B, c) | (c, A) => () |          ^ error[E0408]: variable `B` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:19:31 | LL |         (A, B) | (ref B, c) | (c, A) => () |             -         -       ^^^^^^ pattern doesn't bind `B` |             |         | |             |         variable not in all patterns |             variable not in all patterns error[E0408]: variable `c` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:19:9 | LL |         (A, B) | (ref B, c) | (c, A) => () |         ^^^^^^           -     - variable not in all patterns |         |                | |         |                variable not in all patterns |         pattern doesn't bind `c` error[E0409]: variable `B` is bound in inconsistent ways within the same match arm --> $DIR/resolve-inconsistent-names.rs:19:23 | LL |         (A, B) | (ref B, c) | (c, A) => () |             -         ^ bound in different ways |             | |             first binding error[E0408]: variable `CONST1` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:30:23 | LL |         (CONST1, _) | (_, Const2) => () |          ------       ^^^^^^^^^^^ pattern doesn't bind `CONST1` |          | |          variable not in all patterns | help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::CONST1` --> $DIR/resolve-inconsistent-names.rs:30:10 | LL |         (CONST1, _) | (_, Const2) => () |          ^^^^^^ error[E0408]: variable `Const2` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:30:9 | LL |         (CONST1, _) | (_, Const2) => () |         ^^^^^^^^^^^       ------ variable not in all patterns |         | |         pattern doesn't bind `Const2` | help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::Const2` --> $DIR/resolve-inconsistent-names.rs:30:27 | LL |         (CONST1, _) | (_, Const2) => () |                           ^^^^^^ error[E0308]: mismatched types --> $DIR/resolve-inconsistent-names.rs:19:19 | LL |         (A, B) | (ref B, c) | (c, A) => () |                   ^^^^^ expected enum `E`, found &E | = note: expected type `E` found type `&E` error: aborting due to 9 previous errors </ins> <del> For more information about this error, try `rustc --explain E0408`. </del> <ins> Some errors have detailed explanations: E0308, E0408, E0409. For more information about an error, try `rustc --explain E0308`. </ins>


config::CrateTypeDylib | config::CrateTypeProcMacro => MetadataKind::Compressed, } <del> }).max().unwrap(); </del> <ins> }).max().unwrap_or(MetadataKind::None); </ins> if kind == MetadataKind::None { return (metadata_llcx,


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // compile-flags: --crate-type dylib --target thumbv7em-none-eabihf // compile-pass // error-pattern: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf` #![feature(no_core)] #![no_std] #![no_core] </ins>


<ins> warning: dropping unsupported crate type `dylib` for target `thumbv7em-none-eabihf` </ins>


<ins> // ignore-emscripten no asm! support #![feature(asm)] fn main() { unsafe { asm! {"mov $0,$1"::"0"("bx"),"1"(0x00)} //~^ ERROR: invalid value for constraint in inline assembly } } </ins>


<ins> error[E0669]: invalid value for constraint in inline assembly --> $DIR/issue-51431.rs:7:32 | LL |         asm! {"mov $0,$1"::"0"("bx"),"1"(0x00)} |                                ^^^^ error: aborting due to previous error </ins>


<ins> trait A { const C: usize; fn f() -> ([u8; A::C], [u8; A::C]); //~^ ERROR: type annotations needed: cannot resolve //~| ERROR: type annotations needed: cannot resolve } fn main() {} </ins>


<ins> error[E0283]: type annotations needed: cannot resolve `_: A` --> $DIR/issue-63496.rs:4:21 | LL |     const C: usize; |     --------------- required by `A::C` LL | LL |     fn f() -> ([u8; A::C], [u8; A::C]); |                     ^^^^ error[E0283]: type annotations needed: cannot resolve `_: A` --> $DIR/issue-63496.rs:4:33 | LL |     const C: usize; |     --------------- required by `A::C` LL | LL |     fn f() -> ([u8; A::C], [u8; A::C]); |                                 ^^^^ error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0283`. </ins>


<ins> trait T<'x> { type V; } impl<'g> T<'g> for u32 { type V = u16; } fn main() { (&|_|()) as &dyn for<'x> Fn(<u32 as T<'x>>::V); //~^ ERROR: type mismatch in closure arguments //~| ERROR: type mismatch resolving } </ins>


<ins> error[E0631]: type mismatch in closure arguments --> $DIR/issue-41366.rs:10:5 | LL |     (&|_|()) as &dyn for<'x> Fn(<u32 as T<'x>>::V); |     ^^-----^ |     | | |     | found signature of `fn(_) -> _` |     expected signature of `for<'x> fn(<u32 as T<'x>>::V) -> _` | = note: required for the cast to the object type `dyn for<'x> std::ops::Fn(<u32 as T<'x>>::V)` error[E0271]: type mismatch resolving `for<'x> <[closure@$DIR/issue-41366.rs:10:7: 10:12] as std::ops::FnOnce<(<u32 as T<'x>>::V,)>>::Output == ()` --> $DIR/issue-41366.rs:10:5 | LL |     (&|_|()) as &dyn for<'x> Fn(<u32 as T<'x>>::V); |     ^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime | = note: required for the cast to the object type `dyn for<'x> std::ops::Fn(<u32 as T<'x>>::V)` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0271`. </ins>


<ins> fn main() { [(); &(&'static: loop { |x| {}; }) as *const _ as usize] //~^ ERROR: invalid label name `'static` //~| ERROR: type annotations needed } </ins>


<ins> error: invalid label name `'static` --> $DIR/issue-52437.rs:2:13 | LL |     [(); &(&'static: loop { |x| {}; }) as *const _ as usize] |             ^^^^^^^ error[E0282]: type annotations needed --> $DIR/issue-52437.rs:2:30 | LL |     [(); &(&'static: loop { |x| {}; }) as *const _ as usize] |                              ^ consider giving this closure parameter a type error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0282`. </ins>


Token::Interpolated(ref nt) => may_be_ident(&nt.0), _ => false, }, <ins> "lifetime" => match *token { Token::Lifetime(_) => true, Token::Interpolated(ref nt) => match nt.0 { token::NtLifetime(_) | token::NtTT(_) => true, _ => false, }, _ => false, }, </ins> _ => match *token { token::CloseDelim(_) => false, _ => true,


fn main() { m!(a); <del> //~^ ERROR expected a lifetime, found `a` </del> <ins> //~^ ERROR no rules expected the token `a` </ins> }


//}}} <ins> //{{{ issue 50903 ============================================================== macro_rules! foo_50903 { ($($lif:lifetime ,)* #) => {}; } foo_50903!('a, 'b, #); foo_50903!('a, #); foo_50903!(#); //}}} //{{{ issue 51477 ============================================================== macro_rules! foo_51477 { ($lifetime:lifetime) => { "last token is lifetime" }; ($other:tt) => { "last token is other" }; ($first:tt $($rest:tt)*) => { foo_51477!($($rest)*) }; } fn test_51477() { assert_eq!("last token is lifetime", foo_51477!('a)); assert_eq!("last token is other", foo_51477!(@)); assert_eq!("last token is lifetime", foo_51477!(@ {} 'a)); } //}}} </ins> //{{{ some more tests ========================================================== macro_rules! test_block {


test_meta_block!(windows {}); <ins> macro_rules! test_lifetime { (1. $($l:lifetime)* $($b:block)*) => {}; (2. $($b:block)* $($l:lifetime)*) => {}; } test_lifetime!(1. 'a 'b {} {}); test_lifetime!(2. {} {} 'a 'b); </ins> //}}} fn main() {


test_40569(); test_35650(); test_24189(); <ins> test_51477(); </ins> }


// highlighted text will always be `&<expr>` and // thus can transform to `&mut` by slicing off // first ASCII character and prepending "&mut ". <del> let borrowed_expr = src[1..].to_string(); return (assignment_rhs_span, format!("&mut {}", borrowed_expr)); </del> <ins> if src.starts_with('&') { let borrowed_expr = src[1..].to_string(); return (assignment_rhs_span, format!("&mut {}", borrowed_expr)); } </ins> } }


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. #![feature(nll)] fn main() { let foo = &16; //~^ HELP consider changing this to be a mutable reference //~| SUGGESTION &mut 16 *foo = 32; //~^ ERROR cannot assign to `*foo` which is behind a `&` reference let bar = foo; //~^ HELP consider changing this to be a mutable reference //~| SUGGESTION &mut i32 *bar = 64; //~^ ERROR cannot assign to `*bar` which is behind a `&` reference } </ins>


<ins> error[E0594]: cannot assign to `*foo` which is behind a `&` reference --> $DIR/issue-51515.rs:17:5 | LL |     let foo = &16; |               --- help: consider changing this to be a mutable reference: `&mut 16` ... LL |     *foo = 32; |     ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written error[E0594]: cannot assign to `*bar` which is behind a `&` reference --> $DIR/issue-51515.rs:22:5 | LL |     let bar = foo; |         --- help: consider changing this to be a mutable reference: `&mut i32` ... LL |     *bar = 64; |     ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0594`. </ins>


} let t = cx.tables.expr_ty(&expr); <del> // FIXME(varkor): replace with `t.is_unit() || t.conservative_is_uninhabited()`. let type_permits_no_use = match t.sty { ty::Tuple(ref tys) if tys.is_empty() => true, ty::Never => true, ty::Adt(def, _) => { if def.variants.is_empty() { true } else { check_must_use(cx, def.did, s.span, "") </del> <ins> let type_permits_lack_of_use = if t.is_unit() || cx.tcx.is_ty_uninhabited_from(cx.tcx.hir.get_module_parent(expr.id), t) { true } else { match t.sty { ty::Adt(def, _) => check_must_use(cx, def.did, s.span, "", ""), ty::Opaque(def, _) => { let mut must_use = false; for (predicate, _) in &cx.tcx.predicates_of(def).predicates { if let ty::Predicate::Trait(ref poly_trait_predicate) = predicate { let trait_ref = poly_trait_predicate.skip_binder().trait_ref; if check_must_use(cx, trait_ref.def_id, s.span, "implementer of ", "") { must_use = true; break; } } } must_use } ty::Dynamic(binder, _) => { let mut must_use = false; for predicate in binder.skip_binder().iter() { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate { if check_must_use(cx, trait_ref.def_id, s.span, "", " trait object") { must_use = true; break; } } } must_use </ins> } <ins> _ => false, </ins> } <del> _ => false, </del> }; let mut fn_warned = false;


}; if let Some(def) = maybe_def { let def_id = def.def_id(); <del> fn_warned = check_must_use(cx, def_id, s.span, "return value of "); } else if type_permits_no_use { </del> <ins> fn_warned = check_must_use(cx, def_id, s.span, "return value of ", ""); } else if type_permits_lack_of_use { </ins> // We don't warn about unused unit or uninhabited types. // (See https://github.com/rust-lang/rust/issues/43806 for details.) return;


op_warned = true; } <del> if !(type_permits_no_use || fn_warned || op_warned) { </del> <ins> if !(type_permits_lack_of_use || fn_warned || op_warned) { </ins> cx.span_lint(UNUSED_RESULTS, s.span, "unused result"); } <del> fn check_must_use(cx: &LateContext, def_id: DefId, sp: Span, describe_path: &str) -> bool { </del> <ins> fn check_must_use( cx: &LateContext, def_id: DefId, sp: Span, descr_pre_path: &str, descr_post_path: &str, ) -> bool { </ins> for attr in cx.tcx.get_attrs(def_id).iter() { if attr.check_name("must_use") { <del> let msg = format!("unused {}`{}` that must be used", describe_path, cx.tcx.item_path_str(def_id)); </del> <ins> let msg = format!("unused {}`{}`{} that must be used", descr_pre_path, cx.tcx.item_path_str(def_id), descr_post_path); </ins> let mut err = cx.struct_span_lint(UNUSED_MUST_USE, sp, &msg); // check for #[must_use = "..."] if let Some(note) = attr.value_str() {


<ins> #![deny(unused_must_use)] #[must_use] trait Critical {} trait NotSoCritical {} trait DecidedlyUnimportant {} struct Anon; impl Critical for Anon {} impl NotSoCritical for Anon {} impl DecidedlyUnimportant for Anon {} fn get_critical() -> impl NotSoCritical + Critical + DecidedlyUnimportant { Anon {} } fn main() { get_critical(); //~ ERROR unused implementer of `Critical` that must be used } </ins>


<ins> error: unused implementer of `Critical` that must be used --> $DIR/must_use-trait.rs:21:5 | LL |     get_critical(); //~ ERROR unused implementer of `Critical` that must be used |     ^^^^^^^^^^^^^^^ | note: lint level defined here --> $DIR/must_use-trait.rs:1:9 | LL | #![deny(unused_must_use)] |         ^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>


let crate_types = if options.proc_macro_crate { vec![config::CrateType::ProcMacro] } else { <del> vec![config::CrateType::Dylib] </del> <ins> vec![config::CrateType::Rlib] </ins> }; let sessopts = config::Options {


intravisit::walk_crate(this, krate); }); }); <ins> compiler.session().abort_if_errors(); </ins> let ret: Result<_, ErrorReported> = Ok(collector.tests); ret }) <del> }) .expect("compiler aborted in rustdoc!"); </del> <ins> }); let tests = match tests { Ok(tests) => tests, Err(ErrorReported) => return 1, }; </ins> test_args.insert(0, "rustdoctest".to_string());


<ins> // compile-flags:--test /// ``` /// assert!(true) /// ``` pub fn f() {} pub fn f() {} </ins>


<ins> error[E0428]: the name `f` is defined multiple times --> $DIR/test-compile-fail1.rs:8:1 | 6 | pub fn f() {} | ---------- previous definition of the value `f` here 7 | 8 | pub fn f() {} | ^^^^^^^^^^ `f` redefined here | = note: `f` must be defined only once in the value namespace of this module error: aborting due to previous error For more information about this error, try `rustc --explain E0428`. </ins>


<ins> error: expected one of `!` or `::`, found `<eof>` --> $DIR/test-compile-fail2.rs:3:1 | 3 | fail | ^^^^ expected one of `!` or `::` error: aborting due to previous error </ins>


<ins> error: unterminated double quote string --> $DIR/test-compile-fail3.rs:3:1 | 3 | "fail | ^^^^^^ error: aborting due to previous error </ins>


<ins> // compile-flags:--test // normalize-stdout-test: "src/test/rustdoc-ui" -> "$$DIR" // build-pass #![no_std] extern crate alloc; /// ``` /// assert!(true) /// ``` pub fn f() {} </ins>


<ins> running 1 test test $DIR/test-no_std.rs - f (line 9) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out </ins>


let mut cargo = Command::new(&self.initial_cargo); let out_dir = self.stage_out(compiler, mode); <del> // command specific path, we call clear_if_dirty with this let mut my_out = match cmd { "build" => self.cargo_out(compiler, mode, target), // This is the intended out directory for crate documentation. "doc" | "rustdoc" =>  self.crate_doc_out(target), _ => self.stage_out(compiler, mode), }; // This is for the original compiler, but if we're forced to use stage 1, then // std/test/rustc stamps won't exist in stage 2, so we need to get those from stage 1, since // we copy the libs forward. let cmp = self.compiler_for(compiler.stage, compiler.host, target); let libstd_stamp = match cmd { "check" | "clippy" | "fix" => check::libstd_stamp(self, cmp, target), _ => compile::libstd_stamp(self, cmp, target), }; let libtest_stamp = match cmd { "check" | "clippy" | "fix" => check::libtest_stamp(self, cmp, target), _ => compile::libtest_stamp(self, cmp, target), }; let librustc_stamp = match cmd { "check" | "clippy" | "fix" => check::librustc_stamp(self, cmp, target), _ => compile::librustc_stamp(self, cmp, target), }; </del> <ins> // Codegen backends are not yet tracked by -Zbinary-dep-depinfo, // so we need to explicitly clear out if they've been updated. for backend in self.codegen_backends(compiler) { self.clear_if_dirty(&out_dir, &backend); } </ins> if cmd == "doc" || cmd == "rustdoc" { <del> if mode == Mode::Rustc || mode == Mode::ToolRustc || mode == Mode::Codegen { </del> <ins> let my_out = match mode { </ins> // This is the intended out directory for compiler documentation. <del> my_out = self.compiler_doc_out(target); } </del> <ins> Mode::Rustc | Mode::ToolRustc | Mode::Codegen => self.compiler_doc_out(target), _ => self.crate_doc_out(target), }; </ins> let rustdoc = self.rustdoc(compiler); self.clear_if_dirty(&my_out, &rustdoc); <del> } else if cmd != "test" { match mode { Mode::Std => { self.clear_if_dirty(&my_out, &self.rustc(compiler)); for backend in self.codegen_backends(compiler) { self.clear_if_dirty(&my_out, &backend); } }, Mode::Test => { self.clear_if_dirty(&my_out, &libstd_stamp); }, Mode::Rustc => { self.clear_if_dirty(&my_out, &self.rustc(compiler)); self.clear_if_dirty(&my_out, &libstd_stamp); self.clear_if_dirty(&my_out, &libtest_stamp); }, Mode::Codegen => { self.clear_if_dirty(&my_out, &librustc_stamp); }, Mode::ToolBootstrap => { }, Mode::ToolStd => { self.clear_if_dirty(&my_out, &libstd_stamp); }, Mode::ToolTest => { self.clear_if_dirty(&my_out, &libstd_stamp); self.clear_if_dirty(&my_out, &libtest_stamp); }, Mode::ToolRustc => { self.clear_if_dirty(&my_out, &libstd_stamp); self.clear_if_dirty(&my_out, &libtest_stamp); self.clear_if_dirty(&my_out, &librustc_stamp); }, } </del> } cargo


}, } <ins> // This tells Cargo (and in turn, rustc) to output more complete // dependency information.  Most importantly for rustbuild, this // includes sysroot artifacts, like libstd, which means that we don't // need to track those in rustbuild (an error prone process!). This // feature is currently unstable as there may be some bugs and such, but // it represents a big improvement in rustbuild's reliability on // rebuilds, so we're using it here. // // For some additional context, see #63470 (the PR originally adding // this), as well as #63012 which is the tracking issue for this // feature on the rustc side. cargo.arg("-Zbinary-dep-depinfo"); </ins> cargo.arg("-j").arg(self.jobs().to_string()); // Remove make-related flags to ensure Cargo can correctly set things up cargo.env_remove("MAKEFLAGS");


let libdir = builder.sysroot_libdir(compiler, target); let hostdir = builder.sysroot_libdir(compiler, compiler.host); add_to_sysroot(&builder, &libdir, &hostdir, &rustdoc_stamp(builder, compiler, target)); <del> builder.cargo(compiler, Mode::ToolRustc, target, "clean"); </del> } }


use std::process::{Command, Stdio, exit}; use std::str; <del> use build_helper::{output, mtime, t, up_to_date}; </del> <ins> use build_helper::{output, t, up_to_date}; </ins> use filetime::FileTime; use serde::Deserialize; use serde_json;


// for reason why the sanitizers are not built in stage0. copy_apple_sanitizer_dylibs(builder, &builder.native_dir(target), "osx", &libdir); } <del> builder.cargo(target_compiler, Mode::ToolStd, target, "clean"); </del> } }


&builder.sysroot_libdir(target_compiler, compiler.host), &libtest_stamp(builder, compiler, target) ); <del> builder.cargo(target_compiler, Mode::ToolTest, target, "clean"); </del> } }


&builder.sysroot_libdir(target_compiler, compiler.host), &librustc_stamp(builder, compiler, target) ); <del> builder.cargo(target_compiler, Mode::ToolRustc, target, "clean"); </del> } }


deps.push((path_to_add.into(), false)); } <del> // Now we want to update the contents of the stamp file, if necessary. First // we read off the previous contents along with its mtime. If our new // contents (the list of files to copy) is different or if any dep's mtime // is newer then we rewrite the stamp file. </del> deps.sort(); <del> let stamp_contents = fs::read(stamp); let stamp_mtime = mtime(&stamp); </del> let mut new_contents = Vec::new(); <del> let mut max = None; let mut max_path = None; </del> for (dep, proc_macro) in deps.iter() { <del> let mtime = mtime(dep); if Some(mtime) > max { max = Some(mtime); max_path = Some(dep.clone()); } </del> new_contents.extend(if *proc_macro { b"h" } else { b"t" }); new_contents.extend(dep.to_str().unwrap().as_bytes()); new_contents.extend(b"0"); } <del> let max = max.unwrap(); let max_path = max_path.unwrap(); let contents_equal = stamp_contents .map(|contents| contents == new_contents) .unwrap_or_default(); if contents_equal && max <= stamp_mtime { builder.verbose(&format!("not updating {:?}; contents equal and {:?} <= {:?}", stamp, max, stamp_mtime)); return deps.into_iter().map(|(d, _)| d).collect() } if max > stamp_mtime { builder.verbose(&format!("updating {:?} as {:?} changed", stamp, max_path)); } else { builder.verbose(&format!("updating {:?} as deps changed", stamp)); } </del> t!(fs::write(&stamp, &new_contents)); deps.into_iter().map(|(d, _)| d).collect() }


<ins> #![feature(existential_type)] existential type Foo: Fn() -> Foo; //~^ ERROR: cycle detected when processing `Foo` fn crash(x: Foo) -> Foo { x } fn main() { } </ins>


<ins> error[E0391]: cycle detected when processing `Foo` --> $DIR/existential-types-with-cycle-error.rs:3:1 | LL | existential type Foo: Fn() -> Foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires processing `crash`... --> $DIR/existential-types-with-cycle-error.rs:6:25 | LL |   fn crash(x: Foo) -> Foo { |  _________________________^ LL | |     x LL | | } | |_^ = note: ...which again requires processing `Foo`, completing the cycle note: cycle used when collecting item types in top-level module --> $DIR/existential-types-with-cycle-error.rs:1:1 | LL | / #![feature(existential_type)] LL | | LL | | existential type Foo: Fn() -> Foo; LL | | ...  | LL | | LL | | } | |_^ error: aborting due to previous error For more information about this error, try `rustc --explain E0391`. </ins>


<ins> #![feature(existential_type)] pub trait Bar<T> { type Item; } existential type Foo: Bar<Foo, Item = Foo>; //~^ ERROR: cycle detected when processing `Foo` fn crash(x: Foo) -> Foo { x } fn main() { } </ins>


<ins> error[E0391]: cycle detected when processing `Foo` --> $DIR/existential-types-with-cycle-error2.rs:7:1 | LL | existential type Foo: Bar<Foo, Item = Foo>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: ...which requires processing `crash`... --> $DIR/existential-types-with-cycle-error2.rs:10:25 | LL |   fn crash(x: Foo) -> Foo { |  _________________________^ LL | |     x LL | | } | |_^ = note: ...which again requires processing `Foo`, completing the cycle note: cycle used when collecting item types in top-level module --> $DIR/existential-types-with-cycle-error2.rs:1:1 | LL | / #![feature(existential_type)] LL | | LL | | pub trait Bar<T> { LL | |     type Item; ...  | LL | | LL | | } | |_^ error: aborting due to previous error For more information about this error, try `rustc --explain E0391`. </ins>


pub use vec::{ImmutableEqVector, ImmutableCopyableVector}; pub use vec::{OwnedVector, OwnedCopyableVector}; <ins> /* Reexported runtime types */ pub use comm::{stream, Port, Chan, GenericChan, GenericSmartChan, GenericPort, Peekable}; pub use task::spawn; </ins> /* Reexported modules */ pub use at_vec;


// versions of them accidentally sneak into our dependency graph to // ensure we keep our CI times under control // "cargo", // FIXME(#53005) <del> // "rustc-ap-syntax", // FIXME(#53006) </del> <ins> "rustc-ap-syntax", </ins> ]; let mut name_to_id = HashMap::new(); for node in resolve.nodes.iter() {


<ins> // compile-pass // edition:2018 #![feature(arbitrary_self_types, async_await, await_macro)] use std::task::{self, Poll}; use std::future::Future; use std::marker::Unpin; use std::pin::Pin; // This is a regression test for a ICE/unbounded recursion issue relating to async-await. #[derive(Debug)] #[must_use = "futures do nothing unless polled"] pub struct Lazy<F> { f: Option<F> } impl<F> Unpin for Lazy<F> {} pub fn lazy<F, R>(f: F) -> Lazy<F> where F: FnOnce(&mut task::Context) -> R, { Lazy { f: Some(f) } } impl<R, F> Future for Lazy<F> where F: FnOnce(&mut task::Context) -> R, { type Output = R; fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context) -> Poll<R> { Poll::Ready((self.f.take().unwrap())(cx)) } } async fn __receive<WantFn, Fut>(want: WantFn) -> () where Fut: Future<Output = ()>, WantFn: Fn(&Box<Send + 'static>) -> Fut, { await!(lazy(|_| ())); } pub fn basic_spawn_receive() { async { await!(__receive(|_| async { () })) }; } fn main() {} </ins>


use std::fmt; use rustc_target::spec::abi; use syntax::ast; <del> use errors::DiagnosticBuilder; </del> <ins> use errors::{Applicability, DiagnosticBuilder}; </ins> use syntax_pos::Span; use hir;


db.note("no two closures, even if identical, have the same type"); db.help("consider boxing your closure and/or using it as a trait object"); } <ins> match (&values.found.sty, &values.expected.sty) { // Issue #53280 (ty::TyInfer(ty::IntVar(_)), ty::TyFloat(_)) => { if let Ok(snippet) = self.sess.codemap().span_to_snippet(sp) { if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') { db.span_suggestion_with_applicability( sp, "use a float literal", format!("{}.0", snippet), Applicability::MachineApplicable ); } } }, _ => {} } </ins> }, OldStyleLUB(err) => { db.note("this was previously accepted by the compiler but has been phased out");


--> $DIR/catch-block-type-error.rs:18:9 | LL |         42 <del> |         ^^ expected f32, found integral variable </del> <ins> |         ^^ |         | |         expected f32, found integral variable |         help: use a float literal: `42.0` </ins> | = note: expected type `f32` found type `{integer}`


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn main() { let sixteen: f32 = 16; //~^ ERROR mismatched types //~| HELP use a float literal let a_million_and_seventy: f64 = 1_000_070; //~^ ERROR mismatched types //~| HELP use a float literal let negative_nine: f32 = -9; //~^ ERROR mismatched types //~| HELP use a float literal // only base-10 literals get the suggestion let sixteen_again: f64 = 0x10; //~^ ERROR mismatched types let and_once_more: f32 = 0o20; //~^ ERROR mismatched types } </ins>


<ins> error[E0308]: mismatched types --> $DIR/issue-53280-expected-float-found-integer-literal.rs:12:24 | LL |     let sixteen: f32 = 16; |                        ^^ |                        | |                        expected f32, found integral variable |                        help: use a float literal: `16.0` | = note: expected type `f32` found type `{integer}` error[E0308]: mismatched types --> $DIR/issue-53280-expected-float-found-integer-literal.rs:15:38 | LL |     let a_million_and_seventy: f64 = 1_000_070; |                                      ^^^^^^^^^ |                                      | |                                      expected f64, found integral variable |                                      help: use a float literal: `1_000_070.0` | = note: expected type `f64` found type `{integer}` error[E0308]: mismatched types --> $DIR/issue-53280-expected-float-found-integer-literal.rs:18:30 | LL |     let negative_nine: f32 = -9; |                              ^^ |                              | |                              expected f32, found integral variable |                              help: use a float literal: `-9.0` | = note: expected type `f32` found type `{integer}` error[E0308]: mismatched types --> $DIR/issue-53280-expected-float-found-integer-literal.rs:25:30 | LL |     let sixteen_again: f64 = 0x10; |                              ^^^^ expected f64, found integral variable | = note: expected type `f64` found type `{integer}` error[E0308]: mismatched types --> $DIR/issue-53280-expected-float-found-integer-literal.rs:27:30 | LL |     let and_once_more: f32 = 0o20; |                              ^^^^ expected f32, found integral variable | = note: expected type `f32` found type `{integer}` error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


let mut cmd = Command::new(rustc); cmd.args(&args) <del> .arg("--cfg") .arg(format!("stage{}", stage)) </del> .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); let mut maybe_crate = None; <ins> // Non-zero stages must all be treated uniformly to avoid problems when attempting to uplift // compiler libraries and such from stage 1 to 2. if stage == "0" { cmd.arg("--cfg").arg("bootstrap"); } </ins> // Print backtrace in case of ICE if env::var("RUSTC_BACKTRACE_ON_ICE").is_ok() && env::var("RUST_BACKTRACE").is_err() { cmd.env("RUST_BACKTRACE", "1");


if !up_to_date(src_file, dst_file) { let mut cmd = Command::new(&builder.initial_rustc); builder.run(cmd.env("RUSTC_BOOTSTRAP", "1") <del> .arg("--cfg").arg("stage0") </del> <ins> .arg("--cfg").arg("bootstrap") </ins> .arg("--target").arg(target) .arg("--emit=obj") .arg("-o").arg(dst_file)


/// Returns the result of an unchecked addition, resulting in /// undefined behavior when `x + y > T::max_value()` or `x + y < T::min_value()`. <del> #[cfg(not(stage0))] </del> <ins> #[cfg(not(bootstrap))] </ins> pub fn unchecked_add<T>(x: T, y: T) -> T; /// Returns the result of an unchecked substraction, resulting in /// undefined behavior when `x - y > T::max_value()` or `x - y < T::min_value()`. <del> #[cfg(not(stage0))] </del> <ins> #[cfg(not(bootstrap))] </ins> pub fn unchecked_sub<T>(x: T, y: T) -> T; /// Returns the result of an unchecked multiplication, resulting in /// undefined behavior when `x * y > T::max_value()` or `x * y < T::min_value()`. <del> #[cfg(not(stage0))] </del> <ins> #[cfg(not(bootstrap))] </ins> pub fn unchecked_mul<T>(x: T, y: T) -> T; /// Performs rotate left.


#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] <del> #[cfg_attr(not(stage0), rustc_nonnull_optimization_guaranteed)] </del> <ins> #[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)] </ins> pub struct $Ty($Int); }


#[stable(feature = "nonnull", since = "1.25.0")] #[repr(transparent)] #[rustc_layout_scalar_valid_range_start(1)] <del> #[cfg_attr(not(stage0), rustc_nonnull_optimization_guaranteed)] </del> <ins> #[cfg_attr(not(bootstrap), rustc_nonnull_optimization_guaranteed)] </ins> pub struct NonNull<T: ?Sized> { pointer: *const T, }


if receiver.ends_with(&method_call) { None  // do not suggest code that is already there (#53348) } else { <del> Some(format!("{}{}", receiver, method_call)) </del> <ins> /* methods defined in `method_call_list` will overwrite `.clone()` in copy of `receiver` */ let method_call_list = [".to_vec()", ".to_string()"]; if receiver.ends_with(".clone()") && method_call_list.contains(&method_call.as_str()){ // created copy of `receiver` because we don't want other // suggestion to get affected let mut new_receiver = receiver.clone(); let max_len = new_receiver.rfind(".").unwrap(); new_receiver.truncate(max_len); Some(format!("{}{}", new_receiver, method_call)) } else { Some(format!("{}{}", receiver, method_call)) } </ins> } }) .collect::<Vec<_>>(); if !suggestions.is_empty() {


<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. fn main() { let items = vec![1, 2, 3]; let ref_items: &[i32] = &items; let items_clone: Vec<i32> = ref_items.clone(); // in that case no suggestion will be triggered let items_clone_2:Vec<i32> = items.clone(); let s = "hi"; let string: String = s.clone(); // in that case no suggestion will be triggered let s2 = "hi"; let string_2: String = s2.to_string(); } </ins>


<ins> error[E0308]: mismatched types --> $DIR/issue-53692.rs:13:37 | LL |         let items_clone: Vec<i32> = ref_items.clone(); |                                     ^^^^^^^^^^^^^^^^^ |                                     | |                                     expected struct `std::vec::Vec`, found &[i32] |                                     help: try using a conversion method: `ref_items.to_vec()` | = note: expected type `std::vec::Vec<i32>` found type `&[i32]` error[E0308]: mismatched types --> $DIR/issue-53692.rs:19:30 | LL |         let string: String = s.clone(); |                              ^^^^^^^^^ |                              | |                              expected struct `std::string::String`, found &str |                              help: try using a conversion method: `s.to_string()` | = note: expected type `std::string::String` found type `&str` error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


// for ':' and '-' '-' | ':' => self.path.temp_buf.push('.'), <ins> // Avoid segmentation fault on some platforms, see #60925. 'm' if self.path.temp_buf.ends_with(".llv") => self.path.temp_buf.push_str("$6d$"), </ins> // These are legal symbols 'a'..='z' | 'A'..='Z' | '0'..='9' | '_' | '.' | '$' => self.path.temp_buf.push(c),


<ins> // compile-pass // This test is the same code as in ui/symbol-names/issue-60925.rs but this checks that the // reproduction compiles successfully and doesn't segfault, whereas that test just checks that the // symbol mangling fix produces the correct result. fn dummy() {} mod llvm { pub(crate) struct Foo; } mod foo { pub(crate) struct Foo<T>(T); impl Foo<::llvm::Foo> { pub(crate) fn foo() { for _ in 0..0 { for _ in &[::dummy()] { ::dummy(); ::dummy(); ::dummy(); } } } } pub(crate) fn foo() { Foo::foo(); Foo::foo(); } } pub fn foo() { foo::foo(); } fn main() {} </ins>


<ins> #![feature(rustc_attrs)] // This test is the same code as in ui/issue-53912.rs but this test checks that the symbol mangling // fix produces the correct result, whereas that test just checks that the reproduction compiles // successfully and doesn't segfault fn dummy() {} mod llvm { pub(crate) struct Foo; } mod foo { pub(crate) struct Foo<T>(T); impl Foo<::llvm::Foo> { #[rustc_symbol_name] //~^ ERROR _ZN11issue_609253foo36Foo$LT$issue_60925..llv$6d$..Foo$GT$3foo17h059a991a004536adE pub(crate) fn foo() { for _ in 0..0 { for _ in &[::dummy()] { ::dummy(); ::dummy(); ::dummy(); } } } } pub(crate) fn foo() { Foo::foo(); Foo::foo(); } } pub fn foo() { foo::foo(); } fn main() {} </ins>


<ins> error: symbol-name(_ZN11issue_609253foo36Foo$LT$issue_60925..llv$6d$..Foo$GT$3foo17h059a991a004536adE) --> $DIR/issue-60925.rs:16:9 | LL |         #[rustc_symbol_name] |         ^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error </ins>


<ins> // check-pass // ignore-emscripten no llvm_asm! support #![feature(llvm_asm)] pub fn boot(addr: Option<u32>) { unsafe { llvm_asm!("mov sp, $0"::"r" (addr)); } } fn main() {} </ins>


<ins> // edition:2018 use std::sync::{Arc, Mutex}; pub async fn f(_: ()) {} pub async fn run() { let x: Arc<Mutex<()>> = unimplemented!(); f(*x.lock().unwrap()).await; } </ins>


<ins> // aux-build: issue_67893.rs // edition:2018 // dont-check-compiler-stderr // FIXME(#71222): Add above flag because of the difference of stderrs on some env. extern crate issue_67893; fn g(_: impl Send) {} fn main() { g(issue_67893::run()) //~^ ERROR: `std::sync::MutexGuard<'_, ()>` cannot be sent between threads safely } </ins>


<ins> #![feature(intrinsics)] extern "C" { pub static FOO: extern "rust-intrinsic" fn(); } fn main() { FOO() //~ ERROR: use of extern static is unsafe } </ins>


<ins> error[E0133]: use of extern static is unsafe and requires unsafe function or block --> $DIR/issue-28575.rs:8:5 | LL |     FOO() |     ^^^ use of extern static | = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior error: aborting due to previous error For more information about this error, try `rustc --explain E0133`. </ins>


<ins> pub static TEST_STR: &'static str = "Hello world"; </ins>


<ins> // aux-build: issue_24843.rs // check-pass extern crate issue_24843; static _TEST_STR_2: &'static str = &issue_24843::TEST_STR; fn main() {} </ins>


/// `&mut T` references can be freely coerced into `&T` references with the same referent type, and /// references with longer lifetimes can be freely coerced into references with shorter ones. /// <ins> /// Reference equality by address, instead of comparing the values pointed to, is accomplished via /// implicit reference-pointer coercion and raw pointer equality via [`ptr::eq`], while /// [`PartialEq`] compares values. /// /// [`ptr::eq`]: ptr/fn.eq.html /// [`PartialEq`]: cmp/trait.PartialEq.html /// /// ``` /// use std::ptr; /// /// let five = 5; /// let other_five = 5; /// let five_ref = &five; /// let same_five_ref = &five; /// let other_five_ref = &other_five; /// /// assert!(five_ref == same_five_ref); /// assert!(five_ref == other_five_ref); /// /// assert!(ptr::eq(five_ref, same_five_ref)); /// assert!(!ptr::eq(five_ref, other_five_ref)); /// ``` /// </ins> /// For more information on how to use references, see [the book's section on "References and /// Borrowing"][book-refs]. /// /// [book-refs]: ../book/second-edition/ch04-02-references-and-borrowing.html /// <ins> /// # Trait implementations /// </ins> /// The following traits are implemented for all `&T`, regardless of the type of its referent: /// /// * [`Copy`]


}; if self.can_coerce(ref_ty, expected) { if let Ok(src) = cm.span_to_snippet(sp) { <del> let sugg_expr = match expr.node { // parenthesize if needed (Issue #46756) </del> <ins> let needs_parens = match expr.node { // parenthesize if needed (Issue #46756) </ins> hir::ExprKind::Cast(_, _) | <del> hir::ExprKind::Binary(_, _, _) => format!("({})", src), _ => src, </del> <ins> hir::ExprKind::Binary(_, _, _) => true, // parenthesize borrows of range literals (Issue #54505) _ if self.is_range_literal(expr) => true, _ => false, </ins> }; <ins> let sugg_expr = if needs_parens { format!("({})", src) } else { src }; </ins> if let Some(sugg) = self.can_use_as_ref(expr) { return Some(sugg); }


None } <ins> /// This function checks if the specified expression is a built-in range literal. /// (See: `LoweringContext::lower_expr()` in `src/librustc/hir/lowering.rs`). fn is_range_literal(&self, expr: &hir::Expr) -> bool { use hir::{Path, QPath, ExprKind, TyKind}; // We support `::std::ops::Range` and `::core::ops::Range` prefixes let is_range_path = |path: &Path| { let mut segs = path.segments.iter() .map(|seg| seg.ident.as_str()); if let (Some(root), Some(std_core), Some(ops), Some(range), None) = (segs.next(), segs.next(), segs.next(), segs.next(), segs.next()) { // "{{root}}" is the equivalent of `::` prefix in Path root == "{{root}}" && (std_core == "std" || std_core == "core") && ops == "ops" && range.starts_with("Range") } else { false } }; let span_is_range_literal = |span: &Span| { // Check whether a span corresponding to a range expression // is a range literal, rather than an explicit struct or `new()` call. let source_map = self.tcx.sess.source_map(); let end_point = source_map.end_point(*span); if let Ok(end_string) = source_map.span_to_snippet(end_point) { !(end_string.ends_with("}") || end_string.ends_with(")")) } else { false } }; match expr.node { // All built-in range literals but `..=` and `..` desugar to Structs ExprKind::Struct(QPath::Resolved(None, ref path), _, _) | // `..` desugars to its struct path ExprKind::Path(QPath::Resolved(None, ref path)) => { return is_range_path(&path) && span_is_range_literal(&expr.span); } // `..=` desugars into `::std::ops::RangeInclusive::new(...)` ExprKind::Call(ref func, _) => { if let ExprKind::Path(QPath::TypeRelative(ref ty, ref segment)) = func.node { if let TyKind::Path(QPath::Resolved(None, ref path)) = ty.node { let call_to_new = segment.ident.as_str() == "new"; return is_range_path(&path) && span_is_range_literal(&expr.span) && call_to_new; } } } _ => {} } false } </ins> pub fn check_for_cast(&self, err: &mut DiagnosticBuilder<'tcx>, expr: &hir::Expr,


<ins> // run-rustfix // Regression test for changes introduced while fixing #54505 // This test uses non-literals for Ranges // (expecting no parens with borrow suggestion) use std::ops::RangeBounds; // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(&std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } take_range(&::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } take_range(&std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFrom { start: 1 } take_range(&::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } take_range(&std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFull {} take_range(&::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFull {} take_range(&std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) take_range(&::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) take_range(&std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeTo { end: 5 } take_range(&::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeTo { end: 5 } take_range(&std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } take_range(&::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } } </ins>


<ins> // run-rustfix // Regression test for changes introduced while fixing #54505 // This test uses non-literals for Ranges // (expecting no parens with borrow suggestion) use std::ops::RangeBounds; // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::Range { start: 0, end: 1 } take_range(::std::ops::Range { start: 0, end: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::Range { start: 0, end: 1 } take_range(std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFrom { start: 1 } take_range(::std::ops::RangeFrom { start: 1 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFrom { start: 1 } take_range(std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeFull {} take_range(::std::ops::RangeFull {}); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeFull {} take_range(std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeInclusive::new(0, 1) take_range(::std::ops::RangeInclusive::new(0, 1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeInclusive::new(0, 1) take_range(std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeTo { end: 5 } take_range(::std::ops::RangeTo { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeTo { end: 5 } take_range(std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &std::ops::RangeToInclusive { end: 5 } take_range(::std::ops::RangeToInclusive { end: 5 }); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &::std::ops::RangeToInclusive { end: 5 } } </ins>


<ins> error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:16:16 | LL |     take_range(std::ops::Range { start: 0, end: 1 }); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::Range` |                help: consider borrowing here: `&std::ops::Range { start: 0, end: 1 }` | = note: expected type `&_` found type `std::ops::Range<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:21:16 | LL |     take_range(::std::ops::Range { start: 0, end: 1 }); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::Range` |                help: consider borrowing here: `&::std::ops::Range { start: 0, end: 1 }` | = note: expected type `&_` found type `std::ops::Range<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:26:16 | LL |     take_range(std::ops::RangeFrom { start: 1 }); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeFrom` |                help: consider borrowing here: `&std::ops::RangeFrom { start: 1 }` | = note: expected type `&_` found type `std::ops::RangeFrom<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:31:16 | LL |     take_range(::std::ops::RangeFrom { start: 1 }); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeFrom` |                help: consider borrowing here: `&::std::ops::RangeFrom { start: 1 }` | = note: expected type `&_` found type `std::ops::RangeFrom<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:36:16 | LL |     take_range(std::ops::RangeFull {}); |                ^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeFull` |                help: consider borrowing here: `&std::ops::RangeFull {}` | = note: expected type `&_` found type `std::ops::RangeFull` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:41:16 | LL |     take_range(::std::ops::RangeFull {}); |                ^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeFull` |                help: consider borrowing here: `&::std::ops::RangeFull {}` | = note: expected type `&_` found type `std::ops::RangeFull` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:46:16 | LL |     take_range(std::ops::RangeInclusive::new(0, 1)); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeInclusive` |                help: consider borrowing here: `&std::ops::RangeInclusive::new(0, 1)` | = note: expected type `&_` found type `std::ops::RangeInclusive<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:51:16 | LL |     take_range(::std::ops::RangeInclusive::new(0, 1)); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeInclusive` |                help: consider borrowing here: `&::std::ops::RangeInclusive::new(0, 1)` | = note: expected type `&_` found type `std::ops::RangeInclusive<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:56:16 | LL |     take_range(std::ops::RangeTo { end: 5 }); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeTo` |                help: consider borrowing here: `&std::ops::RangeTo { end: 5 }` | = note: expected type `&_` found type `std::ops::RangeTo<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:61:16 | LL |     take_range(::std::ops::RangeTo { end: 5 }); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeTo` |                help: consider borrowing here: `&::std::ops::RangeTo { end: 5 }` | = note: expected type `&_` found type `std::ops::RangeTo<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:66:16 | LL |     take_range(std::ops::RangeToInclusive { end: 5 }); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeToInclusive` |                help: consider borrowing here: `&std::ops::RangeToInclusive { end: 5 }` | = note: expected type `&_` found type `std::ops::RangeToInclusive<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-literals.rs:71:16 | LL |     take_range(::std::ops::RangeToInclusive { end: 5 }); |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |                | |                expected reference, found struct `std::ops::RangeToInclusive` |                help: consider borrowing here: `&::std::ops::RangeToInclusive { end: 5 }` | = note: expected type `&_` found type `std::ops::RangeToInclusive<{integer}>` error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


<ins> // error-pattern: `#[panic_handler]` function required, but not found // Regression test for #54505 - range borrowing suggestion had // incorrect syntax (missing parentheses). // This test doesn't use std // (so all Ranges resolve to core::ops::Range...) #![no_std] #![feature(lang_items)] use core::ops::RangeBounds; #[cfg(not(target_arch = "wasm32"))] #[lang = "eh_personality"] extern fn eh_personality() {} #[cfg(target_os = "windows")] #[lang = "eh_unwind_resume"] extern fn eh_unwind_resume() {} // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(0..1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..1) take_range(1..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(1..) take_range(..); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..) take_range(0..=1); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..=1) take_range(..5); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..5) take_range(..=42); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..=42) } </ins>


<ins> error: `#[panic_handler]` function required, but not found error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:28:16 | LL |     take_range(0..1); |                ^^^^ |                | |                expected reference, found struct `core::ops::Range` |                help: consider borrowing here: `&(0..1)` | = note: expected type `&_` found type `core::ops::Range<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:33:16 | LL |     take_range(1..); |                ^^^ |                | |                expected reference, found struct `core::ops::RangeFrom` |                help: consider borrowing here: `&(1..)` | = note: expected type `&_` found type `core::ops::RangeFrom<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:38:16 | LL |     take_range(..); |                ^^ |                | |                expected reference, found struct `core::ops::RangeFull` |                help: consider borrowing here: `&(..)` | = note: expected type `&_` found type `core::ops::RangeFull` error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:43:16 | LL |     take_range(0..=1); |                ^^^^^ |                | |                expected reference, found struct `core::ops::RangeInclusive` |                help: consider borrowing here: `&(0..=1)` | = note: expected type `&_` found type `core::ops::RangeInclusive<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:48:16 | LL |     take_range(..5); |                ^^^ |                | |                expected reference, found struct `core::ops::RangeTo` |                help: consider borrowing here: `&(..5)` | = note: expected type `&_` found type `core::ops::RangeTo<{integer}>` error[E0308]: mismatched types --> $DIR/issue-54505-no-std.rs:53:16 | LL |     take_range(..=42); |                ^^^^^ |                | |                expected reference, found struct `core::ops::RangeToInclusive` |                help: consider borrowing here: `&(..=42)` | = note: expected type `&_` found type `core::ops::RangeToInclusive<{integer}>` error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0308`. </ins>


<ins> // run-rustfix // Regression test for #54505 - range borrowing suggestion had // incorrect syntax (missing parentheses). use std::ops::RangeBounds; // take a reference to any built-in range fn take_range(_r: &impl RangeBounds<i8>) {} fn main() { take_range(&(0..1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..1) take_range(&(1..)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(1..) take_range(&(..)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..) take_range(&(0..=1)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(0..=1) take_range(&(..5)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..5) take_range(&(..=42)); //~^ ERROR mismatched types [E0308] //~| HELP consider borrowing here //~| SUGGESTION &(..=42) } </ins>