diff --git a/compiler/rustc_error_codes/src/error_codes/E0424.md b/compiler/rustc_error_codes/src/error_codes/E0424.md index a9f6f579b4275..a58c16b59e91e 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0424.md +++ b/compiler/rustc_error_codes/src/error_codes/E0424.md @@ -21,7 +21,7 @@ impl Foo { The `self` keyword can only be used inside methods, which are associated functions (functions defined inside of a `trait` or `impl` block) that have a `self` receiver as its first parameter, like `self`, `&self`, `&mut self` or -`self: &mut Pin` (this last one is an example of an ["abitrary `self` +`self: &mut Pin` (this last one is an example of an ["arbitrary `self` type"](https://github.com/rust-lang/rust/issues/44874)). Check if the associated function's parameter list should have contained a `self` diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs index d784a86f14cee..c5b59a041abf6 100644 --- a/compiler/rustc_lexer/src/lib.rs +++ b/compiler/rustc_lexer/src/lib.rs @@ -48,6 +48,7 @@ impl Token { } /// Enum representing common lexeme types. +// perf note: Changing all `usize` to `u32` doesn't change performance. See #77629 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum TokenKind { // Multi-char tokens: @@ -160,6 +161,7 @@ pub enum LiteralKind { /// - `r##~"abcde"##`: `InvalidStarter` /// - `r###"abcde"##`: `NoTerminator { expected: 3, found: 2, possible_terminator_offset: Some(11)` /// - Too many `#`s (>65535): `TooManyDelimiters` +// perf note: It doesn't matter that this makes `Token` 36 bytes bigger. See #77629 #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] pub enum RawStrError { /// Non `#` characters exist between `r` and `"` eg. `r#~"..` @@ -689,7 +691,12 @@ impl Cursor<'_> { let mut max_hashes = 0; // Count opening '#' symbols. - let n_start_hashes = self.eat_while(|c| c == '#'); + let mut eaten = 0; + while self.first() == '#' { + eaten += 1; + self.bump(); + } + let n_start_hashes = eaten; // Check that string is started. match self.bump() { @@ -724,16 +731,11 @@ impl Cursor<'_> { // Note that this will not consume extra trailing `#` characters: // `r###"abcde"####` is lexed as a `RawStr { n_hashes: 3 }` // followed by a `#` token. - let mut hashes_left = n_start_hashes; - let is_closing_hash = |c| { - if c == '#' && hashes_left != 0 { - hashes_left -= 1; - true - } else { - false - } - }; - let n_end_hashes = self.eat_while(is_closing_hash); + let mut n_end_hashes = 0; + while self.first() == '#' && n_end_hashes < n_start_hashes { + n_end_hashes += 1; + self.bump(); + } if n_end_hashes == n_start_hashes { return (n_start_hashes, None); @@ -807,17 +809,9 @@ impl Cursor<'_> { } /// Eats symbols while predicate returns true or until the end of file is reached. - /// Returns amount of eaten symbols. - fn eat_while(&mut self, mut predicate: F) -> usize - where - F: FnMut(char) -> bool, - { - let mut eaten: usize = 0; + fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) { while predicate(self.first()) && !self.is_eof() { - eaten += 1; self.bump(); } - - eaten } } diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 9d5b558234b3a..86476dffc0312 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -123,10 +123,26 @@ impl<'tcx> TyCtxt<'tcx> { self_ty: Ty<'tcx>, mut f: F, ) { + let _: Option<()> = self.find_map_relevant_impl(def_id, self_ty, |did| { + f(did); + None + }); + } + + /// Applies function to every impl that could possibly match the self type `self_ty` and returns + /// the first non-none value. + pub fn find_map_relevant_impl Option>( + self, + def_id: DefId, + self_ty: Ty<'tcx>, + mut f: F, + ) -> Option { let impls = self.trait_impls_of(def_id); for &impl_def_id in impls.blanket_impls.iter() { - f(impl_def_id); + if let result @ Some(_) = f(impl_def_id) { + return result; + } } // simplify_type(.., false) basically replaces type parameters and @@ -157,14 +173,20 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(simp) = fast_reject::simplify_type(self, self_ty, true) { if let Some(impls) = impls.non_blanket_impls.get(&simp) { for &impl_def_id in impls { - f(impl_def_id); + if let result @ Some(_) = f(impl_def_id) { + return result; + } } } } else { for &impl_def_id in impls.non_blanket_impls.values().flatten() { - f(impl_def_id); + if let result @ Some(_) = f(impl_def_id) { + return result; + } } } + + None } /// Returns an iterator containing all impls diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 4127b6535bca6..d8ea2f67393b2 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -346,14 +346,14 @@ impl<'tcx> TyCtxt<'tcx> { let drop_trait = self.lang_items().drop_trait()?; self.ensure().coherent_trait(drop_trait); - let mut dtor_did = None; let ty = self.type_of(adt_did); - self.for_each_relevant_impl(drop_trait, ty, |impl_did| { + let dtor_did = self.find_map_relevant_impl(drop_trait, ty, |impl_did| { if let Some(item) = self.associated_items(impl_did).in_definition_order().next() { if validate(self, impl_did).is_ok() { - dtor_did = Some(item.def_id); + return Some(item.def_id); } } + None }); Some(ty::Destructor { did: dtor_did? }) diff --git a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs index 4d4e9b989171a..26993a6b941fb 100644 --- a/compiler/rustc_mir/src/transform/check_const_item_mutation.rs +++ b/compiler/rustc_mir/src/transform/check_const_item_mutation.rs @@ -34,7 +34,6 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> { fn is_const_item_without_destructor(&self, local: Local) -> Option { let def_id = self.is_const_item(local)?; - let mut any_dtor = |_tcx, _def_id| Ok(()); // We avoid linting mutation of a const item if the const's type has a // Drop impl. The Drop logic observes the mutation which was performed. @@ -54,7 +53,7 @@ impl<'a, 'tcx> ConstMutationChecker<'a, 'tcx> { // // #[const_mutation_allowed] // pub const LOG: Log = Log { msg: "" }; - match self.tcx.calculate_dtor(def_id, &mut any_dtor) { + match self.tcx.calculate_dtor(def_id, &mut |_, _| Ok(())) { Some(_) => None, None => Some(def_id), } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index cb3de57cfed07..05e3ed3435113 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1384,17 +1384,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { trait_ref: &ty::PolyTraitRef<'tcx>, ) { let get_trait_impl = |trait_def_id| { - let mut trait_impl = None; - self.tcx.for_each_relevant_impl( + self.tcx.find_map_relevant_impl( trait_def_id, trait_ref.skip_binder().self_ty(), - |impl_def_id| { - if trait_impl.is_none() { - trait_impl = Some(impl_def_id); - } - }, - ); - trait_impl + |impl_def_id| Some(impl_def_id), + ) }; let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); let all_traits = self.tcx.all_traits(LOCAL_CRATE); diff --git a/config.toml.example b/config.toml.example index 6dc9eccbdfceb..e7e37c679e545 100644 --- a/config.toml.example +++ b/config.toml.example @@ -13,7 +13,7 @@ # If it does not match the version that is currently running, # `x.py` will prompt you to update it and read the changelog. # See `src/bootstrap/CHANGELOG.md` for more information. -changelog-seen = 1 +changelog-seen = 2 # ============================================================================= # Global Settings @@ -370,13 +370,13 @@ changelog-seen = 1 # binary, otherwise they are omitted. # # Defaults to rust.debug value -#debug-assertions = debug +#debug-assertions = rust.debug (boolean) # Whether or not debug assertions are enabled for the standard library. # Overrides the `debug-assertions` option, if defined. # # Defaults to rust.debug-assertions value -#debug-assertions-std = debug-assertions +#debug-assertions-std = rust.debug-assertions (boolean) # Whether or not to leave debug! and trace! calls in the rust binary. # Overrides the `debug-assertions` option, if defined. @@ -386,7 +386,7 @@ changelog-seen = 1 # If you see a message from `tracing` saying # `max_level_info` is enabled and means logging won't be shown, # set this value to `true`. -#debug-logging = debug-assertions +#debug-logging = rust.debug-assertions (boolean) # Debuginfo level for most of Rust code, corresponds to the `-C debuginfo=N` option of `rustc`. # `0` - no debug info diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index ce70de6ebdd63..4646d4a833525 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -14,8 +14,9 @@ mod tests; extern "Rust" { // These are the magic symbols to call the global allocator. rustc generates - // them from the `#[global_allocator]` attribute if there is one, or uses the - // default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`) + // them to call `__rg_alloc` etc if there is a `#[global_allocator]` attribute + // (the code expanding that attribute macro generates those functions), or to call + // the default implementations in libstd (`__rdl_alloc` etc in `src/libstd/alloc.rs`) // otherwise. #[rustc_allocator] #[rustc_allocator_nounwind] @@ -26,8 +27,6 @@ extern "Rust" { fn __rust_realloc(ptr: *mut u8, old_size: usize, align: usize, new_size: usize) -> *mut u8; #[rustc_allocator_nounwind] fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8; - #[rustc_allocator_nounwind] - fn __rust_alloc_error_handler(size: usize, align: usize) -> !; } /// The global memory allocator. @@ -323,6 +322,16 @@ pub(crate) unsafe fn box_free(ptr: Unique) { } } +// # Allocation error handler + +extern "Rust" { + // This is the magic symbol to call the global alloc error handler. rustc generates + // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the + // default implementations below (`__rdl_oom`) otherwise. + #[rustc_allocator_nounwind] + fn __rust_alloc_error_handler(size: usize, align: usize) -> !; +} + /// Abort on memory allocation error or failure. /// /// Callers of memory allocation APIs wishing to abort computation @@ -367,7 +376,7 @@ pub fn handle_alloc_error(layout: Layout) -> ! { #[doc(hidden)] #[allow(unused_attributes)] #[unstable(feature = "alloc_internals", issue = "none")] -pub mod __default_lib_allocator { +pub mod __alloc_error_handler { use crate::alloc::Layout; // called via generated `__rust_alloc_error_handler` diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index e8e52299d0b70..5e68f76693fcf 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -1476,7 +1476,8 @@ impl Vec { /// `'a`. If the type has only static references, or none at all, then this /// may be chosen to be `'static`. /// - /// This function is similar to the `leak` function on `Box`. + /// This function is similar to the [`leak`][Box::leak] function on [`Box`] + /// except that there is no way to recover the leaked memory. /// /// This function is mainly useful for data that lives for the remainder of /// the program's life. Dropping the returned reference will cause a memory diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index d4cc2cd239bb7..5224672adb28b 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -85,7 +85,7 @@ //! # Contributing changes to the documentation //! //! Check out the rust contribution guidelines [here]( -//! https://rustc-dev-guide.rust-lang.org/getting-started.html). +//! https://rustc-dev-guide.rust-lang.org/contributing.html#writing-documentation). //! The source for this documentation can be found on //! [GitHub](https://github.com/rust-lang/rust). //! To contribute changes, make sure you read the guidelines first, then submit diff --git a/library/std/src/os/linux/fs.rs b/library/std/src/os/linux/fs.rs index ff23c3d67e3b4..9b7af97616c9d 100644 --- a/library/std/src/os/linux/fs.rs +++ b/library/std/src/os/linux/fs.rs @@ -20,7 +20,7 @@ pub trait MetadataExt { /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the /// cross-Unix abstractions contained within the raw stat. /// - /// [`stat`]: crate::os::linux::raw::stat + /// [`stat`]: struct@crate::os::linux::raw::stat /// /// # Examples /// diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 559c4dc9c7cd8..657421e3fa4cc 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -47,7 +47,6 @@ pub type LPWCH = *mut WCHAR; pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW; pub type LPWSADATA = *mut WSADATA; pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO; -pub type LPSTR = *mut CHAR; pub type LPWSTR = *mut WCHAR; pub type LPFILETIME = *mut FILETIME; pub type LPWSABUF = *mut WSABUF; @@ -876,16 +875,6 @@ extern "system" { pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL; pub fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD; pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL; - pub fn WideCharToMultiByte( - CodePage: UINT, - dwFlags: DWORD, - lpWideCharStr: LPCWSTR, - cchWideChar: c_int, - lpMultiByteStr: LPSTR, - cbMultiByte: c_int, - lpDefaultChar: LPCSTR, - lpUsedDefaultChar: LPBOOL, - ) -> c_int; pub fn closesocket(socket: SOCKET) -> c_int; pub fn recv(socket: SOCKET, buf: *mut c_void, len: c_int, flags: c_int) -> c_int; diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index 8178e6806b9b3..8c19cc78b09cd 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -4,7 +4,6 @@ use crate::ffi::{OsStr, OsString}; use crate::io::ErrorKind; use crate::os::windows::ffi::{OsStrExt, OsStringExt}; use crate::path::PathBuf; -use crate::ptr; use crate::time::Duration; pub use self::rand::hashmap_random_keys; @@ -206,58 +205,6 @@ fn os2path(s: &[u16]) -> PathBuf { PathBuf::from(OsString::from_wide(s)) } -#[allow(dead_code)] // Only used in backtrace::gnu::get_executable_filename() -fn wide_char_to_multi_byte( - code_page: u32, - flags: u32, - s: &[u16], - no_default_char: bool, -) -> crate::io::Result> { - unsafe { - let mut size = c::WideCharToMultiByte( - code_page, - flags, - s.as_ptr(), - s.len() as i32, - ptr::null_mut(), - 0, - ptr::null(), - ptr::null_mut(), - ); - if size == 0 { - return Err(crate::io::Error::last_os_error()); - } - - let mut buf = Vec::with_capacity(size as usize); - buf.set_len(size as usize); - - let mut used_default_char = c::FALSE; - size = c::WideCharToMultiByte( - code_page, - flags, - s.as_ptr(), - s.len() as i32, - buf.as_mut_ptr(), - buf.len() as i32, - ptr::null(), - if no_default_char { &mut used_default_char } else { ptr::null_mut() }, - ); - if size == 0 { - return Err(crate::io::Error::last_os_error()); - } - if no_default_char && used_default_char == c::TRUE { - return Err(crate::io::Error::new( - crate::io::ErrorKind::InvalidData, - "string cannot be converted to requested code page", - )); - } - - buf.set_len(size as usize); - - Ok(buf) - } -} - pub fn truncate_utf16_at_nul(v: &[u16]) -> &[u16] { match unrolled_find_u16s(0, v) { // don't include the 0 diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs index 806df572cf944..ff1d82fc99040 100644 --- a/library/unwind/src/libunwind.rs +++ b/library/unwind/src/libunwind.rs @@ -89,7 +89,7 @@ extern "C" { } cfg_if::cfg_if! { -if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] { +if #[cfg(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm")))] { // Not ARM EHABI #[repr(C)] #[derive(Copy, Clone, PartialEq)] diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 5b5624298a41a..34eac31890cbe 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -650,14 +650,9 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx let ty = cx.tcx.type_of(type_); let iter = in_scope_traits.iter().flat_map(|&trait_| { trace!("considering explicit impl for trait {:?}", trait_); - let mut saw_impl = false; - // Look at each trait implementation to see if it's an impl for `did` - cx.tcx.for_each_relevant_impl(trait_, ty, |impl_| { - // FIXME: this is inefficient, find a way to short-circuit for_each_* so this doesn't take as long - if saw_impl { - return; - } + // Look at each trait implementation to see if it's an impl for `did` + cx.tcx.find_map_relevant_impl(trait_, ty, |impl_| { let trait_ref = cx.tcx.impl_trait_ref(impl_).expect("this is not an inherent impl"); // Check if these are the same type. let impl_type = trait_ref.self_ty(); @@ -668,7 +663,7 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx type_ ); // Fast path: if this is a primitive simple `==` will work - saw_impl = impl_type == ty + let saw_impl = impl_type == ty || match impl_type.kind() { // Check if these are the same def_id ty::Adt(def, _) => { @@ -678,8 +673,9 @@ fn traits_implemented_by(cx: &DocContext<'_>, type_: DefId, module: DefId) -> Fx ty::Foreign(def_id) => *def_id == type_, _ => false, }; - }); - if saw_impl { Some(trait_) } else { None } + + if saw_impl { Some(trait_) } else { None } + }) }); iter.collect() }