diff options
1378 files changed, 16446 insertions, 10714 deletions
diff --git a/COPYRIGHT b/COPYRIGHT index dc9abf84b8e..11335879bd4 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -23,65 +23,251 @@ The Rust Project includes packages written by third parties. The following third party packages are included, and carry their own copyright notices and license terms: -* LLVM. Code for this package is found in src/llvm-project. - - Copyright (c) 2003-2013 University of Illinois at - Urbana-Champaign. All rights reserved. - - Developed by: - - LLVM Team - - University of Illinois at Urbana-Champaign - - http://llvm.org - - Permission is hereby granted, free of charge, to any - person obtaining a copy of this software and associated - documentation files (the "Software"), to deal with the - Software without restriction, including without - limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software - is furnished to do so, subject to the following - conditions: - - * Redistributions of source code must retain the - above copyright notice, this list of conditions - and the following disclaimers. - - * Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimers in the documentation - and/or other materials provided with the - distribution. - - * Neither the names of the LLVM Team, University of - Illinois at Urbana-Champaign, nor the names of its - contributors may be used to endorse or promote - products derived from this Software without - specific prior written permission. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE - FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT - OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS WITH THE SOFTWARE. - -* Additional libraries included in LLVM carry separate - BSD-compatible licenses. See src/llvm-project/llvm/LICENSE.TXT - for details. - -* compiler-rt, in src/compiler-rt is dual licensed under - LLVM's license and MIT: - - Copyright (c) 2009-2014 by the contributors listed in - CREDITS.TXT - +* LLVM, located in src/llvm-project, is licensed under the following + terms. + + ============================================================================== + The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: + ============================================================================== + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + ---- LLVM Exceptions to the Apache 2.0 License ---- + + As an exception, if, as a result of your compiling your source code, portions + of this Software are embedded into an Object form of such source code, you + may redistribute such embedded portions in such Object form without complying + with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + + In addition, if you combine or link compiled forms of this Software with + software that is licensed under the GPLv2 ("Combined Software") and if a + court of competent jurisdiction determines that the patent provision (Section + 3), the indemnity provision (Section 9) or other Section of the License + conflicts with the conditions of the GPLv2, you may retroactively and + prospectively choose to deem waived or otherwise exclude such Section(s) of + the License, but only in their entirety and only with respect to the Combined + Software. + + ============================================================================== + Software from third parties included in the LLVM Project: + ============================================================================== + The LLVM Project contains third party software which is under different license + terms. All such code will be identified clearly using at least one of two + mechanisms: + 1) It will be in a separate directory tree with its own `LICENSE.txt` or + `LICENSE` file at the top containing the specific license and restrictions + which apply to that software, or + 2) It will contain specific license and restriction terms at the top of every + file. + + ============================================================================== + Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): + ============================================================================== + University of Illinois/NCSA + Open Source License + + Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign. All rights reserved. Developed by: @@ -92,70 +278,32 @@ their own copyright notices and license terms: http://llvm.org - Permission is hereby granted, free of charge, to any - person obtaining a copy of this software and associated - documentation files (the "Software"), to deal with the - Software without restriction, including without - limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software - is furnished to do so, subject to the following - conditions: - - * Redistributions of source code must retain the - above copyright notice, this list of conditions - and the following disclaimers. - - * Redistributions in binary form must reproduce the - above copyright notice, this list of conditions - and the following disclaimers in the documentation - and/or other materials provided with the - distribution. - - * Neither the names of the LLVM Team, University of - Illinois at Urbana-Champaign, nor the names of its - contributors may be used to endorse or promote - products derived from this Software without - specific prior written permission. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE - FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT - OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS WITH THE SOFTWARE. - - ======================================================== - - Copyright (c) 2009-2014 by the contributors listed in - CREDITS.TXT - - Permission is hereby granted, free of charge, to any - person obtaining a copy of this software and associated - documentation files (the "Software"), to deal in the - Software without restriction, including without - limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software - is furnished to do so, subject to the following - conditions: - - The above copyright notice and this permission notice - shall be included in all copies or substantial portions - of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF - ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT - SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal with + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimers. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimers in the + documentation and/or other materials provided with the distribution. + + * Neither the names of the LLVM Team, University of Illinois at + Urbana-Champaign, nor the names of its contributors may be used to + endorse or promote products derived from this Software without specific + prior written permission. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE + SOFTWARE. * Portions of the FFI code for interacting with the native ABI is derived from the Clay programming language, which carries @@ -191,41 +339,3 @@ their own copyright notices and license terms: NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -* libbacktrace, under src/libbacktrace: - - Copyright (C) 2012-2014 Free Software Foundation, Inc. - Written by Ian Lance Taylor, Google. - - Redistribution and use in source and binary forms, with - or without modification, are permitted provided that the - following conditions are met: - - (1) Redistributions of source code must retain the - above copyright notice, this list of conditions and - the following disclaimer. - - (2) Redistributions in binary form must reproduce - the above copyright notice, this list of conditions - and the following disclaimer in the documentation - and/or other materials provided with the - distribution. - - (3) The name of the author may not be used to - endorse or promote products derived from this - software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGE. */ diff --git a/Cargo.lock b/Cargo.lock index 6b2146ad3ed..072902f333d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,7 +297,7 @@ dependencies = [ "cargo-test-macro", "cargo-test-support", "cargo-util", - "clap", + "clap 4.0.9", "crates-io", "curl", "curl-sys", @@ -591,7 +591,7 @@ dependencies = [ "atty", "bitflags", "clap_derive", - "clap_lex", + "clap_lex 0.2.2", "indexmap", "once_cell", "strsim", @@ -600,12 +600,25 @@ dependencies = [ ] [[package]] +name = "clap" +version = "4.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30607dd93c420c6f1f80b544be522a0238a7db35e6a12968d28910983fee0df0" +dependencies = [ + "atty", + "bitflags", + "clap_lex 0.3.0", + "strsim", + "termcolor", +] + +[[package]] name = "clap_complete" version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df6f3613c0a3cddfd78b41b10203eb322cb29b600cbdf808a7d3db95691b8e25" dependencies = [ - "clap", + "clap 3.2.20", ] [[package]] @@ -631,6 +644,15 @@ dependencies = [ ] [[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + +[[package]] name = "clippy" version = "0.1.65" dependencies = [ @@ -664,7 +686,7 @@ name = "clippy_dev" version = "0.0.1" dependencies = [ "aho-corasick", - "clap", + "clap 3.2.20", "indoc", "itertools", "opener", @@ -1809,7 +1831,7 @@ name = "installer" version = "0.0.0" dependencies = [ "anyhow", - "clap", + "clap 3.2.20", "flate2", "lazy_static", "num_cpus", @@ -2152,7 +2174,7 @@ dependencies = [ "ammonia", "anyhow", "chrono", - "clap", + "clap 3.2.20", "clap_complete", "elasticlunr-rs", "env_logger 0.9.0", @@ -3024,7 +3046,7 @@ dependencies = [ name = "rustbook" version = "0.1.0" dependencies = [ - "clap", + "clap 3.2.20", "env_logger 0.7.1", "mdbook", ] @@ -3111,7 +3133,7 @@ name = "rustc-workspace-hack" version = "1.0.0" dependencies = [ "bstr", - "clap", + "clap 3.2.20", "libz-sys", "regex", "serde_json", @@ -3297,6 +3319,7 @@ dependencies = [ "rustc_symbol_mangling", "rustc_target", "smallvec", + "tempfile", "tracing", ] @@ -3781,8 +3804,6 @@ dependencies = [ "either", "gsgdt", "polonius-engine", - "rand 0.8.5", - "rand_xoshiro", "rustc-rayon", "rustc-rayon-core", "rustc_apfloat", @@ -4228,6 +4249,8 @@ dependencies = [ name = "rustc_ty_utils" version = "0.0.0" dependencies = [ + "rand 0.8.5", + "rand_xoshiro", "rustc_data_structures", "rustc_errors", "rustc_hir", @@ -4338,7 +4361,7 @@ dependencies = [ "anyhow", "bytecount", "cargo_metadata 0.14.0", - "clap", + "clap 3.2.20", "derive-new", "diff", "dirs", diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index fa6162c5184..16224d71e45 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -256,10 +256,6 @@ pub enum TokenKind { Eof, } -// `TokenKind` is used a lot. Make sure it doesn't unintentionally get bigger. -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(TokenKind, 16); - #[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)] pub struct Token { pub kind: TokenKind, @@ -349,17 +345,14 @@ impl Token { } pub fn is_op(&self) -> bool { - !matches!( - self.kind, - OpenDelim(..) - | CloseDelim(..) - | Literal(..) - | DocComment(..) - | Ident(..) - | Lifetime(..) - | Interpolated(..) - | Eof - ) + match self.kind { + Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | BinOp(_) + | BinOpEq(_) | At | Dot | DotDot | DotDotDot | DotDotEq | Comma | Semi | Colon + | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => true, + + OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..) + | Lifetime(..) | Interpolated(..) | Eof => false, + } } pub fn is_like_plus(&self) -> bool { @@ -728,6 +721,7 @@ impl Token { } impl PartialEq<TokenKind> for Token { + #[inline] fn eq(&self, rhs: &TokenKind) -> bool { self.kind == *rhs } @@ -751,10 +745,6 @@ pub enum Nonterminal { NtVis(P<ast::Visibility>), } -// `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger. -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Nonterminal, 16); - #[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)] pub enum NonterminalKind { Item, @@ -893,3 +883,16 @@ where panic!("interpolated tokens should not be present in the HIR") } } + +// Some types are used a lot. Make sure they don't unintentionally get bigger. +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +mod size_asserts { + use super::*; + use rustc_data_structures::static_assert_size; + // These are in alphabetical order, which is easy to maintain. + static_assert_size!(Lit, 12); + static_assert_size!(LitKind, 2); + static_assert_size!(Nonterminal, 16); + static_assert_size!(Token, 24); + static_assert_size!(TokenKind, 16); +} diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs index 875cd620dfc..4d2049cbc41 100644 --- a/compiler/rustc_ast/src/tokenstream.rs +++ b/compiler/rustc_ast/src/tokenstream.rs @@ -47,10 +47,6 @@ pub enum TokenTree { Delimited(DelimSpan, Delimiter, TokenStream), } -// This type is used a lot. Make sure it doesn't unintentionally get bigger. -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(TokenTree, 32); - // Ensure all fields of `TokenTree` is `Send` and `Sync`. #[cfg(parallel_compiler)] fn _dummy() @@ -308,13 +304,20 @@ pub struct AttributesData { #[derive(Clone, Debug, Default, Encodable, Decodable)] pub struct TokenStream(pub(crate) Lrc<Vec<TokenTree>>); -// `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger. -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(TokenStream, 8); - +/// Similar to `proc_macro::Spacing`, but for tokens. +/// +/// Note that all `ast::TokenTree::Token` instances have a `Spacing`, but when +/// we convert to `proc_macro::TokenTree` for proc macros only `Punct` +/// `TokenTree`s have a `proc_macro::Spacing`. #[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)] pub enum Spacing { + /// The token is not immediately followed by an operator token (as + /// determined by `Token::is_op`). E.g. a `+` token is `Alone` in `+ =`, + /// `+/*foo*/=`, `+ident`, and `+()`. Alone, + + /// The token is immediately followed by an operator token. E.g. a `+` + /// token is `Joint` in `+=` and `++`. Joint, } @@ -664,3 +667,16 @@ impl DelimSpan { self.open.with_hi(self.close.hi()) } } + +// Some types are used a lot. Make sure they don't unintentionally get bigger. +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +mod size_asserts { + use super::*; + use rustc_data_structures::static_assert_size; + // These are in alphabetical order, which is easy to maintain. + static_assert_size!(AttrTokenStream, 8); + static_assert_size!(AttrTokenTree, 32); + static_assert_size!(LazyAttrTokenStream, 8); + static_assert_size!(TokenStream, 8); + static_assert_size!(TokenTree, 32); +} diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index d9b18d68e53..9a46444d823 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -1478,6 +1478,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let bounded_ty = self.ty_path(ty_id, param_span, hir::QPath::Resolved(None, ty_path)); Some(hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { + hir_id: self.next_id(), bounded_ty: self.arena.alloc(bounded_ty), bounds, span, @@ -1508,6 +1509,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ref bounds, span, }) => hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { + hir_id: self.next_id(), bound_generic_params: self.lower_generic_params(bound_generic_params), bounded_ty: self .lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Type)), diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 275ceed30d7..8281164ab12 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -61,8 +61,8 @@ use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::DefPathData; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; use rustc_index::vec::{Idx, IndexVec}; -use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; +use rustc_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DesugaringKind; @@ -1060,13 +1060,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by // constructing the HIR for `impl bounds...` and then lowering that. - let parent_def_id = self.current_hir_id_owner; let impl_trait_node_id = self.next_node_id(); - self.create_def( - parent_def_id.def_id, - impl_trait_node_id, - DefPathData::ImplTrait, - ); self.with_dyn_type_scope(false, |this| { let node_id = this.next_node_id(); @@ -1357,9 +1351,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { def_node_id, bounds, false, - &ImplTraitContext::TypeAliasesOpaqueTy, + itctx, ), ImplTraitContext::Universal => { + self.create_def( + self.current_hir_id_owner.def_id, + def_node_id, + DefPathData::ImplTrait, + ); let span = t.span; let ident = Ident::from_str_and_span(&pprust::ty_to_string(t), span); let (param, bounds, path) = @@ -1453,7 +1452,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id); + let opaque_ty_def_id = match origin { + hir::OpaqueTyOrigin::TyAlias => self.create_def( + self.current_hir_id_owner.def_id, + opaque_ty_node_id, + DefPathData::ImplTrait, + ), + hir::OpaqueTyOrigin::FnReturn(fn_def_id) => { + self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait) + } + hir::OpaqueTyOrigin::AsyncFn(..) => bug!("unreachable"), + }; debug!(?opaque_ty_def_id); // Contains the new lifetime definitions created for the TAIT (if any). diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs index 419e6c81791..4d251cf7ac7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs @@ -864,15 +864,13 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { }; let tcx = self.infcx.tcx; - let body_parent_did = tcx.opt_parent(self.mir_def_id().to_def_id())?; - if tcx.parent(region.def_id) != body_parent_did - || tcx.def_kind(body_parent_did) != DefKind::Impl - { + let region_parent = tcx.parent(region.def_id); + if tcx.def_kind(region_parent) != DefKind::Impl { return None; } let mut found = false; - tcx.fold_regions(tcx.type_of(body_parent_did), |r: ty::Region<'tcx>, _| { + tcx.fold_regions(tcx.type_of(region_parent), |r: ty::Region<'tcx>, _| { if *r == ty::ReEarlyBound(region) { found = true; } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index d03f0369648..28ed88e8345 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -236,7 +236,7 @@ pub(crate) fn type_check<'mir, 'tcx>( .unwrap(); let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); - if hidden_type.has_infer_types_or_consts() { + if hidden_type.has_non_region_infer() { infcx.tcx.sess.delay_span_bug( decl.hidden_type.span, &format!("could not resolve {:#?}", hidden_type.ty.kind()), diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 77e0b6c55a8..7bd344467d0 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -16,6 +16,7 @@ pub fn expand_deriving_copy( let trait_def = TraitDef { span, path: path_std!(marker::Copy), + skip_path_as_bound: false, additional_bounds: Vec::new(), generics: Bounds::empty(), supports_unions: true, diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index c7f2d95e72f..fa8685f5f4e 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -72,6 +72,7 @@ pub fn expand_deriving_clone( let trait_def = TraitDef { span, path: path_std!(clone::Clone), + skip_path_as_bound: false, additional_bounds: bounds, generics: Bounds::empty(), supports_unions: true, diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 5b556c5c9b9..eab67b0d354 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -25,6 +25,7 @@ pub fn expand_deriving_eq( let trait_def = TraitDef { span, path: path_std!(cmp::Eq), + skip_path_as_bound: false, additional_bounds: Vec::new(), generics: Bounds::empty(), supports_unions: true, diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 72625869558..7f117981a9a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -19,6 +19,7 @@ pub fn expand_deriving_ord( let trait_def = TraitDef { span, path: path_std!(cmp::Ord), + skip_path_as_bound: false, additional_bounds: Vec::new(), generics: Bounds::empty(), supports_unions: false, diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs index 42ee65b570a..236cbccaf9f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_eq.rs @@ -83,6 +83,7 @@ pub fn expand_deriving_partial_eq( let trait_def = TraitDef { span, path: path_std!(cmp::PartialEq), + skip_path_as_bound: false, additional_bounds: Vec::new(), generics: Bounds::empty(), supports_unions: false, diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index 516892aeda9..4173403a1b8 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -37,6 +37,7 @@ pub fn expand_deriving_partial_ord( let trait_def = TraitDef { span, path: path_std!(cmp::PartialOrd), + skip_path_as_bound: false, additional_bounds: vec![], generics: Bounds::empty(), supports_unions: false, diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index 4af7fd81653..2cf614ed947 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -20,6 +20,7 @@ pub fn expand_deriving_debug( let trait_def = TraitDef { span, path: path_std!(fmt::Debug), + skip_path_as_bound: false, additional_bounds: Vec::new(), generics: Bounds::empty(), supports_unions: false, diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index 7174dbbe7ea..d669f616802 100644 --- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs @@ -23,6 +23,7 @@ pub fn expand_deriving_rustc_decodable( let trait_def = TraitDef { span, path: Path::new_(vec![krate, sym::Decodable], vec![], PathKind::Global), + skip_path_as_bound: false, additional_bounds: Vec::new(), generics: Bounds::empty(), supports_unions: false, diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index a94c8a996e6..17df9fb279a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -24,6 +24,7 @@ pub fn expand_deriving_default( let trait_def = TraitDef { span, path: Path::new(vec![kw::Default, sym::Default]), + skip_path_as_bound: has_a_default_variant(item), additional_bounds: Vec::new(), generics: Bounds::empty(), supports_unions: false, @@ -262,3 +263,22 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for DetectNonVariantDefaultAttr<'a, ' } } } + +fn has_a_default_variant(item: &Annotatable) -> bool { + struct HasDefaultAttrOnVariant { + found: bool, + } + + impl<'ast> rustc_ast::visit::Visitor<'ast> for HasDefaultAttrOnVariant { + fn visit_variant(&mut self, v: &'ast rustc_ast::Variant) { + if v.attrs.iter().any(|attr| attr.has_name(kw::Default)) { + self.found = true; + } + // no need to subrecurse. + } + } + + let mut visitor = HasDefaultAttrOnVariant { found: false }; + item.visit_with(&mut visitor); + visitor.found +} diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index b220e54238f..f83f58b97d3 100644 --- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs @@ -107,6 +107,7 @@ pub fn expand_deriving_rustc_encodable( let trait_def = TraitDef { span, path: Path::new_(vec![krate, sym::Encodable], vec![], PathKind::Global), + skip_path_as_bound: false, additional_bounds: Vec::new(), generics: Bounds::empty(), supports_unions: false, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 3cc160adb53..6fbd99b5c71 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -174,6 +174,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; use std::cell::RefCell; use std::iter; +use std::ops::Not; use std::vec; use thin_vec::thin_vec; use ty::{Bounds, Path, Ref, Self_, Ty}; @@ -187,6 +188,9 @@ pub struct TraitDef<'a> { /// Path of the trait, including any type parameters pub path: Path, + /// Whether to skip adding the current trait as a bound to the type parameters of the type. + pub skip_path_as_bound: bool, + /// Additional bounds required of any type parameters of the type, /// other than the current trait pub additional_bounds: Vec<Ty>, @@ -596,7 +600,7 @@ impl<'a> TraitDef<'a> { cx.trait_bound(p.to_path(cx, self.span, type_ident, generics)) }).chain( // require the current trait - iter::once(cx.trait_bound(trait_path.clone())) + self.skip_path_as_bound.not().then(|| cx.trait_bound(trait_path.clone())) ).chain( // also add in any bounds from the declaration param.bounds.iter().cloned() diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index f1f02e7ce77..6e9d5f08b94 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -22,6 +22,7 @@ pub fn expand_deriving_hash( let hash_trait_def = TraitDef { span, path, + skip_path_as_bound: false, additional_bounds: Vec::new(), generics: Bounds::empty(), supports_unions: false, diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index b15e2d084ef..8b07c110663 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -159,7 +159,7 @@ pub fn make_format_args( append_newline: bool, ) -> Result<FormatArgs, ()> { let msg = "format argument must be a string literal"; - let fmt_span = efmt.span; + let unexpanded_fmt_span = efmt.span; let (fmt_str, fmt_style, fmt_span) = match expr_to_spanned_string(ecx, efmt, msg) { Ok(mut fmt) if append_newline => { fmt.0 = Symbol::intern(&format!("{}\n", fmt.0)); @@ -174,7 +174,7 @@ pub fn make_format_args( }; if !suggested { err.span_suggestion( - fmt_span.shrink_to_lo(), + unexpanded_fmt_span.shrink_to_lo(), "you might be missing a string literal to format with", format!("\"{}\", ", sugg_fmt), Applicability::MaybeIncorrect, @@ -192,7 +192,7 @@ pub fn make_format_args( }; let fmt_str = fmt_str.as_str(); // for the suggestions below - let fmt_snippet = ecx.source_map().span_to_snippet(fmt_span).ok(); + let fmt_snippet = ecx.source_map().span_to_snippet(unexpanded_fmt_span).ok(); let mut parser = parse::Parser::new( fmt_str, str_style, diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index f058503064b..c7ea7de8f4e 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -7,7 +7,7 @@ #![feature(box_patterns)] #![feature(decl_macro)] #![feature(if_let_guard)] -#![feature(is_some_with)] +#![feature(is_some_and)] #![feature(is_sorted)] #![feature(let_chains)] #![feature(proc_macro_internals)] diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 7efb6cc61ee..705141614e2 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -115,7 +115,7 @@ pub fn expand_test_or_bench( // reworked in the future to not need it, it'd be nice. _ => diag.struct_span_err(attr_sp, msg).forget_guarantee(), }; - err.span_label(attr_sp, "the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions") + err.span_label(attr_sp, "the `#[test]` macro causes a function to be run on a test and has no effect on non-functions") .span_label(item.span, format!("expected a non-associated function, found {} {}", item.kind.article(), item.kind.descr())) .span_suggestion(attr_sp, "replace with conditional compilation to make the item only exist when tests are being run", "#[cfg(test)]", Applicability::MaybeIncorrect) .emit(); diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs index 848c34211ff..6fb1cbfad8c 100644 --- a/compiler/rustc_codegen_gcc/src/abi.rs +++ b/compiler/rustc_codegen_gcc/src/abi.rs @@ -11,10 +11,6 @@ use crate::intrinsic::ArgAbiExt; use crate::type_of::LayoutGccExt; impl<'a, 'gcc, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { - fn apply_attrs_callsite(&mut self, _fn_abi: &FnAbi<'tcx, Ty<'tcx>>, _callsite: Self::Value) { - // TODO(antoyo) - } - fn get_param(&mut self, index: usize) -> Self::Value { let func = self.current_func(); let param = func.get_param(index as i32); diff --git a/compiler/rustc_codegen_gcc/src/archive.rs b/compiler/rustc_codegen_gcc/src/archive.rs index f863abdcc97..ac0342f6b80 100644 --- a/compiler/rustc_codegen_gcc/src/archive.rs +++ b/compiler/rustc_codegen_gcc/src/archive.rs @@ -1,6 +1,8 @@ use std::fs::File; use std::path::{Path, PathBuf}; +use crate::errors::RanlibFailure; + use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; use rustc_session::Session; @@ -181,7 +183,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> { std::process::Command::new("ranlib").arg(output).status().expect("Couldn't run ranlib"); if !status.success() { - self.config.sess.fatal(&format!("Ranlib exited with code {:?}", status.code())); + self.config.sess.emit_fatal(RanlibFailure::new(status.code())); } any_members diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs index 52fd66af065..c346dbd63cc 100644 --- a/compiler/rustc_codegen_gcc/src/asm.rs +++ b/compiler/rustc_codegen_gcc/src/asm.rs @@ -12,6 +12,7 @@ use std::borrow::Cow; use crate::builder::Builder; use crate::context::CodegenCx; +use crate::errors::UnwindingInlineAsm; use crate::type_of::LayoutGccExt; use crate::callee::get_fn; @@ -109,7 +110,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], _instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) { if options.contains(InlineAsmOptions::MAY_UNWIND) { self.sess() - .struct_span_err(span[0], "GCC backend does not support unwinding from inline asm") + .create_err(UnwindingInlineAsm { span: span[0] }) .emit(); return; } @@ -497,7 +498,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { if options.contains(InlineAsmOptions::NORETURN) { let builtin_unreachable = self.context.get_builtin_function("__builtin_unreachable"); let builtin_unreachable: RValue<'gcc> = unsafe { std::mem::transmute(builtin_unreachable) }; - self.call(self.type_void(), builtin_unreachable, &[], None); + self.call(self.type_void(), None, builtin_unreachable, &[], None); } // Write results to outputs. diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 6994eeb00c3..a314b7cc215 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -444,11 +444,23 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.block.end_with_switch(None, value, default_block, &gcc_cases); } - fn invoke(&mut self, typ: Type<'gcc>, func: RValue<'gcc>, args: &[RValue<'gcc>], then: Block<'gcc>, catch: Block<'gcc>, _funclet: Option<&Funclet>) -> RValue<'gcc> { + fn invoke( + &mut self, + typ: Type<'gcc>, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, + func: RValue<'gcc>, + args: &[RValue<'gcc>], + then: Block<'gcc>, + catch: Block<'gcc>, + _funclet: Option<&Funclet>, + ) -> RValue<'gcc> { // TODO(bjorn3): Properly implement unwinding. - let call_site = self.call(typ, func, args, None); + let call_site = self.call(typ, None, func, args, None); let condition = self.context.new_rvalue_from_int(self.bool_type, 1); self.llbb().end_with_conditional(None, condition, then, catch); + if let Some(_fn_abi) = fn_abi { + // TODO(bjorn3): Apply function attributes + } call_site } @@ -643,11 +655,7 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { self.current_func().new_local(None, aligned_type, &format!("stack_var_{}", self.stack_var_count.get())).get_address(None) } - fn dynamic_alloca(&mut self, _ty: Type<'gcc>, _align: Align) -> RValue<'gcc> { - unimplemented!(); - } - - fn array_alloca(&mut self, _ty: Type<'gcc>, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { + fn byte_array_alloca(&mut self, _len: RValue<'gcc>, _align: Align) -> RValue<'gcc> { unimplemented!(); } @@ -1227,16 +1235,27 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> { // TODO(antoyo) } - fn call(&mut self, _typ: Type<'gcc>, func: RValue<'gcc>, args: &[RValue<'gcc>], funclet: Option<&Funclet>) -> RValue<'gcc> { + fn call( + &mut self, + _typ: Type<'gcc>, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, + func: RValue<'gcc>, + args: &[RValue<'gcc>], + funclet: Option<&Funclet>, + ) -> RValue<'gcc> { // FIXME(antoyo): remove when having a proper API. let gcc_func = unsafe { std::mem::transmute(func) }; - if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() { + let call = if self.functions.borrow().values().find(|value| **value == gcc_func).is_some() { self.function_call(func, args, funclet) } else { // If it's a not function that was defined, it's a function pointer. self.function_ptr_call(func, args, funclet) + }; + if let Some(_fn_abi) = fn_abi { + // TODO(bjorn3): Apply function attributes } + call } fn zext(&mut self, value: RValue<'gcc>, dest_typ: Type<'gcc>) -> RValue<'gcc> { diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs index 356c03ee3c1..81f53328867 100644 --- a/compiler/rustc_codegen_gcc/src/consts.rs +++ b/compiler/rustc_codegen_gcc/src/consts.rs @@ -14,6 +14,7 @@ use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRan use crate::base; use crate::context::CodegenCx; +use crate::errors::LinkageConstOrMutType; use crate::type_of::LayoutGccExt; impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { @@ -368,10 +369,7 @@ fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &Codeg cx.layout_of(mt.ty).gcc_type(cx, true) } else { - cx.sess().span_fatal( - span, - "must have type `*const T` or `*mut T` due to `#[linkage]` attribute", - ) + cx.sess().emit_fatal(LinkageConstOrMutType { span: span }) }; // Declare a symbol `foo` with the desired linkage. let global1 = cx.declare_global_with_linkage(&sym, llty2, base::global_linkage_to_gcc(linkage)); diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 478f6d893dd..62a61eb8548 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -13,7 +13,7 @@ use rustc_middle::mir::mono::CodegenUnit; use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt}; use rustc_middle::ty::layout::{FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, TyAndLayout, LayoutOfHelpers}; use rustc_session::Session; -use rustc_span::Span; +use rustc_span::{Span, source_map::respan}; use rustc_target::abi::{call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx}; use rustc_target::spec::{HasTargetSpec, Target, TlsModel}; @@ -293,7 +293,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { self.is_native_int_type(typ) || self.is_non_native_int_type(typ) || typ.is_compatible_with(self.bool_type) } - pub fn sess(&self) -> &Session { + pub fn sess(&self) -> &'tcx Session { &self.tcx.sess } @@ -416,10 +416,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { self.codegen_unit } - fn used_statics(&self) -> &RefCell<Vec<RValue<'gcc>>> { - unimplemented!(); - } - fn set_frame_pointer_type(&self, _llfn: RValue<'gcc>) { // TODO(antoyo) } @@ -428,10 +424,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { // TODO(antoyo) } - fn create_used_variable(&self) { - unimplemented!(); - } - fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> { if self.get_declared_value("main").is_none() { Some(self.declare_cfn("main", fn_type)) @@ -443,14 +435,6 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { None } } - - fn compiler_used_statics(&self) -> &RefCell<Vec<RValue<'gcc>>> { - unimplemented!() - } - - fn create_compiler_used_variable(&self) { - unimplemented!() - } } impl<'gcc, 'tcx> HasTyCtxt<'tcx> for CodegenCx<'gcc, 'tcx> { @@ -477,7 +461,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { #[inline] fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! { if let LayoutError::SizeOverflow(_) = err { - self.sess().span_fatal(span, &err.to_string()) + self.sess().emit_fatal(respan(span, err)) } else { span_bug!(span, "failed to get layout for `{}`: {}", ty, err) } @@ -495,7 +479,7 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err { - self.sess().span_fatal(span, &err.to_string()) + self.sess().emit_fatal(respan(span, err)) } else { match fn_abi_request { FnAbiRequest::OfFnPtr { sig, extra_args } => { diff --git a/compiler/rustc_codegen_gcc/src/errors.rs b/compiler/rustc_codegen_gcc/src/errors.rs new file mode 100644 index 00000000000..d7816e395c8 --- /dev/null +++ b/compiler/rustc_codegen_gcc/src/errors.rs @@ -0,0 +1,242 @@ +use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; +use rustc_macros::Diagnostic; +use rustc_middle::ty::Ty; +use rustc_span::{Span, Symbol}; +use std::borrow::Cow; + +struct ExitCode(Option<i32>); + +impl IntoDiagnosticArg for ExitCode { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + let ExitCode(exit_code) = self; + match exit_code { + Some(t) => t.into_diagnostic_arg(), + None => DiagnosticArgValue::Str(Cow::Borrowed("<signal>")), + } + } +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::ranlib_failure)] +pub(crate) struct RanlibFailure { + exit_code: ExitCode, +} + +impl RanlibFailure { + pub fn new(exit_code: Option<i32>) -> Self { + RanlibFailure { exit_code: ExitCode(exit_code) } + } +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_basic_integer, code = "E0511")] +pub(crate) struct InvalidMonomorphizationBasicInteger<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_invalid_float_vector, code = "E0511")] +pub(crate) struct InvalidMonomorphizationInvalidFloatVector<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub elem_ty: &'a str, + pub vec_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_not_float, code = "E0511")] +pub(crate) struct InvalidMonomorphizationNotFloat<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_unrecognized, code = "E0511")] +pub(crate) struct InvalidMonomorphizationUnrecognized { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_expected_signed_unsigned, code = "E0511")] +pub(crate) struct InvalidMonomorphizationExpectedSignedUnsigned<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub elem_ty: Ty<'a>, + pub vec_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_unsupported_element, code = "E0511")] +pub(crate) struct InvalidMonomorphizationUnsupportedElement<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_ty: Ty<'a>, + pub elem_ty: Ty<'a>, + pub ret_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_invalid_bitmask, code = "E0511")] +pub(crate) struct InvalidMonomorphizationInvalidBitmask<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, + pub expected_int_bits: u64, + pub expected_bytes: u64, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_simd_shuffle, code = "E0511")] +pub(crate) struct InvalidMonomorphizationSimdShuffle<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_expected_simd, code = "E0511")] +pub(crate) struct InvalidMonomorphizationExpectedSimd<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub position: &'a str, + pub found_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_mask_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationMaskType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_return_length, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnLength<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_len: u64, + pub ret_ty: Ty<'a>, + pub out_len: u64, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_return_length_input_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnLengthInputType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_len: u64, + pub in_ty: Ty<'a>, + pub ret_ty: Ty<'a>, + pub out_len: u64, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_return_element, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnElement<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_elem: Ty<'a>, + pub in_ty: Ty<'a>, + pub ret_ty: Ty<'a>, + pub out_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_return_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_elem: Ty<'a>, + pub in_ty: Ty<'a>, + pub ret_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_inserted_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationInsertedType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_elem: Ty<'a>, + pub in_ty: Ty<'a>, + pub out_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_return_integer_type, code = "E0511")] +pub(crate) struct InvalidMonomorphizationReturnIntegerType<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub ret_ty: Ty<'a>, + pub out_ty: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_mismatched_lengths, code = "E0511")] +pub(crate) struct InvalidMonomorphizationMismatchedLengths { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub m_len: u64, + pub v_len: u64, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_unsupported_cast, code = "E0511")] +pub(crate) struct InvalidMonomorphizationUnsupportedCast<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_ty: Ty<'a>, + pub in_elem: Ty<'a>, + pub ret_ty: Ty<'a>, + pub out_elem: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::invalid_monomorphization_unsupported_operation, code = "E0511")] +pub(crate) struct InvalidMonomorphizationUnsupportedOperation<'a> { + #[primary_span] + pub span: Span, + pub name: Symbol, + pub in_ty: Ty<'a>, + pub in_elem: Ty<'a>, +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::linkage_const_or_mut_type)] +pub(crate) struct LinkageConstOrMutType { + #[primary_span] + pub span: Span +} + +#[derive(Diagnostic)] +#[diag(codegen_gcc::lto_not_supported)] +pub(crate) struct LTONotSupported; + +#[derive(Diagnostic)] +#[diag(codegen_gcc::unwinding_inline_asm)] +pub(crate) struct UnwindingInlineAsm { + #[primary_span] + pub span: Span +} diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 02cedd4646b..49be6c649e6 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -4,7 +4,7 @@ mod simd; use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp, FunctionType}; use rustc_codegen_ssa::MemFlags; use rustc_codegen_ssa::base::wants_msvc_seh; -use rustc_codegen_ssa::common::{IntPredicate, span_invalid_monomorphization_error}; +use rustc_codegen_ssa::common::IntPredicate; use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue}; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{ArgAbiMethods, BaseTypeMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods}; @@ -20,6 +20,7 @@ use crate::abi::GccType; use crate::builder::Builder; use crate::common::{SignType, TypeReflection}; use crate::context::CodegenCx; +use crate::errors::InvalidMonomorphizationBasicInteger; use crate::type_of::LayoutGccExt; use crate::intrinsic::simd::generic_simd_intrinsic; @@ -99,7 +100,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { _ if simple.is_some() => { // FIXME(antoyo): remove this cast when the API supports function. let func = unsafe { std::mem::transmute(simple.expect("simple")) }; - self.call(self.type_void(), func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None) + self.call(self.type_void(), None, func, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None) }, sym::likely => { self.expect(args[0].immediate(), true) @@ -242,15 +243,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { _ => bug!(), }, None => { - span_invalid_monomorphization_error( - tcx.sess, - span, - &format!( - "invalid monomorphization of `{}` intrinsic: \ - expected basic integer type, found `{}`", - name, ty - ), - ); + tcx.sess.emit_err(InvalidMonomorphizationBasicInteger { span, name, ty }); return; } } @@ -348,7 +341,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { fn abort(&mut self) { let func = self.context.get_builtin_function("abort"); let func: RValue<'gcc> = unsafe { std::mem::transmute(func) }; - self.call(self.type_void(), func, &[], None); + self.call(self.type_void(), None, func, &[], None); } fn assume(&mut self, value: Self::Value) { @@ -1131,7 +1124,7 @@ fn try_intrinsic<'gcc, 'tcx>(bx: &mut Builder<'_, 'gcc, 'tcx>, try_func: RValue< // NOTE: the `|| true` here is to use the panic=abort strategy with panic=unwind too if bx.sess().panic_strategy() == PanicStrategy::Abort || true { // TODO(bjorn3): Properly implement unwinding and remove the `|| true` once this is done. - bx.call(bx.type_void(), try_func, &[data], None); + bx.call(bx.type_void(), None, try_func, &[data], None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. let ret_align = bx.tcx.data_layout.i32_align.abi; diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs index 2401f335018..12e416f62a4 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs @@ -2,7 +2,7 @@ use std::cmp::Ordering; use gccjit::{BinaryOp, RValue, Type, ToRValue}; use rustc_codegen_ssa::base::compare_simd_types; -use rustc_codegen_ssa::common::{TypeKind, span_invalid_monomorphization_error}; +use rustc_codegen_ssa::common::TypeKind; use rustc_codegen_ssa::mir::operand::OperandRef; use rustc_codegen_ssa::mir::place::PlaceRef; use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods}; @@ -14,43 +14,48 @@ use rustc_span::{Span, Symbol, sym}; use rustc_target::abi::Align; use crate::builder::Builder; +use crate::errors::{ + InvalidMonomorphizationInvalidFloatVector, + InvalidMonomorphizationNotFloat, + InvalidMonomorphizationUnrecognized, + InvalidMonomorphizationExpectedSignedUnsigned, + InvalidMonomorphizationUnsupportedElement, + InvalidMonomorphizationInvalidBitmask, + InvalidMonomorphizationSimdShuffle, + InvalidMonomorphizationExpectedSimd, + InvalidMonomorphizationMaskType, + InvalidMonomorphizationReturnLength, + InvalidMonomorphizationReturnLengthInputType, + InvalidMonomorphizationReturnElement, + InvalidMonomorphizationReturnType, + InvalidMonomorphizationInsertedType, + InvalidMonomorphizationReturnIntegerType, + InvalidMonomorphizationMismatchedLengths, + InvalidMonomorphizationUnsupportedCast, + InvalidMonomorphizationUnsupportedOperation +}; use crate::intrinsic; pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, name: Symbol, callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx, RValue<'gcc>>], ret_ty: Ty<'tcx>, llret_ty: Type<'gcc>, span: Span) -> Result<RValue<'gcc>, ()> { // macros for error handling: - #[allow(unused_macro_rules)] - macro_rules! emit_error { - ($msg: tt) => { - emit_error!($msg, ) - }; - ($msg: tt, $($fmt: tt)*) => { - span_invalid_monomorphization_error( - bx.sess(), span, - &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg), - name, $($fmt)*)); - } - } - macro_rules! return_error { - ($($fmt: tt)*) => { + ($err:expr) => { { - emit_error!($($fmt)*); + bx.sess().emit_err($err); return Err(()); } } } - macro_rules! require { - ($cond: expr, $($fmt: tt)*) => { + ($cond:expr, $err:expr) => { if !$cond { - return_error!($($fmt)*); + return_error!($err); } - }; + } } - macro_rules! require_simd { ($ty: expr, $position: expr) => { - require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty) + require!($ty.is_simd(), InvalidMonomorphizationExpectedSimd { span, name, position: $position, found_ty: $ty }) }; } @@ -82,10 +87,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, bx.load(int_ty, ptr, Align::ONE) } _ => return_error!( - "invalid bitmask `{}`, expected `u{}` or `[u8; {}]`", - mask_ty, - expected_int_bits, - expected_bytes + InvalidMonomorphizationInvalidBitmask { span, name, ty: mask_ty, expected_int_bits, expected_bytes } ), }; @@ -127,18 +129,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ - found `{}` with length {}", - in_len, - in_ty, - ret_ty, - out_len + InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len } ); require!( bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer, - "expected return type with integer elements, found `{}` with non-integer `{}`", - ret_ty, - out_ty + InvalidMonomorphizationReturnIntegerType {span, name, ret_ty, out_ty} ); return Ok(compare_simd_types( @@ -163,8 +158,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, }) } _ => return_error!( - "simd_shuffle index must be an array of `u32`, got `{}`", - args[2].layout.ty + InvalidMonomorphizationSimdShuffle { span, name, ty: args[2].layout.ty } ), } } @@ -179,19 +173,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx()); require!( out_len == n, - "expected return type of length {}, found `{}` with length {}", - n, - ret_ty, - out_len + InvalidMonomorphizationReturnLength { span, name, in_len: n, ret_ty, out_len } ); require!( in_elem == out_ty, - "expected return element type `{}` (element of input `{}`), \ - found `{}` with element type `{}`", - in_elem, - in_ty, - ret_ty, - out_ty + InvalidMonomorphizationReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty } ); let vector = args[2].immediate(); @@ -207,10 +193,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, if name == sym::simd_insert { require!( in_elem == arg_tys[2], - "expected inserted type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - arg_tys[2] + InvalidMonomorphizationInsertedType { span, name, in_elem, in_ty, out_ty: arg_tys[2] } ); let vector = args[0].immediate(); let index = args[1].immediate(); @@ -263,10 +246,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, if name == sym::simd_extract { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty } ); let vector = args[0].immediate(); return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue()); @@ -279,13 +259,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx()); require!( m_len == v_len, - "mismatched lengths: mask length `{}` != other vector length `{}`", - m_len, - v_len + InvalidMonomorphizationMismatchedLengths { span, name, m_len, v_len } ); match m_elem_ty.kind() { ty::Int(_) => {} - _ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty), + _ => return_error!(InvalidMonomorphizationMaskType { span, name, ty: m_elem_ty }), } return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate())); } @@ -295,12 +273,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx()); require!( in_len == out_len, - "expected return type with length {} (same as input type `{}`), \ - found `{}` with length {}", - in_len, - in_ty, - ret_ty, - out_len + InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len } ); // casting cares about nominal type, not just structural type if in_elem == out_elem { @@ -412,13 +385,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, } _ => { /* Unsupported. Fallthrough. */ } } - require!( - false, - "unsupported cast from `{}` with element `{}` to `{}` with element `{}`", - in_ty, - in_elem, - ret_ty, - out_elem + return_error!( + InvalidMonomorphizationUnsupportedCast { span, name, in_ty, in_elem, ret_ty, out_elem } ); } @@ -431,10 +399,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, })* _ => {}, } - require!(false, - "unsupported operation on `{}` with element `{}`", - in_ty, - in_elem) + return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem }) })* } } @@ -448,23 +413,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, span: Span, args: &[OperandRef<'tcx, RValue<'gcc>>], ) -> Result<RValue<'gcc>, ()> { - macro_rules! emit_error { - ($msg: tt, $($fmt: tt)*) => { - span_invalid_monomorphization_error( - bx.sess(), span, - &format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg), - name, $($fmt)*)); - } - } macro_rules! return_error { - ($($fmt: tt)*) => { + ($err:expr) => { { - emit_error!($($fmt)*); + bx.sess().emit_err($err); return Err(()); } } } - let (elem_ty_str, elem_ty) = if let ty::Float(f) = in_elem.kind() { let elem_ty = bx.cx.type_float_from_ty(*f); @@ -472,16 +428,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, 32 => ("f32", elem_ty), 64 => ("f64", elem_ty), _ => { - return_error!( - "unsupported element type `{}` of floating-point vector `{}`", - f.name_str(), - in_ty - ); + return_error!(InvalidMonomorphizationInvalidFloatVector { span, name, elem_ty: f.name_str(), vec_ty: in_ty }); } } } else { - return_error!("`{}` is not a floating-point type", in_ty); + return_error!(InvalidMonomorphizationNotFloat { span, name, ty: in_ty }); }; let vec_ty = bx.cx.type_vector(elem_ty, in_len); @@ -504,12 +456,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)), sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)), sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)), - _ => return_error!("unrecognized intrinsic `{}`", name), + _ => return_error!(InvalidMonomorphizationUnrecognized { span, name }) }; let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str); let function = intrinsic::llvm::intrinsic(llvm_name, &bx.cx); let function: RValue<'gcc> = unsafe { std::mem::transmute(function) }; - let c = bx.call(fn_ty, function, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None); + let c = bx.call(fn_ty, None, function, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None); Ok(c) } @@ -557,10 +509,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, })* _ => {}, } - require!(false, - "unsupported operation on `{}` with element `{}`", - in_ty, - in_elem) + return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem }) })* } } @@ -579,12 +528,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)), ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_uint_from_ty(i)), _ => { - return_error!( - "expected element type `{}` of vector type `{}` \ - to be a signed or unsigned integer type", - arg_tys[0].simd_size_and_type(bx.tcx()).1, - arg_tys[0] - ); + return_error!(InvalidMonomorphizationExpectedSignedUnsigned { + span, + name, + elem_ty: arg_tys[0].simd_size_and_type(bx.tcx()).1, + vec_ty: arg_tys[0], + }); } }; let builtin_name = @@ -617,10 +566,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, if name == sym::$name { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty } ); return match in_elem.kind() { ty::Int(_) | ty::Uint(_) => { @@ -644,13 +590,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op)) } } - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, - in_ty, - in_elem, - ret_ty - ), + _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }), }; } }; @@ -676,20 +616,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, if name == sym::$name { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty } ); return match in_elem.kind() { ty::Int(_) | ty::Uint(_) | ty::Float(_) => Ok(bx.$reduction(args[0].immediate())), - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, - in_ty, - in_elem, - ret_ty - ), + _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }), }; } }; @@ -704,22 +635,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, let input = if !$boolean { require!( ret_ty == in_elem, - "expected return type `{}` (element of input `{}`), found `{}`", - in_elem, - in_ty, - ret_ty + InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty } ); args[0].immediate() } else { match in_elem.kind() { ty::Int(_) | ty::Uint(_) => {} - _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, - in_ty, - in_elem, - ret_ty - ), + _ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }), } // boolean reductions operate on vectors of i1s: @@ -733,11 +655,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) }) } _ => return_error!( - "unsupported {} from `{}` with element `{}` to `{}`", - sym::$name, - in_ty, - in_elem, - ret_ty + InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty } ), }; } diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 223466fb9b5..accd02ab002 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -18,6 +18,8 @@ #![recursion_limit="256"] #![warn(rust_2018_idioms)] #![warn(unused_lifetimes)] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] extern crate rustc_apfloat; extern crate rustc_ast; @@ -25,6 +27,7 @@ extern crate rustc_codegen_ssa; extern crate rustc_data_structures; extern crate rustc_errors; extern crate rustc_hir; +extern crate rustc_macros; extern crate rustc_metadata; extern crate rustc_middle; extern crate rustc_session; @@ -50,6 +53,7 @@ mod context; mod coverageinfo; mod debuginfo; mod declare; +mod errors; mod int; mod intrinsic; mod mono_item; @@ -59,6 +63,7 @@ mod type_of; use std::any::Any; use std::sync::{Arc, Mutex}; +use crate::errors::LTONotSupported; use gccjit::{Context, OptimizationLevel, CType}; use rustc_ast::expand::allocator::AllocatorKind; use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen}; @@ -97,7 +102,7 @@ pub struct GccCodegenBackend { impl CodegenBackend for GccCodegenBackend { fn init(&self, sess: &Session) { if sess.lto() != Lto::No { - sess.warn("LTO is not supported. You may get a linker error."); + sess.emit_warning(LTONotSupported {}); } let temp_dir = TempDir::new().expect("cannot create temporary directory"); @@ -166,15 +171,6 @@ impl ExtraBackendMethods for GccCodegenBackend { Ok(()) }) } - - fn target_cpu<'b>(&self, _sess: &'b Session) -> &'b str { - unimplemented!(); - } - - fn tune_cpu<'b>(&self, _sess: &'b Session) -> Option<&'b str> { - None - // TODO(antoyo) - } } pub struct ModuleBuffer; @@ -205,7 +201,6 @@ impl WriteBackendMethods for GccCodegenBackend { type Module = GccContext; type TargetMachine = (); type ModuleBuffer = ModuleBuffer; - type Context = (); type ThinData = (); type ThinBuffer = ThinBuffer; diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index a068aa2ec62..df4a9fea19d 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -34,3 +34,4 @@ rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } +tempfile = "3.2.0" diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index 26f5225f6b4..d478efc863a 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -592,10 +592,6 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { - fn apply_attrs_callsite(&mut self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, callsite: Self::Value) { - fn_abi.apply_attrs_callsite(self, callsite) - } - fn get_param(&mut self, index: usize) -> Self::Value { llvm::get_param(self.llfn(), index as c_uint) } diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 5202ac697e9..e723187ff1f 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -430,9 +430,9 @@ pub(crate) fn inline_asm_call<'ll>( ); let call = if let Some((dest, catch, funclet)) = dest_catch_funclet { - bx.invoke(fty, v, inputs, dest, catch, funclet) + bx.invoke(fty, None, v, inputs, dest, catch, funclet) } else { - bx.call(fty, v, inputs, None) + bx.call(fty, None, v, inputs, None) }; // Store mark in a metadata node so we can map LLVM errors diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index 38a366095b4..20a063f80fd 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -2,16 +2,20 @@ use std::env; use std::ffi::{CStr, CString, OsString}; -use std::io; +use std::fs; +use std::io::{self, Write}; use std::mem; use std::path::{Path, PathBuf}; use std::ptr; use std::str; +use object::read::macho::FatArch; + use crate::common; use crate::llvm::archive_ro::{ArchiveRO, Child}; use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport}; use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; +use rustc_data_structures::memmap::Mmap; use rustc_session::cstore::DllImport; use rustc_session::Session; @@ -53,13 +57,70 @@ fn llvm_machine_type(cpu: &str) -> LLVMMachineType { } } +fn try_filter_fat_archs( + archs: object::read::Result<&[impl FatArch]>, + target_arch: object::Architecture, + archive_path: &Path, + archive_map_data: &[u8], +) -> io::Result<Option<PathBuf>> { + let archs = archs.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; + + let desired = match archs.iter().filter(|a| a.architecture() == target_arch).next() { + Some(a) => a, + None => return Ok(None), + }; + + let (mut new_f, extracted_path) = tempfile::Builder::new() + .suffix(archive_path.file_name().unwrap()) + .tempfile()? + .keep() + .unwrap(); + + new_f.write_all( + desired.data(archive_map_data).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?, + )?; + + Ok(Some(extracted_path)) +} + +fn try_extract_macho_fat_archive( + sess: &Session, + archive_path: &Path, +) -> io::Result<Option<PathBuf>> { + let archive_map = unsafe { Mmap::map(fs::File::open(&archive_path)?)? }; + let target_arch = match sess.target.arch.as_ref() { + "aarch64" => object::Architecture::Aarch64, + "x86_64" => object::Architecture::X86_64, + _ => return Ok(None), + }; + + match object::macho::FatHeader::parse(&*archive_map) { + Ok(h) if h.magic.get(object::endian::BigEndian) == object::macho::FAT_MAGIC => { + let archs = object::macho::FatHeader::parse_arch32(&*archive_map); + try_filter_fat_archs(archs, target_arch, archive_path, &*archive_map) + } + Ok(h) if h.magic.get(object::endian::BigEndian) == object::macho::FAT_MAGIC_64 => { + let archs = object::macho::FatHeader::parse_arch64(&*archive_map); + try_filter_fat_archs(archs, target_arch, archive_path, &*archive_map) + } + // Not a FatHeader at all, just return None. + _ => Ok(None), + } +} + impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { fn add_archive( &mut self, archive: &Path, skip: Box<dyn FnMut(&str) -> bool + 'static>, ) -> io::Result<()> { - let archive_ro = match ArchiveRO::open(archive) { + let mut archive = archive.to_path_buf(); + if self.sess.target.llvm_target.contains("-apple-macosx") { + if let Some(new_archive) = try_extract_macho_fat_archive(&self.sess, &archive)? { + archive = new_archive + } + } + let archive_ro = match ArchiveRO::open(&archive) { Ok(ar) => ar, Err(e) => return Err(io::Error::new(io::ErrorKind::Other, e)), }; @@ -67,7 +128,7 @@ impl<'a> ArchiveBuilder<'a> for LlvmArchiveBuilder<'a> { return Ok(()); } self.additions.push(Addition::Archive { - path: archive.to_path_buf(), + path: archive, archive: archive_ro, skip: Box::new(skip), }); diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 86f92dc0239..5b2bbdb4bde 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -19,6 +19,8 @@ use crate::context::CodegenCx; use crate::llvm; use crate::value::Value; +use cstr::cstr; + use rustc_codegen_ssa::base::maybe_create_entry_wrapper; use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::*; @@ -107,11 +109,14 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen } // Create the llvm.used and llvm.compiler.used variables. - if !cx.used_statics().borrow().is_empty() { - cx.create_used_variable() + if !cx.used_statics.borrow().is_empty() { + cx.create_used_variable_impl(cstr!("llvm.used"), &*cx.used_statics.borrow()); } - if !cx.compiler_used_statics().borrow().is_empty() { - cx.create_compiler_used_variable() + if !cx.compiler_used_statics.borrow().is_empty() { + cx.create_used_variable_impl( + cstr!("llvm.compiler.used"), + &*cx.compiler_used_statics.borrow(), + ); } // Run replace-all-uses-with for statics that need it. This must diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 59b1c7fb5db..fca43a0d86d 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1,3 +1,4 @@ +use crate::abi::FnAbiLlvmExt; use crate::attributes; use crate::common::Funclet; use crate::context::CodegenCx; @@ -214,6 +215,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn invoke( &mut self, llty: &'ll Type, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: &'ll Value, args: &[&'ll Value], then: &'ll BasicBlock, @@ -226,7 +228,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let bundle = funclet.map(|funclet| funclet.bundle()); let bundle = bundle.as_ref().map(|b| &*b.raw); - unsafe { + let invoke = unsafe { llvm::LLVMRustBuildInvoke( self.llbuilder, llty, @@ -238,7 +240,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { bundle, UNNAMED, ) + }; + if let Some(fn_abi) = fn_abi { + fn_abi.apply_attrs_callsite(self, invoke); } + invoke } fn unreachable(&mut self) { @@ -405,20 +411,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value { let mut bx = Builder::with_cx(self.cx); bx.position_at_start(unsafe { llvm::LLVMGetFirstBasicBlock(self.llfn()) }); - bx.dynamic_alloca(ty, align) - } - - fn dynamic_alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value { unsafe { - let alloca = llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED); + let alloca = llvm::LLVMBuildAlloca(bx.llbuilder, ty, UNNAMED); llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); alloca } } - fn array_alloca(&mut self, ty: &'ll Type, len: &'ll Value, align: Align) -> &'ll Value { + fn byte_array_alloca(&mut self, len: &'ll Value, align: Align) -> &'ll Value { unsafe { - let alloca = llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, UNNAMED); + let alloca = + llvm::LLVMBuildArrayAlloca(self.llbuilder, self.cx().type_i8(), len, UNNAMED); llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); alloca } @@ -1145,6 +1148,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn call( &mut self, llty: &'ll Type, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: &'ll Value, args: &[&'ll Value], funclet: Option<&Funclet<'ll>>, @@ -1155,7 +1159,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { let bundle = funclet.map(|funclet| funclet.bundle()); let bundle = bundle.as_ref().map(|b| &*b.raw); - unsafe { + let call = unsafe { llvm::LLVMRustBuildCall( self.llbuilder, llty, @@ -1164,7 +1168,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { args.len() as c_uint, bundle, ) + }; + if let Some(fn_abi) = fn_abi { + fn_abi.apply_attrs_callsite(self, call); } + call } fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value { @@ -1397,7 +1405,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { pub(crate) fn call_intrinsic(&mut self, intrinsic: &str, args: &[&'ll Value]) -> &'ll Value { let (ty, f) = self.cx.get_intrinsic(intrinsic); - self.call(ty, f, args, None) + self.call(ty, None, f, args, None) } fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) { @@ -1459,7 +1467,7 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> { format!("llvm.{}.sat.i{}.f{}", instr, int_width, float_width) }; let f = self.declare_cfn(&name, llvm::UnnamedAddr::No, self.type_func(&[src_ty], dest_ty)); - self.call(self.type_func(&[src_ty], dest_ty), f, &[val], None) + self.call(self.type_func(&[src_ty], dest_ty), None, f, &[val], None) } pub(crate) fn landing_pad( diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 67ffc7cb951..79ddfd884df 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -154,6 +154,11 @@ pub unsafe fn create_module<'ll>( target_data_layout = target_data_layout.replace("-p10:8:8-p20:8:8", ""); } } + if llvm_version < (16, 0, 0) { + if sess.target.arch == "s390x" { + target_data_layout = target_data_layout.replace("-v128:64", ""); + } + } // Ensure the data-layout values hardcoded remain the defaults. if sess.target.is_builtin { @@ -453,7 +458,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { self.coverage_cx.as_ref() } - fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) { + pub(crate) fn create_used_variable_impl(&self, name: &'static CStr, values: &[&'ll Value]) { let section = cstr!("llvm.metadata"); let array = self.const_array(self.type_ptr_to(self.type_i8()), values); @@ -551,14 +556,6 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { self.codegen_unit } - fn used_statics(&self) -> &RefCell<Vec<&'ll Value>> { - &self.used_statics - } - - fn compiler_used_statics(&self) -> &RefCell<Vec<&'ll Value>> { - &self.compiler_used_statics - } - fn set_frame_pointer_type(&self, llfn: &'ll Value) { if let Some(attr) = attributes::frame_pointer_type_attr(self) { attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[attr]); @@ -572,17 +569,6 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &attrs); } - fn create_used_variable(&self) { - self.create_used_variable_impl(cstr!("llvm.used"), &*self.used_statics.borrow()); - } - - fn create_compiler_used_variable(&self) { - self.create_used_variable_impl( - cstr!("llvm.compiler.used"), - &*self.compiler_used_statics.borrow(), - ); - } - fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> { if self.get_declared_value("main").is_none() { Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type)) diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index 0f663a26732..f79ef11720d 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -32,6 +32,7 @@ fn declare_raw_fn<'ll>( name: &str, callconv: llvm::CallConv, unnamed: llvm::UnnamedAddr, + visibility: llvm::Visibility, ty: &'ll Type, ) -> &'ll Value { debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty); @@ -41,6 +42,7 @@ fn declare_raw_fn<'ll>( llvm::SetFunctionCallConv(llfn, callconv); llvm::SetUnnamedAddress(llfn, unnamed); + llvm::set_visibility(llfn, visibility); let mut attrs = SmallVec::<[_; 4]>::new(); @@ -78,7 +80,14 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { unnamed: llvm::UnnamedAddr, fn_type: &'ll Type, ) -> &'ll Value { - declare_raw_fn(self, name, llvm::CCallConv, unnamed, fn_type) + // Declare C ABI functions with the visibility used by C by default. + let visibility = if self.tcx.sess.target.default_hidden_visibility { + llvm::Visibility::Hidden + } else { + llvm::Visibility::Default + }; + + declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type) } /// Declare a Rust function. @@ -95,6 +104,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { name, fn_abi.llvm_cconv(), llvm::UnnamedAddr::Global, + llvm::Visibility::Default, fn_abi.llvm_type(self), ); fn_abi.apply_attrs_llfn(self, llfn); diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index a640de42a6a..825011941a2 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -108,6 +108,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { let (simple_ty, simple_fn) = simple.unwrap(); self.call( simple_ty, + None, simple_fn, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None, @@ -435,7 +436,7 @@ fn try_intrinsic<'ll>( ) { if bx.sess().panic_strategy() == PanicStrategy::Abort { let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void()); - bx.call(try_func_ty, try_func, &[data], None); + bx.call(try_func_ty, None, try_func, &[data], None); // Return 0 unconditionally from the intrinsic call; // we can never unwind. let ret_align = bx.tcx().data_layout.i32_align.abi; @@ -534,7 +535,7 @@ fn codegen_msvc_try<'ll>( let ptr_align = bx.tcx().data_layout.pointer_align.abi; let slot = bx.alloca(bx.type_i8p(), ptr_align); let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void()); - bx.invoke(try_func_ty, try_func, &[data], normal, catchswitch, None); + bx.invoke(try_func_ty, None, try_func, &[data], normal, catchswitch, None); bx.switch_to_block(normal); bx.ret(bx.const_i32(0)); @@ -578,7 +579,7 @@ fn codegen_msvc_try<'ll>( let funclet = bx.catch_pad(cs, &[tydesc, flags, slot]); let ptr = bx.load(bx.type_i8p(), slot, ptr_align); let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void()); - bx.call(catch_ty, catch_func, &[data, ptr], Some(&funclet)); + bx.call(catch_ty, None, catch_func, &[data, ptr], Some(&funclet)); bx.catch_ret(&funclet, caught); // The flag value of 64 indicates a "catch-all". @@ -586,7 +587,7 @@ fn codegen_msvc_try<'ll>( let flags = bx.const_i32(64); let null = bx.const_null(bx.type_i8p()); let funclet = bx.catch_pad(cs, &[null, flags, null]); - bx.call(catch_ty, catch_func, &[data, null], Some(&funclet)); + bx.call(catch_ty, None, catch_func, &[data, null], Some(&funclet)); bx.catch_ret(&funclet, caught); bx.switch_to_block(caught); @@ -595,7 +596,7 @@ fn codegen_msvc_try<'ll>( // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None); + let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None); let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -638,7 +639,7 @@ fn codegen_gnu_try<'ll>( let data = llvm::get_param(bx.llfn(), 1); let catch_func = llvm::get_param(bx.llfn(), 2); let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void()); - bx.invoke(try_func_ty, try_func, &[data], then, catch, None); + bx.invoke(try_func_ty, None, try_func, &[data], then, catch, None); bx.switch_to_block(then); bx.ret(bx.const_i32(0)); @@ -656,13 +657,13 @@ fn codegen_gnu_try<'ll>( bx.add_clause(vals, tydesc); let ptr = bx.extract_value(vals, 0); let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void()); - bx.call(catch_ty, catch_func, &[data, ptr], None); + bx.call(catch_ty, None, catch_func, &[data, ptr], None); bx.ret(bx.const_i32(1)); }); // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None); + let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None); let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -702,7 +703,7 @@ fn codegen_emcc_try<'ll>( let data = llvm::get_param(bx.llfn(), 1); let catch_func = llvm::get_param(bx.llfn(), 2); let try_func_ty = bx.type_func(&[bx.type_i8p()], bx.type_void()); - bx.invoke(try_func_ty, try_func, &[data], then, catch, None); + bx.invoke(try_func_ty, None, try_func, &[data], then, catch, None); bx.switch_to_block(then); bx.ret(bx.const_i32(0)); @@ -741,13 +742,13 @@ fn codegen_emcc_try<'ll>( let catch_data = bx.bitcast(catch_data, bx.type_i8p()); let catch_ty = bx.type_func(&[bx.type_i8p(), bx.type_i8p()], bx.type_void()); - bx.call(catch_ty, catch_func, &[data, catch_data], None); + bx.call(catch_ty, None, catch_func, &[data, catch_data], None); bx.ret(bx.const_i32(1)); }); // Note that no invoke is used here because by definition this function // can't panic (that's what it's catching). - let ret = bx.call(llty, llfn, &[try_func, data, catch_func], None); + let ret = bx.call(llty, None, llfn, &[try_func, data, catch_func], None); let i32_align = bx.tcx().data_layout.i32_align.abi; bx.store(ret, dest, i32_align); } @@ -1217,8 +1218,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>( }; let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str); let f = bx.declare_cfn(llvm_name, llvm::UnnamedAddr::No, fn_ty); - let c = - bx.call(fn_ty, f, &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), None); + let c = bx.call( + fn_ty, + None, + f, + &args.iter().map(|arg| arg.immediate()).collect::<Vec<_>>(), + None, + ); Ok(c) } @@ -1417,8 +1423,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>( llvm_elem_vec_ty, ); let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); - let v = - bx.call(fn_ty, f, &[args[1].immediate(), alignment, mask, args[0].immediate()], None); + let v = bx.call( + fn_ty, + None, + f, + &[args[1].immediate(), alignment, mask, args[0].immediate()], + None, + ); return Ok(v); } @@ -1543,8 +1554,13 @@ fn generic_simd_intrinsic<'ll, 'tcx>( let fn_ty = bx.type_func(&[llvm_elem_vec_ty, llvm_pointer_vec_ty, alignment_ty, mask_ty], ret_t); let f = bx.declare_cfn(&llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); - let v = - bx.call(fn_ty, f, &[args[0].immediate(), args[1].immediate(), alignment, mask], None); + let v = bx.call( + fn_ty, + None, + f, + &[args[0].immediate(), args[1].immediate(), alignment, mask], + None, + ); return Ok(v); } @@ -1992,7 +2008,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#, let fn_ty = bx.type_func(&[vec_ty, vec_ty], vec_ty); let f = bx.declare_cfn(llvm_intrinsic, llvm::UnnamedAddr::No, fn_ty); - let v = bx.call(fn_ty, f, &[lhs, rhs], None); + let v = bx.call(fn_ty, None, f, &[lhs, rhs], None); return Ok(v); } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 15bfa843046..89c7e51d09e 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -131,12 +131,6 @@ impl ExtraBackendMethods for LlvmCodegenBackend { ) -> TargetMachineFactoryFn<Self> { back::write::target_machine_factory(sess, optlvl, target_features) } - fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str { - llvm_util::target_cpu(sess) - } - fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str> { - llvm_util::tune_cpu(sess) - } fn spawn_thread<F, T>(time_trace: bool, f: F) -> std::thread::JoinHandle<T> where @@ -170,7 +164,6 @@ impl ExtraBackendMethods for LlvmCodegenBackend { impl WriteBackendMethods for LlvmCodegenBackend { type Module = ModuleLlvm; type ModuleBuffer = back::lto::ModuleBuffer; - type Context = llvm::Context; type TargetMachine = &'static mut llvm::TargetMachine; type ThinData = back::lto::ThinData; type ThinBuffer = back::lto::ThinBuffer; diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index e0bd7a33f73..2cd746ccb6a 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1180,22 +1180,19 @@ impl<'a> WasmLd<'a> { // sharing memory and instantiating the module multiple times. As a // result if it were exported then we'd just have no sharing. // - // * `--export=__wasm_init_memory` - when using `--passive-segments` the - // linker will synthesize this function, and so we need to make sure - // that our usage of `--export` below won't accidentally cause this - // function to get deleted. - // - // * `--export=*tls*` - when `#[thread_local]` symbols are used these - // symbols are how the TLS segments are initialized and configured. + // On wasm32-unknown-unknown, we also export symbols for glue code to use: + // * `--export=*tls*` - when `#[thread_local]` symbols are used these + // symbols are how the TLS segments are initialized and configured. if sess.target_features.contains(&sym::atomics) { cmd.arg("--shared-memory"); cmd.arg("--max-memory=1073741824"); cmd.arg("--import-memory"); - cmd.arg("--export=__wasm_init_memory"); - cmd.arg("--export=__wasm_init_tls"); - cmd.arg("--export=__tls_size"); - cmd.arg("--export=__tls_align"); - cmd.arg("--export=__tls_base"); + if sess.target.os == "unknown" { + cmd.arg("--export=__wasm_init_tls"); + cmd.arg("--export=__tls_size"); + cmd.arg("--export=__tls_align"); + cmd.arg("--export=__tls_base"); + } } WasmLd { cmd, sess } } @@ -1320,10 +1317,12 @@ impl<'a> Linker for WasmLd<'a> { // LLD will hide these otherwise-internal symbols since it only exports // symbols explicitly passed via the `--export` flags above and hides all - // others. Various bits and pieces of tooling use this, so be sure these - // symbols make their way out of the linker as well. - self.cmd.arg("--export=__heap_base"); - self.cmd.arg("--export=__data_end"); + // others. Various bits and pieces of wasm32-unknown-unknown tooling use + // this, so be sure these symbols make their way out of the linker as well. + if self.sess.target.os == "unknown" { + self.cmd.arg("--export=__heap_base"); + self.cmd.arg("--export=__data_end"); + } } fn subsystem(&mut self, _subsystem: &str) {} diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 35fd86c1735..cb5436fd61a 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -474,7 +474,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( (rust_main, start_ty, vec![arg_argc, arg_argv]) }; - let result = bx.call(start_ty, start_fn, &args, None); + let result = bx.call(start_ty, None, start_fn, &args, None); let cast = bx.intcast(result, cx.type_int(), true); bx.ret(cast); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index a6b226ef720..bd4f0cac7eb 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -162,9 +162,15 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { } else { fx.unreachable_block() }; - let invokeret = - bx.invoke(fn_ty, fn_ptr, &llargs, ret_llbb, unwind_block, self.funclet(fx)); - bx.apply_attrs_callsite(&fn_abi, invokeret); + let invokeret = bx.invoke( + fn_ty, + Some(&fn_abi), + fn_ptr, + &llargs, + ret_llbb, + unwind_block, + self.funclet(fx), + ); if fx.mir[self.bb].is_cleanup { bx.do_not_inline(invokeret); } @@ -178,8 +184,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> { fx.store_return(bx, ret_dest, &fn_abi.ret, invokeret); } } else { - let llret = bx.call(fn_ty, fn_ptr, &llargs, self.funclet(fx)); - bx.apply_attrs_callsite(&fn_abi, llret); + let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &llargs, self.funclet(fx)); if fx.mir[self.bb].is_cleanup { // Cleanup is always the cold path. Don't inline // drop glue. Also, when there is a deeply-nested @@ -1533,8 +1538,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let (fn_abi, fn_ptr) = common::build_langcall(&bx, None, LangItem::PanicNoUnwind); let fn_ty = bx.fn_decl_backend_type(&fn_abi); - let llret = bx.call(fn_ty, fn_ptr, &[], None); - bx.apply_attrs_callsite(&fn_abi, llret); + let llret = bx.call(fn_ty, Some(&fn_abi), fn_ptr, &[], None); bx.do_not_inline(llret); bx.unreachable(); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 37b1e036247..e6ba642a7ed 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -352,7 +352,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> { // Allocate an appropriate region on the stack, and copy the value into it let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); - let lldst = bx.array_alloca(bx.cx().type_i8(), llsize, max_align); + let lldst = bx.byte_array_alloca(llsize, max_align); bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags); // Store the allocated region and the extra to the indirect place. diff --git a/compiler/rustc_codegen_ssa/src/traits/abi.rs b/compiler/rustc_codegen_ssa/src/traits/abi.rs index a00d78daf4d..60d8f2a9ece 100644 --- a/compiler/rustc_codegen_ssa/src/traits/abi.rs +++ b/compiler/rustc_codegen_ssa/src/traits/abi.rs @@ -1,8 +1,5 @@ use super::BackendTypes; -use rustc_middle::ty::Ty; -use rustc_target::abi::call::FnAbi; pub trait AbiBuilderMethods<'tcx>: BackendTypes { - fn apply_attrs_callsite(&mut self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, callsite: Self::Value); fn get_param(&mut self, index: usize) -> Self::Value; } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 779bd3ea278..87e347c61e2 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -134,8 +134,6 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se opt_level: config::OptLevel, target_features: &[String], ) -> TargetMachineFactoryFn<Self>; - fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str; - fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str>; fn spawn_thread<F, T>(_time_trace: bool, f: F) -> std::thread::JoinHandle<T> where diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs index 10cf8948b5a..01408f39fb3 100644 --- a/compiler/rustc_codegen_ssa/src/traits/builder.rs +++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs @@ -17,6 +17,7 @@ use crate::MemFlags; use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout}; use rustc_middle::ty::Ty; use rustc_span::Span; +use rustc_target::abi::call::FnAbi; use rustc_target::abi::{Abi, Align, Scalar, Size, WrappingRange}; use rustc_target::spec::HasTargetSpec; @@ -71,6 +72,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn invoke( &mut self, llty: Self::Type, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: Self::Value, args: &[Self::Value], then: Self::BasicBlock, @@ -133,8 +135,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value; fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value; - fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value; - fn array_alloca(&mut self, ty: Self::Type, len: Self::Value, align: Align) -> Self::Value; + fn byte_array_alloca(&mut self, len: Self::Value, align: Align) -> Self::Value; fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value; fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value; @@ -320,6 +321,7 @@ pub trait BuilderMethods<'a, 'tcx>: fn call( &mut self, llty: Self::Type, + fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, llfn: Self::Value, args: &[Self::Value], funclet: Option<&Self::Funclet>, diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs index 4266e42ec2b..04e2b8796c4 100644 --- a/compiler/rustc_codegen_ssa/src/traits/misc.rs +++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs @@ -15,12 +15,8 @@ pub trait MiscMethods<'tcx>: BackendTypes { fn eh_personality(&self) -> Self::Value; fn sess(&self) -> &Session; fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx>; - fn used_statics(&self) -> &RefCell<Vec<Self::Value>>; - fn compiler_used_statics(&self) -> &RefCell<Vec<Self::Value>>; fn set_frame_pointer_type(&self, llfn: Self::Function); fn apply_target_cpu_attr(&self, llfn: Self::Function); - fn create_used_variable(&self); - fn create_compiler_used_variable(&self); /// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists. fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function>; } diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index e54ec34f1ce..e0e8ffa89ed 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -9,7 +9,6 @@ pub trait WriteBackendMethods: 'static + Sized + Clone { type Module: Send + Sync; type TargetMachine; type ModuleBuffer: ModuleBufferMethods; - type Context: ?Sized; type ThinData: Send + Sync; type ThinBuffer: ThinBufferMethods; diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 09d53331b5b..09c92ae0361 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -233,10 +233,10 @@ impl<'tcx> ConstEvalErr<'tcx> { rustc_session::lint::builtin::CONST_ERR, hir_id, tcx.span, + message, |lint| { - let mut lint = lint.build(message); - finish(&mut lint, Some(err_msg)); - lint.emit(); + finish(lint, Some(err_msg)); + lint }, ); ErrorHandled::Linted diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 7a01b85381a..eeeb7d6d3e5 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -640,11 +640,17 @@ where // avoid force_allocation. let src = match self.read_immediate_raw(src)? { Ok(src_val) => { - assert!(!src.layout.is_unsized(), "cannot copy unsized immediates"); - assert!( - !dest.layout.is_unsized(), - "the src is sized, so the dest must also be sized" - ); + // FIXME(const_prop): Const-prop can possibly evaluate an + // unsized copy operation when it thinks that the type is + // actually sized, due to a trivially false where-clause + // predicate like `where Self: Sized` with `Self = dyn Trait`. + // See #102553 for an example of such a predicate. + if src.layout.is_unsized() { + throw_inval!(SizeOfUnsizedType(src.layout.ty)); + } + if dest.layout.is_unsized() { + throw_inval!(SizeOfUnsizedType(dest.layout.ty)); + } assert_eq!(src.layout.size, dest.layout.size); // Yay, we got a value that we can write directly. return if layout_compat { diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 7c4c7db1035..230f841cf4d 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -20,7 +20,7 @@ Rust MIR: a lowered representation of Rust. #![feature(trusted_step)] #![feature(try_blocks)] #![feature(yeet_expr)] -#![feature(is_some_with)] +#![feature(is_some_and)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] @@ -32,7 +32,6 @@ extern crate rustc_middle; pub mod const_eval; mod errors; pub mod interpret; -mod might_permit_raw_init; pub mod transform; pub mod util; @@ -61,7 +60,6 @@ pub fn provide(providers: &mut Providers) { const_eval::deref_mir_constant(tcx, param_env, value) }; providers.permits_uninit_init = - |tcx, ty| might_permit_raw_init::might_permit_raw_init(tcx, ty, InitKind::Uninit); - providers.permits_zero_init = - |tcx, ty| might_permit_raw_init::might_permit_raw_init(tcx, ty, InitKind::Zero); + |tcx, ty| util::might_permit_raw_init(tcx, ty, InitKind::UninitMitigated0x01Fill); + providers.permits_zero_init = |tcx, ty| util::might_permit_raw_init(tcx, ty, InitKind::Zero); } diff --git a/compiler/rustc_const_eval/src/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/might_permit_raw_init.rs deleted file mode 100644 index 37ffa19ccd6..00000000000 --- a/compiler/rustc_const_eval/src/might_permit_raw_init.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::const_eval::CompileTimeInterpreter; -use crate::interpret::{InterpCx, MemoryKind, OpTy}; -use rustc_middle::ty::layout::LayoutCx; -use rustc_middle::ty::{layout::TyAndLayout, ParamEnv, TyCtxt}; -use rustc_session::Limit; -use rustc_target::abi::InitKind; - -pub fn might_permit_raw_init<'tcx>( - tcx: TyCtxt<'tcx>, - ty: TyAndLayout<'tcx>, - kind: InitKind, -) -> bool { - let strict = tcx.sess.opts.unstable_opts.strict_init_checks; - - if strict { - let machine = CompileTimeInterpreter::new( - Limit::new(0), - /*can_access_statics:*/ false, - /*check_alignment:*/ true, - ); - - let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine); - - let allocated = cx - .allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap)) - .expect("OOM: failed to allocate for uninit check"); - - if kind == InitKind::Zero { - cx.write_bytes_ptr( - allocated.ptr, - std::iter::repeat(0_u8).take(ty.layout.size().bytes_usize()), - ) - .expect("failed to write bytes for zero valid check"); - } - - let ot: OpTy<'_, _> = allocated.into(); - - // Assume that if it failed, it's a validation failure. - cx.validate_operand(&ot).is_ok() - } else { - let layout_cx = LayoutCx { tcx, param_env: ParamEnv::reveal_all() }; - ty.might_permit_raw_init(&layout_cx, kind) - } -} diff --git a/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs new file mode 100644 index 00000000000..6ca71223391 --- /dev/null +++ b/compiler/rustc_const_eval/src/util/might_permit_raw_init.rs @@ -0,0 +1,151 @@ +use rustc_middle::ty::layout::{LayoutCx, LayoutOf, TyAndLayout}; +use rustc_middle::ty::{ParamEnv, TyCtxt}; +use rustc_session::Limit; +use rustc_target::abi::{Abi, FieldsShape, InitKind, Scalar, Variants}; + +use crate::const_eval::CompileTimeInterpreter; +use crate::interpret::{InterpCx, MemoryKind, OpTy}; + +/// Determines if this type permits "raw" initialization by just transmuting some memory into an +/// instance of `T`. +/// +/// `init_kind` indicates if the memory is zero-initialized or left uninitialized. We assume +/// uninitialized memory is mitigated by filling it with 0x01, which reduces the chance of causing +/// LLVM UB. +/// +/// By default we check whether that operation would cause *LLVM UB*, i.e., whether the LLVM IR we +/// generate has UB or not. This is a mitigation strategy, which is why we are okay with accepting +/// Rust UB as long as there is no risk of miscompilations. The `strict_init_checks` can be set to +/// do a full check against Rust UB instead (in which case we will also ignore the 0x01-filling and +/// to the full uninit check). +pub fn might_permit_raw_init<'tcx>( + tcx: TyCtxt<'tcx>, + ty: TyAndLayout<'tcx>, + kind: InitKind, +) -> bool { + if tcx.sess.opts.unstable_opts.strict_init_checks { + might_permit_raw_init_strict(ty, tcx, kind) + } else { + let layout_cx = LayoutCx { tcx, param_env: ParamEnv::reveal_all() }; + might_permit_raw_init_lax(ty, &layout_cx, kind) + } +} + +/// Implements the 'strict' version of the `might_permit_raw_init` checks; see that function for +/// details. +fn might_permit_raw_init_strict<'tcx>( + ty: TyAndLayout<'tcx>, + tcx: TyCtxt<'tcx>, + kind: InitKind, +) -> bool { + let machine = CompileTimeInterpreter::new( + Limit::new(0), + /*can_access_statics:*/ false, + /*check_alignment:*/ true, + ); + + let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine); + + let allocated = cx + .allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap)) + .expect("OOM: failed to allocate for uninit check"); + + if kind == InitKind::Zero { + cx.write_bytes_ptr( + allocated.ptr, + std::iter::repeat(0_u8).take(ty.layout.size().bytes_usize()), + ) + .expect("failed to write bytes for zero valid check"); + } + + let ot: OpTy<'_, _> = allocated.into(); + + // Assume that if it failed, it's a validation failure. + // This does *not* actually check that references are dereferenceable, but since all types that + // require dereferenceability also require non-null, we don't actually get any false negatives + // due to this. + cx.validate_operand(&ot).is_ok() +} + +/// Implements the 'lax' (default) version of the `might_permit_raw_init` checks; see that function for +/// details. +fn might_permit_raw_init_lax<'tcx>( + this: TyAndLayout<'tcx>, + cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, + init_kind: InitKind, +) -> bool { + let scalar_allows_raw_init = move |s: Scalar| -> bool { + match init_kind { + InitKind::Zero => { + // The range must contain 0. + s.valid_range(cx).contains(0) + } + InitKind::UninitMitigated0x01Fill => { + // The range must include an 0x01-filled buffer. + let mut val: u128 = 0x01; + for _ in 1..s.size(cx).bytes() { + // For sizes >1, repeat the 0x01. + val = (val << 8) | 0x01; + } + s.valid_range(cx).contains(val) + } + } + }; + + // Check the ABI. + let valid = match this.abi { + Abi::Uninhabited => false, // definitely UB + Abi::Scalar(s) => scalar_allows_raw_init(s), + Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2), + Abi::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s), + Abi::Aggregate { .. } => true, // Fields are checked below. + }; + if !valid { + // This is definitely not okay. + return false; + } + + // Special magic check for references and boxes (i.e., special pointer types). + if let Some(pointee) = this.ty.builtin_deref(false) { + let pointee = cx.layout_of(pointee.ty).expect("need to be able to compute layouts"); + // We need to ensure that the LLVM attributes `aligned` and `dereferenceable(size)` are satisfied. + if pointee.align.abi.bytes() > 1 { + // 0x01-filling is not aligned. + return false; + } + if pointee.size.bytes() > 0 { + // A 'fake' integer pointer is not sufficiently dereferenceable. + return false; + } + } + + // If we have not found an error yet, we need to recursively descend into fields. + match &this.fields { + FieldsShape::Primitive | FieldsShape::Union { .. } => {} + FieldsShape::Array { .. } => { + // Arrays never have scalar layout in LLVM, so if the array is not actually + // accessed, there is no LLVM UB -- therefore we can skip this. + } + FieldsShape::Arbitrary { offsets, .. } => { + for idx in 0..offsets.len() { + if !might_permit_raw_init_lax(this.field(cx, idx), cx, init_kind) { + // We found a field that is unhappy with this kind of initialization. + return false; + } + } + } + } + + match &this.variants { + Variants::Single { .. } => { + // All fields of this single variant have already been checked above, there is nothing + // else to do. + } + Variants::Multiple { .. } => { + // We cannot tell LLVM anything about the details of this multi-variant layout, so + // invalid values "hidden" inside the variant cannot cause LLVM trouble. + } + } + + true +} diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index a1876bed83e..7a05cfd235f 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -3,8 +3,10 @@ mod alignment; mod call_kind; pub mod collect_writes; mod find_self_call; +mod might_permit_raw_init; pub use self::aggregate::expand_aggregate; pub use self::alignment::is_disaligned; pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind}; pub use self::find_self_call::find_self_call; +pub use self::might_permit_raw_init::might_permit_raw_init; diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs index 937cb671573..fe257e10205 100644 --- a/compiler/rustc_data_structures/src/sorted_map.rs +++ b/compiler/rustc_data_structures/src/sorted_map.rs @@ -96,6 +96,23 @@ impl<K: Ord, V> SortedMap<K, V> { } } + /// Gets a mutable reference to the value in the entry, or insert a new one. + #[inline] + pub fn get_mut_or_insert_default(&mut self, key: K) -> &mut V + where + K: Eq, + V: Default, + { + let index = match self.lookup_index_for(&key) { + Ok(index) => index, + Err(index) => { + self.data.insert(index, (key, V::default())); + index + } + }; + unsafe { &mut self.data.get_unchecked_mut(index).1 } + } + #[inline] pub fn clear(&mut self) { self.data.clear(); diff --git a/compiler/rustc_error_codes/src/error_codes/E0045.md b/compiler/rustc_error_codes/src/error_codes/E0045.md index 143c693bf7c..1cb214531e8 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0045.md +++ b/compiler/rustc_error_codes/src/error_codes/E0045.md @@ -3,9 +3,7 @@ Variadic parameters have been used on a non-C ABI function. Erroneous code example: ```compile_fail,E0045 -#![feature(unboxed_closures)] - -extern "rust-call" { +extern "Rust" { fn foo(x: u8, ...); // error! } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0092.md b/compiler/rustc_error_codes/src/error_codes/E0092.md index 496174b28ef..5cbe2a188b0 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0092.md +++ b/compiler/rustc_error_codes/src/error_codes/E0092.md @@ -19,6 +19,6 @@ functions are defined in `compiler/rustc_codegen_llvm/src/intrinsic.rs` and in #![feature(intrinsics)] extern "rust-intrinsic" { - fn atomic_fence(); // ok! + fn atomic_fence_seqcst(); // ok! } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md index ec86ec44ece..cc546bdbb3b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0094.md +++ b/compiler/rustc_error_codes/src/error_codes/E0094.md @@ -6,6 +6,7 @@ Erroneous code example: #![feature(intrinsics)] extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of<T, U>() -> usize; // error: intrinsic has wrong number // of type parameters } @@ -19,6 +20,7 @@ Example: #![feature(intrinsics)] extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of<T>() -> usize; // ok! } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0161.md b/compiler/rustc_error_codes/src/error_codes/E0161.md index ebd2c97698b..643990ef1c7 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0161.md +++ b/compiler/rustc_error_codes/src/error_codes/E0161.md @@ -3,7 +3,6 @@ A value was moved whose size was not known at compile time. Erroneous code example: ```compile_fail,E0161 -#![feature(box_syntax)] trait Bar { fn f(self); } @@ -13,7 +12,7 @@ impl Bar for i32 { } fn main() { - let b: Box<dyn Bar> = box (0 as i32); + let b: Box<dyn Bar> = Box::new(0i32); b.f(); // error: cannot move a value of type dyn Bar: the size of dyn Bar cannot // be statically determined @@ -27,8 +26,6 @@ either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move it around as usual. Example: ``` -#![feature(box_syntax)] - trait Bar { fn f(&self); } @@ -38,7 +35,7 @@ impl Bar for i32 { } fn main() { - let b: Box<dyn Bar> = box (0 as i32); + let b: Box<dyn Bar> = Box::new(0i32); b.f(); // ok! } diff --git a/compiler/rustc_error_codes/src/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md index 77289f01900..8c2462ebd9b 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0211.md +++ b/compiler/rustc_error_codes/src/error_codes/E0211.md @@ -7,6 +7,7 @@ used. Erroneous code examples: #![feature(intrinsics)] extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of<T>(); // error: intrinsic has wrong type } @@ -42,6 +43,7 @@ For the first code example, please check the function definition. Example: #![feature(intrinsics)] extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of<T>() -> usize; // ok! } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0579.md b/compiler/rustc_error_codes/src/error_codes/E0579.md index f554242a3d4..e7e6fb68256 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0579.md +++ b/compiler/rustc_error_codes/src/error_codes/E0579.md @@ -8,9 +8,9 @@ Erroneous code example: fn main() { match 5u32 { // This range is ok, albeit pointless. - 1 .. 2 => {} + 1..2 => {} // This range is empty, and the compiler can tell. - 5 .. 5 => {} // error! + 5..5 => {} // error! } } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0622.md b/compiler/rustc_error_codes/src/error_codes/E0622.md index 990a2549412..3ba3ed10e5c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0622.md +++ b/compiler/rustc_error_codes/src/error_codes/E0622.md @@ -5,7 +5,7 @@ Erroneous code example: ```compile_fail,E0622 #![feature(intrinsics)] extern "rust-intrinsic" { - pub static breakpoint : fn(); // error: intrinsic must be a function + pub static breakpoint: fn(); // error: intrinsic must be a function } fn main() { unsafe { breakpoint(); } } diff --git a/compiler/rustc_error_codes/src/error_codes/E0743.md b/compiler/rustc_error_codes/src/error_codes/E0743.md index ddd3136df0c..a19d3ef96e9 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0743.md +++ b/compiler/rustc_error_codes/src/error_codes/E0743.md @@ -3,8 +3,6 @@ The C-variadic type `...` has been nested inside another type. Erroneous code example: ```compile_fail,E0743 -#![feature(c_variadic)] - fn foo2(x: u8, y: &...) {} // error! ``` diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl new file mode 100644 index 00000000000..178e1a67cce --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl @@ -0,0 +1,68 @@ +codegen_gcc_ranlib_failure = + Ranlib exited with code {$exit_code} + +codegen_gcc_linkage_const_or_mut_type = + must have type `*const T` or `*mut T` due to `#[linkage]` attribute + +codegen_gcc_unwinding_inline_asm = + GCC backend does not support unwinding from inline asm + +codegen_gcc_lto_not_supported = + LTO is not supported. You may get a linker error. + +codegen_gcc_invalid_monomorphization_basic_integer = + invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}` + +codegen_gcc_invalid_monomorphization_invalid_float_vector = + invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$elem_ty}` of floating-point vector `{$vec_ty}` + +codegen_gcc_invalid_monomorphization_not_float = + invalid monomorphization of `{$name}` intrinsic: `{$ty}` is not a floating-point type + +codegen_gcc_invalid_monomorphization_unrecognized = + invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}` + +codegen_gcc_invalid_monomorphization_expected_signed_unsigned = + invalid monomorphization of `{$name}` intrinsic: expected element type `{$elem_ty}` of vector type `{$vec_ty}` to be a signed or unsigned integer type + +codegen_gcc_invalid_monomorphization_unsupported_element = + invalid monomorphization of `{$name}` intrinsic: unsupported {$name} from `{$in_ty}` with element `{$elem_ty}` to `{$ret_ty}` + +codegen_gcc_invalid_monomorphization_invalid_bitmask = + invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]` + +codegen_gcc_invalid_monomorphization_simd_shuffle = + invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}` + +codegen_gcc_invalid_monomorphization_expected_simd = + invalid monomorphization of `{$name}` intrinsic: expected SIMD {$expected_ty} type, found non-SIMD `{$found_ty}` + +codegen_gcc_invalid_monomorphization_mask_type = + invalid monomorphization of `{$name}` intrinsic: mask element type is `{$ty}`, expected `i_` + +codegen_gcc_invalid_monomorphization_return_length = + invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len} + +codegen_gcc_invalid_monomorphization_return_length_input_type = + invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len} + +codegen_gcc_invalid_monomorphization_return_element = + invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}` + +codegen_gcc_invalid_monomorphization_return_type = + invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` + +codegen_gcc_invalid_monomorphization_inserted_type = + invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}` + +codegen_gcc_invalid_monomorphization_return_integer_type = + invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}` + +codegen_gcc_invalid_monomorphization_mismatched_lengths = + invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}` + +codegen_gcc_invalid_monomorphization_unsupported_cast = + invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}` + +codegen_gcc_invalid_monomorphization_unsupported_operation = + invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}` diff --git a/compiler/rustc_error_messages/locales/en-US/compiletest.ftl b/compiler/rustc_error_messages/locales/en-US/compiletest.ftl new file mode 100644 index 00000000000..55061fbce7e --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/compiletest.ftl @@ -0,0 +1,5 @@ +compiletest_example = this is an example message used in testing + .note = with a note + .help = with a help + .suggestion = with a suggestion + .label = with a label diff --git a/compiler/rustc_error_messages/locales/en-US/typeck.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl index 272731d9914..c6a4ff6f0e0 100644 --- a/compiler/rustc_error_messages/locales/en-US/typeck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl @@ -1,101 +1,101 @@ -typeck_field_multiply_specified_in_initializer = +hir_analysis_field_multiply_specified_in_initializer = field `{$ident}` specified more than once .label = used more than once .previous_use_label = first use of `{$ident}` -typeck_unrecognized_atomic_operation = +hir_analysis_unrecognized_atomic_operation = unrecognized atomic operation function: `{$op}` .label = unrecognized atomic operation -typeck_wrong_number_of_generic_arguments_to_intrinsic = +hir_analysis_wrong_number_of_generic_arguments_to_intrinsic = intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected} .label = expected {$expected} {$descr} {$expected -> [one] parameter *[other] parameters } -typeck_unrecognized_intrinsic_function = +hir_analysis_unrecognized_intrinsic_function = unrecognized intrinsic function: `{$name}` .label = unrecognized intrinsic -typeck_lifetimes_or_bounds_mismatch_on_trait = +hir_analysis_lifetimes_or_bounds_mismatch_on_trait = lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration .label = lifetimes do not match {$item_kind} in trait .generics_label = lifetimes in impl do not match this {$item_kind} in trait -typeck_drop_impl_on_wrong_item = +hir_analysis_drop_impl_on_wrong_item = the `Drop` trait may only be implemented for local structs, enums, and unions .label = must be a struct, enum, or union in the current crate -typeck_field_already_declared = +hir_analysis_field_already_declared = field `{$field_name}` is already declared .label = field already declared .previous_decl_label = `{$field_name}` first declared here -typeck_copy_impl_on_type_with_dtor = +hir_analysis_copy_impl_on_type_with_dtor = the trait `Copy` may not be implemented for this type; the type has a destructor .label = `Copy` not allowed on types with destructors -typeck_multiple_relaxed_default_bounds = +hir_analysis_multiple_relaxed_default_bounds = type parameter has more than one relaxed default bound, only one is supported -typeck_copy_impl_on_non_adt = +hir_analysis_copy_impl_on_non_adt = the trait `Copy` may not be implemented for this type .label = type is not a structure or enumeration -typeck_trait_object_declared_with_no_traits = +hir_analysis_trait_object_declared_with_no_traits = at least one trait is required for an object type .alias_span = this alias does not contain a trait -typeck_ambiguous_lifetime_bound = +hir_analysis_ambiguous_lifetime_bound = ambiguous lifetime bound, explicit lifetime bound required -typeck_assoc_type_binding_not_allowed = +hir_analysis_assoc_type_binding_not_allowed = associated type bindings are not allowed here .label = associated type not allowed here -typeck_functional_record_update_on_non_struct = +hir_analysis_functional_record_update_on_non_struct = functional record update syntax requires a struct -typeck_typeof_reserved_keyword_used = +hir_analysis_typeof_reserved_keyword_used = `typeof` is a reserved keyword but unimplemented .suggestion = consider replacing `typeof(...)` with an actual type .label = reserved keyword -typeck_return_stmt_outside_of_fn_body = +hir_analysis_return_stmt_outside_of_fn_body = return statement outside of function body .encl_body_label = the return is part of this body... .encl_fn_label = ...not the enclosing function body -typeck_yield_expr_outside_of_generator = +hir_analysis_yield_expr_outside_of_generator = yield expression outside of generator literal -typeck_struct_expr_non_exhaustive = +hir_analysis_struct_expr_non_exhaustive = cannot create non-exhaustive {$what} using struct expression -typeck_method_call_on_unknown_type = +hir_analysis_method_call_on_unknown_type = the type of this value must be known to call a method on a raw pointer on it -typeck_value_of_associated_struct_already_specified = +hir_analysis_value_of_associated_struct_already_specified = the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified .label = re-bound here .previous_bound_label = `{$item_name}` bound here first -typeck_address_of_temporary_taken = cannot take address of a temporary +hir_analysis_address_of_temporary_taken = cannot take address of a temporary .label = temporary value -typeck_add_return_type_add = try adding a return type +hir_analysis_add_return_type_add = try adding a return type -typeck_add_return_type_missing_here = a return type might be missing here +hir_analysis_add_return_type_missing_here = a return type might be missing here -typeck_expected_default_return_type = expected `()` because of default return type +hir_analysis_expected_default_return_type = expected `()` because of default return type -typeck_expected_return_type = expected `{$expected}` because of return type +hir_analysis_expected_return_type = expected `{$expected}` because of return type -typeck_unconstrained_opaque_type = unconstrained opaque type +hir_analysis_unconstrained_opaque_type = unconstrained opaque type .note = `{$name}` must be used in combination with a concrete type within the same module -typeck_missing_type_params = +hir_analysis_missing_type_params = the type {$parameterCount -> [one] parameter *[other] parameters @@ -117,19 +117,19 @@ typeck_missing_type_params = } to {$parameters} .note = because of the default `Self` reference, type parameters must be specified on object types -typeck_manual_implementation = +hir_analysis_manual_implementation = manual implementations of `{$trait_name}` are experimental .label = manual implementations of `{$trait_name}` are experimental .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable -typeck_substs_on_overridden_impl = could not resolve substs on overridden impl +hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl -typeck_unused_extern_crate = +hir_analysis_unused_extern_crate = unused extern crate .suggestion = remove it -typeck_extern_crate_not_idiomatic = +hir_analysis_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edition .suggestion = convert it to a `{$msg_code}` -typeck_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` +hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl index 80b0b1a8904..0fd9b0ead16 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl @@ -433,3 +433,7 @@ lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}` lint_check_name_warning = {$msg} lint_check_name_deprecated = lint name `{$lint_name}` is deprecated and does not have an effect anymore. Use: {$new_name} + +lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its associated type bounds + .specifically = this associated type bound is unsatisfied for `{$proj_ty}` + .suggestion = add this bound diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_error_messages/locales/en-US/middle.ftl index ed834886453..ca3c91ce24a 100644 --- a/compiler/rustc_error_messages/locales/en-US/middle.ftl +++ b/compiler/rustc_error_messages/locales/en-US/middle.ftl @@ -15,3 +15,6 @@ middle_previous_use_here = middle_limit_invalid = `limit` must be a non-negative integer .label = {$error_str} + +middle_const_eval_non_int = + constant evaluation of enum discriminant resulted in non-integer diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 6d34cdce340..13c368d1c58 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -245,7 +245,7 @@ parser_assignment_else_not_allowed = <assignment> ... else {"{"} ... {"}"} is no parser_expected_statement_after_outer_attr = expected statement after outer attribute parser_doc_comment_does_not_document_anything = found a documentation comment that doesn't document anything - .help = doc comments must come before what they document, maybe a comment was intended with `//`? + .help = doc comments must come before what they document, if a comment was intended use `//` .suggestion = missing comma here parser_const_let_mutually_exclusive = `const` and `let` are mutually exclusive diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index ff33ae7e8f2..18be60975e4 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -40,27 +40,29 @@ fluent_messages! { attr => "../locales/en-US/attr.ftl", borrowck => "../locales/en-US/borrowck.ftl", builtin_macros => "../locales/en-US/builtin_macros.ftl", + compiletest => "../locales/en-US/compiletest.ftl", const_eval => "../locales/en-US/const_eval.ftl", + codegen_gcc => "../locales/en-US/codegen_gcc.ftl", driver => "../locales/en-US/driver.ftl", expand => "../locales/en-US/expand.ftl", - session => "../locales/en-US/session.ftl", - interface => "../locales/en-US/interface.ftl", + hir_analysis => "../locales/en-US/hir_analysis.ftl", infer => "../locales/en-US/infer.ftl", + interface => "../locales/en-US/interface.ftl", lint => "../locales/en-US/lint.ftl", + metadata => "../locales/en-US/metadata.ftl", middle => "../locales/en-US/middle.ftl", + mir_dataflow => "../locales/en-US/mir_dataflow.ftl", monomorphize => "../locales/en-US/monomorphize.ftl", - metadata => "../locales/en-US/metadata.ftl", parser => "../locales/en-US/parser.ftl", passes => "../locales/en-US/passes.ftl", plugin_impl => "../locales/en-US/plugin_impl.ftl", privacy => "../locales/en-US/privacy.ftl", query_system => "../locales/en-US/query_system.ftl", - trait_selection => "../locales/en-US/trait_selection.ftl", save_analysis => "../locales/en-US/save_analysis.ftl", - ty_utils => "../locales/en-US/ty_utils.ftl", - typeck => "../locales/en-US/typeck.ftl", - mir_dataflow => "../locales/en-US/mir_dataflow.ftl", + session => "../locales/en-US/session.ftl", symbol_mangling => "../locales/en-US/symbol_mangling.ftl", + trait_selection => "../locales/en-US/trait_selection.ftl", + ty_utils => "../locales/en-US/ty_utils.ftl", } pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; @@ -357,6 +359,17 @@ impl<S: Into<String>> From<S> for DiagnosticMessage { } } +/// A workaround for "good path" ICEs when formatting types in disables lints. +/// +/// Delays formatting until `.into(): DiagnosticMessage` is used. +pub struct DelayDm<F>(pub F); + +impl<F: FnOnce() -> String> From<DelayDm<F>> for DiagnosticMessage { + fn from(DelayDm(f): DelayDm<F>) -> Self { + DiagnosticMessage::from(f()) + } +} + /// Translating *into* a subdiagnostic message from a diagnostic message is a little strange - but /// the subdiagnostic functions (e.g. `span_label`) take a `SubdiagnosticMessage` and the /// subdiagnostic derive refers to typed identifiers that are `DiagnosticMessage`s, so need to be diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 5520e22e476..31e410aaaf0 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -1,6 +1,6 @@ use crate::snippet::Style; use crate::{ - CodeSuggestion, DiagnosticMessage, EmissionGuarantee, Level, LintDiagnosticBuilder, MultiSpan, + CodeSuggestion, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, Level, MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle, }; use rustc_ast as ast; @@ -209,7 +209,12 @@ pub trait AddToDiagnostic { #[rustc_diagnostic_item = "DecorateLint"] pub trait DecorateLint<'a, G: EmissionGuarantee> { /// Decorate and emit a lint. - fn decorate_lint(self, diag: LintDiagnosticBuilder<'a, G>); + fn decorate_lint<'b>( + self, + diag: &'b mut DiagnosticBuilder<'a, G>, + ) -> &'b mut DiagnosticBuilder<'a, G>; + + fn msg(&self) -> DiagnosticMessage; } #[must_use] @@ -359,9 +364,10 @@ impl Diagnostic { // The lint index inside the attribute is manually transferred here. let lint_index = expectation_id.get_lint_index(); expectation_id.set_lint_index(None); - let mut stable_id = *unstable_to_stable + let mut stable_id = unstable_to_stable .get(&expectation_id) - .expect("each unstable `LintExpectationId` must have a matching stable id"); + .expect("each unstable `LintExpectationId` must have a matching stable id") + .normalize(); stable_id.set_lint_index(lint_index); *expectation_id = stable_id; diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index b4ba65ca96d..bbe6435be59 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -5,6 +5,7 @@ use crate::{ }; use crate::{Handler, Level, MultiSpan, StashKey}; use rustc_lint_defs::Applicability; +use rustc_span::source_map::Spanned; use rustc_span::Span; use std::borrow::Cow; @@ -23,6 +24,18 @@ pub trait IntoDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, T>; } +impl<'a, T, E> IntoDiagnostic<'a, E> for Spanned<T> +where + T: IntoDiagnostic<'a, E>, + E: EmissionGuarantee, +{ + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, E> { + let mut diag = self.node.into_diagnostic(handler); + diag.set_span(self.span); + diag + } +} + /// Used for emitting structured error messages and other diagnostic information. /// /// If there is some state in a downstream crate you would like to @@ -629,27 +642,3 @@ macro_rules! struct_span_err { macro_rules! error_code { ($code:ident) => {{ $crate::DiagnosticId::Error(stringify!($code).to_owned()) }}; } - -/// Wrapper around a `DiagnosticBuilder` for creating lints. -pub struct LintDiagnosticBuilder<'a, G: EmissionGuarantee>(DiagnosticBuilder<'a, G>); - -impl<'a, G: EmissionGuarantee> LintDiagnosticBuilder<'a, G> { - #[rustc_lint_diagnostics] - /// Return the inner `DiagnosticBuilder`, first setting the primary message to `msg`. - pub fn build(mut self, msg: impl Into<DiagnosticMessage>) -> DiagnosticBuilder<'a, G> { - self.0.set_primary_message(msg); - self.0.set_is_lint(); - self.0 - } - - /// Create a `LintDiagnosticBuilder` from some existing `DiagnosticBuilder`. - pub fn new(err: DiagnosticBuilder<'a, G>) -> LintDiagnosticBuilder<'a, G> { - LintDiagnosticBuilder(err) - } -} - -impl<'a> LintDiagnosticBuilder<'a, ErrorGuaranteed> { - pub fn forget_guarantee(self) -> LintDiagnosticBuilder<'a, ()> { - LintDiagnosticBuilder(self.0.forget_guarantee()) - } -} diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index d3effb7c1c0..7c312da6279 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -30,7 +30,7 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{self, Lock, Lrc}; use rustc_data_structures::AtomicRef; pub use rustc_error_messages::{ - fallback_fluent_bundle, fluent, fluent_bundle, DiagnosticMessage, FluentBundle, + fallback_fluent_bundle, fluent, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage, DEFAULT_LOCALE_RESOURCES, }; @@ -66,7 +66,7 @@ pub type PErr<'a> = DiagnosticBuilder<'a, ErrorGuaranteed>; pub type PResult<'a, T> = Result<T, PErr<'a>>; // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. -// (See also the comment on `DiagnosticBuilder`'s `diagnostic` field.) +// (See also the comment on `DiagnosticBuilderInner`'s `diagnostic` field.) #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16); #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] @@ -374,7 +374,7 @@ pub use diagnostic::{ AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgFromDisplay, DiagnosticArgValue, DiagnosticId, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic, }; -pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, LintDiagnosticBuilder}; +pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee}; use std::backtrace::Backtrace; /// A handler deals with errors and other compiler output. @@ -1134,6 +1134,12 @@ impl Handler { ); std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) } + + pub fn flush_delayed(&self) { + let mut inner = self.inner.lock(); + let bugs = std::mem::replace(&mut inner.delayed_span_bugs, Vec::new()); + inner.flush_delayed(bugs, "no errors encountered even though `delay_span_bug` issued"); + } } impl HandlerInner { @@ -1205,7 +1211,7 @@ impl HandlerInner { if let Some(expectation_id) = diagnostic.level.get_expectation_id() { self.suppressed_expected_diag = true; - self.fulfilled_expectations.insert(expectation_id); + self.fulfilled_expectations.insert(expectation_id.normalize()); } if matches!(diagnostic.level, Warning(_)) diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index 59a7b668a83..17a348ec6ba 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -110,10 +110,26 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre tokenstream::TokenTree::Token(token, spacing) => (token, spacing == Joint), }; + // Split the operator into one or more `Punct`s, one per character. + // The final one inherits the jointness of the original token. Any + // before that get `joint = true`. let mut op = |s: &str| { assert!(s.is_ascii()); - trees.extend(s.as_bytes().iter().enumerate().map(|(idx, &ch)| { - TokenTree::Punct(Punct { ch, joint: joint || idx != s.len() - 1, span }) + trees.extend(s.bytes().enumerate().map(|(i, ch)| { + let is_final = i == s.len() - 1; + // Split the token span into single chars. Unless the span + // is an unusual one, e.g. due to proc macro expansion. We + // determine this by assuming any span with a length that + // matches the operator length is a normal one, and any + // span with a different length is an unusual one. + let span = if (span.hi() - span.lo()).to_usize() == s.len() { + let lo = span.lo() + BytePos::from_usize(i); + let hi = lo + BytePos::from_usize(1); + span.with_lo(lo).with_hi(hi) + } else { + span + }; + TokenTree::Punct(Punct { ch, joint: if is_final { joint } else { true }, span }) })); }; diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 700d9dab64b..5ee6c9f2387 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -499,6 +499,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), ungated!(rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk), ungated!(rustc_const_stable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk), + ungated!(rustc_safe_intrinsic, Normal, template!(Word), DuplicatesOk), ungated!( rustc_default_body_unstable, Normal, template!(List: r#"feature = "name", reason = "...", issue = "N""#), DuplicatesOk diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index e7c26bd726f..f1f0c224bbd 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -314,74 +314,75 @@ pub enum Res<Id = hir::HirId> { /// **Belongs to the type namespace.** PrimTy(hir::PrimTy), - /// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and - /// optionally with the [`DefId`] of the item introducing the `Self` type alias. + /// The `Self` type, as used within a trait. + /// + /// **Belongs to the type namespace.** + /// + /// See the examples on [`Res::SelfTyAlias`] for details. + SelfTyParam { + /// The trait this `Self` is a generic parameter for. + trait_: DefId, + }, + + /// The `Self` type, as used somewhere other than within a trait. /// /// **Belongs to the type namespace.** /// /// Examples: /// ``` - /// struct Bar(Box<Self>); - /// // `Res::SelfTy { trait_: None, alias_of: Some(Bar) }` + /// struct Bar(Box<Self>); // SelfTyAlias /// /// trait Foo { - /// fn foo() -> Box<Self>; - /// // `Res::SelfTy { trait_: Some(Foo), alias_of: None }` + /// fn foo() -> Box<Self>; // SelfTyParam /// } /// /// impl Bar { /// fn blah() { - /// let _: Self; - /// // `Res::SelfTy { trait_: None, alias_of: Some(::{impl#0}) }` + /// let _: Self; // SelfTyAlias /// } /// } /// /// impl Foo for Bar { - /// fn foo() -> Box<Self> { - /// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }` - /// let _: Self; - /// // `Res::SelfTy { trait_: Some(Foo), alias_of: Some(::{impl#1}) }` + /// fn foo() -> Box<Self> { // SelfTyAlias + /// let _: Self; // SelfTyAlias /// /// todo!() /// } /// } /// ``` - /// /// *See also [`Res::SelfCtor`].* /// - /// ----- - /// - /// HACK(min_const_generics): self types also have an optional requirement to **not** mention - /// any generic parameters to allow the following with `min_const_generics`: - /// ``` - /// # struct Foo; - /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } } - /// - /// struct Bar([u8; baz::<Self>()]); - /// const fn baz<T>() -> usize { 10 } - /// ``` - /// We do however allow `Self` in repeat expression even if it is generic to not break code - /// which already works on stable while causing the `const_evaluatable_unchecked` future compat - /// lint: - /// ``` - /// fn foo<T>() { - /// let _bar = [1_u8; std::mem::size_of::<*mut T>()]; - /// } - /// ``` - // FIXME(generic_const_exprs): Remove this bodge once that feature is stable. - SelfTy { - /// The trait this `Self` is a generic arg for. - trait_: Option<DefId>, + SelfTyAlias { /// The item introducing the `Self` type alias. Can be used in the `type_of` query - /// to get the underlying type. Additionally whether the `Self` type is disallowed - /// from mentioning generics (i.e. when used in an anonymous constant). - alias_to: Option<(DefId, bool)>, - }, + /// to get the underlying type. + alias_to: DefId, - /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`. - /// - /// **Belongs to the type namespace.** - ToolMod, + /// Whether the `Self` type is disallowed from mentioning generics (i.e. when used in an + /// anonymous constant). + /// + /// HACK(min_const_generics): self types also have an optional requirement to **not** + /// mention any generic parameters to allow the following with `min_const_generics`: + /// ``` + /// # struct Foo; + /// impl Foo { fn test() -> [u8; std::mem::size_of::<Self>()] { todo!() } } + /// + /// struct Bar([u8; baz::<Self>()]); + /// const fn baz<T>() -> usize { 10 } + /// ``` + /// We do however allow `Self` in repeat expression even if it is generic to not break code + /// which already works on stable while causing the `const_evaluatable_unchecked` future + /// compat lint: + /// ``` + /// fn foo<T>() { + /// let _bar = [1_u8; std::mem::size_of::<*mut T>()]; + /// } + /// ``` + // FIXME(generic_const_exprs): Remove this bodge once that feature is stable. + forbid_generic: bool, + + /// Is this within an `impl Foo for bar`? + is_trait_impl: bool, + }, // Value namespace /// The `Self` constructor, along with the [`DefId`] @@ -389,7 +390,7 @@ pub enum Res<Id = hir::HirId> { /// /// **Belongs to the value namespace.** /// - /// *See also [`Res::SelfTy`].* + /// *See also [`Res::SelfTyParam`] and [`Res::SelfTyAlias`].* SelfCtor(DefId), /// A local variable or function parameter. @@ -397,6 +398,11 @@ pub enum Res<Id = hir::HirId> { /// **Belongs to the value namespace.** Local(Id), + /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`. + /// + /// **Belongs to the type namespace.** + ToolMod, + // Macro namespace /// An attribute that is *not* implemented via macro. /// E.g., `#[inline]` and `#[rustfmt::skip]`, which are essentially directives, @@ -606,7 +612,8 @@ impl<Id> Res<Id> { Res::Local(..) | Res::PrimTy(..) - | Res::SelfTy { .. } + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } | Res::SelfCtor(..) | Res::ToolMod | Res::NonMacroAttr(..) @@ -629,7 +636,7 @@ impl<Id> Res<Id> { Res::SelfCtor(..) => "self constructor", Res::PrimTy(..) => "builtin type", Res::Local(..) => "local variable", - Res::SelfTy { .. } => "self type", + Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => "self type", Res::ToolMod => "tool module", Res::NonMacroAttr(attr_kind) => attr_kind.descr(), Res::Err => "unresolved item", @@ -652,7 +659,10 @@ impl<Id> Res<Id> { Res::SelfCtor(id) => Res::SelfCtor(id), Res::PrimTy(id) => Res::PrimTy(id), Res::Local(id) => Res::Local(map(id)), - Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to }, + Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ }, + Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => { + Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } + } Res::ToolMod => Res::ToolMod, Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind), Res::Err => Res::Err, @@ -665,7 +675,10 @@ impl<Id> Res<Id> { Res::SelfCtor(id) => Res::SelfCtor(id), Res::PrimTy(id) => Res::PrimTy(id), Res::Local(id) => Res::Local(map(id)?), - Res::SelfTy { trait_, alias_to } => Res::SelfTy { trait_, alias_to }, + Res::SelfTyParam { trait_ } => Res::SelfTyParam { trait_ }, + Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } => { + Res::SelfTyAlias { alias_to, forbid_generic, is_trait_impl } + } Res::ToolMod => Res::ToolMod, Res::NonMacroAttr(attr_kind) => Res::NonMacroAttr(attr_kind), Res::Err => Res::Err, @@ -692,7 +705,9 @@ impl<Id> Res<Id> { pub fn ns(&self) -> Option<Namespace> { match self { Res::Def(kind, ..) => kind.ns(), - Res::PrimTy(..) | Res::SelfTy { .. } | Res::ToolMod => Some(Namespace::TypeNS), + Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::ToolMod => { + Some(Namespace::TypeNS) + } Res::SelfCtor(..) | Res::Local(..) => Some(Namespace::ValueNS), Res::NonMacroAttr(..) => Some(Namespace::MacroNS), Res::Err => None, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index c1948052e3c..922ce738dbb 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -731,6 +731,7 @@ pub enum PredicateOrigin { /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). #[derive(Debug, HashStable_Generic)] pub struct WhereBoundPredicate<'hir> { + pub hir_id: HirId, pub span: Span, /// Origin of the predicate. pub origin: PredicateOrigin, @@ -2403,8 +2404,9 @@ impl<'hir> Ty<'hir> { return None; }; match path.res { - Res::Def(DefKind::TyParam, def_id) - | Res::SelfTy { trait_: Some(def_id), alias_to: None } => Some((def_id, segment.ident)), + Res::Def(DefKind::TyParam, def_id) | Res::SelfTyParam { trait_: def_id } => { + Some((def_id, segment.ident)) + } _ => None, } } @@ -3532,9 +3534,10 @@ mod size_asserts { static_assert_size!(Param<'_>, 32); static_assert_size!(Pat<'_>, 72); static_assert_size!(PatKind<'_>, 48); - static_assert_size!(Path<'_>, 48); - static_assert_size!(PathSegment<'_>, 56); + static_assert_size!(Path<'_>, 40); + static_assert_size!(PathSegment<'_>, 48); static_assert_size!(QPath<'_>, 24); + static_assert_size!(Res, 12); static_assert_size!(Stmt<'_>, 32); static_assert_size!(StmtKind<'_>, 16); static_assert_size!(TraitItem<'_>, 88); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 8f5f314ecae..8777a54ba09 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -847,20 +847,28 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>( ) { match *predicate { WherePredicate::BoundPredicate(WhereBoundPredicate { + hir_id, ref bounded_ty, bounds, bound_generic_params, - .. + origin: _, + span: _, }) => { + visitor.visit_id(hir_id); visitor.visit_ty(bounded_ty); walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_generic_param, bound_generic_params); } - WherePredicate::RegionPredicate(WhereRegionPredicate { ref lifetime, bounds, .. }) => { + WherePredicate::RegionPredicate(WhereRegionPredicate { + ref lifetime, + bounds, + span: _, + in_where_clause: _, + }) => { visitor.visit_lifetime(lifetime); walk_list!(visitor, visit_param_bound, bounds); } - WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => { + WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, span: _ }) => { visitor.visit_ty(lhs_ty); visitor.visit_ty(rhs_ty); } diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index afac75de2d9..b66e59d8ac6 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -448,8 +448,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let infer_lifetimes = (gen_pos != GenericArgPosition::Type || infer_args) && !gen_args.has_lifetime_params(); - if gen_pos != GenericArgPosition::Type && !gen_args.bindings.is_empty() { - Self::prohibit_assoc_ty_binding(tcx, gen_args.bindings[0].span); + if gen_pos != GenericArgPosition::Type && let Some(b) = gen_args.bindings.first() { + Self::prohibit_assoc_ty_binding(tcx, b.span); } let explicit_late_bound = @@ -649,9 +649,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].hir_id(), multispan, - |lint| { - lint.build(msg).emit(); - }, + msg, + |lint| lint, ); } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 244018ebbeb..6e373e41b4c 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -276,9 +276,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.infer_args, None, ); - let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args()); - - if let Some(b) = assoc_bindings.first() { + if let Some(b) = item_segment.args().bindings.first() { Self::prohibit_assoc_ty_binding(self.tcx(), b.span); } @@ -605,8 +603,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { None, ); - let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args()); - if let Some(b) = assoc_bindings.first() { + if let Some(b) = item_segment.args().bindings.first() { Self::prohibit_assoc_ty_binding(self.tcx(), b.span); } @@ -794,8 +791,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { trait_segment, is_impl, ); - let assoc_bindings = self.create_assoc_bindings_for_generic_args(trait_segment.args()); - if let Some(b) = assoc_bindings.first() { + if let Some(b) = trait_segment.args().bindings.first() { Self::prohibit_assoc_ty_binding(self.tcx(), b.span); } ty::TraitRef::new(trait_def_id, substs) @@ -1902,7 +1898,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Find the type of the associated item, and the trait where the associated // item is declared. let bound = match (&qself_ty.kind(), qself_res) { - (_, Res::SelfTy { trait_: Some(_), alias_to: Some((impl_def_id, _)) }) => { + (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => { // `Self` in an impl of a trait -- we have a concrete self type and a // trait reference. let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else { @@ -1921,8 +1917,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } ( &ty::Param(_), - Res::SelfTy { trait_: Some(param_did), alias_to: None } - | Res::Def(DefKind::TyParam, param_did), + Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did), ) => self.find_bound_for_assoc_item(param_did.expect_local(), assoc_ident, span)?, _ => { let reported = if variant_resolution.is_some() { @@ -2015,30 +2010,35 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.check_stability(item.def_id, Some(hir_ref_id), span, None); if let Some(variant_def_id) = variant_resolution { - tcx.struct_span_lint_hir(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| { - let mut err = lint.build("ambiguous associated item"); - let mut could_refer_to = |kind: DefKind, def_id, also| { - let note_msg = format!( - "`{}` could{} refer to the {} defined here", - assoc_ident, - also, - kind.descr(def_id) - ); - err.span_note(tcx.def_span(def_id), ¬e_msg); - }; + tcx.struct_span_lint_hir( + AMBIGUOUS_ASSOCIATED_ITEMS, + hir_ref_id, + span, + "ambiguous associated item", + |lint| { + let mut could_refer_to = |kind: DefKind, def_id, also| { + let note_msg = format!( + "`{}` could{} refer to the {} defined here", + assoc_ident, + also, + kind.descr(def_id) + ); + lint.span_note(tcx.def_span(def_id), ¬e_msg); + }; - could_refer_to(DefKind::Variant, variant_def_id, ""); - could_refer_to(kind, item.def_id, " also"); + could_refer_to(DefKind::Variant, variant_def_id, ""); + could_refer_to(kind, item.def_id, " also"); - err.span_suggestion( - span, - "use fully-qualified syntax", - format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), - Applicability::MachineApplicable, - ); + lint.span_suggestion( + span, + "use fully-qualified syntax", + format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident), + Applicability::MachineApplicable, + ); - err.emit(); - }); + lint + }, + ); } Ok((ty, kind, item.def_id)) } @@ -2208,8 +2208,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { for segment in segments { // Only emit the first error to avoid overloading the user with error messages. - if let [binding, ..] = segment.args().bindings { - Self::prohibit_assoc_ty_binding(self.tcx(), binding.span); + if let Some(b) = segment.args().bindings.first() { + Self::prohibit_assoc_ty_binding(self.tcx(), b.span); return true; } } @@ -2417,7 +2417,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let index = generics.param_def_id_to_index[&def_id.to_def_id()]; tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id)) } - Res::SelfTy { trait_: Some(_), alias_to: None } => { + Res::SelfTyParam { .. } => { // `Self` in trait or type alias. assert_eq!(opt_self_ty, None); self.prohibit_generics(path.segments.iter(), |err| { @@ -2432,7 +2432,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { }); tcx.types.self_param } - Res::SelfTy { trait_: _, alias_to: Some((def_id, forbid_generic)) } => { + Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => { // `Self` in impl (we know the concrete type). assert_eq!(opt_self_ty, None); // Try to evaluate any array length constants. @@ -3084,15 +3084,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, + msg, |lint| { - let mut diag = lint.build(msg); - diag.multipart_suggestion_verbose( + lint.multipart_suggestion_verbose( "use `dyn`", sugg, Applicability::MachineApplicable, ); - self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag); - diag.emit(); + self.maybe_lint_blanket_trait_impl(&self_ty, lint); + lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/callee.rs b/compiler/rustc_hir_analysis/src/check/callee.rs index c82a31e65cf..080771844a4 100644 --- a/compiler/rustc_hir_analysis/src/check/callee.rs +++ b/compiler/rustc_hir_analysis/src/check/callee.rs @@ -394,140 +394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::FnPtr(sig) => (sig, None), _ => { - let mut unit_variant = None; - if let hir::ExprKind::Path(qpath) = &callee_expr.kind - && let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _) - = self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id) - // Only suggest removing parens if there are no arguments - && arg_exprs.is_empty() - { - let descr = match kind { - def::CtorOf::Struct => "struct", - def::CtorOf::Variant => "enum variant", - }; - let removal_span = - callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); - unit_variant = - Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(qpath))); - } - - let callee_ty = self.resolve_vars_if_possible(callee_ty); - let mut err = type_error_struct!( - self.tcx.sess, - callee_expr.span, - callee_ty, - E0618, - "expected function, found {}", - match &unit_variant { - Some((_, kind, path)) => format!("{kind} `{path}`"), - None => format!("`{callee_ty}`"), - } - ); - - self.identify_bad_closure_def_and_call( - &mut err, - call_expr.hir_id, - &callee_expr.kind, - callee_expr.span, - ); - - if let Some((removal_span, kind, path)) = &unit_variant { - err.span_suggestion_verbose( - *removal_span, - &format!( - "`{path}` is a unit {kind}, and does not take parentheses to be constructed", - ), - "", - Applicability::MachineApplicable, - ); - } - - let mut inner_callee_path = None; - let def = match callee_expr.kind { - hir::ExprKind::Path(ref qpath) => { - self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id) - } - hir::ExprKind::Call(ref inner_callee, _) => { - // If the call spans more than one line and the callee kind is - // itself another `ExprCall`, that's a clue that we might just be - // missing a semicolon (Issue #51055) - let call_is_multiline = - self.tcx.sess.source_map().is_multiline(call_expr.span); - if call_is_multiline { - err.span_suggestion( - callee_expr.span.shrink_to_hi(), - "consider using a semicolon here", - ";", - Applicability::MaybeIncorrect, - ); - } - if let hir::ExprKind::Path(ref inner_qpath) = inner_callee.kind { - inner_callee_path = Some(inner_qpath); - self.typeck_results.borrow().qpath_res(inner_qpath, inner_callee.hir_id) - } else { - Res::Err - } - } - _ => Res::Err, - }; - - if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) { - if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_expr, callee_ty) - && !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span) - { - let descr = match maybe_def { - DefIdOrName::DefId(def_id) => self.tcx.def_kind(def_id).descr(def_id), - DefIdOrName::Name(name) => name, - }; - err.span_label( - callee_expr.span, - format!("this {descr} returns an unsized value `{output_ty}`, so it cannot be called") - ); - if let DefIdOrName::DefId(def_id) = maybe_def - && let Some(def_span) = self.tcx.hir().span_if_local(def_id) - { - err.span_label(def_span, "the callable type is defined here"); - } - } else { - err.span_label(call_expr.span, "call expression requires function"); - } - } - - if let Some(span) = self.tcx.hir().res_span(def) { - let callee_ty = callee_ty.to_string(); - let label = match (unit_variant, inner_callee_path) { - (Some((_, kind, path)), _) => Some(format!("{kind} `{path}` defined here")), - (_, Some(hir::QPath::Resolved(_, path))) => self - .tcx - .sess - .source_map() - .span_to_snippet(path.span) - .ok() - .map(|p| format!("`{p}` defined here returns `{callee_ty}`")), - _ => { - match def { - // Emit a different diagnostic for local variables, as they are not - // type definitions themselves, but rather variables *of* that type. - Res::Local(hir_id) => Some(format!( - "`{}` has type `{}`", - self.tcx.hir().name(hir_id), - callee_ty - )), - Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => { - Some(format!( - "`{}` defined here", - self.tcx.def_path_str(def_id), - )) - } - _ => Some(format!("`{callee_ty}` defined here")), - } - } - }; - if let Some(label) = label { - err.span_label(span, label); - } - } - err.emit(); + self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs); // This is the "default" function signature, used in case of error. // In that case, we check each argument against "error" in order to @@ -574,6 +441,145 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_sig.output() } + fn report_invalid_callee( + &self, + call_expr: &'tcx hir::Expr<'tcx>, + callee_expr: &'tcx hir::Expr<'tcx>, + callee_ty: Ty<'tcx>, + arg_exprs: &'tcx [hir::Expr<'tcx>], + ) { + let mut unit_variant = None; + if let hir::ExprKind::Path(qpath) = &callee_expr.kind + && let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _) + = self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id) + // Only suggest removing parens if there are no arguments + && arg_exprs.is_empty() + { + let descr = match kind { + def::CtorOf::Struct => "struct", + def::CtorOf::Variant => "enum variant", + }; + let removal_span = + callee_expr.span.shrink_to_hi().to(call_expr.span.shrink_to_hi()); + unit_variant = + Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(qpath))); + } + + let callee_ty = self.resolve_vars_if_possible(callee_ty); + let mut err = type_error_struct!( + self.tcx.sess, + callee_expr.span, + callee_ty, + E0618, + "expected function, found {}", + match &unit_variant { + Some((_, kind, path)) => format!("{kind} `{path}`"), + None => format!("`{callee_ty}`"), + } + ); + + self.identify_bad_closure_def_and_call( + &mut err, + call_expr.hir_id, + &callee_expr.kind, + callee_expr.span, + ); + + if let Some((removal_span, kind, path)) = &unit_variant { + err.span_suggestion_verbose( + *removal_span, + &format!( + "`{path}` is a unit {kind}, and does not take parentheses to be constructed", + ), + "", + Applicability::MachineApplicable, + ); + } + + let mut inner_callee_path = None; + let def = match callee_expr.kind { + hir::ExprKind::Path(ref qpath) => { + self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id) + } + hir::ExprKind::Call(ref inner_callee, _) => { + // If the call spans more than one line and the callee kind is + // itself another `ExprCall`, that's a clue that we might just be + // missing a semicolon (Issue #51055) + let call_is_multiline = self.tcx.sess.source_map().is_multiline(call_expr.span); + if call_is_multiline { + err.span_suggestion( + callee_expr.span.shrink_to_hi(), + "consider using a semicolon here", + ";", + Applicability::MaybeIncorrect, + ); + } + if let hir::ExprKind::Path(ref inner_qpath) = inner_callee.kind { + inner_callee_path = Some(inner_qpath); + self.typeck_results.borrow().qpath_res(inner_qpath, inner_callee.hir_id) + } else { + Res::Err + } + } + _ => Res::Err, + }; + + if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) { + if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_expr, callee_ty) + && !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span) + { + let descr = match maybe_def { + DefIdOrName::DefId(def_id) => self.tcx.def_kind(def_id).descr(def_id), + DefIdOrName::Name(name) => name, + }; + err.span_label( + callee_expr.span, + format!("this {descr} returns an unsized value `{output_ty}`, so it cannot be called") + ); + if let DefIdOrName::DefId(def_id) = maybe_def + && let Some(def_span) = self.tcx.hir().span_if_local(def_id) + { + err.span_label(def_span, "the callable type is defined here"); + } + } else { + err.span_label(call_expr.span, "call expression requires function"); + } + } + + if let Some(span) = self.tcx.hir().res_span(def) { + let callee_ty = callee_ty.to_string(); + let label = match (unit_variant, inner_callee_path) { + (Some((_, kind, path)), _) => Some(format!("{kind} `{path}` defined here")), + (_, Some(hir::QPath::Resolved(_, path))) => self + .tcx + .sess + .source_map() + .span_to_snippet(path.span) + .ok() + .map(|p| format!("`{p}` defined here returns `{callee_ty}`")), + _ => { + match def { + // Emit a different diagnostic for local variables, as they are not + // type definitions themselves, but rather variables *of* that type. + Res::Local(hir_id) => Some(format!( + "`{}` has type `{}`", + self.tcx.hir().name(hir_id), + callee_ty + )), + Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => { + Some(format!("`{}` defined here", self.tcx.def_path_str(def_id),)) + } + _ => Some(format!("`{callee_ty}` defined here")), + } + } + }; + if let Some(label) = label { + err.span_label(span, label); + } + } + err.emit(); + } + fn confirm_deferred_closure_call( &self, call_expr: &'tcx hir::Expr<'tcx>, diff --git a/compiler/rustc_hir_analysis/src/check/cast.rs b/compiler/rustc_hir_analysis/src/check/cast.rs index 81a979865ac..01badc133c9 100644 --- a/compiler/rustc_hir_analysis/src/check/cast.rs +++ b/compiler/rustc_hir_analysis/src/check/cast.rs @@ -33,7 +33,7 @@ use super::FnCtxt; use crate::hir::def_id::DefId; use crate::type_error_struct; use hir::def_id::LOCAL_CRATE; -use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{struct_span_err, Applicability, DelayDm, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode}; use rustc_middle::mir::Mutability; @@ -754,19 +754,25 @@ impl<'a, 'tcx> CastCheck<'tcx> { } else { ("", lint::builtin::TRIVIAL_CASTS) }; - fcx.tcx.struct_span_lint_hir(lint, self.expr.hir_id, self.span, |err| { - err.build(&format!( - "trivial {}cast: `{}` as `{}`", - adjective, - fcx.ty_to_string(t_expr), - fcx.ty_to_string(t_cast) - )) - .help(&format!( - "cast can be replaced by coercion; this might \ - require {type_asc_or}a temporary variable" - )) - .emit(); - }); + fcx.tcx.struct_span_lint_hir( + lint, + self.expr.hir_id, + self.span, + DelayDm(|| { + format!( + "trivial {}cast: `{}` as `{}`", + adjective, + fcx.ty_to_string(t_expr), + fcx.ty_to_string(t_cast) + ) + }), + |lint| { + lint.help(format!( + "cast can be replaced by coercion; this might \ + require {type_asc_or}a temporary variable" + )) + }, + ); } #[instrument(skip(fcx), level = "debug")] @@ -1074,12 +1080,12 @@ impl<'a, 'tcx> CastCheck<'tcx> { lint::builtin::CENUM_IMPL_DROP_CAST, self.expr.hir_id, self.span, - |err| { - err.build(&format!( - "cannot cast enum `{}` into integer `{}` because it implements `Drop`", - self.expr_ty, self.cast_ty - )) - .emit(); + DelayDm(|| format!( + "cannot cast enum `{}` into integer `{}` because it implements `Drop`", + self.expr_ty, self.cast_ty + )), + |lint| { + lint }, ); } @@ -1090,12 +1096,11 @@ impl<'a, 'tcx> CastCheck<'tcx> { lint::builtin::LOSSY_PROVENANCE_CASTS, self.expr.hir_id, self.span, - |err| { - let mut err = err.build(&format!( + DelayDm(|| format!( "under strict provenance it is considered bad style to cast pointer `{}` to integer `{}`", self.expr_ty, self.cast_ty - )); - + )), + |lint| { let msg = "use `.addr()` to obtain the address of a pointer"; let expr_prec = self.expr.precedence().order(); @@ -1114,9 +1119,9 @@ impl<'a, 'tcx> CastCheck<'tcx> { (cast_span, format!(").addr(){scalar_cast}")), ]; - err.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect); + lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect); } else { - err.span_suggestion( + lint.span_suggestion( cast_span, msg, format!(".addr(){scalar_cast}"), @@ -1124,12 +1129,12 @@ impl<'a, 'tcx> CastCheck<'tcx> { ); } - err.help( + lint.help( "if you can't comply with strict provenance and need to expose the pointer \ provenance you can use `.expose_addr()` instead" ); - err.emit(); + lint }, ); } @@ -1139,24 +1144,24 @@ impl<'a, 'tcx> CastCheck<'tcx> { lint::builtin::FUZZY_PROVENANCE_CASTS, self.expr.hir_id, self.span, - |err| { - let mut err = err.build(&format!( - "strict provenance disallows casting integer `{}` to pointer `{}`", - self.expr_ty, self.cast_ty - )); + DelayDm(|| format!( + "strict provenance disallows casting integer `{}` to pointer `{}`", + self.expr_ty, self.cast_ty + )), + |lint| { let msg = "use `.with_addr()` to adjust a valid pointer in the same allocation, to this address"; let suggestions = vec![ (self.expr_span.shrink_to_lo(), String::from("(...).with_addr(")), (self.expr_span.shrink_to_hi().to(self.cast_span), String::from(")")), ]; - err.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect); - err.help( + lint.multipart_suggestion(msg, suggestions, Applicability::MaybeIncorrect); + lint.help( "if you can't comply with strict provenance and don't have a pointer with \ the correct provenance you can use `std::ptr::from_exposed_addr()` instead" ); - err.emit(); + lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index d82ee8f48c5..824144aeac0 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -48,9 +48,13 @@ pub(super) fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Ab .emit(); } None => { - tcx.struct_span_lint_hir(UNSUPPORTED_CALLING_CONVENTIONS, hir_id, span, |lint| { - lint.build("use of calling convention not supported on this target").emit(); - }); + tcx.struct_span_lint_hir( + UNSUPPORTED_CALLING_CONVENTIONS, + hir_id, + span, + "use of calling convention not supported on this target", + |lint| lint, + ); } } @@ -510,10 +514,10 @@ fn check_static_inhabited<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { UNINHABITED_STATIC, tcx.hir().local_def_id_to_hir_id(def_id), span, + "static of uninhabited type", |lint| { - lint.build("static of uninhabited type") + lint .note("uninhabited statics cannot be initialized, and any access would be an immediate error") - .emit(); }, ); } @@ -609,9 +613,12 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) { match arg.kind { hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments { - [PathSegment { res: Res::SelfTy { trait_: _, alias_to: impl_ref }, .. }] => { - let impl_ty_name = - impl_ref.map(|(def_id, _)| self.tcx.def_path_str(def_id)); + [PathSegment { res: Res::SelfTyParam { .. }, .. }] => { + let impl_ty_name = None; + self.selftys.push((path.span, impl_ty_name)); + } + [PathSegment { res: Res::SelfTyAlias { alias_to: def_id, .. }, .. }] => { + let impl_ty_name = Some(self.tcx.def_path_str(*def_id)); self.selftys.push((path.span, impl_ty_name)); } _ => {} @@ -1434,6 +1441,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, tcx.hir().local_def_id_to_hir_id(adt.did().expect_local()), span, + "zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types", |lint| { let note = if non_exhaustive { "is marked with `#[non_exhaustive]`" @@ -1441,10 +1449,9 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, sp: Span, adt: ty::AdtD "contains private fields" }; let field_ty = tcx.def_path_str_with_substs(def_id, substs); - lint.build("zero-sized fields in repr(transparent) cannot contain external non-exhaustive types") + lint .note(format!("this {descr} contains `{field_ty}`, which {note}, \ and makes it not a breaking change to become non-zero-sized in the future.")) - .emit(); }, ) } diff --git a/compiler/rustc_hir_analysis/src/check/demand.rs b/compiler/rustc_hir_analysis/src/check/demand.rs index 264df8b914b..d396c801c09 100644 --- a/compiler/rustc_hir_analysis/src/check/demand.rs +++ b/compiler/rustc_hir_analysis/src/check/demand.rs @@ -32,17 +32,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: Option<TypeError<'tcx>>, ) { self.annotate_expected_due_to_let_ty(err, expr, error); - self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr); - self.suggest_compatible_variants(err, expr, expected, expr_ty); - self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty); - if self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) { - return; - } - self.suggest_no_capture_closure(err, expected, expr_ty); - self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty); - self.suggest_missing_parentheses(err, expr); - self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected); - self.suggest_copied_or_cloned(err, expr, expr_ty, expected); + + // Use `||` to give these suggestions a precedence + let _ = self.suggest_missing_parentheses(err, expr) + || self.suggest_deref_ref_or_into(err, expr, expected, expr_ty, expected_ty_expr) + || self.suggest_compatible_variants(err, expr, expected, expr_ty) + || self.suggest_non_zero_new_unwrap(err, expr, expected, expr_ty) + || self.suggest_calling_boxed_future_when_appropriate(err, expr, expected, expr_ty) + || self.suggest_no_capture_closure(err, expected, expr_ty) + || self.suggest_boxing_when_appropriate(err, expr, expected, expr_ty) + || self.suggest_block_to_brackets_peeling_refs(err, expr, expr_ty, expected) + || self.suggest_copied_or_cloned(err, expr, expr_ty, expected) + || self.suggest_into(err, expr, expr_ty, expected); + self.note_type_is_not_clone(err, expected, expr_ty, expr); self.note_need_for_fn_pointer(err, expected, expr_ty); self.note_internal_mutation_in_method(err, expr, expected, expr_ty); @@ -286,7 +288,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, expected: Ty<'tcx>, expr_ty: Ty<'tcx>, - ) { + ) -> bool { if let ty::Adt(expected_adt, substs) = expected.kind() { if let hir::ExprKind::Field(base, ident) = expr.kind { let base_ty = self.typeck_results.borrow().expr_ty(base); @@ -299,7 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "", Applicability::MaybeIncorrect, ); - return + return true; } } @@ -338,7 +340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if self.tcx.is_diagnostic_item(sym::Option, expected_adt.did()) { vec!["None", "Some(())"] } else { - return; + return false; }; if let Some(indent) = self.tcx.sess.source_map().indentation_before(span.shrink_to_lo()) @@ -358,7 +360,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MaybeIncorrect, ); } - return; + return true; } } } @@ -445,6 +447,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { suggestions_for(&**variant, *ctor_kind, *field_name), Applicability::MaybeIncorrect, ); + return true; } _ => { // More than one matching variant. @@ -460,9 +463,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), Applicability::MaybeIncorrect, ); + return true; } } } + + false } fn suggest_non_zero_new_unwrap( @@ -471,19 +477,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, expected: Ty<'tcx>, expr_ty: Ty<'tcx>, - ) { + ) -> bool { let tcx = self.tcx; let (adt, unwrap) = match expected.kind() { // In case Option<NonZero*> is wanted, but * is provided, suggest calling new ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => { // Unwrap option - let ty::Adt(adt, _) = substs.type_at(0).kind() else { return }; + let ty::Adt(adt, _) = substs.type_at(0).kind() else { return false; }; (adt, "") } // In case NonZero* is wanted, but * is provided also add `.unwrap()` to satisfy types ty::Adt(adt, _) => (adt, ".unwrap()"), - _ => return, + _ => return false, }; let map = [ @@ -502,7 +508,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let Some((s, _)) = map .iter() .find(|&&(s, t)| self.tcx.is_diagnostic_item(s, adt.did()) && self.can_coerce(expr_ty, t)) - else { return }; + else { return false; }; let path = self.tcx.def_path_str(adt.non_enum_variant().def_id); @@ -514,6 +520,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ], Applicability::MaybeIncorrect, ); + + true } pub fn get_conversion_methods( diff --git a/compiler/rustc_hir_analysis/src/check/expr.rs b/compiler/rustc_hir_analysis/src/check/expr.rs index 48a4f40780b..b9459887c46 100644 --- a/compiler/rustc_hir_analysis/src/check/expr.rs +++ b/compiler/rustc_hir_analysis/src/check/expr.rs @@ -41,6 +41,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; use rustc_middle::ty::error::TypeError::FieldMisMatch; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitable}; +use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::parse::feature_err; use rustc_span::hygiene::DesugaringKind; use rustc_span::lev_distance::find_best_match_for_name; @@ -394,7 +395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(sp) = tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) { - tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp); + err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } err.emit(); oprnd_t = tcx.ty_error(); @@ -541,7 +542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // been resolved or we errored. This is important as we can only check transmute // on concrete types, but the output type may not be known yet (it would only // be known if explicitly specified via turbofish). - self.deferred_transmute_checks.borrow_mut().push((from, to, expr.span)); + self.deferred_transmute_checks.borrow_mut().push((from, to, expr.hir_id)); } if !tcx.features().unsized_fn_params { // We want to remove some Sized bounds from std functions, diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs index 4522678802b..e51e5280620 100644 --- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/_impl.rs @@ -58,17 +58,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind); - self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| { - let msg = format!("unreachable {}", kind); - lint.build(&msg) - .span_label(span, &msg) - .span_label( + let msg = format!("unreachable {}", kind); + self.tcx().struct_span_lint_hir( + lint::builtin::UNREACHABLE_CODE, + id, + span, + &msg, + |lint| { + lint.span_label(span, &msg).span_label( orig_span, custom_note .unwrap_or("any code following this expression is unreachable"), ) - .emit(); - }) + }, + ) } } } @@ -88,14 +91,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mutate_fulfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>), ) -> Ty<'tcx> { // No Infer()? Nothing needs doing. - if !ty.has_infer_types_or_consts() { + if !ty.has_non_region_infer() { debug!("no inference var, nothing needs doing"); return ty; } // If `ty` is a type variable, see whether we already know what it is. ty = self.resolve_vars_if_possible(ty); - if !ty.has_infer_types_or_consts() { + if !ty.has_non_region_infer() { debug!(?ty); return ty; } diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs index 64e7fa1a42b..13e74021b9e 100644 --- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/checks.rs @@ -50,8 +50,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn check_transmutes(&self) { let mut deferred_transmute_checks = self.deferred_transmute_checks.borrow_mut(); debug!("FnCtxt::check_transmutes: {} deferred checks", deferred_transmute_checks.len()); - for (from, to, span) in deferred_transmute_checks.drain(..) { - self.check_transmute(span, from, to); + for (from, to, hir_id) in deferred_transmute_checks.drain(..) { + self.check_transmute(from, to, hir_id); } } @@ -63,7 +63,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let get_operand_ty = |expr| { let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); let ty = self.resolve_vars_if_possible(ty); - if ty.has_infer_types_or_consts() { + if ty.has_non_region_infer() { assert!(self.is_tainted_by_errors()); self.tcx.ty_error() } else { @@ -1199,7 +1199,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => bug!("unexpected type: {:?}", ty), }, Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) - | Res::SelfTy { .. } => match ty.kind() { + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } => match ty.kind() { ty::Adt(adt, substs) if !adt.is_enum() => { Some((adt.non_enum_variant(), adt.did(), substs)) } diff --git a/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs index c32d1309031..09890c55cd3 100644 --- a/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_analysis/src/check/fn_ctxt/suggestions.rs @@ -3,7 +3,7 @@ use crate::astconv::AstConv; use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel}; use hir::def_id::DefId; -use rustc_ast::util::parser::ExprPrecedence; +use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX}; use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind}; @@ -15,6 +15,7 @@ use rustc_infer::infer::{self, TyCtxtInferExt}; use rustc_infer::traits::{self, StatementAsExpression}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, Binder, IsSuggestable, ToPredicate, Ty}; +use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_trait_selection::infer::InferCtxtExt; @@ -64,7 +65,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// When encountering an fn-like type, try accessing the output of the type - /// // and suggesting calling it if it satisfies a predicate (i.e. if the + /// and suggesting calling it if it satisfies a predicate (i.e. if the /// output has a method or a field): /// ```compile_fail,E0308 /// fn foo(x: usize) -> usize { x } @@ -138,7 +139,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg, applicability, ); - return true; } false @@ -327,7 +327,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, found: Ty<'tcx>, expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, - ) { + ) -> bool { let expr = expr.peel_blocks(); if let Some((sp, msg, suggestion, applicability, verbose)) = self.check_ref(expr, found, expected) @@ -337,12 +337,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err.span_suggestion(sp, &msg, suggestion, applicability); } + return true; + } else if self.suggest_else_fn_with_closure(err, expr, found, expected) + { + return true; } else if self.suggest_fn_call(err, expr, found, |output| self.can_coerce(output, expected)) && let ty::FnDef(def_id, ..) = &found.kind() && let Some(sp) = self.tcx.hir().span_if_local(*def_id) { err.span_label(sp, format!("{found} defined here")); - } else if !self.check_for_cast(err, expr, found, expected, expected_ty_expr) { + return true; + } else if self.check_for_cast(err, expr, found, expected, expected_ty_expr) { + return true; + } else { let methods = self.get_conversion_methods(expr.span, expected, found, expr.hir_id); if !methods.is_empty() { let mut suggestions = methods.iter() @@ -393,6 +400,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { suggestions, Applicability::MaybeIncorrect, ); + return true; } } else if let ty::Adt(found_adt, found_substs) = found.kind() && self.tcx.is_diagnostic_item(sym::Option, found_adt.did()) @@ -417,9 +425,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!(".map(|x| &*{}x)", "*".repeat(ref_cnt)), Applicability::MaybeIncorrect, ); + return true; } } } + + false } /// When encountering the expected boxed value allocated in the stack, suggest allocating it @@ -430,13 +441,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, expected: Ty<'tcx>, found: Ty<'tcx>, - ) { + ) -> bool { if self.tcx.hir().is_inside_const_context(expr.hir_id) { // Do not suggest `Box::new` in const context. - return; + return false; } if !expected.is_box() || found.is_box() { - return; + return false; } let boxed_found = self.tcx.mk_box(found); if self.can_coerce(boxed_found, expected) { @@ -454,6 +465,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { https://doc.rust-lang.org/rust-by-example/std/box.html, and \ https://doc.rust-lang.org/std/boxed/index.html", ); + true + } else { + false } } @@ -464,7 +478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err: &mut Diagnostic, expected: Ty<'tcx>, found: Ty<'tcx>, - ) { + ) -> bool { if let (ty::FnPtr(_), ty::Closure(def_id, _)) = (expected.kind(), found.kind()) { if let Some(upvars) = self.tcx.upvars_mentioned(*def_id) { // Report upto four upvars being captured to reduce the amount error messages @@ -488,8 +502,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { multi_span, "closures can only be coerced to `fn` types if they do not capture any variables" ); + return true; } } + false } /// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`. @@ -891,11 +907,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, err: &mut Diagnostic, expr: &hir::Expr<'_>, - ) { + ) -> bool { let sp = self.tcx.sess.source_map().start_point(expr.span); if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) { // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }` - self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp); + err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); + true + } else { + false } } @@ -908,7 +927,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mut expr: &hir::Expr<'_>, mut expr_ty: Ty<'tcx>, mut expected_ty: Ty<'tcx>, - ) { + ) -> bool { loop { match (&expr.kind, expr_ty.kind(), expected_ty.kind()) { ( @@ -922,9 +941,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } (hir::ExprKind::Block(blk, _), _, _) => { self.suggest_block_to_brackets(diag, *blk, expr_ty, expected_ty); - break; + break true; } - _ => break, + _ => break false, } } } @@ -935,11 +954,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'_>, expr_ty: Ty<'tcx>, expected_ty: Ty<'tcx>, - ) { - let ty::Adt(adt_def, substs) = expr_ty.kind() else { return; }; - let ty::Adt(expected_adt_def, expected_substs) = expected_ty.kind() else { return; }; + ) -> bool { + let ty::Adt(adt_def, substs) = expr_ty.kind() else { return false; }; + let ty::Adt(expected_adt_def, expected_substs) = expected_ty.kind() else { return false; }; if adt_def != expected_adt_def { - return; + return false; } let mut suggest_copied_or_cloned = || { @@ -958,6 +977,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ".copied()", Applicability::MachineApplicable, ); + return true; } else if let Some(clone_did) = self.tcx.lang_items().clone_trait() && rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions( self, @@ -975,8 +995,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ".cloned()", Applicability::MachineApplicable, ); + return true; } } + false }; if let Some(result_did) = self.tcx.get_diagnostic_item(sym::Result) @@ -984,12 +1006,67 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check that the error types are equal && self.can_eq(self.param_env, substs.type_at(1), expected_substs.type_at(1)).is_ok() { - suggest_copied_or_cloned(); + return suggest_copied_or_cloned(); } else if let Some(option_did) = self.tcx.get_diagnostic_item(sym::Option) && adt_def.did() == option_did { - suggest_copied_or_cloned(); + return suggest_copied_or_cloned(); + } + + false + } + + pub(crate) fn suggest_into( + &self, + diag: &mut Diagnostic, + expr: &hir::Expr<'_>, + expr_ty: Ty<'tcx>, + expected_ty: Ty<'tcx>, + ) -> bool { + let expr = expr.peel_blocks(); + + // We have better suggestions for scalar interconversions... + if expr_ty.is_scalar() && expected_ty.is_scalar() { + return false; + } + + // Don't suggest turning a block into another type (e.g. `{}.into()`) + if matches!(expr.kind, hir::ExprKind::Block(..)) { + return false; + } + + // We'll later suggest `.as_ref` when noting the type error, + // so skip if we will suggest that instead. + if self.should_suggest_as_ref(expected_ty, expr_ty).is_some() { + return false; + } + + if let Some(into_def_id) = self.tcx.get_diagnostic_item(sym::Into) + && self.predicate_must_hold_modulo_regions(&traits::Obligation::new( + self.misc(expr.span), + self.param_env, + ty::Binder::dummy(ty::TraitRef { + def_id: into_def_id, + substs: self.tcx.mk_substs_trait(expr_ty, &[expected_ty.into()]), + }) + .to_poly_trait_predicate() + .to_predicate(self.tcx), + )) + { + let sugg = if expr.precedence().order() >= PREC_POSTFIX { + vec![(expr.span.shrink_to_hi(), ".into()".to_owned())] + } else { + vec![(expr.span.shrink_to_lo(), "(".to_owned()), (expr.span.shrink_to_hi(), ").into()".to_owned())] + }; + diag.multipart_suggestion( + format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"), + sugg, + Applicability::MaybeIncorrect + ); + return true; } + + false } /// Suggest wrapping the block in square brackets instead of curly braces @@ -1121,7 +1198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err.span_suggestion_short( span_semi, - "remove this semicolon", + "remove this semicolon to return this value", "", Applicability::MachineApplicable, ); diff --git a/compiler/rustc_hir_analysis/src/check/generator_interior.rs b/compiler/rustc_hir_analysis/src/check/generator_interior.rs index 254a19368bf..898419b5b23 100644 --- a/compiler/rustc_hir_analysis/src/check/generator_interior.rs +++ b/compiler/rustc_hir_analysis/src/check/generator_interior.rs @@ -6,7 +6,7 @@ use self::drop_ranges::DropRanges; use super::FnCtxt; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_errors::pluralize; +use rustc_errors::{pluralize, DelayDm}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -610,33 +610,33 @@ fn check_must_not_suspend_def( rustc_session::lint::builtin::MUST_NOT_SUSPEND, hir_id, data.source_span, - |lint| { - let msg = format!( + DelayDm(|| { + format!( "{}`{}`{} held across a suspend point, but should not be", data.descr_pre, tcx.def_path_str(def_id), data.descr_post, - ); - let mut err = lint.build(&msg); - + ) + }), + |lint| { // add span pointing to the offending yield/await - err.span_label(data.yield_span, "the value is held across this suspend point"); + lint.span_label(data.yield_span, "the value is held across this suspend point"); // Add optional reason note if let Some(note) = attr.value_str() { // FIXME(guswynn): consider formatting this better - err.span_note(data.source_span, note.as_str()); + lint.span_note(data.source_span, note.as_str()); } // Add some quick suggestions on what to do // FIXME: can `drop` work as a suggestion here as well? - err.span_help( + lint.span_help( data.source_span, "consider using a block (`{ ... }`) \ to shrink the value's scope, ending before the suspend point", ); - err.emit(); + lint }, ); diff --git a/compiler/rustc_hir_analysis/src/check/inherited.rs b/compiler/rustc_hir_analysis/src/check/inherited.rs index 37c830d4e38..2546227e138 100644 --- a/compiler/rustc_hir_analysis/src/check/inherited.rs +++ b/compiler/rustc_hir_analysis/src/check/inherited.rs @@ -55,7 +55,7 @@ pub struct Inherited<'a, 'tcx> { pub(super) deferred_cast_checks: RefCell<Vec<super::cast::CastCheck<'tcx>>>, - pub(super) deferred_transmute_checks: RefCell<Vec<(Ty<'tcx>, Ty<'tcx>, Span)>>, + pub(super) deferred_transmute_checks: RefCell<Vec<(Ty<'tcx>, Ty<'tcx>, hir::HirId)>>, pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, hir::HirId)>>, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index ae484b4feda..8be1cf04f8b 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -7,7 +7,8 @@ use crate::errors::{ }; use crate::require_same_types; -use rustc_errors::struct_span_err; +use hir::def_id::DefId; +use rustc_errors::{struct_span_err, DiagnosticMessage}; use rustc_hir as hir; use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{self, TyCtxt}; @@ -61,8 +62,12 @@ fn equate_intrinsic_type<'tcx>( } /// Returns the unsafety of the given intrinsic. -pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety { - match intrinsic { +pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir::Unsafety { + let has_safe_attr = match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) { + true => hir::Unsafety::Normal, + false => hir::Unsafety::Unsafe, + }; + let is_in_list = match tcx.item_name(intrinsic_id) { // When adding a new intrinsic to this list, // it's usually worth updating that intrinsic's documentation // to note that it's safe to call, since @@ -106,14 +111,26 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety { | sym::variant_count | sym::ptr_mask => hir::Unsafety::Normal, _ => hir::Unsafety::Unsafe, + }; + + if has_safe_attr != is_in_list { + tcx.sess.struct_span_err( + tcx.def_span(intrinsic_id), + DiagnosticMessage::Str(format!( + "intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`", + tcx.item_name(intrinsic_id) + ))).emit(); } + + is_in_list } /// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`, /// and in `library/core/src/intrinsics.rs`. pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n))); - let intrinsic_name = tcx.item_name(it.def_id.to_def_id()); + let intrinsic_id = it.def_id.to_def_id(); + let intrinsic_name = tcx.item_name(intrinsic_id); let name_str = intrinsic_name.as_str(); let bound_vars = tcx.mk_bound_variable_kinds( @@ -160,7 +177,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { }; (n_tps, 0, inputs, output, hir::Unsafety::Unsafe) } else { - let unsafety = intrinsic_operation_unsafety(intrinsic_name); + let unsafety = intrinsic_operation_unsafety(tcx, intrinsic_id); let (n_tps, inputs, output) = match intrinsic_name { sym::abort => (0, Vec::new(), tcx.types.never), sym::unreachable => (0, Vec::new(), tcx.types.never), diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index d8fe63dbf08..4abc00cefb6 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -1,3 +1,4 @@ +use hir::HirId; use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; @@ -6,7 +7,7 @@ use rustc_index::vec::Idx; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy}; use rustc_session::lint; -use rustc_span::{Span, Symbol, DUMMY_SP}; +use rustc_span::{Symbol, DUMMY_SP}; use rustc_target::abi::{Pointer, VariantIdx}; use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType}; @@ -40,11 +41,13 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { - pub fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>) { + pub fn check_transmute(&self, from: Ty<'tcx>, to: Ty<'tcx>, hir_id: HirId) { + let tcx = self.tcx; + let span = tcx.hir().span(hir_id); let convert = |ty: Ty<'tcx>| { let ty = self.resolve_vars_if_possible(ty); - let ty = self.tcx.normalize_erasing_regions(self.param_env, ty); - (SizeSkeleton::compute(ty, self.tcx, self.param_env), ty) + let ty = tcx.normalize_erasing_regions(self.param_env, ty); + (SizeSkeleton::compute(ty, tcx, self.param_env), ty) }; let (sk_from, from) = convert(from); let (sk_to, to) = convert(to); @@ -57,9 +60,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Special-case transmuting from `typeof(function)` and // `Option<typeof(function)>` to present a clearer error. - let from = unpack_option_like(self.tcx, from); - if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&self.tcx) { - struct_span_err!(self.tcx.sess, span, E0591, "can't transmute zero-sized type") + let from = unpack_option_like(tcx, from); + if let (&ty::FnDef(..), SizeSkeleton::Known(size_to)) = (from.kind(), sk_to) && size_to == Pointer.size(&tcx) { + struct_span_err!(tcx.sess, span, E0591, "can't transmute zero-sized type") .note(&format!("source type: {from}")) .note(&format!("target type: {to}")) .help("cast with `as` to a pointer instead") @@ -83,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let mut err = struct_span_err!( - self.tcx.sess, + tcx.sess, span, E0512, "cannot transmute between types of different sizes, \ @@ -146,7 +149,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { target_features: &FxHashSet<Symbol>, ) -> Option<InlineAsmType> { let ty = (self.get_operand_ty)(expr); - if ty.has_infer_types_or_consts() { + if ty.has_non_region_infer() { bug!("inference variable in asm operand ty: {:?} {:?}", expr, ty); } let asm_ty_isize = match self.tcx.sess.target.pointer_width { @@ -328,17 +331,16 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { lint::builtin::ASM_SUB_REGISTER, expr.hir_id, spans, + "formatting may not be suitable for sub-register argument", |lint| { - let msg = "formatting may not be suitable for sub-register argument"; - let mut err = lint.build(msg); - err.span_label(expr.span, "for this argument"); - err.help(&format!( + lint.span_label(expr.span, "for this argument"); + lint.help(&format!( "use `{{{idx}:{suggested_modifier}}}` to have the register formatted as `{suggested_result}`", )); - err.help(&format!( + lint.help(&format!( "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`", )); - err.emit(); + lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs b/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs index 392695cca68..ca4cdf5a0d0 100644 --- a/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs +++ b/compiler/rustc_hir_analysis/src/check/method/prelude2021.rs @@ -82,14 +82,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, self_expr.hir_id, self_expr.span, + format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name), |lint| { let sp = self_expr.span; - let mut lint = lint.build(&format!( - "trait method `{}` will become ambiguous in Rust 2021", - segment.ident.name - )); - let derefs = "*".repeat(pick.autoderefs); let autoref = match pick.autoref_or_ptr_adjustment { @@ -133,7 +129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - lint.emit(); + lint }, ); } else { @@ -143,6 +139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { prelude_or_array_lint, call_expr.hir_id, call_expr.span, + format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name), |lint| { let sp = call_expr.span; let trait_name = self.trait_path_or_bare_name( @@ -151,11 +148,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pick.item.container_id(self.tcx), ); - let mut lint = lint.build(&format!( - "trait method `{}` will become ambiguous in Rust 2021", - segment.ident.name - )); - let (self_adjusted, precise) = self.adjust_expr(pick, self_expr, sp); if precise { let args = args @@ -202,7 +194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - lint.emit(); + lint }, ); } @@ -257,15 +249,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return; } - self.tcx.struct_span_lint_hir(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| { - // "type" refers to either a type or, more likely, a trait from which - // the associated function or method is from. - let container_id = pick.item.container_id(self.tcx); - let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id); - let trait_generics = self.tcx.generics_of(container_id); - - let trait_name = - if trait_generics.params.len() <= trait_generics.has_self as usize { + self.tcx.struct_span_lint_hir( + RUST_2021_PRELUDE_COLLISIONS, + expr_id, + span, + format!( + "trait-associated function `{}` will become ambiguous in Rust 2021", + method_name.name + ), + |lint| { + // "type" refers to either a type or, more likely, a trait from which + // the associated function or method is from. + let container_id = pick.item.container_id(self.tcx); + let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id); + let trait_generics = self.tcx.generics_of(container_id); + + let trait_name = if trait_generics.params.len() <= trait_generics.has_self as usize + { trait_path } else { let counts = trait_generics.own_counts(); @@ -282,44 +282,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) }; - let mut lint = lint.build(&format!( - "trait-associated function `{}` will become ambiguous in Rust 2021", - method_name.name - )); - - let mut self_ty_name = self_ty_span - .find_ancestor_inside(span) - .and_then(|span| self.sess().source_map().span_to_snippet(span).ok()) - .unwrap_or_else(|| self_ty.to_string()); - - // Get the number of generics the self type has (if an Adt) unless we can determine that - // the user has written the self type with generics already which we (naively) do by looking - // for a "<" in `self_ty_name`. - if !self_ty_name.contains('<') { - if let Adt(def, _) = self_ty.kind() { - let generics = self.tcx.generics_of(def.did()); - if !generics.params.is_empty() { - let counts = generics.own_counts(); - self_ty_name += &format!( - "<{}>", - std::iter::repeat("'_") - .take(counts.lifetimes) - .chain(std::iter::repeat("_").take(counts.types + counts.consts)) - .collect::<Vec<_>>() - .join(", ") - ); + let mut self_ty_name = self_ty_span + .find_ancestor_inside(span) + .and_then(|span| self.sess().source_map().span_to_snippet(span).ok()) + .unwrap_or_else(|| self_ty.to_string()); + + // Get the number of generics the self type has (if an Adt) unless we can determine that + // the user has written the self type with generics already which we (naively) do by looking + // for a "<" in `self_ty_name`. + if !self_ty_name.contains('<') { + if let Adt(def, _) = self_ty.kind() { + let generics = self.tcx.generics_of(def.did()); + if !generics.params.is_empty() { + let counts = generics.own_counts(); + self_ty_name += &format!( + "<{}>", + std::iter::repeat("'_") + .take(counts.lifetimes) + .chain( + std::iter::repeat("_").take(counts.types + counts.consts) + ) + .collect::<Vec<_>>() + .join(", ") + ); + } } } - } - lint.span_suggestion( - span, - "disambiguate the associated function", - format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), - Applicability::MachineApplicable, - ); - - lint.emit(); - }); + lint.span_suggestion( + span, + "disambiguate the associated function", + format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,), + Applicability::MachineApplicable, + ); + + lint + }, + ); } fn trait_path_or_bare_name( diff --git a/compiler/rustc_hir_analysis/src/check/method/probe.rs b/compiler/rustc_hir_analysis/src/check/method/probe.rs index 6cd7ced01a3..a761a93dea4 100644 --- a/compiler/rustc_hir_analysis/src/check/method/probe.rs +++ b/compiler/rustc_hir_analysis/src/check/method/probe.rs @@ -409,9 +409,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::TYVAR_BEHIND_RAW_POINTER, scope_expr_id, span, - |lint| { - lint.build("type annotations needed").emit(); - }, + "type annotations needed", + |lint| lint, ); } } else { @@ -1358,24 +1357,24 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { stable_pick: &Pick<'_>, unstable_candidates: &[(Candidate<'tcx>, Symbol)], ) { + let def_kind = stable_pick.item.kind.as_def_kind(); self.tcx.struct_span_lint_hir( lint::builtin::UNSTABLE_NAME_COLLISIONS, self.scope_expr_id, self.span, + format!( + "{} {} with this name may be added to the standard library in the future", + def_kind.article(), + def_kind.descr(stable_pick.item.def_id), + ), |lint| { - let def_kind = stable_pick.item.kind.as_def_kind(); - let mut diag = lint.build(&format!( - "{} {} with this name may be added to the standard library in the future", - def_kind.article(), - def_kind.descr(stable_pick.item.def_id), - )); match (stable_pick.item.kind, stable_pick.item.container) { (ty::AssocKind::Fn, _) => { // FIXME: This should be a `span_suggestion` instead of `help` // However `self.span` only // highlights the method name, so we can't use it. Also consider reusing // the code from `report_method_error()`. - diag.help(&format!( + lint.help(&format!( "call with fully qualified syntax `{}(...)` to keep using the current \ method", self.tcx.def_path_str(stable_pick.item.def_id), @@ -1383,7 +1382,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => { let def_id = stable_pick.item.container_id(self.tcx); - diag.span_suggestion( + lint.span_suggestion( self.span, "use the fully qualified path to the associated const", format!( @@ -1399,7 +1398,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } if self.tcx.sess.is_nightly_build() { for (candidate, feature) in unstable_candidates { - diag.help(&format!( + lint.help(&format!( "add `#![feature({})]` to the crate attributes to enable `{}`", feature, self.tcx.def_path_str(candidate.item.def_id), @@ -1407,7 +1406,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - diag.emit(); + lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/method/suggest.rs b/compiler/rustc_hir_analysis/src/check/method/suggest.rs index 0e82e4956c7..ad1084bd1b1 100644 --- a/compiler/rustc_hir_analysis/src/check/method/suggest.rs +++ b/compiler/rustc_hir_analysis/src/check/method/suggest.rs @@ -2324,6 +2324,60 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + /// issue #102320, for `unwrap_or` with closure as argument, suggest `unwrap_or_else` + /// FIXME: currently not working for suggesting `map_or_else`, see #102408 + pub(crate) fn suggest_else_fn_with_closure( + &self, + err: &mut Diagnostic, + expr: &hir::Expr<'_>, + found: Ty<'tcx>, + expected: Ty<'tcx>, + ) -> bool { + let Some((_def_id_or_name, output, _inputs)) = self.extract_callable_info(expr, found) + else { return false; }; + + if !self.can_coerce(output, expected) { + return false; + } + + let parent = self.tcx.hir().get_parent_node(expr.hir_id); + if let Some(Node::Expr(call_expr)) = self.tcx.hir().find(parent) && + let hir::ExprKind::MethodCall( + hir::PathSegment { ident: method_name, .. }, + self_expr, + args, + .., + ) = call_expr.kind && + let Some(self_ty) = self.typeck_results.borrow().expr_ty_opt(self_expr) { + let new_name = Ident { + name: Symbol::intern(&format!("{}_else", method_name.as_str())), + span: method_name.span, + }; + let probe = self.lookup_probe( + expr.span, + new_name, + self_ty, + self_expr, + ProbeScope::TraitsInScope, + ); + + // check the method arguments number + if let Ok(pick) = probe && + let fn_sig = self.tcx.fn_sig(pick.item.def_id) && + let fn_args = fn_sig.skip_binder().inputs() && + fn_args.len() == args.len() + 1 { + err.span_suggestion_verbose( + method_name.span.shrink_to_hi(), + &format!("try calling `{}` instead", new_name.name.as_str()), + "_else", + Applicability::MaybeIncorrect, + ); + return true; + } + } + false + } + /// Checks whether there is a local type somewhere in the chain of /// autoderefs of `rcvr_ty`. fn type_derefs_to_local( diff --git a/compiler/rustc_hir_analysis/src/check/op.rs b/compiler/rustc_hir_analysis/src/check/op.rs index 4754717c29a..d876b1d20fe 100644 --- a/compiler/rustc_hir_analysis/src/check/op.rs +++ b/compiler/rustc_hir_analysis/src/check/op.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitable}; +use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; @@ -470,7 +471,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This has nothing here because it means we did string // concatenation (e.g., "Hello " + "World!"). This means // we don't want the note in the else clause to be emitted - } else if lhs_ty.has_param_types_or_consts() { + } else if lhs_ty.has_non_region_param() { // Look for a TraitPredicate in the Fulfillment errors, // and use it to generate a suggestion. // @@ -656,7 +657,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("cannot apply unary operator `{}`", op.as_str()), ); - if operand_ty.has_param_types_or_consts() { + if operand_ty.has_non_region_param() { let predicates = errors.iter().filter_map(|error| { error.obligation.predicate.to_opt_poly_trait_pred() }); @@ -677,7 +678,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the previous expression was a block expression, suggest parentheses // (turning this into a binary subtraction operation instead.) // for example, `{2} - 2` -> `({2}) - 2` (see src\test\ui\parser\expr-as-stmt.rs) - self.tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp); + err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } else { match actual.kind() { Uint(_) if op == hir::UnOp::Neg => { diff --git a/compiler/rustc_hir_analysis/src/check/pat.rs b/compiler/rustc_hir_analysis/src/check/pat.rs index 8906b622b68..178326cfdc4 100644 --- a/compiler/rustc_hir_analysis/src/check/pat.rs +++ b/compiler/rustc_hir_analysis/src/check/pat.rs @@ -1790,10 +1790,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &unmentioned_fields.iter().map(|(_, i)| i).collect::<Vec<_>>(), ); - self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, |build| { - let mut lint = build.build("some fields are not explicitly listed"); + self.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, pat.hir_id, pat.span, "some fields are not explicitly listed", |lint| { lint.span_label(pat.span, format!("field{} {} not listed", rustc_errors::pluralize!(unmentioned_fields.len()), joined_patterns)); - lint.help( "ensure that all fields are mentioned explicitly by adding the suggested fields", ); @@ -1801,7 +1799,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "the pattern is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found", ty, )); - lint.emit(); + + lint }); } diff --git a/compiler/rustc_hir_analysis/src/check/upvar.rs b/compiler/rustc_hir_analysis/src/check/upvar.rs index 0b207a6c0be..4f495641691 100644 --- a/compiler/rustc_hir_analysis/src/check/upvar.rs +++ b/compiler/rustc_hir_analysis/src/check/upvar.rs @@ -749,10 +749,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { lint::builtin::RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES, closure_hir_id, closure_head_span, + reasons.migration_message(), |lint| { - let mut diagnostics_builder = lint.build( - &reasons.migration_message(), - ); for NeededMigration { var_hir_id, diagnostics_info } in &need_migrations { // Labels all the usage of the captured variable and why they are responsible // for migration being needed @@ -760,13 +758,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { source_expr: Some(capture_expr_id), var_name: captured_name } => { let cause_span = self.tcx.hir().span(*capture_expr_id); - diagnostics_builder.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`", + lint.span_label(cause_span, format!("in Rust 2018, this closure captures all of `{}`, but in Rust 2021, it will only capture `{}`", self.tcx.hir().name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span } => { - diagnostics_builder.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect", + lint.span_label(*use_span, format!("in Rust 2018, this causes the closure to capture `{}`, but in Rust 2021, it has no effect", self.tcx.hir().name(*var_hir_id), )); } @@ -781,13 +779,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { - diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure", + lint.span_label(drop_location_span, format!("in Rust 2018, `{}` is dropped here, but in Rust 2021, only `{}` will be dropped here as part of the closure", self.tcx.hir().name(*var_hir_id), captured_name, )); } UpvarMigrationInfo::CapturingNothing { use_span: _ } => { - diagnostics_builder.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure", + lint.span_label(drop_location_span, format!("in Rust 2018, `{v}` is dropped here along with the closure, but in Rust 2021 `{v}` is not part of the closure", v = self.tcx.hir().name(*var_hir_id), )); } @@ -800,7 +798,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match &lint_note.captures_info { UpvarMigrationInfo::CapturingPrecise { var_name: captured_name, .. } => { let var_name = self.tcx.hir().name(*var_hir_id); - diagnostics_builder.span_label(closure_head_span, format!("\ + lint.span_label(closure_head_span, format!("\ in Rust 2018, this closure implements {missing_trait} \ as `{var_name}` implements {missing_trait}, but in Rust 2021, \ this closure will no longer implement {missing_trait} \ @@ -814,7 +812,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - diagnostics_builder.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>"); + lint.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html>"); let diagnostic_msg = format!( "add a dummy let to cause {} to be fully captured", @@ -857,7 +855,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We take the indentation from the next non-empty line. let line2 = lines.find(|line| !line.is_empty()).unwrap_or_default(); let indent = line2.split_once(|c: char| !c.is_whitespace()).unwrap_or_default().0; - diagnostics_builder.span_suggestion( + lint.span_suggestion( closure_body_span.with_lo(closure_body_span.lo() + BytePos::from_usize(line1.len())).shrink_to_lo(), &diagnostic_msg, format!("\n{indent}{migration_string};"), @@ -868,7 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // braces, but with more than just the opening // brace on the first line. We put the `let` // directly after the `{`. - diagnostics_builder.span_suggestion( + lint.span_suggestion( closure_body_span.with_lo(closure_body_span.lo() + BytePos(1)).shrink_to_lo(), &diagnostic_msg, format!(" {migration_string};"), @@ -877,7 +875,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // This is a closure without braces around the body. // We add braces to add the `let` before the body. - diagnostics_builder.multipart_suggestion( + lint.multipart_suggestion( &diagnostic_msg, vec![ (closure_body_span.shrink_to_lo(), format!("{{ {migration_string}; ")), @@ -887,7 +885,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } else { - diagnostics_builder.span_suggestion( + lint.span_suggestion( closure_span, &diagnostic_msg, migration_string, @@ -895,7 +893,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - diagnostics_builder.emit(); + lint }, ); } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 7965ec1b43f..d607f901420 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1428,9 +1428,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id let substituted_pred = predicates.rebind(pred).subst(tcx, substs); // Don't check non-defaulted params, dependent defaults (including lifetimes) // or preds with multiple params. - if substituted_pred.has_param_types_or_consts() - || param_count.params.len() > 1 - || has_region + if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region { None } else if predicates.0.predicates.iter().any(|&(p, _)| p == substituted_pred) { diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 1d23ed92921..922833f8580 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -29,14 +29,18 @@ pub fn check_crate(tcx: TyCtxt<'_>) { continue; } let hir::ItemKind::Use(path, _) = item.kind else { unreachable!() }; - tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item.hir_id(), path.span, |lint| { - let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) { - format!("unused import: `{}`", snippet) - } else { - "unused import".to_owned() - }; - lint.build(&msg).emit(); - }); + let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(path.span) { + format!("unused import: `{}`", snippet) + } else { + "unused import".to_owned() + }; + tcx.struct_span_lint_hir( + lint::builtin::UNUSED_IMPORTS, + item.hir_id(), + path.span, + msg, + |lint| lint, + ); } unused_crates_lint(tcx); diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 7d15e5a7f3c..1307f74f210 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -2,7 +2,7 @@ //! crate or pertains to a type defined in this crate. use rustc_data_structures::fx::FxHashSet; -use rustc_errors::struct_span_err; +use rustc_errors::{struct_span_err, DelayDm}; use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; use rustc_middle::ty::subst::GenericArgKind; @@ -412,30 +412,31 @@ fn lint_auto_trait_impl<'tcx>( lint::builtin::SUSPICIOUS_AUTO_TRAIT_IMPLS, tcx.hir().local_def_id_to_hir_id(impl_def_id), tcx.def_span(impl_def_id), - |err| { - let item_span = tcx.def_span(self_type_did); - let self_descr = tcx.def_kind(self_type_did).descr(self_type_did); - let mut err = err.build(&format!( + DelayDm(|| { + format!( "cross-crate traits with a default impl, like `{}`, \ should not be specialized", tcx.def_path_str(trait_ref.def_id), - )); + ) + }), + |lint| { + let item_span = tcx.def_span(self_type_did); + let self_descr = tcx.def_kind(self_type_did).descr(self_type_did); match arg { ty::util::NotUniqueParam::DuplicateParam(arg) => { - err.note(&format!("`{}` is mentioned multiple times", arg)); + lint.note(&format!("`{}` is mentioned multiple times", arg)); } ty::util::NotUniqueParam::NotParam(arg) => { - err.note(&format!("`{}` is not a generic parameter", arg)); + lint.note(&format!("`{}` is not a generic parameter", arg)); } } - err.span_note( + lint.span_note( item_span, &format!( "try using the same sequence of generic parameters as the {} definition", self_descr, ), - ); - err.emit(); + ) }, ); } diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index e7deae2b557..ab4b861b6cb 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -15,46 +15,40 @@ //! crate as a kind of pass. This should eventually be factored away. use crate::astconv::AstConv; -use crate::bounds::Bounds; use crate::check::intrinsic::intrinsic_operation_unsafety; -use crate::constrained_generic_params as cgp; use crate::errors; -use crate::middle::resolve_lifetime as rl; use rustc_ast as ast; use rustc_ast::{MetaItemKind, NestedMetaItem}; use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr}; use rustc_data_structures::captures::Captures; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey}; use rustc_hir as hir; -use rustc_hir::def::{CtorKind, DefKind}; +use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::weak_lang_items; -use rustc_hir::{GenericParamKind, HirId, Node}; +use rustc_hir::{GenericParamKind, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::util::Discr; -use rustc_middle::ty::util::IntTypeExt; +use rustc_middle::ty::util::{Discr, IntTypeExt}; +use rustc_middle::ty::ReprOptions; use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, IsSuggestable, Ty, TyCtxt}; -use rustc_middle::ty::{ReprOptions, ToPredicate}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use rustc_target::spec::{abi, SanitizerSet}; use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName; use std::iter; +mod generics_of; mod item_bounds; +mod predicates_of; mod type_of; -#[derive(Debug)] -struct OnlySelfBounds(bool); - /////////////////////////////////////////////////////////////////////////// // Main entry point @@ -68,14 +62,15 @@ pub fn provide(providers: &mut Providers) { type_of: type_of::type_of, item_bounds: item_bounds::item_bounds, explicit_item_bounds: item_bounds::explicit_item_bounds, - generics_of, - predicates_of, + generics_of: generics_of::generics_of, + predicates_of: predicates_of::predicates_of, predicates_defined_on, - explicit_predicates_of, - super_predicates_of, - super_predicates_that_define_assoc_type, - trait_explicit_predicates_and_bounds, - type_param_predicates, + explicit_predicates_of: predicates_of::explicit_predicates_of, + super_predicates_of: predicates_of::super_predicates_of, + super_predicates_that_define_assoc_type: + predicates_of::super_predicates_that_define_assoc_type, + trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds, + type_param_predicates: predicates_of::type_param_predicates, trait_def, adt_def, fn_sig, @@ -572,160 +567,6 @@ fn get_new_lifetime_name<'tcx>( (1..).flat_map(a_to_z_repeat_n).find(|lt| !existing_lifetimes.contains(lt.as_str())).unwrap() } -/// Returns the predicates defined on `item_def_id` of the form -/// `X: Foo` where `X` is the type parameter `def_id`. -#[instrument(level = "trace", skip(tcx))] -fn type_param_predicates( - tcx: TyCtxt<'_>, - (item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident), -) -> ty::GenericPredicates<'_> { - use rustc_hir::*; - - // In the AST, bounds can derive from two places. Either - // written inline like `<T: Foo>` or in a where-clause like - // `where T: Foo`. - - let param_id = tcx.hir().local_def_id_to_hir_id(def_id); - let param_owner = tcx.hir().ty_param_owner(def_id); - let generics = tcx.generics_of(param_owner); - let index = generics.param_def_id_to_index[&def_id.to_def_id()]; - let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id)); - - // Don't look for bounds where the type parameter isn't in scope. - let parent = if item_def_id == param_owner.to_def_id() { - None - } else { - tcx.generics_of(item_def_id).parent - }; - - let mut result = parent - .map(|parent| { - let icx = ItemCtxt::new(tcx, parent); - icx.get_type_parameter_bounds(DUMMY_SP, def_id.to_def_id(), assoc_name) - }) - .unwrap_or_default(); - let mut extend = None; - - let item_hir_id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local()); - let ast_generics = match tcx.hir().get(item_hir_id) { - Node::TraitItem(item) => &item.generics, - - Node::ImplItem(item) => &item.generics, - - Node::Item(item) => { - match item.kind { - ItemKind::Fn(.., ref generics, _) - | ItemKind::Impl(hir::Impl { ref generics, .. }) - | ItemKind::TyAlias(_, ref generics) - | ItemKind::OpaqueTy(OpaqueTy { - ref generics, - origin: hir::OpaqueTyOrigin::TyAlias, - .. - }) - | ItemKind::Enum(_, ref generics) - | ItemKind::Struct(_, ref generics) - | ItemKind::Union(_, ref generics) => generics, - ItemKind::Trait(_, _, ref generics, ..) => { - // Implied `Self: Trait` and supertrait bounds. - if param_id == item_hir_id { - let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); - extend = - Some((identity_trait_ref.without_const().to_predicate(tcx), item.span)); - } - generics - } - _ => return result, - } - } - - Node::ForeignItem(item) => match item.kind { - ForeignItemKind::Fn(_, _, ref generics) => generics, - _ => return result, - }, - - _ => return result, - }; - - let icx = ItemCtxt::new(tcx, item_def_id); - let extra_predicates = extend.into_iter().chain( - icx.type_parameter_bounds_in_generics( - ast_generics, - param_id, - ty, - OnlySelfBounds(true), - Some(assoc_name), - ) - .into_iter() - .filter(|(predicate, _)| match predicate.kind().skip_binder() { - ty::PredicateKind::Trait(data) => data.self_ty().is_param(index), - _ => false, - }), - ); - result.predicates = - tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(extra_predicates)); - result -} - -impl<'tcx> ItemCtxt<'tcx> { - /// Finds bounds from `hir::Generics`. This requires scanning through the - /// AST. We do this to avoid having to convert *all* the bounds, which - /// would create artificial cycles. Instead, we can only convert the - /// bounds for a type parameter `X` if `X::Foo` is used. - #[instrument(level = "trace", skip(self, ast_generics))] - fn type_parameter_bounds_in_generics( - &self, - ast_generics: &'tcx hir::Generics<'tcx>, - param_id: hir::HirId, - ty: Ty<'tcx>, - only_self_bounds: OnlySelfBounds, - assoc_name: Option<Ident>, - ) -> Vec<(ty::Predicate<'tcx>, Span)> { - let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id(); - trace!(?param_def_id); - ast_generics - .predicates - .iter() - .filter_map(|wp| match *wp { - hir::WherePredicate::BoundPredicate(ref bp) => Some(bp), - _ => None, - }) - .flat_map(|bp| { - let bt = if bp.is_param_bound(param_def_id) { - Some(ty) - } else if !only_self_bounds.0 { - Some(self.to_ty(bp.bounded_ty)) - } else { - None - }; - let bvars = self.tcx.late_bound_vars(bp.bounded_ty.hir_id); - - bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter( - |(_, b, _)| match assoc_name { - Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name), - None => true, - }, - ) - }) - .flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars)) - .collect() - } - - #[instrument(level = "trace", skip(self))] - fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool { - match b { - hir::GenericBound::Trait(poly_trait_ref, _) => { - let trait_ref = &poly_trait_ref.trait_ref; - if let Some(trait_did) = trait_ref.trait_def_id() { - self.tcx.trait_may_define_assoc_type(trait_did, assoc_name) - } else { - false - } - } - _ => false, - } - } -} - fn convert_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) { let it = tcx.hir().item(item_id); debug!("convert: item {} with id {}", it.ident, it.hir_id()); @@ -1097,96 +938,6 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> { tcx.alloc_adt_def(def_id.to_def_id(), kind, variants, repr) } -/// Ensures that the super-predicates of the trait with a `DefId` -/// of `trait_def_id` are converted and stored. This also ensures that -/// the transitive super-predicates are converted. -fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredicates<'_> { - debug!("super_predicates(trait_def_id={:?})", trait_def_id); - tcx.super_predicates_that_define_assoc_type((trait_def_id, None)) -} - -/// Ensures that the super-predicates of the trait with a `DefId` -/// of `trait_def_id` are converted and stored. This also ensures that -/// the transitive super-predicates are converted. -fn super_predicates_that_define_assoc_type( - tcx: TyCtxt<'_>, - (trait_def_id, assoc_name): (DefId, Option<Ident>), -) -> ty::GenericPredicates<'_> { - debug!( - "super_predicates_that_define_assoc_type(trait_def_id={:?}, assoc_name={:?})", - trait_def_id, assoc_name - ); - if trait_def_id.is_local() { - debug!("super_predicates_that_define_assoc_type: local trait_def_id={:?}", trait_def_id); - let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local()); - - let Node::Item(item) = tcx.hir().get(trait_hir_id) else { - bug!("trait_node_id {} is not an item", trait_hir_id); - }; - - let (generics, bounds) = match item.kind { - hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits), - hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits), - _ => span_bug!(item.span, "super_predicates invoked on non-trait"), - }; - - let icx = ItemCtxt::new(tcx, trait_def_id); - - // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`. - let self_param_ty = tcx.types.self_param; - let superbounds1 = if let Some(assoc_name) = assoc_name { - <dyn AstConv<'_>>::compute_bounds_that_match_assoc_type( - &icx, - self_param_ty, - bounds, - assoc_name, - ) - } else { - <dyn AstConv<'_>>::compute_bounds(&icx, self_param_ty, bounds) - }; - - let superbounds1 = superbounds1.predicates(tcx, self_param_ty); - - // Convert any explicit superbounds in the where-clause, - // e.g., `trait Foo where Self: Bar`. - // In the case of trait aliases, however, we include all bounds in the where-clause, - // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>` - // as one of its "superpredicates". - let is_trait_alias = tcx.is_trait_alias(trait_def_id); - let superbounds2 = icx.type_parameter_bounds_in_generics( - generics, - item.hir_id(), - self_param_ty, - OnlySelfBounds(!is_trait_alias), - assoc_name, - ); - - // Combine the two lists to form the complete set of superbounds: - let superbounds = &*tcx.arena.alloc_from_iter(superbounds1.into_iter().chain(superbounds2)); - debug!(?superbounds); - - // Now require that immediate supertraits are converted, - // which will, in turn, reach indirect supertraits. - if assoc_name.is_none() { - // Now require that immediate supertraits are converted, - // which will, in turn, reach indirect supertraits. - for &(pred, span) in superbounds { - debug!("superbound: {:?}", pred); - if let ty::PredicateKind::Trait(bound) = pred.kind().skip_binder() { - tcx.at(span).super_predicates_of(bound.def_id()); - } - } - } - - ty::GenericPredicates { parent: None, predicates: superbounds } - } else { - // if `assoc_name` is None, then the query should've been redirected to an - // external provider - assert!(assoc_name.is_some()); - tcx.super_predicates_of(trait_def_id) - } -} - fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { let item = tcx.hir().expect_item(def_id.expect_local()); @@ -1328,475 +1079,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { ) } -fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<Span> { - struct LateBoundRegionsDetector<'tcx> { - tcx: TyCtxt<'tcx>, - outer_index: ty::DebruijnIndex, - has_late_bound_regions: Option<Span>, - } - - impl<'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'tcx> { - fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { - if self.has_late_bound_regions.is_some() { - return; - } - match ty.kind { - hir::TyKind::BareFn(..) => { - self.outer_index.shift_in(1); - intravisit::walk_ty(self, ty); - self.outer_index.shift_out(1); - } - _ => intravisit::walk_ty(self, ty), - } - } - - fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) { - if self.has_late_bound_regions.is_some() { - return; - } - self.outer_index.shift_in(1); - intravisit::walk_poly_trait_ref(self, tr); - self.outer_index.shift_out(1); - } - - fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) { - if self.has_late_bound_regions.is_some() { - return; - } - - match self.tcx.named_region(lt.hir_id) { - Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {} - Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {} - Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => { - self.has_late_bound_regions = Some(lt.span); - } - } - } - } - - fn has_late_bound_regions<'tcx>( - tcx: TyCtxt<'tcx>, - generics: &'tcx hir::Generics<'tcx>, - decl: &'tcx hir::FnDecl<'tcx>, - ) -> Option<Span> { - let mut visitor = LateBoundRegionsDetector { - tcx, - outer_index: ty::INNERMOST, - has_late_bound_regions: None, - }; - for param in generics.params { - if let GenericParamKind::Lifetime { .. } = param.kind { - if tcx.is_late_bound(param.hir_id) { - return Some(param.span); - } - } - } - visitor.visit_fn_decl(decl); - visitor.has_late_bound_regions - } - - match node { - Node::TraitItem(item) => match item.kind { - hir::TraitItemKind::Fn(ref sig, _) => { - has_late_bound_regions(tcx, &item.generics, sig.decl) - } - _ => None, - }, - Node::ImplItem(item) => match item.kind { - hir::ImplItemKind::Fn(ref sig, _) => { - has_late_bound_regions(tcx, &item.generics, sig.decl) - } - _ => None, - }, - Node::ForeignItem(item) => match item.kind { - hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => { - has_late_bound_regions(tcx, generics, fn_decl) - } - _ => None, - }, - Node::Item(item) => match item.kind { - hir::ItemKind::Fn(ref sig, .., ref generics, _) => { - has_late_bound_regions(tcx, generics, sig.decl) - } - _ => None, - }, - _ => None, - } -} - -struct AnonConstInParamTyDetector { - in_param_ty: bool, - found_anon_const_in_param_ty: bool, - ct: HirId, -} - -impl<'v> Visitor<'v> for AnonConstInParamTyDetector { - fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) { - if let GenericParamKind::Const { ty, default: _ } = p.kind { - let prev = self.in_param_ty; - self.in_param_ty = true; - self.visit_ty(ty); - self.in_param_ty = prev; - } - } - - fn visit_anon_const(&mut self, c: &'v hir::AnonConst) { - if self.in_param_ty && self.ct == c.hir_id { - self.found_anon_const_in_param_ty = true; - } else { - intravisit::walk_anon_const(self, c) - } - } -} - -fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { - use rustc_hir::*; - - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - - let node = tcx.hir().get(hir_id); - let parent_def_id = match node { - Node::ImplItem(_) - | Node::TraitItem(_) - | Node::Variant(_) - | Node::Ctor(..) - | Node::Field(_) => { - let parent_id = tcx.hir().get_parent_item(hir_id); - Some(parent_id.to_def_id()) - } - // FIXME(#43408) always enable this once `lazy_normalization` is - // stable enough and does not need a feature gate anymore. - Node::AnonConst(_) => { - let parent_def_id = tcx.hir().get_parent_item(hir_id); - - let mut in_param_ty = false; - for (_parent, node) in tcx.hir().parent_iter(hir_id) { - if let Some(generics) = node.generics() { - let mut visitor = AnonConstInParamTyDetector { - in_param_ty: false, - found_anon_const_in_param_ty: false, - ct: hir_id, - }; - - visitor.visit_generics(generics); - in_param_ty = visitor.found_anon_const_in_param_ty; - break; - } - } - - if in_param_ty { - // We do not allow generic parameters in anon consts if we are inside - // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed. - None - } else if tcx.lazy_normalization() { - if let Some(param_id) = tcx.hir().opt_const_param_default_param_hir_id(hir_id) { - // If the def_id we are calling generics_of on is an anon ct default i.e: - // - // struct Foo<const N: usize = { .. }>; - // ^^^ ^ ^^^^^^ def id of this anon const - // ^ ^ param_id - // ^ parent_def_id - // - // then we only want to return generics for params to the left of `N`. If we don't do that we - // end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, substs: [N#0])`. - // - // This causes ICEs (#86580) when building the substs for Foo in `fn foo() -> Foo { .. }` as - // we substitute the defaults with the partially built substs when we build the substs. Subst'ing - // the `N#0` on the unevaluated const indexes into the empty substs we're in the process of building. - // - // We fix this by having this function return the parent's generics ourselves and truncating the - // generics to only include non-forward declared params (with the exception of the `Self` ty) - // - // For the above code example that means we want `substs: []` - // For the following struct def we want `substs: [N#0]` when generics_of is called on - // the def id of the `{ N + 1 }` anon const - // struct Foo<const N: usize, const M: usize = { N + 1 }>; - // - // This has some implications for how we get the predicates available to the anon const - // see `explicit_predicates_of` for more information on this - let generics = tcx.generics_of(parent_def_id.to_def_id()); - let param_def = tcx.hir().local_def_id(param_id).to_def_id(); - let param_def_idx = generics.param_def_id_to_index[¶m_def]; - // In the above example this would be .params[..N#0] - let params = generics.params[..param_def_idx as usize].to_owned(); - let param_def_id_to_index = - params.iter().map(|param| (param.def_id, param.index)).collect(); - - return ty::Generics { - // we set the parent of these generics to be our parent's parent so that we - // dont end up with substs: [N, M, N] for the const default on a struct like this: - // struct Foo<const N: usize, const M: usize = { ... }>; - parent: generics.parent, - parent_count: generics.parent_count, - params, - param_def_id_to_index, - has_self: generics.has_self, - has_late_bound_regions: generics.has_late_bound_regions, - }; - } - - // HACK(eddyb) this provides the correct generics when - // `feature(generic_const_expressions)` is enabled, so that const expressions - // used with const generics, e.g. `Foo<{N+1}>`, can work at all. - // - // Note that we do not supply the parent generics when using - // `min_const_generics`. - Some(parent_def_id.to_def_id()) - } else { - let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); - match parent_node { - // HACK(eddyb) this provides the correct generics for repeat - // expressions' count (i.e. `N` in `[x; N]`), and explicit - // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`), - // as they shouldn't be able to cause query cycle errors. - Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) - if constant.hir_id() == hir_id => - { - Some(parent_def_id.to_def_id()) - } - Node::Variant(Variant { disr_expr: Some(ref constant), .. }) - if constant.hir_id == hir_id => - { - Some(parent_def_id.to_def_id()) - } - Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => { - Some(tcx.typeck_root_def_id(def_id)) - } - // Exclude `GlobalAsm` here which cannot have generics. - Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) - if asm.operands.iter().any(|(op, _op_sp)| match op { - hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => { - anon_const.hir_id == hir_id - } - _ => false, - }) => - { - Some(parent_def_id.to_def_id()) - } - _ => None, - } - } - } - Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { - Some(tcx.typeck_root_def_id(def_id)) - } - Node::Item(item) => match item.kind { - ItemKind::OpaqueTy(hir::OpaqueTy { - origin: - hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id), - in_trait, - .. - }) => { - if in_trait { - assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn)) - } else { - assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn)) - } - Some(fn_def_id.to_def_id()) - } - ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => { - let parent_id = tcx.hir().get_parent_item(hir_id); - assert_ne!(parent_id, hir::CRATE_OWNER_ID); - debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); - // Opaque types are always nested within another item, and - // inherit the generics of the item. - Some(parent_id.to_def_id()) - } - _ => None, - }, - _ => None, - }; - - enum Defaults { - Allowed, - // See #36887 - FutureCompatDisallowed, - Deny, - } - - let no_generics = hir::Generics::empty(); - let ast_generics = node.generics().unwrap_or(&no_generics); - let (opt_self, allow_defaults) = match node { - Node::Item(item) => { - match item.kind { - ItemKind::Trait(..) | ItemKind::TraitAlias(..) => { - // Add in the self type parameter. - // - // Something of a hack: use the node id for the trait, also as - // the node id for the Self type parameter. - let opt_self = Some(ty::GenericParamDef { - index: 0, - name: kw::SelfUpper, - def_id, - pure_wrt_drop: false, - kind: ty::GenericParamDefKind::Type { - has_default: false, - synthetic: false, - }, - }); - - (opt_self, Defaults::Allowed) - } - ItemKind::TyAlias(..) - | ItemKind::Enum(..) - | ItemKind::Struct(..) - | ItemKind::OpaqueTy(..) - | ItemKind::Union(..) => (None, Defaults::Allowed), - _ => (None, Defaults::FutureCompatDisallowed), - } - } - - // GATs - Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => { - (None, Defaults::Deny) - } - Node::ImplItem(item) if matches!(item.kind, ImplItemKind::TyAlias(..)) => { - (None, Defaults::Deny) - } - - _ => (None, Defaults::FutureCompatDisallowed), - }; - - let has_self = opt_self.is_some(); - let mut parent_has_self = false; - let mut own_start = has_self as u32; - let parent_count = parent_def_id.map_or(0, |def_id| { - let generics = tcx.generics_of(def_id); - assert!(!has_self); - parent_has_self = generics.has_self; - own_start = generics.count() as u32; - generics.parent_count + generics.params.len() - }); - - let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize); - - if let Some(opt_self) = opt_self { - params.push(opt_self); - } - - let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics); - params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef { - name: param.name.ident().name, - index: own_start + i as u32, - def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(), - pure_wrt_drop: param.pure_wrt_drop, - kind: ty::GenericParamDefKind::Lifetime, - })); - - // Now create the real type and const parameters. - let type_start = own_start - has_self as u32 + params.len() as u32; - let mut i = 0; - - const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \ - `struct`, `enum`, `type`, or `trait` definitions"; - - params.extend(ast_generics.params.iter().filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => None, - GenericParamKind::Type { ref default, synthetic, .. } => { - if default.is_some() { - match allow_defaults { - Defaults::Allowed => {} - Defaults::FutureCompatDisallowed - if tcx.features().default_type_parameter_fallback => {} - Defaults::FutureCompatDisallowed => { - tcx.struct_span_lint_hir( - lint::builtin::INVALID_TYPE_PARAM_DEFAULT, - param.hir_id, - param.span, - |lint| { - lint.build(TYPE_DEFAULT_NOT_ALLOWED).emit(); - }, - ); - } - Defaults::Deny => { - tcx.sess.span_err(param.span, TYPE_DEFAULT_NOT_ALLOWED); - } - } - } - - let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic }; - - let param_def = ty::GenericParamDef { - index: type_start + i as u32, - name: param.name.ident().name, - def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(), - pure_wrt_drop: param.pure_wrt_drop, - kind, - }; - i += 1; - Some(param_def) - } - GenericParamKind::Const { default, .. } => { - if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() { - tcx.sess.span_err( - param.span, - "defaults for const parameters are only allowed in \ - `struct`, `enum`, `type`, or `trait` definitions", - ); - } - - let param_def = ty::GenericParamDef { - index: type_start + i as u32, - name: param.name.ident().name, - def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(), - pure_wrt_drop: param.pure_wrt_drop, - kind: ty::GenericParamDefKind::Const { has_default: default.is_some() }, - }; - i += 1; - Some(param_def) - } - })); - - // provide junk type parameter defs - the only place that - // cares about anything but the length is instantiation, - // and we don't do that for closures. - if let Node::Expr(&hir::Expr { - kind: hir::ExprKind::Closure(hir::Closure { movability: gen, .. }), - .. - }) = node - { - let dummy_args = if gen.is_some() { - &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..] - } else { - &["<closure_kind>", "<closure_signature>", "<upvars>"][..] - }; - - params.extend(dummy_args.iter().enumerate().map(|(i, &arg)| ty::GenericParamDef { - index: type_start + i as u32, - name: Symbol::intern(arg), - def_id, - pure_wrt_drop: false, - kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false }, - })); - } - - // provide junk type parameter defs for const blocks. - if let Node::AnonConst(_) = node { - let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); - if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node { - params.push(ty::GenericParamDef { - index: type_start, - name: Symbol::intern("<const_ty>"), - def_id, - pure_wrt_drop: false, - kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false }, - }); - } - } - - let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect(); - - ty::Generics { - parent: parent_def_id, - parent_count, - params, - param_def_id_to_index, - has_self: has_self || parent_has_self, - has_late_bound_regions: has_late_bound_regions(tcx, node), - } -} - fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool { generic_args.iter().any(|arg| match arg { hir::GenericArg::Type(ty) => is_suggestable_infer_ty(ty), @@ -2093,450 +1375,6 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate result } -/// Returns a list of all type predicates (explicit and implicit) for the definition with -/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus -/// `Self: Trait` predicates for traits. -fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { - let mut result = tcx.predicates_defined_on(def_id); - - if tcx.is_trait(def_id) { - // For traits, add `Self: Trait` predicate. This is - // not part of the predicates that a user writes, but it - // is something that one must prove in order to invoke a - // method or project an associated type. - // - // In the chalk setup, this predicate is not part of the - // "predicates" for a trait item. But it is useful in - // rustc because if you directly (e.g.) invoke a trait - // method like `Trait::method(...)`, you must naturally - // prove that the trait applies to the types that were - // used, and adding the predicate into this list ensures - // that this is done. - // - // We use a DUMMY_SP here as a way to signal trait bounds that come - // from the trait itself that *shouldn't* be shown as the source of - // an obligation and instead be skipped. Otherwise we'd use - // `tcx.def_span(def_id);` - - let constness = if tcx.has_attr(def_id, sym::const_trait) { - ty::BoundConstness::ConstIfConst - } else { - ty::BoundConstness::NotConst - }; - - let span = rustc_span::DUMMY_SP; - result.predicates = - tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( - ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx), - span, - )))); - } - debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); - result -} - -/// Returns a list of user-specified type predicates for the definition with ID `def_id`. -/// N.B., this does not include any implied/inferred constraints. -#[instrument(level = "trace", skip(tcx), ret)] -fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { - use rustc_hir::*; - - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - let node = tcx.hir().get(hir_id); - - let mut is_trait = None; - let mut is_default_impl_trait = None; - - let icx = ItemCtxt::new(tcx, def_id); - - const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty(); - - // We use an `IndexSet` to preserves order of insertion. - // Preserving the order of insertion is important here so as not to break UI tests. - let mut predicates: FxIndexSet<(ty::Predicate<'_>, Span)> = FxIndexSet::default(); - - let ast_generics = match node { - Node::TraitItem(item) => item.generics, - - Node::ImplItem(item) => item.generics, - - Node::Item(item) => { - match item.kind { - ItemKind::Impl(ref impl_) => { - if impl_.defaultness.is_default() { - is_default_impl_trait = tcx.impl_trait_ref(def_id).map(ty::Binder::dummy); - } - &impl_.generics - } - ItemKind::Fn(.., ref generics, _) - | ItemKind::TyAlias(_, ref generics) - | ItemKind::Enum(_, ref generics) - | ItemKind::Struct(_, ref generics) - | ItemKind::Union(_, ref generics) => *generics, - - ItemKind::Trait(_, _, ref generics, ..) => { - is_trait = Some(ty::TraitRef::identity(tcx, def_id)); - *generics - } - ItemKind::TraitAlias(ref generics, _) => { - is_trait = Some(ty::TraitRef::identity(tcx, def_id)); - *generics - } - ItemKind::OpaqueTy(OpaqueTy { - origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), - .. - }) => { - // return-position impl trait - // - // We don't inherit predicates from the parent here: - // If we have, say `fn f<'a, T: 'a>() -> impl Sized {}` - // then the return type is `f::<'static, T>::{{opaque}}`. - // - // If we inherited the predicates of `f` then we would - // require that `T: 'static` to show that the return - // type is well-formed. - // - // The only way to have something with this opaque type - // is from the return type of the containing function, - // which will ensure that the function's predicates - // hold. - return ty::GenericPredicates { parent: None, predicates: &[] }; - } - ItemKind::OpaqueTy(OpaqueTy { - ref generics, - origin: hir::OpaqueTyOrigin::TyAlias, - .. - }) => { - // type-alias impl trait - generics - } - - _ => NO_GENERICS, - } - } - - Node::ForeignItem(item) => match item.kind { - ForeignItemKind::Static(..) => NO_GENERICS, - ForeignItemKind::Fn(_, _, ref generics) => *generics, - ForeignItemKind::Type => NO_GENERICS, - }, - - _ => NO_GENERICS, - }; - - let generics = tcx.generics_of(def_id); - let parent_count = generics.parent_count as u32; - let has_own_self = generics.has_self && parent_count == 0; - - // Below we'll consider the bounds on the type parameters (including `Self`) - // and the explicit where-clauses, but to get the full set of predicates - // on a trait we need to add in the supertrait bounds and bounds found on - // associated types. - if let Some(_trait_ref) = is_trait { - predicates.extend(tcx.super_predicates_of(def_id).predicates.iter().cloned()); - } - - // In default impls, we can assume that the self type implements - // the trait. So in: - // - // default impl Foo for Bar { .. } - // - // we add a default where clause `Foo: Bar`. We do a similar thing for traits - // (see below). Recall that a default impl is not itself an impl, but rather a - // set of defaults that can be incorporated into another impl. - if let Some(trait_ref) = is_default_impl_trait { - predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id))); - } - - // Collect the region predicates that were declared inline as - // well. In the case of parameters declared on a fn or method, we - // have to be careful to only iterate over early-bound regions. - let mut index = parent_count - + has_own_self as u32 - + early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32; - - trace!(?predicates); - trace!(?ast_generics); - - // Collect the predicates that were written inline by the user on each - // type parameter (e.g., `<T: Foo>`). - for param in ast_generics.params { - match param.kind { - // We already dealt with early bound lifetimes above. - GenericParamKind::Lifetime { .. } => (), - GenericParamKind::Type { .. } => { - let name = param.name.ident().name; - let param_ty = ty::ParamTy::new(index, name).to_ty(tcx); - index += 1; - - let mut bounds = Bounds::default(); - // Params are implicitly sized unless a `?Sized` bound is found - <dyn AstConv<'_>>::add_implicitly_sized( - &icx, - &mut bounds, - &[], - Some((param.hir_id, ast_generics.predicates)), - param.span, - ); - trace!(?bounds); - predicates.extend(bounds.predicates(tcx, param_ty)); - trace!(?predicates); - } - GenericParamKind::Const { .. } => { - // Bounds on const parameters are currently not possible. - index += 1; - } - } - } - - trace!(?predicates); - // Add in the bounds that appear in the where-clause. - for predicate in ast_generics.predicates { - match predicate { - hir::WherePredicate::BoundPredicate(bound_pred) => { - let ty = icx.to_ty(bound_pred.bounded_ty); - let bound_vars = icx.tcx.late_bound_vars(bound_pred.bounded_ty.hir_id); - - // Keep the type around in a dummy predicate, in case of no bounds. - // That way, `where Ty:` is not a complete noop (see #53696) and `Ty` - // is still checked for WF. - if bound_pred.bounds.is_empty() { - if let ty::Param(_) = ty.kind() { - // This is a `where T:`, which can be in the HIR from the - // transformation that moves `?Sized` to `T`'s declaration. - // We can skip the predicate because type parameters are - // trivially WF, but also we *should*, to avoid exposing - // users who never wrote `where Type:,` themselves, to - // compiler/tooling bugs from not handling WF predicates. - } else { - let span = bound_pred.bounded_ty.span; - let predicate = ty::Binder::bind_with_vars( - ty::PredicateKind::WellFormed(ty.into()), - bound_vars, - ); - predicates.insert((predicate.to_predicate(tcx), span)); - } - } - - let mut bounds = Bounds::default(); - <dyn AstConv<'_>>::add_bounds( - &icx, - ty, - bound_pred.bounds.iter(), - &mut bounds, - bound_vars, - ); - predicates.extend(bounds.predicates(tcx, ty)); - } - - hir::WherePredicate::RegionPredicate(region_pred) => { - let r1 = <dyn AstConv<'_>>::ast_region_to_region(&icx, ®ion_pred.lifetime, None); - predicates.extend(region_pred.bounds.iter().map(|bound| { - let (r2, span) = match bound { - hir::GenericBound::Outlives(lt) => { - (<dyn AstConv<'_>>::ast_region_to_region(&icx, lt, None), lt.span) - } - _ => bug!(), - }; - let pred = ty::Binder::dummy(ty::PredicateKind::RegionOutlives( - ty::OutlivesPredicate(r1, r2), - )) - .to_predicate(icx.tcx); - - (pred, span) - })) - } - - hir::WherePredicate::EqPredicate(..) => { - // FIXME(#20041) - } - } - } - - if tcx.features().generic_const_exprs { - predicates.extend(const_evaluatable_predicates_of(tcx, def_id.expect_local())); - } - - let mut predicates: Vec<_> = predicates.into_iter().collect(); - - // Subtle: before we store the predicates into the tcx, we - // sort them so that predicates like `T: Foo<Item=U>` come - // before uses of `U`. This avoids false ambiguity errors - // in trait checking. See `setup_constraining_predicates` - // for details. - if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node { - let self_ty = tcx.type_of(def_id); - let trait_ref = tcx.impl_trait_ref(def_id); - cgp::setup_constraining_predicates( - tcx, - &mut predicates, - trait_ref, - &mut cgp::parameters_for_impl(self_ty, trait_ref), - ); - } - - ty::GenericPredicates { - parent: generics.parent, - predicates: tcx.arena.alloc_from_iter(predicates), - } -} - -fn const_evaluatable_predicates_of<'tcx>( - tcx: TyCtxt<'tcx>, - def_id: LocalDefId, -) -> FxIndexSet<(ty::Predicate<'tcx>, Span)> { - struct ConstCollector<'tcx> { - tcx: TyCtxt<'tcx>, - preds: FxIndexSet<(ty::Predicate<'tcx>, Span)>, - } - - impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> { - fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) { - let def_id = self.tcx.hir().local_def_id(c.hir_id); - let ct = ty::Const::from_anon_const(self.tcx, def_id); - if let ty::ConstKind::Unevaluated(uv) = ct.kind() { - let span = self.tcx.hir().span(c.hir_id); - self.preds.insert(( - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv)) - .to_predicate(self.tcx), - span, - )); - } - } - - fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::AnonConst) { - // Do not look into const param defaults, - // these get checked when they are actually instantiated. - // - // We do not want the following to error: - // - // struct Foo<const N: usize, const M: usize = { N + 1 }>; - // struct Bar<const N: usize>(Foo<N, 3>); - } - } - - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - let node = tcx.hir().get(hir_id); - - let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() }; - if let hir::Node::Item(item) = node && let hir::ItemKind::Impl(ref impl_) = item.kind { - if let Some(of_trait) = &impl_.of_trait { - debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id); - collector.visit_trait_ref(of_trait); - } - - debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id); - collector.visit_ty(impl_.self_ty); - } - - if let Some(generics) = node.generics() { - debug!("const_evaluatable_predicates_of({:?}): visit_generics", def_id); - collector.visit_generics(generics); - } - - if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id) { - debug!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id); - collector.visit_fn_decl(fn_sig.decl); - } - debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.preds); - - collector.preds -} - -fn trait_explicit_predicates_and_bounds( - tcx: TyCtxt<'_>, - def_id: LocalDefId, -) -> ty::GenericPredicates<'_> { - assert_eq!(tcx.def_kind(def_id), DefKind::Trait); - gather_explicit_predicates_of(tcx, def_id.to_def_id()) -} - -fn explicit_predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericPredicates<'tcx> { - let def_kind = tcx.def_kind(def_id); - if let DefKind::Trait = def_kind { - // Remove bounds on associated types from the predicates, they will be - // returned by `explicit_item_bounds`. - let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id.expect_local()); - let trait_identity_substs = InternalSubsts::identity_for_item(tcx, def_id); - - let is_assoc_item_ty = |ty: Ty<'tcx>| { - // For a predicate from a where clause to become a bound on an - // associated type: - // * It must use the identity substs of the item. - // * Since any generic parameters on the item are not in scope, - // this means that the item is not a GAT, and its identity - // substs are the same as the trait's. - // * It must be an associated type for this trait (*not* a - // supertrait). - if let ty::Projection(projection) = ty.kind() { - projection.substs == trait_identity_substs - && tcx.associated_item(projection.item_def_id).container_id(tcx) == def_id - } else { - false - } - }; - - let predicates: Vec<_> = predicates_and_bounds - .predicates - .iter() - .copied() - .filter(|(pred, _)| match pred.kind().skip_binder() { - ty::PredicateKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()), - ty::PredicateKind::Projection(proj) => { - !is_assoc_item_ty(proj.projection_ty.self_ty()) - } - ty::PredicateKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0), - _ => true, - }) - .collect(); - if predicates.len() == predicates_and_bounds.predicates.len() { - predicates_and_bounds - } else { - ty::GenericPredicates { - parent: predicates_and_bounds.parent, - predicates: tcx.arena.alloc_slice(&predicates), - } - } - } else { - if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() { - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); - if tcx.hir().opt_const_param_default_param_hir_id(hir_id).is_some() { - // In `generics_of` we set the generics' parent to be our parent's parent which means that - // we lose out on the predicates of our actual parent if we dont return those predicates here. - // (See comment in `generics_of` for more information on why the parent shenanigans is necessary) - // - // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait; - // ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling - // ^^^ explicit_predicates_of on - // parent item we dont have set as the - // parent of generics returned by `generics_of` - // - // In the above code we want the anon const to have predicates in its param env for `T: Trait` - let item_def_id = tcx.hir().get_parent_item(hir_id); - // In the above code example we would be calling `explicit_predicates_of(Foo)` here - return tcx.explicit_predicates_of(item_def_id); - } - } - gather_explicit_predicates_of(tcx, def_id) - } -} - -/// Converts a specific `GenericBound` from the AST into a set of -/// predicates that apply to the self type. A vector is returned -/// because this can be anywhere from zero predicates (`T: ?Sized` adds no -/// predicates) to one (`T: Foo`) to many (`T: Bar<X = i32>` adds `T: Bar` -/// and `<T as Bar>::X == i32`). -fn predicates_from_bound<'tcx>( - astconv: &dyn AstConv<'tcx>, - param_ty: Ty<'tcx>, - bound: &'tcx hir::GenericBound<'tcx>, - bound_vars: &'tcx ty::List<ty::BoundVariableKind>, -) -> Vec<(ty::Predicate<'tcx>, Span)> { - let mut bounds = Bounds::default(); - astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars); - bounds.predicates(astconv.tcx(), param_ty).collect() -} - fn compute_sig_of_foreign_fn_decl<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, @@ -2544,7 +1382,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( abi: abi::Abi, ) -> ty::PolyFnSig<'tcx> { let unsafety = if abi == abi::Abi::RustIntrinsic { - intrinsic_operation_unsafety(tcx.item_name(def_id)) + intrinsic_operation_unsafety(tcx, def_id) } else { hir::Unsafety::Unsafe }; @@ -3229,11 +2067,8 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { lint::builtin::INLINE_NO_SANITIZE, hir_id, no_sanitize_span, - |lint| { - lint.build("`no_sanitize` will have no effect after inlining") - .span_note(inline_span, "inlining requested here") - .emit(); - }, + "`no_sanitize` will have no effect after inlining", + |lint| lint.span_note(inline_span, "inlining requested here"), ) } } diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs new file mode 100644 index 00000000000..7ffacbecf5f --- /dev/null +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -0,0 +1,480 @@ +use crate::middle::resolve_lifetime as rl; +use hir::{ + intravisit::{self, Visitor}, + GenericParamKind, HirId, Node, +}; +use rustc_hir as hir; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::DefId; +use rustc_middle::ty::{self, TyCtxt}; +use rustc_session::lint; +use rustc_span::symbol::{kw, Symbol}; +use rustc_span::Span; + +pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { + use rustc_hir::*; + + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + + let node = tcx.hir().get(hir_id); + let parent_def_id = match node { + Node::ImplItem(_) + | Node::TraitItem(_) + | Node::Variant(_) + | Node::Ctor(..) + | Node::Field(_) => { + let parent_id = tcx.hir().get_parent_item(hir_id); + Some(parent_id.to_def_id()) + } + // FIXME(#43408) always enable this once `lazy_normalization` is + // stable enough and does not need a feature gate anymore. + Node::AnonConst(_) => { + let parent_def_id = tcx.hir().get_parent_item(hir_id); + + let mut in_param_ty = false; + for (_parent, node) in tcx.hir().parent_iter(hir_id) { + if let Some(generics) = node.generics() { + let mut visitor = AnonConstInParamTyDetector { + in_param_ty: false, + found_anon_const_in_param_ty: false, + ct: hir_id, + }; + + visitor.visit_generics(generics); + in_param_ty = visitor.found_anon_const_in_param_ty; + break; + } + } + + if in_param_ty { + // We do not allow generic parameters in anon consts if we are inside + // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed. + None + } else if tcx.lazy_normalization() { + if let Some(param_id) = tcx.hir().opt_const_param_default_param_hir_id(hir_id) { + // If the def_id we are calling generics_of on is an anon ct default i.e: + // + // struct Foo<const N: usize = { .. }>; + // ^^^ ^ ^^^^^^ def id of this anon const + // ^ ^ param_id + // ^ parent_def_id + // + // then we only want to return generics for params to the left of `N`. If we don't do that we + // end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, substs: [N#0])`. + // + // This causes ICEs (#86580) when building the substs for Foo in `fn foo() -> Foo { .. }` as + // we substitute the defaults with the partially built substs when we build the substs. Subst'ing + // the `N#0` on the unevaluated const indexes into the empty substs we're in the process of building. + // + // We fix this by having this function return the parent's generics ourselves and truncating the + // generics to only include non-forward declared params (with the exception of the `Self` ty) + // + // For the above code example that means we want `substs: []` + // For the following struct def we want `substs: [N#0]` when generics_of is called on + // the def id of the `{ N + 1 }` anon const + // struct Foo<const N: usize, const M: usize = { N + 1 }>; + // + // This has some implications for how we get the predicates available to the anon const + // see `explicit_predicates_of` for more information on this + let generics = tcx.generics_of(parent_def_id.to_def_id()); + let param_def = tcx.hir().local_def_id(param_id).to_def_id(); + let param_def_idx = generics.param_def_id_to_index[¶m_def]; + // In the above example this would be .params[..N#0] + let params = generics.params[..param_def_idx as usize].to_owned(); + let param_def_id_to_index = + params.iter().map(|param| (param.def_id, param.index)).collect(); + + return ty::Generics { + // we set the parent of these generics to be our parent's parent so that we + // dont end up with substs: [N, M, N] for the const default on a struct like this: + // struct Foo<const N: usize, const M: usize = { ... }>; + parent: generics.parent, + parent_count: generics.parent_count, + params, + param_def_id_to_index, + has_self: generics.has_self, + has_late_bound_regions: generics.has_late_bound_regions, + }; + } + + // HACK(eddyb) this provides the correct generics when + // `feature(generic_const_expressions)` is enabled, so that const expressions + // used with const generics, e.g. `Foo<{N+1}>`, can work at all. + // + // Note that we do not supply the parent generics when using + // `min_const_generics`. + Some(parent_def_id.to_def_id()) + } else { + let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); + match parent_node { + // HACK(eddyb) this provides the correct generics for repeat + // expressions' count (i.e. `N` in `[x; N]`), and explicit + // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`), + // as they shouldn't be able to cause query cycle errors. + Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) + if constant.hir_id() == hir_id => + { + Some(parent_def_id.to_def_id()) + } + Node::Variant(Variant { disr_expr: Some(ref constant), .. }) + if constant.hir_id == hir_id => + { + Some(parent_def_id.to_def_id()) + } + Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) => { + Some(tcx.typeck_root_def_id(def_id)) + } + // Exclude `GlobalAsm` here which cannot have generics. + Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. }) + if asm.operands.iter().any(|(op, _op_sp)| match op { + hir::InlineAsmOperand::Const { anon_const } + | hir::InlineAsmOperand::SymFn { anon_const } => { + anon_const.hir_id == hir_id + } + _ => false, + }) => + { + Some(parent_def_id.to_def_id()) + } + _ => None, + } + } + } + Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure { .. }, .. }) => { + Some(tcx.typeck_root_def_id(def_id)) + } + Node::Item(item) => match item.kind { + ItemKind::OpaqueTy(hir::OpaqueTy { + origin: + hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id), + in_trait, + .. + }) => { + if in_trait { + assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn)) + } else { + assert!(matches!(tcx.def_kind(fn_def_id), DefKind::AssocFn | DefKind::Fn)) + } + Some(fn_def_id.to_def_id()) + } + ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => { + let parent_id = tcx.hir().get_parent_item(hir_id); + assert_ne!(parent_id, hir::CRATE_OWNER_ID); + debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); + // Opaque types are always nested within another item, and + // inherit the generics of the item. + Some(parent_id.to_def_id()) + } + _ => None, + }, + _ => None, + }; + + enum Defaults { + Allowed, + // See #36887 + FutureCompatDisallowed, + Deny, + } + + let no_generics = hir::Generics::empty(); + let ast_generics = node.generics().unwrap_or(&no_generics); + let (opt_self, allow_defaults) = match node { + Node::Item(item) => { + match item.kind { + ItemKind::Trait(..) | ItemKind::TraitAlias(..) => { + // Add in the self type parameter. + // + // Something of a hack: use the node id for the trait, also as + // the node id for the Self type parameter. + let opt_self = Some(ty::GenericParamDef { + index: 0, + name: kw::SelfUpper, + def_id, + pure_wrt_drop: false, + kind: ty::GenericParamDefKind::Type { + has_default: false, + synthetic: false, + }, + }); + + (opt_self, Defaults::Allowed) + } + ItemKind::TyAlias(..) + | ItemKind::Enum(..) + | ItemKind::Struct(..) + | ItemKind::OpaqueTy(..) + | ItemKind::Union(..) => (None, Defaults::Allowed), + _ => (None, Defaults::FutureCompatDisallowed), + } + } + + // GATs + Node::TraitItem(item) if matches!(item.kind, TraitItemKind::Type(..)) => { + (None, Defaults::Deny) + } + Node::ImplItem(item) if matches!(item.kind, ImplItemKind::TyAlias(..)) => { + (None, Defaults::Deny) + } + + _ => (None, Defaults::FutureCompatDisallowed), + }; + + let has_self = opt_self.is_some(); + let mut parent_has_self = false; + let mut own_start = has_self as u32; + let parent_count = parent_def_id.map_or(0, |def_id| { + let generics = tcx.generics_of(def_id); + assert!(!has_self); + parent_has_self = generics.has_self; + own_start = generics.count() as u32; + generics.parent_count + generics.params.len() + }); + + let mut params: Vec<_> = Vec::with_capacity(ast_generics.params.len() + has_self as usize); + + if let Some(opt_self) = opt_self { + params.push(opt_self); + } + + let early_lifetimes = super::early_bound_lifetimes_from_generics(tcx, ast_generics); + params.extend(early_lifetimes.enumerate().map(|(i, param)| ty::GenericParamDef { + name: param.name.ident().name, + index: own_start + i as u32, + def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(), + pure_wrt_drop: param.pure_wrt_drop, + kind: ty::GenericParamDefKind::Lifetime, + })); + + // Now create the real type and const parameters. + let type_start = own_start - has_self as u32 + params.len() as u32; + let mut i = 0; + + const TYPE_DEFAULT_NOT_ALLOWED: &'static str = "defaults for type parameters are only allowed in \ + `struct`, `enum`, `type`, or `trait` definitions"; + + params.extend(ast_generics.params.iter().filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => None, + GenericParamKind::Type { ref default, synthetic, .. } => { + if default.is_some() { + match allow_defaults { + Defaults::Allowed => {} + Defaults::FutureCompatDisallowed + if tcx.features().default_type_parameter_fallback => {} + Defaults::FutureCompatDisallowed => { + tcx.struct_span_lint_hir( + lint::builtin::INVALID_TYPE_PARAM_DEFAULT, + param.hir_id, + param.span, + TYPE_DEFAULT_NOT_ALLOWED, + |lint| lint, + ); + } + Defaults::Deny => { + tcx.sess.span_err(param.span, TYPE_DEFAULT_NOT_ALLOWED); + } + } + } + + let kind = ty::GenericParamDefKind::Type { has_default: default.is_some(), synthetic }; + + let param_def = ty::GenericParamDef { + index: type_start + i as u32, + name: param.name.ident().name, + def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(), + pure_wrt_drop: param.pure_wrt_drop, + kind, + }; + i += 1; + Some(param_def) + } + GenericParamKind::Const { default, .. } => { + if !matches!(allow_defaults, Defaults::Allowed) && default.is_some() { + tcx.sess.span_err( + param.span, + "defaults for const parameters are only allowed in \ + `struct`, `enum`, `type`, or `trait` definitions", + ); + } + + let param_def = ty::GenericParamDef { + index: type_start + i as u32, + name: param.name.ident().name, + def_id: tcx.hir().local_def_id(param.hir_id).to_def_id(), + pure_wrt_drop: param.pure_wrt_drop, + kind: ty::GenericParamDefKind::Const { has_default: default.is_some() }, + }; + i += 1; + Some(param_def) + } + })); + + // provide junk type parameter defs - the only place that + // cares about anything but the length is instantiation, + // and we don't do that for closures. + if let Node::Expr(&hir::Expr { + kind: hir::ExprKind::Closure(hir::Closure { movability: gen, .. }), + .. + }) = node + { + let dummy_args = if gen.is_some() { + &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..] + } else { + &["<closure_kind>", "<closure_signature>", "<upvars>"][..] + }; + + params.extend(dummy_args.iter().enumerate().map(|(i, &arg)| ty::GenericParamDef { + index: type_start + i as u32, + name: Symbol::intern(arg), + def_id, + pure_wrt_drop: false, + kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false }, + })); + } + + // provide junk type parameter defs for const blocks. + if let Node::AnonConst(_) = node { + let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); + if let Node::Expr(&Expr { kind: ExprKind::ConstBlock(_), .. }) = parent_node { + params.push(ty::GenericParamDef { + index: type_start, + name: Symbol::intern("<const_ty>"), + def_id, + pure_wrt_drop: false, + kind: ty::GenericParamDefKind::Type { has_default: false, synthetic: false }, + }); + } + } + + let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect(); + + ty::Generics { + parent: parent_def_id, + parent_count, + params, + param_def_id_to_index, + has_self: has_self || parent_has_self, + has_late_bound_regions: has_late_bound_regions(tcx, node), + } +} + +fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<Span> { + struct LateBoundRegionsDetector<'tcx> { + tcx: TyCtxt<'tcx>, + outer_index: ty::DebruijnIndex, + has_late_bound_regions: Option<Span>, + } + + impl<'tcx> Visitor<'tcx> for LateBoundRegionsDetector<'tcx> { + fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { + if self.has_late_bound_regions.is_some() { + return; + } + match ty.kind { + hir::TyKind::BareFn(..) => { + self.outer_index.shift_in(1); + intravisit::walk_ty(self, ty); + self.outer_index.shift_out(1); + } + _ => intravisit::walk_ty(self, ty), + } + } + + fn visit_poly_trait_ref(&mut self, tr: &'tcx hir::PolyTraitRef<'tcx>) { + if self.has_late_bound_regions.is_some() { + return; + } + self.outer_index.shift_in(1); + intravisit::walk_poly_trait_ref(self, tr); + self.outer_index.shift_out(1); + } + + fn visit_lifetime(&mut self, lt: &'tcx hir::Lifetime) { + if self.has_late_bound_regions.is_some() { + return; + } + + match self.tcx.named_region(lt.hir_id) { + Some(rl::Region::Static | rl::Region::EarlyBound(..)) => {} + Some(rl::Region::LateBound(debruijn, _, _)) if debruijn < self.outer_index => {} + Some(rl::Region::LateBound(..) | rl::Region::Free(..)) | None => { + self.has_late_bound_regions = Some(lt.span); + } + } + } + } + + fn has_late_bound_regions<'tcx>( + tcx: TyCtxt<'tcx>, + generics: &'tcx hir::Generics<'tcx>, + decl: &'tcx hir::FnDecl<'tcx>, + ) -> Option<Span> { + let mut visitor = LateBoundRegionsDetector { + tcx, + outer_index: ty::INNERMOST, + has_late_bound_regions: None, + }; + for param in generics.params { + if let GenericParamKind::Lifetime { .. } = param.kind { + if tcx.is_late_bound(param.hir_id) { + return Some(param.span); + } + } + } + visitor.visit_fn_decl(decl); + visitor.has_late_bound_regions + } + + match node { + Node::TraitItem(item) => match item.kind { + hir::TraitItemKind::Fn(ref sig, _) => { + has_late_bound_regions(tcx, &item.generics, sig.decl) + } + _ => None, + }, + Node::ImplItem(item) => match item.kind { + hir::ImplItemKind::Fn(ref sig, _) => { + has_late_bound_regions(tcx, &item.generics, sig.decl) + } + _ => None, + }, + Node::ForeignItem(item) => match item.kind { + hir::ForeignItemKind::Fn(fn_decl, _, ref generics) => { + has_late_bound_regions(tcx, generics, fn_decl) + } + _ => None, + }, + Node::Item(item) => match item.kind { + hir::ItemKind::Fn(ref sig, .., ref generics, _) => { + has_late_bound_regions(tcx, generics, sig.decl) + } + _ => None, + }, + _ => None, + } +} + +struct AnonConstInParamTyDetector { + in_param_ty: bool, + found_anon_const_in_param_ty: bool, + ct: HirId, +} + +impl<'v> Visitor<'v> for AnonConstInParamTyDetector { + fn visit_generic_param(&mut self, p: &'v hir::GenericParam<'v>) { + if let GenericParamKind::Const { ty, default: _ } = p.kind { + let prev = self.in_param_ty; + self.in_param_ty = true; + self.visit_ty(ty); + self.in_param_ty = prev; + } + } + + fn visit_anon_const(&mut self, c: &'v hir::AnonConst) { + if self.in_param_ty && self.ct == c.hir_id { + self.found_anon_const_in_param_ty = true; + } else { + intravisit::walk_anon_const(self, c) + } + } +} diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs new file mode 100644 index 00000000000..db8f8de68f2 --- /dev/null +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -0,0 +1,707 @@ +use crate::astconv::AstConv; +use crate::bounds::Bounds; +use crate::collect::ItemCtxt; +use crate::constrained_generic_params as cgp; +use hir::{HirId, Node}; +use rustc_data_structures::fx::FxIndexSet; +use rustc_hir as hir; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit::{self, Visitor}; +use rustc_middle::ty::subst::InternalSubsts; +use rustc_middle::ty::ToPredicate; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::symbol::{sym, Ident}; +use rustc_span::{Span, DUMMY_SP}; + +#[derive(Debug)] +struct OnlySelfBounds(bool); + +/// Returns a list of all type predicates (explicit and implicit) for the definition with +/// ID `def_id`. This includes all predicates returned by `predicates_defined_on`, plus +/// `Self: Trait` predicates for traits. +pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { + let mut result = tcx.predicates_defined_on(def_id); + + if tcx.is_trait(def_id) { + // For traits, add `Self: Trait` predicate. This is + // not part of the predicates that a user writes, but it + // is something that one must prove in order to invoke a + // method or project an associated type. + // + // In the chalk setup, this predicate is not part of the + // "predicates" for a trait item. But it is useful in + // rustc because if you directly (e.g.) invoke a trait + // method like `Trait::method(...)`, you must naturally + // prove that the trait applies to the types that were + // used, and adding the predicate into this list ensures + // that this is done. + // + // We use a DUMMY_SP here as a way to signal trait bounds that come + // from the trait itself that *shouldn't* be shown as the source of + // an obligation and instead be skipped. Otherwise we'd use + // `tcx.def_span(def_id);` + + let constness = if tcx.has_attr(def_id, sym::const_trait) { + ty::BoundConstness::ConstIfConst + } else { + ty::BoundConstness::NotConst + }; + + let span = rustc_span::DUMMY_SP; + result.predicates = + tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( + ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx), + span, + )))); + } + debug!("predicates_of(def_id={:?}) = {:?}", def_id, result); + result +} + +/// Returns a list of user-specified type predicates for the definition with ID `def_id`. +/// N.B., this does not include any implied/inferred constraints. +#[instrument(level = "trace", skip(tcx), ret)] +fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> { + use rustc_hir::*; + + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + let node = tcx.hir().get(hir_id); + + let mut is_trait = None; + let mut is_default_impl_trait = None; + + let icx = ItemCtxt::new(tcx, def_id); + + const NO_GENERICS: &hir::Generics<'_> = hir::Generics::empty(); + + // We use an `IndexSet` to preserves order of insertion. + // Preserving the order of insertion is important here so as not to break UI tests. + let mut predicates: FxIndexSet<(ty::Predicate<'_>, Span)> = FxIndexSet::default(); + + let ast_generics = match node { + Node::TraitItem(item) => item.generics, + + Node::ImplItem(item) => item.generics, + + Node::Item(item) => { + match item.kind { + ItemKind::Impl(ref impl_) => { + if impl_.defaultness.is_default() { + is_default_impl_trait = tcx.impl_trait_ref(def_id).map(ty::Binder::dummy); + } + &impl_.generics + } + ItemKind::Fn(.., ref generics, _) + | ItemKind::TyAlias(_, ref generics) + | ItemKind::Enum(_, ref generics) + | ItemKind::Struct(_, ref generics) + | ItemKind::Union(_, ref generics) => *generics, + + ItemKind::Trait(_, _, ref generics, ..) => { + is_trait = Some(ty::TraitRef::identity(tcx, def_id)); + *generics + } + ItemKind::TraitAlias(ref generics, _) => { + is_trait = Some(ty::TraitRef::identity(tcx, def_id)); + *generics + } + ItemKind::OpaqueTy(OpaqueTy { + origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), + .. + }) => { + // return-position impl trait + // + // We don't inherit predicates from the parent here: + // If we have, say `fn f<'a, T: 'a>() -> impl Sized {}` + // then the return type is `f::<'static, T>::{{opaque}}`. + // + // If we inherited the predicates of `f` then we would + // require that `T: 'static` to show that the return + // type is well-formed. + // + // The only way to have something with this opaque type + // is from the return type of the containing function, + // which will ensure that the function's predicates + // hold. + return ty::GenericPredicates { parent: None, predicates: &[] }; + } + ItemKind::OpaqueTy(OpaqueTy { + ref generics, + origin: hir::OpaqueTyOrigin::TyAlias, + .. + }) => { + // type-alias impl trait + generics + } + + _ => NO_GENERICS, + } + } + + Node::ForeignItem(item) => match item.kind { + ForeignItemKind::Static(..) => NO_GENERICS, + ForeignItemKind::Fn(_, _, ref generics) => *generics, + ForeignItemKind::Type => NO_GENERICS, + }, + + _ => NO_GENERICS, + }; + + let generics = tcx.generics_of(def_id); + let parent_count = generics.parent_count as u32; + let has_own_self = generics.has_self && parent_count == 0; + + // Below we'll consider the bounds on the type parameters (including `Self`) + // and the explicit where-clauses, but to get the full set of predicates + // on a trait we need to add in the supertrait bounds and bounds found on + // associated types. + if let Some(_trait_ref) = is_trait { + predicates.extend(tcx.super_predicates_of(def_id).predicates.iter().cloned()); + } + + // In default impls, we can assume that the self type implements + // the trait. So in: + // + // default impl Foo for Bar { .. } + // + // we add a default where clause `Foo: Bar`. We do a similar thing for traits + // (see below). Recall that a default impl is not itself an impl, but rather a + // set of defaults that can be incorporated into another impl. + if let Some(trait_ref) = is_default_impl_trait { + predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id))); + } + + // Collect the region predicates that were declared inline as + // well. In the case of parameters declared on a fn or method, we + // have to be careful to only iterate over early-bound regions. + let mut index = parent_count + + has_own_self as u32 + + super::early_bound_lifetimes_from_generics(tcx, ast_generics).count() as u32; + + trace!(?predicates); + trace!(?ast_generics); + + // Collect the predicates that were written inline by the user on each + // type parameter (e.g., `<T: Foo>`). + for param in ast_generics.params { + match param.kind { + // We already dealt with early bound lifetimes above. + GenericParamKind::Lifetime { .. } => (), + GenericParamKind::Type { .. } => { + let name = param.name.ident().name; + let param_ty = ty::ParamTy::new(index, name).to_ty(tcx); + index += 1; + + let mut bounds = Bounds::default(); + // Params are implicitly sized unless a `?Sized` bound is found + <dyn AstConv<'_>>::add_implicitly_sized( + &icx, + &mut bounds, + &[], + Some((param.hir_id, ast_generics.predicates)), + param.span, + ); + trace!(?bounds); + predicates.extend(bounds.predicates(tcx, param_ty)); + trace!(?predicates); + } + GenericParamKind::Const { .. } => { + // Bounds on const parameters are currently not possible. + index += 1; + } + } + } + + trace!(?predicates); + // Add in the bounds that appear in the where-clause. + for predicate in ast_generics.predicates { + match predicate { + hir::WherePredicate::BoundPredicate(bound_pred) => { + let ty = icx.to_ty(bound_pred.bounded_ty); + let bound_vars = icx.tcx.late_bound_vars(bound_pred.hir_id); + + // Keep the type around in a dummy predicate, in case of no bounds. + // That way, `where Ty:` is not a complete noop (see #53696) and `Ty` + // is still checked for WF. + if bound_pred.bounds.is_empty() { + if let ty::Param(_) = ty.kind() { + // This is a `where T:`, which can be in the HIR from the + // transformation that moves `?Sized` to `T`'s declaration. + // We can skip the predicate because type parameters are + // trivially WF, but also we *should*, to avoid exposing + // users who never wrote `where Type:,` themselves, to + // compiler/tooling bugs from not handling WF predicates. + } else { + let span = bound_pred.bounded_ty.span; + let predicate = ty::Binder::bind_with_vars( + ty::PredicateKind::WellFormed(ty.into()), + bound_vars, + ); + predicates.insert((predicate.to_predicate(tcx), span)); + } + } + + let mut bounds = Bounds::default(); + <dyn AstConv<'_>>::add_bounds( + &icx, + ty, + bound_pred.bounds.iter(), + &mut bounds, + bound_vars, + ); + predicates.extend(bounds.predicates(tcx, ty)); + } + + hir::WherePredicate::RegionPredicate(region_pred) => { + let r1 = <dyn AstConv<'_>>::ast_region_to_region(&icx, ®ion_pred.lifetime, None); + predicates.extend(region_pred.bounds.iter().map(|bound| { + let (r2, span) = match bound { + hir::GenericBound::Outlives(lt) => { + (<dyn AstConv<'_>>::ast_region_to_region(&icx, lt, None), lt.span) + } + _ => bug!(), + }; + let pred = ty::Binder::dummy(ty::PredicateKind::RegionOutlives( + ty::OutlivesPredicate(r1, r2), + )) + .to_predicate(icx.tcx); + + (pred, span) + })) + } + + hir::WherePredicate::EqPredicate(..) => { + // FIXME(#20041) + } + } + } + + if tcx.features().generic_const_exprs { + predicates.extend(const_evaluatable_predicates_of(tcx, def_id.expect_local())); + } + + let mut predicates: Vec<_> = predicates.into_iter().collect(); + + // Subtle: before we store the predicates into the tcx, we + // sort them so that predicates like `T: Foo<Item=U>` come + // before uses of `U`. This avoids false ambiguity errors + // in trait checking. See `setup_constraining_predicates` + // for details. + if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node { + let self_ty = tcx.type_of(def_id); + let trait_ref = tcx.impl_trait_ref(def_id); + cgp::setup_constraining_predicates( + tcx, + &mut predicates, + trait_ref, + &mut cgp::parameters_for_impl(self_ty, trait_ref), + ); + } + + ty::GenericPredicates { + parent: generics.parent, + predicates: tcx.arena.alloc_from_iter(predicates), + } +} + +fn const_evaluatable_predicates_of<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: LocalDefId, +) -> FxIndexSet<(ty::Predicate<'tcx>, Span)> { + struct ConstCollector<'tcx> { + tcx: TyCtxt<'tcx>, + preds: FxIndexSet<(ty::Predicate<'tcx>, Span)>, + } + + impl<'tcx> intravisit::Visitor<'tcx> for ConstCollector<'tcx> { + fn visit_anon_const(&mut self, c: &'tcx hir::AnonConst) { + let def_id = self.tcx.hir().local_def_id(c.hir_id); + let ct = ty::Const::from_anon_const(self.tcx, def_id); + if let ty::ConstKind::Unevaluated(uv) = ct.kind() { + let span = self.tcx.hir().span(c.hir_id); + self.preds.insert(( + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(uv)) + .to_predicate(self.tcx), + span, + )); + } + } + + fn visit_const_param_default(&mut self, _param: HirId, _ct: &'tcx hir::AnonConst) { + // Do not look into const param defaults, + // these get checked when they are actually instantiated. + // + // We do not want the following to error: + // + // struct Foo<const N: usize, const M: usize = { N + 1 }>; + // struct Bar<const N: usize>(Foo<N, 3>); + } + } + + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let node = tcx.hir().get(hir_id); + + let mut collector = ConstCollector { tcx, preds: FxIndexSet::default() }; + if let hir::Node::Item(item) = node && let hir::ItemKind::Impl(ref impl_) = item.kind { + if let Some(of_trait) = &impl_.of_trait { + debug!("const_evaluatable_predicates_of({:?}): visit impl trait_ref", def_id); + collector.visit_trait_ref(of_trait); + } + + debug!("const_evaluatable_predicates_of({:?}): visit_self_ty", def_id); + collector.visit_ty(impl_.self_ty); + } + + if let Some(generics) = node.generics() { + debug!("const_evaluatable_predicates_of({:?}): visit_generics", def_id); + collector.visit_generics(generics); + } + + if let Some(fn_sig) = tcx.hir().fn_sig_by_hir_id(hir_id) { + debug!("const_evaluatable_predicates_of({:?}): visit_fn_decl", def_id); + collector.visit_fn_decl(fn_sig.decl); + } + debug!("const_evaluatable_predicates_of({:?}) = {:?}", def_id, collector.preds); + + collector.preds +} + +pub(super) fn trait_explicit_predicates_and_bounds( + tcx: TyCtxt<'_>, + def_id: LocalDefId, +) -> ty::GenericPredicates<'_> { + assert_eq!(tcx.def_kind(def_id), DefKind::Trait); + gather_explicit_predicates_of(tcx, def_id.to_def_id()) +} + +pub(super) fn explicit_predicates_of<'tcx>( + tcx: TyCtxt<'tcx>, + def_id: DefId, +) -> ty::GenericPredicates<'tcx> { + let def_kind = tcx.def_kind(def_id); + if let DefKind::Trait = def_kind { + // Remove bounds on associated types from the predicates, they will be + // returned by `explicit_item_bounds`. + let predicates_and_bounds = tcx.trait_explicit_predicates_and_bounds(def_id.expect_local()); + let trait_identity_substs = InternalSubsts::identity_for_item(tcx, def_id); + + let is_assoc_item_ty = |ty: Ty<'tcx>| { + // For a predicate from a where clause to become a bound on an + // associated type: + // * It must use the identity substs of the item. + // * Since any generic parameters on the item are not in scope, + // this means that the item is not a GAT, and its identity + // substs are the same as the trait's. + // * It must be an associated type for this trait (*not* a + // supertrait). + if let ty::Projection(projection) = ty.kind() { + projection.substs == trait_identity_substs + && tcx.associated_item(projection.item_def_id).container_id(tcx) == def_id + } else { + false + } + }; + + let predicates: Vec<_> = predicates_and_bounds + .predicates + .iter() + .copied() + .filter(|(pred, _)| match pred.kind().skip_binder() { + ty::PredicateKind::Trait(tr) => !is_assoc_item_ty(tr.self_ty()), + ty::PredicateKind::Projection(proj) => { + !is_assoc_item_ty(proj.projection_ty.self_ty()) + } + ty::PredicateKind::TypeOutlives(outlives) => !is_assoc_item_ty(outlives.0), + _ => true, + }) + .collect(); + if predicates.len() == predicates_and_bounds.predicates.len() { + predicates_and_bounds + } else { + ty::GenericPredicates { + parent: predicates_and_bounds.parent, + predicates: tcx.arena.alloc_slice(&predicates), + } + } + } else { + if matches!(def_kind, DefKind::AnonConst) && tcx.lazy_normalization() { + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); + if tcx.hir().opt_const_param_default_param_hir_id(hir_id).is_some() { + // In `generics_of` we set the generics' parent to be our parent's parent which means that + // we lose out on the predicates of our actual parent if we dont return those predicates here. + // (See comment in `generics_of` for more information on why the parent shenanigans is necessary) + // + // struct Foo<T, const N: usize = { <T as Trait>::ASSOC }>(T) where T: Trait; + // ^^^ ^^^^^^^^^^^^^^^^^^^^^^^ the def id we are calling + // ^^^ explicit_predicates_of on + // parent item we dont have set as the + // parent of generics returned by `generics_of` + // + // In the above code we want the anon const to have predicates in its param env for `T: Trait` + let item_def_id = tcx.hir().get_parent_item(hir_id); + // In the above code example we would be calling `explicit_predicates_of(Foo)` here + return tcx.explicit_predicates_of(item_def_id); + } + } + gather_explicit_predicates_of(tcx, def_id) + } +} + +/// Ensures that the super-predicates of the trait with a `DefId` +/// of `trait_def_id` are converted and stored. This also ensures that +/// the transitive super-predicates are converted. +pub(super) fn super_predicates_of( + tcx: TyCtxt<'_>, + trait_def_id: DefId, +) -> ty::GenericPredicates<'_> { + tcx.super_predicates_that_define_assoc_type((trait_def_id, None)) +} + +/// Ensures that the super-predicates of the trait with a `DefId` +/// of `trait_def_id` are converted and stored. This also ensures that +/// the transitive super-predicates are converted. +pub(super) fn super_predicates_that_define_assoc_type( + tcx: TyCtxt<'_>, + (trait_def_id, assoc_name): (DefId, Option<Ident>), +) -> ty::GenericPredicates<'_> { + if trait_def_id.is_local() { + debug!("local trait"); + let trait_hir_id = tcx.hir().local_def_id_to_hir_id(trait_def_id.expect_local()); + + let Node::Item(item) = tcx.hir().get(trait_hir_id) else { + bug!("trait_node_id {} is not an item", trait_hir_id); + }; + + let (generics, bounds) = match item.kind { + hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits), + hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits), + _ => span_bug!(item.span, "super_predicates invoked on non-trait"), + }; + + let icx = ItemCtxt::new(tcx, trait_def_id); + + // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`. + let self_param_ty = tcx.types.self_param; + let superbounds1 = if let Some(assoc_name) = assoc_name { + <dyn AstConv<'_>>::compute_bounds_that_match_assoc_type( + &icx, + self_param_ty, + bounds, + assoc_name, + ) + } else { + <dyn AstConv<'_>>::compute_bounds(&icx, self_param_ty, bounds) + }; + + let superbounds1 = superbounds1.predicates(tcx, self_param_ty); + + // Convert any explicit superbounds in the where-clause, + // e.g., `trait Foo where Self: Bar`. + // In the case of trait aliases, however, we include all bounds in the where-clause, + // so e.g., `trait Foo = where u32: PartialEq<Self>` would include `u32: PartialEq<Self>` + // as one of its "superpredicates". + let is_trait_alias = tcx.is_trait_alias(trait_def_id); + let superbounds2 = icx.type_parameter_bounds_in_generics( + generics, + item.hir_id(), + self_param_ty, + OnlySelfBounds(!is_trait_alias), + assoc_name, + ); + + // Combine the two lists to form the complete set of superbounds: + let superbounds = &*tcx.arena.alloc_from_iter(superbounds1.into_iter().chain(superbounds2)); + debug!(?superbounds); + + // Now require that immediate supertraits are converted, + // which will, in turn, reach indirect supertraits. + if assoc_name.is_none() { + // Now require that immediate supertraits are converted, + // which will, in turn, reach indirect supertraits. + for &(pred, span) in superbounds { + debug!("superbound: {:?}", pred); + if let ty::PredicateKind::Trait(bound) = pred.kind().skip_binder() { + tcx.at(span).super_predicates_of(bound.def_id()); + } + } + } + + ty::GenericPredicates { parent: None, predicates: superbounds } + } else { + // if `assoc_name` is None, then the query should've been redirected to an + // external provider + assert!(assoc_name.is_some()); + tcx.super_predicates_of(trait_def_id) + } +} + +/// Returns the predicates defined on `item_def_id` of the form +/// `X: Foo` where `X` is the type parameter `def_id`. +#[instrument(level = "trace", skip(tcx))] +pub(super) fn type_param_predicates( + tcx: TyCtxt<'_>, + (item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident), +) -> ty::GenericPredicates<'_> { + use rustc_hir::*; + + // In the AST, bounds can derive from two places. Either + // written inline like `<T: Foo>` or in a where-clause like + // `where T: Foo`. + + let param_id = tcx.hir().local_def_id_to_hir_id(def_id); + let param_owner = tcx.hir().ty_param_owner(def_id); + let generics = tcx.generics_of(param_owner); + let index = generics.param_def_id_to_index[&def_id.to_def_id()]; + let ty = tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id)); + + // Don't look for bounds where the type parameter isn't in scope. + let parent = if item_def_id == param_owner.to_def_id() { + None + } else { + tcx.generics_of(item_def_id).parent + }; + + let mut result = parent + .map(|parent| { + let icx = ItemCtxt::new(tcx, parent); + icx.get_type_parameter_bounds(DUMMY_SP, def_id.to_def_id(), assoc_name) + }) + .unwrap_or_default(); + let mut extend = None; + + let item_hir_id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local()); + let ast_generics = match tcx.hir().get(item_hir_id) { + Node::TraitItem(item) => &item.generics, + + Node::ImplItem(item) => &item.generics, + + Node::Item(item) => { + match item.kind { + ItemKind::Fn(.., ref generics, _) + | ItemKind::Impl(hir::Impl { ref generics, .. }) + | ItemKind::TyAlias(_, ref generics) + | ItemKind::OpaqueTy(OpaqueTy { + ref generics, + origin: hir::OpaqueTyOrigin::TyAlias, + .. + }) + | ItemKind::Enum(_, ref generics) + | ItemKind::Struct(_, ref generics) + | ItemKind::Union(_, ref generics) => generics, + ItemKind::Trait(_, _, ref generics, ..) => { + // Implied `Self: Trait` and supertrait bounds. + if param_id == item_hir_id { + let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id); + extend = + Some((identity_trait_ref.without_const().to_predicate(tcx), item.span)); + } + generics + } + _ => return result, + } + } + + Node::ForeignItem(item) => match item.kind { + ForeignItemKind::Fn(_, _, ref generics) => generics, + _ => return result, + }, + + _ => return result, + }; + + let icx = ItemCtxt::new(tcx, item_def_id); + let extra_predicates = extend.into_iter().chain( + icx.type_parameter_bounds_in_generics( + ast_generics, + param_id, + ty, + OnlySelfBounds(true), + Some(assoc_name), + ) + .into_iter() + .filter(|(predicate, _)| match predicate.kind().skip_binder() { + ty::PredicateKind::Trait(data) => data.self_ty().is_param(index), + _ => false, + }), + ); + result.predicates = + tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(extra_predicates)); + result +} + +impl<'tcx> ItemCtxt<'tcx> { + /// Finds bounds from `hir::Generics`. This requires scanning through the + /// AST. We do this to avoid having to convert *all* the bounds, which + /// would create artificial cycles. Instead, we can only convert the + /// bounds for a type parameter `X` if `X::Foo` is used. + #[instrument(level = "trace", skip(self, ast_generics))] + fn type_parameter_bounds_in_generics( + &self, + ast_generics: &'tcx hir::Generics<'tcx>, + param_id: hir::HirId, + ty: Ty<'tcx>, + only_self_bounds: OnlySelfBounds, + assoc_name: Option<Ident>, + ) -> Vec<(ty::Predicate<'tcx>, Span)> { + let param_def_id = self.tcx.hir().local_def_id(param_id).to_def_id(); + trace!(?param_def_id); + ast_generics + .predicates + .iter() + .filter_map(|wp| match *wp { + hir::WherePredicate::BoundPredicate(ref bp) => Some(bp), + _ => None, + }) + .flat_map(|bp| { + let bt = if bp.is_param_bound(param_def_id) { + Some(ty) + } else if !only_self_bounds.0 { + Some(self.to_ty(bp.bounded_ty)) + } else { + None + }; + let bvars = self.tcx.late_bound_vars(bp.hir_id); + + bp.bounds.iter().filter_map(move |b| bt.map(|bt| (bt, b, bvars))).filter( + |(_, b, _)| match assoc_name { + Some(assoc_name) => self.bound_defines_assoc_item(b, assoc_name), + None => true, + }, + ) + }) + .flat_map(|(bt, b, bvars)| predicates_from_bound(self, bt, b, bvars)) + .collect() + } + + #[instrument(level = "trace", skip(self))] + fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool { + match b { + hir::GenericBound::Trait(poly_trait_ref, _) => { + let trait_ref = &poly_trait_ref.trait_ref; + if let Some(trait_did) = trait_ref.trait_def_id() { + self.tcx.trait_may_define_assoc_type(trait_did, assoc_name) + } else { + false + } + } + _ => false, + } + } +} + +/// Converts a specific `GenericBound` from the AST into a set of +/// predicates that apply to the self type. A vector is returned +/// because this can be anywhere from zero predicates (`T: ?Sized` adds no +/// predicates) to one (`T: Foo`) to many (`T: Bar<X = i32>` adds `T: Bar` +/// and `<T as Bar>::X == i32`). +fn predicates_from_bound<'tcx>( + astconv: &dyn AstConv<'tcx>, + param_ty: Ty<'tcx>, + bound: &'tcx hir::GenericBound<'tcx>, + bound_vars: &'tcx ty::List<ty::BoundVariableKind>, +) -> Vec<(ty::Predicate<'tcx>, Span)> { + let mut bounds = Bounds::default(); + astconv.add_bounds(param_ty, [bound].into_iter(), &mut bounds, bound_vars); + bounds.predicates(astconv.tcx(), param_ty).collect() +} diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 24fb0b1fd26..f8a62c84910 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -333,7 +333,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { find_opaque_ty_constraints_for_tait(tcx, def_id) } // Opaque types desugared from `impl Trait`. - ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), in_trait, .. }) => { + ItemKind::OpaqueTy(OpaqueTy { + origin: + hir::OpaqueTyOrigin::FnReturn(owner) | hir::OpaqueTyOrigin::AsyncFn(owner), + in_trait, + .. + }) => { if in_trait { span_bug!(item.span, "impl-trait in trait has no default") } else { @@ -378,7 +383,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { Node::Field(field) => icx.to_ty(field.ty), - Node::Expr(&Expr { kind: ExprKind::Closure{..}, .. }) => tcx.typeck(def_id).node_type(hir_id), + Node::Expr(&Expr { kind: ExprKind::Closure { .. }, .. }) => { + tcx.typeck(def_id).node_type(hir_id) + } Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => { // We defer to `type_of` of the corresponding parameter @@ -410,40 +417,91 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. }) if asm.operands.iter().any(|(op, _op_sp)| match op { hir::InlineAsmOperand::Const { anon_const } - | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id, + | hir::InlineAsmOperand::SymFn { anon_const } => { + anon_const.hir_id == hir_id + } _ => false, }) => { tcx.typeck(def_id).node_type(hir_id) } - Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => tcx - .adt_def(tcx.hir().get_parent_item(hir_id)) - .repr() - .discr_type() - .to_ty(tcx), + Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => { + tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx) + } - Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. }) - if let Node::TraitRef(trait_ref) = tcx.hir().get( - tcx.hir().get_parent_node(binding_id) - ) => + Node::TypeBinding( + binding @ &TypeBinding { + hir_id: binding_id, + kind: TypeBindingKind::Equality { term: Term::Const(ref e) }, + .. + }, + ) if let Node::TraitRef(trait_ref) = + tcx.hir().get(tcx.hir().get_parent_node(binding_id)) + && e.hir_id == hir_id => { - let Some(trait_def_id) = trait_ref.trait_def_id() else { - return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"); - }; - let assoc_items = tcx.associated_items(trait_def_id); - let assoc_item = assoc_items.find_by_name_and_kind( - tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(), - ); - if let Some(assoc_item) = assoc_item { - tcx.type_of(assoc_item.def_id) - } else { - // FIXME(associated_const_equality): add a useful error message here. - tcx.ty_error_with_message( - DUMMY_SP, - "Could not find associated const on trait", - ) - } + let Some(trait_def_id) = trait_ref.trait_def_id() else { + return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"); + }; + let assoc_items = tcx.associated_items(trait_def_id); + let assoc_item = assoc_items.find_by_name_and_kind( + tcx, + binding.ident, + ty::AssocKind::Const, + def_id.to_def_id(), + ); + if let Some(assoc_item) = assoc_item { + tcx.type_of(assoc_item.def_id) + } else { + // FIXME(associated_const_equality): add a useful error message here. + tcx.ty_error_with_message( + DUMMY_SP, + "Could not find associated const on trait", + ) + } + } + + Node::TypeBinding( + binding @ &TypeBinding { hir_id: binding_id, gen_args, ref kind, .. }, + ) if let Node::TraitRef(trait_ref) = + tcx.hir().get(tcx.hir().get_parent_node(binding_id)) + && let Some((idx, _)) = + gen_args.args.iter().enumerate().find(|(_, arg)| { + if let GenericArg::Const(ct) = arg { + ct.value.hir_id == hir_id + } else { + false + } + }) => + { + let Some(trait_def_id) = trait_ref.trait_def_id() else { + return tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"); + }; + let assoc_items = tcx.associated_items(trait_def_id); + let assoc_item = assoc_items.find_by_name_and_kind( + tcx, + binding.ident, + match kind { + // I think `<A: T>` type bindings requires that `A` is a type + TypeBindingKind::Constraint { .. } + | TypeBindingKind::Equality { term: Term::Ty(..) } => { + ty::AssocKind::Type + } + TypeBindingKind::Equality { term: Term::Const(..) } => { + ty::AssocKind::Const + } + }, + def_id.to_def_id(), + ); + if let Some(assoc_item) = assoc_item { + tcx.type_of(tcx.generics_of(assoc_item.def_id).params[idx].def_id) + } else { + // FIXME(associated_const_equality): add a useful error message here. + tcx.ty_error_with_message( + DUMMY_SP, + "Could not find associated const on trait", + ) + } } Node::GenericParam(&GenericParam { @@ -452,8 +510,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { .. }) if ct.hir_id == hir_id => tcx.type_of(tcx.hir().local_def_id(param_hir_id)), - x => - tcx.ty_error_with_message( + x => tcx.ty_error_with_message( DUMMY_SP, &format!("unexpected const parent in type_of(): {x:?}"), ), diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 44df47e2fa0..d891171b824 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1,4 +1,5 @@ -//! Errors emitted by typeck. +//! Errors emitted by `hir_analysis`. + use rustc_errors::IntoDiagnostic; use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -6,18 +7,18 @@ use rustc_middle::ty::Ty; use rustc_span::{symbol::Ident, Span, Symbol}; #[derive(Diagnostic)] -#[diag(typeck::field_multiply_specified_in_initializer, code = "E0062")] +#[diag(hir_analysis::field_multiply_specified_in_initializer, code = "E0062")] pub struct FieldMultiplySpecifiedInInitializer { #[primary_span] #[label] pub span: Span, - #[label(typeck::previous_use_label)] + #[label(hir_analysis::previous_use_label)] pub prev_span: Span, pub ident: Ident, } #[derive(Diagnostic)] -#[diag(typeck::unrecognized_atomic_operation, code = "E0092")] +#[diag(hir_analysis::unrecognized_atomic_operation, code = "E0092")] pub struct UnrecognizedAtomicOperation<'a> { #[primary_span] #[label] @@ -26,7 +27,7 @@ pub struct UnrecognizedAtomicOperation<'a> { } #[derive(Diagnostic)] -#[diag(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")] +#[diag(hir_analysis::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")] pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { #[primary_span] #[label] @@ -37,7 +38,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { } #[derive(Diagnostic)] -#[diag(typeck::unrecognized_intrinsic_function, code = "E0093")] +#[diag(hir_analysis::unrecognized_intrinsic_function, code = "E0093")] pub struct UnrecognizedIntrinsicFunction { #[primary_span] #[label] @@ -46,19 +47,19 @@ pub struct UnrecognizedIntrinsicFunction { } #[derive(Diagnostic)] -#[diag(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")] +#[diag(hir_analysis::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")] pub struct LifetimesOrBoundsMismatchOnTrait { #[primary_span] #[label] pub span: Span, - #[label(typeck::generics_label)] + #[label(hir_analysis::generics_label)] pub generics_span: Option<Span>, pub item_kind: &'static str, pub ident: Ident, } #[derive(Diagnostic)] -#[diag(typeck::drop_impl_on_wrong_item, code = "E0120")] +#[diag(hir_analysis::drop_impl_on_wrong_item, code = "E0120")] pub struct DropImplOnWrongItem { #[primary_span] #[label] @@ -66,18 +67,18 @@ pub struct DropImplOnWrongItem { } #[derive(Diagnostic)] -#[diag(typeck::field_already_declared, code = "E0124")] +#[diag(hir_analysis::field_already_declared, code = "E0124")] pub struct FieldAlreadyDeclared { pub field_name: Ident, #[primary_span] #[label] pub span: Span, - #[label(typeck::previous_decl_label)] + #[label(hir_analysis::previous_decl_label)] pub prev_span: Span, } #[derive(Diagnostic)] -#[diag(typeck::copy_impl_on_type_with_dtor, code = "E0184")] +#[diag(hir_analysis::copy_impl_on_type_with_dtor, code = "E0184")] pub struct CopyImplOnTypeWithDtor { #[primary_span] #[label] @@ -85,14 +86,14 @@ pub struct CopyImplOnTypeWithDtor { } #[derive(Diagnostic)] -#[diag(typeck::multiple_relaxed_default_bounds, code = "E0203")] +#[diag(hir_analysis::multiple_relaxed_default_bounds, code = "E0203")] pub struct MultipleRelaxedDefaultBounds { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::copy_impl_on_non_adt, code = "E0206")] +#[diag(hir_analysis::copy_impl_on_non_adt, code = "E0206")] pub struct CopyImplOnNonAdt { #[primary_span] #[label] @@ -100,23 +101,23 @@ pub struct CopyImplOnNonAdt { } #[derive(Diagnostic)] -#[diag(typeck::trait_object_declared_with_no_traits, code = "E0224")] +#[diag(hir_analysis::trait_object_declared_with_no_traits, code = "E0224")] pub struct TraitObjectDeclaredWithNoTraits { #[primary_span] pub span: Span, - #[label(typeck::alias_span)] + #[label(hir_analysis::alias_span)] pub trait_alias_span: Option<Span>, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0227")] +#[diag(hir_analysis::ambiguous_lifetime_bound, code = "E0227")] pub struct AmbiguousLifetimeBound { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::assoc_type_binding_not_allowed, code = "E0229")] +#[diag(hir_analysis::assoc_type_binding_not_allowed, code = "E0229")] pub struct AssocTypeBindingNotAllowed { #[primary_span] #[label] @@ -124,14 +125,14 @@ pub struct AssocTypeBindingNotAllowed { } #[derive(Diagnostic)] -#[diag(typeck::functional_record_update_on_non_struct, code = "E0436")] +#[diag(hir_analysis::functional_record_update_on_non_struct, code = "E0436")] pub struct FunctionalRecordUpdateOnNonStruct { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::typeof_reserved_keyword_used, code = "E0516")] +#[diag(hir_analysis::typeof_reserved_keyword_used, code = "E0516")] pub struct TypeofReservedKeywordUsed<'tcx> { pub ty: Ty<'tcx>, #[primary_span] @@ -142,25 +143,25 @@ pub struct TypeofReservedKeywordUsed<'tcx> { } #[derive(Diagnostic)] -#[diag(typeck::return_stmt_outside_of_fn_body, code = "E0572")] +#[diag(hir_analysis::return_stmt_outside_of_fn_body, code = "E0572")] pub struct ReturnStmtOutsideOfFnBody { #[primary_span] pub span: Span, - #[label(typeck::encl_body_label)] + #[label(hir_analysis::encl_body_label)] pub encl_body_span: Option<Span>, - #[label(typeck::encl_fn_label)] + #[label(hir_analysis::encl_fn_label)] pub encl_fn_span: Option<Span>, } #[derive(Diagnostic)] -#[diag(typeck::yield_expr_outside_of_generator, code = "E0627")] +#[diag(hir_analysis::yield_expr_outside_of_generator, code = "E0627")] pub struct YieldExprOutsideOfGenerator { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::struct_expr_non_exhaustive, code = "E0639")] +#[diag(hir_analysis::struct_expr_non_exhaustive, code = "E0639")] pub struct StructExprNonExhaustive { #[primary_span] pub span: Span, @@ -168,26 +169,26 @@ pub struct StructExprNonExhaustive { } #[derive(Diagnostic)] -#[diag(typeck::method_call_on_unknown_type, code = "E0699")] +#[diag(hir_analysis::method_call_on_unknown_type, code = "E0699")] pub struct MethodCallOnUnknownType { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(typeck::value_of_associated_struct_already_specified, code = "E0719")] +#[diag(hir_analysis::value_of_associated_struct_already_specified, code = "E0719")] pub struct ValueOfAssociatedStructAlreadySpecified { #[primary_span] #[label] pub span: Span, - #[label(typeck::previous_bound_label)] + #[label(hir_analysis::previous_bound_label)] pub prev_span: Span, pub item_name: Ident, pub def_path: String, } #[derive(Diagnostic)] -#[diag(typeck::address_of_temporary_taken, code = "E0745")] +#[diag(hir_analysis::address_of_temporary_taken, code = "E0745")] pub struct AddressOfTemporaryTaken { #[primary_span] #[label] @@ -197,7 +198,7 @@ pub struct AddressOfTemporaryTaken { #[derive(Subdiagnostic)] pub enum AddReturnTypeSuggestion { #[suggestion( - typeck::add_return_type_add, + hir_analysis::add_return_type_add, code = "-> {found} ", applicability = "machine-applicable" )] @@ -207,7 +208,7 @@ pub enum AddReturnTypeSuggestion { found: String, }, #[suggestion( - typeck::add_return_type_missing_here, + hir_analysis::add_return_type_missing_here, code = "-> _ ", applicability = "has-placeholders" )] @@ -219,12 +220,12 @@ pub enum AddReturnTypeSuggestion { #[derive(Subdiagnostic)] pub enum ExpectedReturnTypeLabel<'tcx> { - #[label(typeck::expected_default_return_type)] + #[label(hir_analysis::expected_default_return_type)] Unit { #[primary_span] span: Span, }, - #[label(typeck::expected_return_type)] + #[label(hir_analysis::expected_return_type)] Other { #[primary_span] span: Span, @@ -233,7 +234,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> { } #[derive(Diagnostic)] -#[diag(typeck::unconstrained_opaque_type)] +#[diag(hir_analysis::unconstrained_opaque_type)] #[note] pub struct UnconstrainedOpaqueType { #[primary_span] @@ -254,7 +255,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = handler.struct_span_err_with_code( self.span, - rustc_errors::fluent::typeck::missing_type_params, + rustc_errors::fluent::hir_analysis::missing_type_params, error_code!(E0393), ); err.set_arg("parameterCount", self.missing_type_params.len()); @@ -267,7 +268,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { .join(", "), ); - err.span_label(self.def_span, rustc_errors::fluent::typeck::label); + err.span_label(self.def_span, rustc_errors::fluent::hir_analysis::label); let mut suggested = false; // Don't suggest setting the type params if there are some already: the order is @@ -282,7 +283,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { // least we can clue them to the correct syntax `Iterator<Type>`. err.span_suggestion( self.span, - rustc_errors::fluent::typeck::suggestion, + rustc_errors::fluent::hir_analysis::suggestion, format!( "{}<{}>", snippet, @@ -298,16 +299,16 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { } } if !suggested { - err.span_label(self.span, rustc_errors::fluent::typeck::no_suggestion_label); + err.span_label(self.span, rustc_errors::fluent::hir_analysis::no_suggestion_label); } - err.note(rustc_errors::fluent::typeck::note); + err.note(rustc_errors::fluent::hir_analysis::note); err } } #[derive(Diagnostic)] -#[diag(typeck::manual_implementation, code = "E0183")] +#[diag(hir_analysis::manual_implementation, code = "E0183")] #[help] pub struct ManualImplementation { #[primary_span] @@ -317,21 +318,21 @@ pub struct ManualImplementation { } #[derive(Diagnostic)] -#[diag(typeck::substs_on_overridden_impl)] +#[diag(hir_analysis::substs_on_overridden_impl)] pub struct SubstsOnOverriddenImpl { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(typeck::unused_extern_crate)] +#[diag(hir_analysis::unused_extern_crate)] pub struct UnusedExternCrate { #[suggestion(applicability = "machine-applicable", code = "")] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(typeck::extern_crate_not_idiomatic)] +#[diag(hir_analysis::extern_crate_not_idiomatic)] pub struct ExternCrateNotIdiomatic { #[suggestion_short(applicability = "machine-applicable", code = "{suggestion_code}")] pub span: Span, @@ -340,7 +341,7 @@ pub struct ExternCrateNotIdiomatic { } #[derive(Diagnostic)] -#[diag(typeck::expected_used_symbol)] +#[diag(hir_analysis::expected_used_symbol)] pub struct ExpectedUsedSymbol { #[primary_span] pub span: Span, diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 1859473166a..d31b9b7ae46 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -70,7 +70,7 @@ This API is completely unstable and subject to change. #![feature(once_cell)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] -#![feature(is_some_with)] +#![feature(is_some_and)] #![feature(type_alias_impl_trait)] #![recursion_limit = "256"] diff --git a/compiler/rustc_hir_analysis/src/mem_categorization.rs b/compiler/rustc_hir_analysis/src/mem_categorization.rs index 39610e3ae38..46b49647836 100644 --- a/compiler/rustc_hir_analysis/src/mem_categorization.rs +++ b/compiler/rustc_hir_analysis/src/mem_categorization.rs @@ -560,7 +560,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _) | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _) | Res::SelfCtor(..) - | Res::SelfTy { .. } => { + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } => { // Structs and Unions have only have one variant. Ok(VariantIdx::new(0)) } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 99de5b65981..9d56764d489 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2158,8 +2158,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, diag: &mut Diagnostic, ) { + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) + && let Some(msg) = self.should_suggest_as_ref(exp_found.expected, exp_found.found) + { + diag.span_suggestion( + span, + msg, + // HACK: fix issue# 100605, suggesting convert from &Option<T> to Option<&T>, remove the extra `&` + format!("{}.as_ref()", snippet.trim_start_matches('&')), + Applicability::MachineApplicable, + ); + } + } + + pub fn should_suggest_as_ref(&self, expected: Ty<'tcx>, found: Ty<'tcx>) -> Option<&str> { if let (ty::Adt(exp_def, exp_substs), ty::Ref(_, found_ty, _)) = - (exp_found.expected.kind(), exp_found.found.kind()) + (expected.kind(), found.kind()) { if let ty::Adt(found_def, found_substs) = *found_ty.kind() { if exp_def == &found_def { @@ -2197,21 +2211,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { _ => show_suggestion = false, } } - if let (Ok(snippet), true) = - (self.tcx.sess.source_map().span_to_snippet(span), show_suggestion) - { - diag.span_suggestion( - span, - *msg, - // HACK: fix issue# 100605, suggesting convert from &Option<T> to Option<&T>, remove the extra `&` - format!("{}.as_ref()", snippet.trim_start_matches('&')), - Applicability::MachineApplicable, - ); + if show_suggestion { + return Some(*msg); } } } } } + None } pub fn report_and_explain_type_error( diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index baa97d72a4b..2775d14a847 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -435,6 +435,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { generics_def_id, def_id: _, generic_args, + have_turbofish, } => { let generics = self.tcx.generics_of(generics_def_id); let is_type = matches!(arg.unpack(), GenericArgKind::Type(_)); @@ -482,11 +483,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .unwrap() .into_buffer(); - infer_subdiags.push(SourceKindSubdiag::GenericSuggestion { - span: insert_span, - arg_count: generic_args.len(), - args, - }); + if !have_turbofish { + infer_subdiags.push(SourceKindSubdiag::GenericSuggestion { + span: insert_span, + arg_count: generic_args.len(), + args, + }); + } } InferSourceKind::FullyQualifiedMethodCall { receiver, successor, substs, def_id } => { let printer = fmt_printer(self, Namespace::ValueNS); @@ -616,6 +619,7 @@ enum InferSourceKind<'tcx> { generics_def_id: DefId, def_id: DefId, generic_args: &'tcx [GenericArg<'tcx>], + have_turbofish: bool, }, FullyQualifiedMethodCall { receiver: &'tcx Expr<'tcx>, @@ -676,6 +680,7 @@ struct InsertableGenericArgs<'tcx> { substs: SubstsRef<'tcx>, generics_def_id: DefId, def_id: DefId, + have_turbofish: bool, } /// A visitor which searches for the "best" spot to use in the inference error. @@ -916,6 +921,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { substs, generics_def_id: def_id, def_id, + have_turbofish: false, } }; return Box::new(insertable.into_iter()); @@ -933,6 +939,9 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { substs: SubstsRef<'tcx>, ) -> impl Iterator<Item = InsertableGenericArgs<'tcx>> + 'a { let tcx = self.infcx.tcx; + let have_turbofish = path.segments.iter().any(|segment| { + segment.args.map_or(false, |args| args.args.iter().any(|arg| arg.is_ty_or_const())) + }); // The last segment of a path often has `Res::Err` and the // correct `Res` is the one of the whole path. // @@ -942,7 +951,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { let generics_def_id = tcx.res_generics_def_id(path.res)?; let generics = tcx.generics_of(generics_def_id); if generics.has_impl_trait() { - None? + None?; } let insert_span = path.segments.last().unwrap().ident.span.shrink_to_hi().with_hi(path.span.hi()); @@ -951,6 +960,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { substs, generics_def_id, def_id: path.res.def_id(), + have_turbofish, } }; @@ -970,6 +980,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { substs, generics_def_id, def_id: res.def_id(), + have_turbofish, }) }) .chain(last_segment_using_path_data) @@ -998,7 +1009,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { } let span = tcx.hir().span(segment.hir_id); let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); - InsertableGenericArgs { insert_span, substs, generics_def_id: def_id, def_id } + InsertableGenericArgs { + insert_span, + substs, + generics_def_id: def_id, + def_id, + have_turbofish: false, + } }; let parent_def_id = generics.parent.unwrap(); @@ -1021,7 +1038,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> { } // There cannot be inference variables in the self type, // so there's nothing for us to do here. - Res::SelfTy { .. } => {} + Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {} _ => warn!( "unexpected path: def={:?} substs={:?} path={:?}", def, substs, path, @@ -1121,7 +1138,13 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { for args in self.expr_inferred_subst_iter(expr) { debug!(?args); - let InsertableGenericArgs { insert_span, substs, generics_def_id, def_id } = args; + let InsertableGenericArgs { + insert_span, + substs, + generics_def_id, + def_id, + have_turbofish, + } = args; let generics = tcx.generics_of(generics_def_id); if let Some(argument_index) = generics .own_substs(substs) @@ -1144,6 +1167,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> { generics_def_id, def_id, generic_args, + have_turbofish, }, }); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index a6a39d062d5..778c4fc01c8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -156,7 +156,8 @@ impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> { [segment] if matches!( segment.res, - Res::SelfTy { trait_: _, alias_to: _ } + Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } | Res::Def(hir::def::DefKind::TyParam, _) ) => { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index b9fd79e0d2f..70edcd10f5f 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -712,9 +712,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ) -> bool { // Reject any attempt to unify two unevaluated constants that contain inference // variables, since inference variables in queries lead to ICEs. - if a.substs.has_infer_types_or_consts() - || b.substs.has_infer_types_or_consts() - || param_env.has_infer_types_or_consts() + if a.substs.has_non_region_infer() + || b.substs.has_non_region_infer() + || param_env.has_non_region_infer() { debug!("a or b or param_env contain infer vars in its substs -> cannot unify"); return false; @@ -1734,7 +1734,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Postpone the evaluation of constants whose substs depend on inference // variables - if substs.has_infer_types_or_consts() { + if substs.has_non_region_infer() { let ac = AbstractConst::new(self.tcx, unevaluated); match ac { Ok(None) => { @@ -2072,21 +2072,17 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( ) -> SubstsRef<'tcx> { tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| { match arg.unpack() { - GenericArgKind::Type(_) - if arg.has_param_types_or_consts() || arg.has_infer_types_or_consts() => - { + GenericArgKind::Type(_) if arg.has_non_region_param() || arg.has_non_region_infer() => { tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name: ty::BoundVar::from_usize(idx), })) .into() } - GenericArgKind::Const(ct) - if ct.has_infer_types_or_consts() || ct.has_param_types_or_consts() => - { + GenericArgKind::Const(ct) if ct.has_non_region_infer() || ct.has_non_region_param() => { let ty = ct.ty(); // If the type references param or infer, replace that too... - if ty.has_param_types_or_consts() || ty.has_infer_types_or_consts() { + if ty.has_non_region_param() || ty.has_non_region_infer() { bug!("const `{ct}`'s type should not reference params or types"); } tcx.mk_const(ty::ConstS { diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index bb6f6ae60e2..91e73451a0f 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -357,7 +357,7 @@ where // In NLL, we don't have type inference variables // floating around, so we can do this rather imprecise // variant of the occurs-check. - assert!(!generalized_ty.has_infer_types_or_consts()); + assert!(!generalized_ty.has_non_region_infer()); } self.infcx.inner.borrow_mut().type_variables().instantiate(vid, generalized_ty); diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 3d99f0958f7..bb188496caa 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if !t.has_infer_types_or_consts() { + if !t.has_non_region_infer() { t // micro-optimize -- if there is nothing in this type that this fold affects... } else { let t = self.infcx.shallow_resolve(t); @@ -41,7 +41,7 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticVarResolver<'a, 'tcx> { } fn fold_const(&mut self, ct: Const<'tcx>) -> Const<'tcx> { - if !ct.has_infer_types_or_consts() { + if !ct.has_non_region_infer() { ct // micro-optimize -- if there is nothing in this const that this fold affects... } else { let ct = self.infcx.shallow_resolve(ct); diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 6c725a01b53..91d180e1eb7 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -246,6 +246,10 @@ impl<'tcx> Queries<'tcx> { // Don't do code generation if there were any errors self.session().compile_status()?; + // If we have any delayed bugs, for example because we created TyKind::Error earlier, + // it's likely that codegen will only cause more ICEs, obscuring the original problem + self.session().diagnostic().flush_delayed(); + // Hook for UI tests. Self::check_for_rustc_errors_attr(tcx); diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs index b97f8acb37f..bd6b637f76f 100644 --- a/compiler/rustc_lint/src/array_into_iter.rs +++ b/compiler/rustc_lint/src/array_into_iter.rs @@ -118,37 +118,41 @@ impl<'tcx> LateLintPass<'tcx> for ArrayIntoIter { // to an array or to a slice. _ => bug!("array type coerced to something other than array or slice"), }; - cx.struct_span_lint(ARRAY_INTO_ITER, call.ident.span, |lint| { - let mut diag = lint.build(fluent::lint::array_into_iter); - diag.set_arg("target", target); - diag.span_suggestion( - call.ident.span, - fluent::lint::use_iter_suggestion, - "iter", - Applicability::MachineApplicable, - ); - if self.for_expr_span == expr.span { + cx.struct_span_lint( + ARRAY_INTO_ITER, + call.ident.span, + fluent::lint::array_into_iter, + |diag| { + diag.set_arg("target", target); diag.span_suggestion( - receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), - fluent::lint::remove_into_iter_suggestion, - "", - Applicability::MaybeIncorrect, + call.ident.span, + fluent::lint::use_iter_suggestion, + "iter", + Applicability::MachineApplicable, ); - } else if receiver_ty.is_array() { - diag.multipart_suggestion( - fluent::lint::use_explicit_into_iter_suggestion, - vec![ - (expr.span.shrink_to_lo(), "IntoIterator::into_iter(".into()), - ( - receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), - ")".into(), - ), - ], - Applicability::MaybeIncorrect, - ); - } - diag.emit(); - }) + if self.for_expr_span == expr.span { + diag.span_suggestion( + receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), + fluent::lint::remove_into_iter_suggestion, + "", + Applicability::MaybeIncorrect, + ); + } else if receiver_ty.is_array() { + diag.multipart_suggestion( + fluent::lint::use_explicit_into_iter_suggestion, + vec![ + (expr.span.shrink_to_lo(), "IntoIterator::into_iter(".into()), + ( + receiver_arg.span.shrink_to_hi().to(expr.span.shrink_to_hi()), + ")".into(), + ), + ], + Applicability::MaybeIncorrect, + ); + } + diag + }, + ) } } } diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 146c4971348..f28cfbd8b4c 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -33,8 +33,8 @@ use rustc_ast_pretty::pprust::{self, expr_to_string}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_errors::{ - fluent, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString, - LintDiagnosticBuilder, MultiSpan, + fluent, Applicability, DelayDm, Diagnostic, DiagnosticBuilder, DiagnosticMessage, + DiagnosticStyledString, MultiSpan, }; use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability}; use rustc_hir as hir; @@ -97,30 +97,31 @@ fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr { impl EarlyLintPass for WhileTrue { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { - if let ast::ExprKind::While(cond, _, label) = &e.kind { - if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind { - if let ast::LitKind::Bool(true) = lit.kind { - if !lit.span.from_expansion() { - let condition_span = e.span.with_hi(cond.span.hi()); - cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| { - lint.build(fluent::lint::builtin_while_true) - .span_suggestion_short( - condition_span, - fluent::lint::suggestion, - format!( - "{}loop", - label.map_or_else(String::new, |label| format!( - "{}: ", - label.ident, - )) - ), - Applicability::MachineApplicable, - ) - .emit(); - }) - } - } - } + if let ast::ExprKind::While(cond, _, label) = &e.kind + && let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind + && let ast::LitKind::Bool(true) = lit.kind + && !lit.span.from_expansion() + { + let condition_span = e.span.with_hi(cond.span.hi()); + cx.struct_span_lint( + WHILE_TRUE, + condition_span, + fluent::lint::builtin_while_true, + |lint| { + lint.span_suggestion_short( + condition_span, + fluent::lint::suggestion, + format!( + "{}loop", + label.map_or_else(String::new, |label| format!( + "{}: ", + label.ident, + )) + ), + Applicability::MachineApplicable, + ) + }, + ) } } } @@ -156,9 +157,12 @@ impl BoxPointers { for leaf in ty.walk() { if let GenericArgKind::Type(leaf_ty) = leaf.unpack() { if leaf_ty.is_box() { - cx.struct_span_lint(BOX_POINTERS, span, |lint| { - lint.build(fluent::lint::builtin_box_pointers).set_arg("ty", ty).emit(); - }); + cx.struct_span_lint( + BOX_POINTERS, + span, + fluent::lint::builtin_box_pointers, + |lint| lint.set_arg("ty", ty), + ); } } } @@ -257,19 +261,21 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns { if cx.tcx.find_field_index(ident, &variant) == Some(cx.tcx.field_index(fieldpat.hir_id, cx.typeck_results())) { - cx.struct_span_lint(NON_SHORTHAND_FIELD_PATTERNS, fieldpat.span, |lint| { - let suggested_ident = - format!("{}{}", binding_annot.prefix_str(), ident); - lint.build(fluent::lint::builtin_non_shorthand_field_patterns) - .set_arg("ident", ident.clone()) - .span_suggestion( + cx.struct_span_lint( + NON_SHORTHAND_FIELD_PATTERNS, + fieldpat.span, + fluent::lint::builtin_non_shorthand_field_patterns, + |lint| { + let suggested_ident = + format!("{}{}", binding_annot.prefix_str(), ident); + lint.set_arg("ident", ident.clone()).span_suggestion( fieldpat.span, fluent::lint::suggestion, suggested_ident, Applicability::MachineApplicable, ) - .emit(); - }); + }, + ); } } } @@ -309,14 +315,17 @@ impl UnsafeCode { &self, cx: &EarlyContext<'_>, span: Span, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { // This comes from a macro that has `#[allow_internal_unsafe]`. if span.allows_unsafe() { return; } - cx.struct_span_lint(UNSAFE_CODE, span, decorate); + cx.struct_span_lint(UNSAFE_CODE, span, msg, decorate); } fn report_overridden_symbol_name( @@ -325,8 +334,8 @@ impl UnsafeCode { span: Span, msg: DiagnosticMessage, ) { - self.report_unsafe(cx, span, |lint| { - lint.build(msg).note(fluent::lint::builtin_overridden_symbol_name).emit(); + self.report_unsafe(cx, span, msg, |lint| { + lint.note(fluent::lint::builtin_overridden_symbol_name) }) } @@ -336,8 +345,8 @@ impl UnsafeCode { span: Span, msg: DiagnosticMessage, ) { - self.report_unsafe(cx, span, |lint| { - lint.build(msg).note(fluent::lint::builtin_overridden_symbol_section).emit(); + self.report_unsafe(cx, span, msg, |lint| { + lint.note(fluent::lint::builtin_overridden_symbol_section) }) } } @@ -345,9 +354,12 @@ impl UnsafeCode { impl EarlyLintPass for UnsafeCode { fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &ast::Attribute) { if attr.has_name(sym::allow_internal_unsafe) { - self.report_unsafe(cx, attr.span, |lint| { - lint.build(fluent::lint::builtin_allow_internal_unsafe).emit(); - }); + self.report_unsafe( + cx, + attr.span, + fluent::lint::builtin_allow_internal_unsafe, + |lint| lint, + ); } } @@ -355,24 +367,20 @@ impl EarlyLintPass for UnsafeCode { if let ast::ExprKind::Block(ref blk, _) = e.kind { // Don't warn about generated blocks; that'll just pollute the output. if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) { - self.report_unsafe(cx, blk.span, |lint| { - lint.build(fluent::lint::builtin_unsafe_block).emit(); - }); + self.report_unsafe(cx, blk.span, fluent::lint::builtin_unsafe_block, |lint| lint); } } } fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) { match it.kind { - ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => self - .report_unsafe(cx, it.span, |lint| { - lint.build(fluent::lint::builtin_unsafe_trait).emit(); - }), + ast::ItemKind::Trait(box ast::Trait { unsafety: ast::Unsafe::Yes(_), .. }) => { + self.report_unsafe(cx, it.span, fluent::lint::builtin_unsafe_trait, |lint| lint) + } - ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => self - .report_unsafe(cx, it.span, |lint| { - lint.build(fluent::lint::builtin_unsafe_impl).emit(); - }), + ast::ItemKind::Impl(box ast::Impl { unsafety: ast::Unsafe::Yes(_), .. }) => { + self.report_unsafe(cx, it.span, fluent::lint::builtin_unsafe_impl, |lint| lint) + } ast::ItemKind::Fn(..) => { if let Some(attr) = cx.sess().find_by_name(&it.attrs, sym::no_mangle) { @@ -465,9 +473,7 @@ impl EarlyLintPass for UnsafeCode { FnCtxt::Assoc(_) if body.is_none() => fluent::lint::builtin_decl_unsafe_method, FnCtxt::Assoc(_) => fluent::lint::builtin_impl_unsafe_method, }; - self.report_unsafe(cx, span, |lint| { - lint.build(msg).emit(); - }); + self.report_unsafe(cx, span, msg, |lint| lint); } } } @@ -568,12 +574,12 @@ impl MissingDoc { let attrs = cx.tcx.hir().attrs(cx.tcx.hir().local_def_id_to_hir_id(def_id)); let has_doc = attrs.iter().any(has_doc); if !has_doc { - cx.struct_span_lint(MISSING_DOCS, cx.tcx.def_span(def_id), |lint| { - lint.build(fluent::lint::builtin_missing_doc) - .set_arg("article", article) - .set_arg("desc", desc) - .emit(); - }); + cx.struct_span_lint( + MISSING_DOCS, + cx.tcx.def_span(def_id), + fluent::lint::builtin_missing_doc, + |lint| lint.set_arg("article", article).set_arg("desc", desc), + ); } } } @@ -760,9 +766,12 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { ) .is_ok() { - cx.struct_span_lint(MISSING_COPY_IMPLEMENTATIONS, item.span, |lint| { - lint.build(fluent::lint::builtin_missing_copy_impl).emit(); - }) + cx.struct_span_lint( + MISSING_COPY_IMPLEMENTATIONS, + item.span, + fluent::lint::builtin_missing_copy_impl, + |lint| lint, + ) } } } @@ -836,11 +845,12 @@ impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations { } if !self.impling_types.as_ref().unwrap().contains(&item.def_id.def_id) { - cx.struct_span_lint(MISSING_DEBUG_IMPLEMENTATIONS, item.span, |lint| { - lint.build(fluent::lint::builtin_missing_debug_impl) - .set_arg("debug", cx.tcx.def_path_str(debug)) - .emit(); - }); + cx.struct_span_lint( + MISSING_DEBUG_IMPLEMENTATIONS, + item.span, + fluent::lint::builtin_missing_debug_impl, + |lint| lint.set_arg("debug", cx.tcx.def_path_str(debug)), + ); } } } @@ -908,24 +918,26 @@ impl EarlyLintPass for AnonymousParameters { for arg in sig.decl.inputs.iter() { if let ast::PatKind::Ident(_, ident, None) = arg.pat.kind { if ident.name == kw::Empty { - cx.struct_span_lint(ANONYMOUS_PARAMETERS, arg.pat.span, |lint| { - let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span); - - let (ty_snip, appl) = if let Ok(ref snip) = ty_snip { - (snip.as_str(), Applicability::MachineApplicable) - } else { - ("<type>", Applicability::HasPlaceholders) - }; + let ty_snip = cx.sess().source_map().span_to_snippet(arg.ty.span); - lint.build(fluent::lint::builtin_anonymous_params) - .span_suggestion( + let (ty_snip, appl) = if let Ok(ref snip) = ty_snip { + (snip.as_str(), Applicability::MachineApplicable) + } else { + ("<type>", Applicability::HasPlaceholders) + }; + cx.struct_span_lint( + ANONYMOUS_PARAMETERS, + arg.pat.span, + fluent::lint::builtin_anonymous_params, + |lint| { + lint.span_suggestion( arg.pat.span, fluent::lint::suggestion, format!("_: {}", ty_snip), appl, ) - .emit(); - }) + }, + ) } } } @@ -960,38 +972,44 @@ impl EarlyLintPass for DeprecatedAttr { _, ) = gate { - cx.struct_span_lint(DEPRECATED, attr.span, |lint| { - // FIXME(davidtwco) translatable deprecated attr - lint.build(fluent::lint::builtin_deprecated_attr_link) - .set_arg("name", name) - .set_arg("reason", reason) - .set_arg("link", link) - .span_suggestion_short( - attr.span, - suggestion.map(|s| s.into()).unwrap_or( - fluent::lint::builtin_deprecated_attr_default_suggestion, - ), - "", - Applicability::MachineApplicable, - ) - .emit(); - }); + // FIXME(davidtwco) translatable deprecated attr + cx.struct_span_lint( + DEPRECATED, + attr.span, + fluent::lint::builtin_deprecated_attr_link, + |lint| { + lint.set_arg("name", name) + .set_arg("reason", reason) + .set_arg("link", link) + .span_suggestion_short( + attr.span, + suggestion.map(|s| s.into()).unwrap_or( + fluent::lint::builtin_deprecated_attr_default_suggestion, + ), + "", + Applicability::MachineApplicable, + ) + }, + ); } return; } } if attr.has_name(sym::no_start) || attr.has_name(sym::crate_id) { - cx.struct_span_lint(DEPRECATED, attr.span, |lint| { - lint.build(fluent::lint::builtin_deprecated_attr_used) - .set_arg("name", pprust::path_to_string(&attr.get_normal_item().path)) - .span_suggestion_short( - attr.span, - fluent::lint::builtin_deprecated_attr_default_suggestion, - "", - Applicability::MachineApplicable, - ) - .emit(); - }); + cx.struct_span_lint( + DEPRECATED, + attr.span, + fluent::lint::builtin_deprecated_attr_used, + |lint| { + lint.set_arg("name", pprust::path_to_string(&attr.get_normal_item().path)) + .span_suggestion_short( + attr.span, + fluent::lint::builtin_deprecated_attr_default_suggestion, + "", + Applicability::MachineApplicable, + ) + }, + ); } } } @@ -1018,20 +1036,21 @@ fn warn_if_doc(cx: &EarlyContext<'_>, node_span: Span, node_kind: &str, attrs: & let span = sugared_span.take().unwrap_or(attr.span); if is_doc_comment || attr.has_name(sym::doc) { - cx.struct_span_lint(UNUSED_DOC_COMMENTS, span, |lint| { - let mut err = lint.build(fluent::lint::builtin_unused_doc_comment); - err.set_arg("kind", node_kind); - err.span_label(node_span, fluent::lint::label); - match attr.kind { - AttrKind::DocComment(CommentKind::Line, _) | AttrKind::Normal(..) => { - err.help(fluent::lint::plain_help); - } - AttrKind::DocComment(CommentKind::Block, _) => { - err.help(fluent::lint::block_help); - } - } - err.emit(); - }); + cx.struct_span_lint( + UNUSED_DOC_COMMENTS, + span, + fluent::lint::builtin_unused_doc_comment, + |lint| { + lint.set_arg("kind", node_kind).span_label(node_span, fluent::lint::label).help( + match attr.kind { + AttrKind::DocComment(CommentKind::Line, _) | AttrKind::Normal(..) => { + fluent::lint::plain_help + } + AttrKind::DocComment(CommentKind::Block, _) => fluent::lint::block_help, + }, + ) + }, + ); } } } @@ -1145,9 +1164,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { match param.kind { GenericParamKind::Lifetime { .. } => {} GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { - cx.struct_span_lint(NO_MANGLE_GENERIC_ITEMS, span, |lint| { - lint.build(fluent::lint::builtin_no_mangle_generic) - .span_suggestion_short( + cx.struct_span_lint( + NO_MANGLE_GENERIC_ITEMS, + span, + fluent::lint::builtin_no_mangle_generic, + |lint| { + lint.span_suggestion_short( no_mangle_attr.span, fluent::lint::suggestion, "", @@ -1155,8 +1177,8 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { // fix may be to monomorphize source by hand Applicability::MaybeIncorrect, ) - .emit(); - }); + }, + ); break; } } @@ -1172,27 +1194,29 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { if cx.sess().contains_name(attrs, sym::no_mangle) { // Const items do not refer to a particular location in memory, and therefore // don't have anything to attach a symbol to - cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, |lint| { - let mut err = lint.build(fluent::lint::builtin_const_no_mangle); - - // account for "pub const" (#45562) - let start = cx - .tcx - .sess - .source_map() - .span_to_snippet(it.span) - .map(|snippet| snippet.find("const").unwrap_or(0)) - .unwrap_or(0) as u32; - // `const` is 5 chars - let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5)); - err.span_suggestion( - const_span, - fluent::lint::suggestion, - "pub static", - Applicability::MachineApplicable, - ); - err.emit(); - }); + cx.struct_span_lint( + NO_MANGLE_CONST_ITEMS, + it.span, + fluent::lint::builtin_const_no_mangle, + |lint| { + // account for "pub const" (#45562) + let start = cx + .tcx + .sess + .source_map() + .span_to_snippet(it.span) + .map(|snippet| snippet.find("const").unwrap_or(0)) + .unwrap_or(0) as u32; + // `const` is 5 chars + let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5)); + lint.span_suggestion( + const_span, + fluent::lint::suggestion, + "pub static", + Applicability::MachineApplicable, + ) + }, + ); } } hir::ItemKind::Impl(hir::Impl { generics, items, .. }) => { @@ -1252,9 +1276,12 @@ impl<'tcx> LateLintPass<'tcx> for MutableTransmutes { get_transmute_from_to(cx, expr).map(|(ty1, ty2)| (ty1.kind(), ty2.kind())) { if to_mt == hir::Mutability::Mut && from_mt == hir::Mutability::Not { - cx.struct_span_lint(MUTABLE_TRANSMUTES, expr.span, |lint| { - lint.build(fluent::lint::builtin_mutable_transmutes).emit(); - }); + cx.struct_span_lint( + MUTABLE_TRANSMUTES, + expr.span, + fluent::lint::builtin_mutable_transmutes, + |lint| lint, + ); } } @@ -1302,9 +1329,12 @@ impl<'tcx> LateLintPass<'tcx> for UnstableFeatures { if attr.has_name(sym::feature) { if let Some(items) = attr.meta_item_list() { for item in items { - cx.struct_span_lint(UNSTABLE_FEATURES, item.span(), |lint| { - lint.build(fluent::lint::builtin_unstable_features).emit(); - }); + cx.struct_span_lint( + UNSTABLE_FEATURES, + item.span(), + fluent::lint::builtin_unstable_features, + |lint| lint, + ); } } } @@ -1363,21 +1393,25 @@ impl UnreachablePub { applicability = Applicability::MaybeIncorrect; } let def_span = cx.tcx.def_span(def_id); - cx.struct_span_lint(UNREACHABLE_PUB, def_span, |lint| { - let mut err = lint.build(fluent::lint::builtin_unreachable_pub); - err.set_arg("what", what); - - err.span_suggestion( - vis_span, - fluent::lint::suggestion, - "pub(crate)", - applicability, - ); - if exportable { - err.help(fluent::lint::help); - } - err.emit(); - }); + cx.struct_span_lint( + UNREACHABLE_PUB, + def_span, + fluent::lint::builtin_unreachable_pub, + |lint| { + lint.set_arg("what", what); + + lint.span_suggestion( + vis_span, + fluent::lint::suggestion, + "pub(crate)", + applicability, + ); + if exportable { + lint.help(fluent::lint::help); + } + lint + }, + ); } } } @@ -1507,36 +1541,34 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { let mut suggested_changing_assoc_types = false; if !where_spans.is_empty() { - cx.lint(TYPE_ALIAS_BOUNDS, |lint| { - let mut err = lint.build(fluent::lint::builtin_type_alias_where_clause); - err.set_span(where_spans); - err.span_suggestion( + cx.lint(TYPE_ALIAS_BOUNDS, fluent::lint::builtin_type_alias_where_clause, |lint| { + lint.set_span(where_spans); + lint.span_suggestion( type_alias_generics.where_clause_span, fluent::lint::suggestion, "", Applicability::MachineApplicable, ); if !suggested_changing_assoc_types { - TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); + TypeAliasBounds::suggest_changing_assoc_types(ty, lint); suggested_changing_assoc_types = true; } - err.emit(); + lint }); } if !inline_spans.is_empty() { - cx.lint(TYPE_ALIAS_BOUNDS, |lint| { - let mut err = lint.build(fluent::lint::builtin_type_alias_generic_bounds); - err.set_span(inline_spans); - err.multipart_suggestion( + cx.lint(TYPE_ALIAS_BOUNDS, fluent::lint::builtin_type_alias_generic_bounds, |lint| { + lint.set_span(inline_spans); + lint.multipart_suggestion( fluent::lint::suggestion, inline_sugg, Applicability::MachineApplicable, ); if !suggested_changing_assoc_types { - TypeAliasBounds::suggest_changing_assoc_types(ty, &mut err); + TypeAliasBounds::suggest_changing_assoc_types(ty, lint); } - err.emit(); + lint }); } } @@ -1635,12 +1667,15 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { TypeWellFormedFromEnv(..) => continue, }; if predicate.is_global() { - cx.struct_span_lint(TRIVIAL_BOUNDS, span, |lint| { - lint.build(fluent::lint::builtin_trivial_bounds) - .set_arg("predicate_kind_name", predicate_kind_name) - .set_arg("predicate", predicate) - .emit(); - }); + cx.struct_span_lint( + TRIVIAL_BOUNDS, + span, + fluent::lint::builtin_trivial_bounds, + |lint| { + lint.set_arg("predicate_kind_name", predicate_kind_name) + .set_arg("predicate", predicate) + }, + ); } } } @@ -1756,15 +1791,13 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { replace, }); } else { - cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, |lint| { - lint.build(msg) - .span_suggestion( - pat.span, - suggestion, - replace, - Applicability::MachineApplicable, - ) - .emit(); + cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, pat.span, msg, |lint| { + lint.span_suggestion( + pat.span, + suggestion, + replace, + Applicability::MachineApplicable, + ) }); } } else { @@ -1776,15 +1809,13 @@ impl EarlyLintPass for EllipsisInclusiveRangePatterns { replace: replace.to_string(), }); } else { - cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, |lint| { - lint.build(msg) - .span_suggestion_short( - join, - suggestion, - replace, - Applicability::MachineApplicable, - ) - .emit(); + cx.struct_span_lint(ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, join, msg, |lint| { + lint.span_suggestion_short( + join, + suggestion, + replace, + Applicability::MachineApplicable, + ) }); } }; @@ -1865,9 +1896,12 @@ impl<'tcx> LateLintPass<'tcx> for UnnameableTestItems { let attrs = cx.tcx.hir().attrs(it.hir_id()); if let Some(attr) = cx.sess().find_by_name(attrs, sym::rustc_test_marker) { - cx.struct_span_lint(UNNAMEABLE_TEST_ITEMS, attr.span, |lint| { - lint.build(fluent::lint::builtin_unnameable_test_items).emit(); - }); + cx.struct_span_lint( + UNNAMEABLE_TEST_ITEMS, + attr.span, + fluent::lint::builtin_unnameable_test_items, + |lint| lint, + ); } } @@ -1983,18 +2017,19 @@ impl KeywordIdents { return; } - cx.struct_span_lint(KEYWORD_IDENTS, ident.span, |lint| { - lint.build(fluent::lint::builtin_keyword_idents) - .set_arg("kw", ident.clone()) - .set_arg("next", next_edition) - .span_suggestion( + cx.struct_span_lint( + KEYWORD_IDENTS, + ident.span, + fluent::lint::builtin_keyword_idents, + |lint| { + lint.set_arg("kw", ident.clone()).set_arg("next", next_edition).span_suggestion( ident.span, fluent::lint::suggestion, format!("r#{}", ident), Applicability::MachineApplicable, ) - .emit(); - }); + }, + ); } } @@ -2245,10 +2280,12 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { } if !lint_spans.is_empty() { - cx.struct_span_lint(EXPLICIT_OUTLIVES_REQUIREMENTS, lint_spans.clone(), |lint| { - lint.build(fluent::lint::builtin_explicit_outlives) - .set_arg("count", bound_count) - .multipart_suggestion( + cx.struct_span_lint( + EXPLICIT_OUTLIVES_REQUIREMENTS, + lint_spans.clone(), + fluent::lint::builtin_explicit_outlives, + |lint| { + lint.set_arg("count", bound_count).multipart_suggestion( fluent::lint::suggestion, lint_spans .into_iter() @@ -2256,8 +2293,8 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements { .collect::<Vec<_>>(), Applicability::MachineApplicable, ) - .emit(); - }); + }, + ); } } } @@ -2304,18 +2341,24 @@ impl EarlyLintPass for IncompleteFeatures { .chain(features.declared_lib_features.iter().map(|(name, span)| (name, span))) .filter(|(&name, _)| features.incomplete(name)) .for_each(|(&name, &span)| { - cx.struct_span_lint(INCOMPLETE_FEATURES, span, |lint| { - let mut builder = lint.build(fluent::lint::builtin_incomplete_features); - builder.set_arg("name", name); - if let Some(n) = rustc_feature::find_feature_issue(name, GateIssue::Language) { - builder.set_arg("n", n); - builder.note(fluent::lint::note); - } - if HAS_MIN_FEATURES.contains(&name) { - builder.help(fluent::lint::help); - } - builder.emit(); - }) + cx.struct_span_lint( + INCOMPLETE_FEATURES, + span, + fluent::lint::builtin_incomplete_features, + |lint| { + lint.set_arg("name", name); + if let Some(n) = + rustc_feature::find_feature_issue(name, GateIssue::Language) + { + lint.set_arg("n", n); + lint.note(fluent::lint::note); + } + if HAS_MIN_FEATURES.contains(&name) { + lint.help(fluent::lint::help); + } + lint + }, + ) }); } } @@ -2630,28 +2673,37 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { with_no_trimmed_paths!(ty_find_init_error(cx, conjured_ty, init)) { // FIXME(davidtwco): make translatable - cx.struct_span_lint(INVALID_VALUE, expr.span, |lint| { - let mut err = lint.build(&format!( - "the type `{}` does not permit {}", - conjured_ty, - match init { - InitKind::Zeroed => "zero-initialization", - InitKind::Uninit => "being left uninitialized", - }, - )); - err.span_label(expr.span, "this code causes undefined behavior when executed"); - err.span_label( - expr.span, - "help: use `MaybeUninit<T>` instead, \ + cx.struct_span_lint( + INVALID_VALUE, + expr.span, + DelayDm(|| { + format!( + "the type `{}` does not permit {}", + conjured_ty, + match init { + InitKind::Zeroed => "zero-initialization", + InitKind::Uninit => "being left uninitialized", + }, + ) + }), + |lint| { + lint.span_label( + expr.span, + "this code causes undefined behavior when executed", + ); + lint.span_label( + expr.span, + "help: use `MaybeUninit<T>` instead, \ and only call `assume_init` after initialization is done", - ); - if let Some(span) = span { - err.span_note(span, &msg); - } else { - err.note(&msg); - } - err.emit(); - }); + ); + if let Some(span) = span { + lint.span_note(span, &msg); + } else { + lint.note(&msg); + } + lint + }, + ); } } } @@ -2997,31 +3049,35 @@ impl<'tcx> LateLintPass<'tcx> for ClashingExternDeclarations { SymbolName::Link(_, annot_span) => fi.span.to(annot_span), }; // Finally, emit the diagnostic. + + let msg = if orig.get_name() == this_fi.ident.name { + fluent::lint::builtin_clashing_extern_same_name + } else { + fluent::lint::builtin_clashing_extern_diff_name + }; tcx.struct_span_lint_hir( CLASHING_EXTERN_DECLARATIONS, this_fi.hir_id(), get_relevant_span(this_fi), + msg, |lint| { let mut expected_str = DiagnosticStyledString::new(); expected_str.push(existing_decl_ty.fn_sig(tcx).to_string(), false); let mut found_str = DiagnosticStyledString::new(); found_str.push(this_decl_ty.fn_sig(tcx).to_string(), true); - lint.build(if orig.get_name() == this_fi.ident.name { - fluent::lint::builtin_clashing_extern_same_name - } else { - fluent::lint::builtin_clashing_extern_diff_name - }) - .set_arg("this_fi", this_fi.ident.name) - .set_arg("orig", orig.get_name()) - .span_label( - get_relevant_span(orig_fi), - fluent::lint::previous_decl_label, - ) - .span_label(get_relevant_span(this_fi), fluent::lint::mismatch_label) - // FIXME(davidtwco): translatable expected/found - .note_expected_found(&"", expected_str, &"", found_str) - .emit(); + lint.set_arg("this_fi", this_fi.ident.name) + .set_arg("orig", orig.get_name()) + .span_label( + get_relevant_span(orig_fi), + fluent::lint::previous_decl_label, + ) + .span_label( + get_relevant_span(this_fi), + fluent::lint::mismatch_label, + ) + // FIXME(davidtwco): translatable expected/found + .note_expected_found(&"", expected_str, &"", found_str) }, ); } @@ -3102,11 +3158,12 @@ impl<'tcx> LateLintPass<'tcx> for DerefNullPtr { if let rustc_hir::ExprKind::Unary(rustc_hir::UnOp::Deref, expr_deref) = expr.kind { if is_null_ptr(cx, expr_deref) { - cx.struct_span_lint(DEREF_NULLPTR, expr.span, |lint| { - let mut err = lint.build(fluent::lint::builtin_deref_nullptr); - err.span_label(expr.span, fluent::lint::label); - err.emit(); - }); + cx.struct_span_lint( + DEREF_NULLPTR, + expr.span, + fluent::lint::builtin_deref_nullptr, + |lint| lint.span_label(expr.span, fluent::lint::label), + ); } } } @@ -3216,9 +3273,8 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels { cx.lookup_with_diagnostics( NAMED_ASM_LABELS, Some(target_spans), - |diag| { - diag.build(fluent::lint::builtin_asm_labels).emit(); - }, + fluent::lint::builtin_asm_labels, + |lint| lint, BuiltinLintDiagnostics::NamedAsmLabel( "only local labels of the form `<number>:` should be used in inline asm" .to_string(), @@ -3290,16 +3346,14 @@ impl EarlyLintPass for SpecialModuleName { } match item.ident.name.as_str() { - "lib" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| { - lint.build("found module declaration for lib.rs") + "lib" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, "found module declaration for lib.rs", |lint| { + lint .note("lib.rs is the root of this crate's library target") .help("to refer to it from other targets, use the library's name as the path") - .emit() }), - "main" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, |lint| { - lint.build("found module declaration for main.rs") + "main" => cx.struct_span_lint(SPECIAL_MODULE_NAME, item.span, "found module declaration for main.rs", |lint| { + lint .note("a binary crate cannot be used as library") - .emit() }), _ => continue } @@ -3319,24 +3373,27 @@ impl EarlyLintPass for UnexpectedCfgs { for &(name, value) in cfg { if let Some(names_valid) = &check_cfg.names_valid { if !names_valid.contains(&name) { - cx.lookup(UNEXPECTED_CFGS, None::<MultiSpan>, |diag| { - diag.build(fluent::lint::builtin_unexpected_cli_config_name) - .help(fluent::lint::help) - .set_arg("name", name) - .emit(); - }); + cx.lookup( + UNEXPECTED_CFGS, + None::<MultiSpan>, + fluent::lint::builtin_unexpected_cli_config_name, + |diag| diag.help(fluent::lint::help).set_arg("name", name), + ); } } if let Some(value) = value { if let Some(values) = &check_cfg.values_valid.get(&name) { if !values.contains(&value) { - cx.lookup(UNEXPECTED_CFGS, None::<MultiSpan>, |diag| { - diag.build(fluent::lint::builtin_unexpected_cli_config_value) - .help(fluent::lint::help) - .set_arg("name", name) - .set_arg("value", value) - .emit(); - }); + cx.lookup( + UNEXPECTED_CFGS, + None::<MultiSpan>, + fluent::lint::builtin_unexpected_cli_config_value, + |diag| { + diag.help(fluent::lint::help) + .set_arg("name", name) + .set_arg("value", value) + }, + ); } } } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index cbab56f2066..74e35afc87d 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -25,10 +25,8 @@ use crate::passes::{EarlyLintPassObject, LateLintPassObject}; use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync; -use rustc_errors::add_elided_lifetime_in_path_suggestion; -use rustc_errors::{ - Applicability, DecorateLint, LintDiagnosticBuilder, MultiSpan, SuggestionStyle, -}; +use rustc_errors::{add_elided_lifetime_in_path_suggestion, DiagnosticBuilder, DiagnosticMessage}; +use rustc_errors::{Applicability, DecorateLint, MultiSpan, SuggestionStyle}; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::{CrateNum, DefId}; @@ -560,7 +558,7 @@ pub struct LateContext<'tcx> { /// Context for lint checking of the AST, after expansion, before lowering to HIR. pub struct EarlyContext<'a> { - pub builder: LintLevelsBuilder<'a>, + pub builder: LintLevelsBuilder<'a, crate::levels::TopDown>, pub buffered: LintBuffer, } @@ -580,13 +578,14 @@ pub trait LintContext: Sized { &self, lint: &'static Lint, span: Option<impl Into<MultiSpan>>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, diagnostic: BuiltinLintDiagnostics, ) { - self.lookup(lint, span, |lint| { - // We first generate a blank diagnostic. - let mut db = lint.build(""); - + // We first generate a blank diagnostic. + self.lookup(lint, span, msg,|db| { // Now, set up surrounding context. let sess = self.sess(); match diagnostic { @@ -660,7 +659,7 @@ pub trait LintContext: Sized { ) => { add_elided_lifetime_in_path_suggestion( sess.source_map(), - &mut db, + db, n, path_span, incl_angl_brckt, @@ -696,7 +695,7 @@ pub trait LintContext: Sized { } } BuiltinLintDiagnostics::DeprecatedMacro(suggestion, span) => { - stability::deprecation_suggestion(&mut db, "macro", suggestion, span) + stability::deprecation_suggestion(db, "macro", suggestion, span) } BuiltinLintDiagnostics::UnusedDocComment(span) => { db.span_label(span, "rustdoc does not generate documentation for macro invocations"); @@ -867,7 +866,7 @@ pub trait LintContext: Sized { } } // Rewrap `db`, and pass control to the user. - decorate(LintDiagnosticBuilder::new(db)); + decorate(db) }); } @@ -877,7 +876,10 @@ pub trait LintContext: Sized { &self, lint: &'static Lint, span: Option<S>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ); /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, @@ -888,31 +890,39 @@ pub trait LintContext: Sized { span: S, decorator: impl for<'a> DecorateLint<'a, ()>, ) { - self.lookup(lint, Some(span), |diag| decorator.decorate_lint(diag)); + self.lookup(lint, Some(span), decorator.msg(), |diag| decorator.decorate_lint(diag)); } fn struct_span_lint<S: Into<MultiSpan>>( &self, lint: &'static Lint, span: S, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { - self.lookup(lint, Some(span), decorate); + self.lookup(lint, Some(span), msg, decorate); } /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically /// generated by `#[derive(LintDiagnostic)]`). fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a, ()>) { - self.lookup(lint, None as Option<Span>, |diag| decorator.decorate_lint(diag)); + self.lookup(lint, None as Option<Span>, decorator.msg(), |diag| { + decorator.decorate_lint(diag) + }); } /// Emit a lint at the appropriate level, with no associated span. fn lint( &self, lint: &'static Lint, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { - self.lookup(lint, None as Option<Span>, decorate); + self.lookup(lint, None as Option<Span>, msg, decorate); } /// This returns the lint level for the given lint at the current location. @@ -975,13 +985,16 @@ impl<'tcx> LintContext for LateContext<'tcx> { &self, lint: &'static Lint, span: Option<S>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { let hir_id = self.last_node_with_lint_attrs; match span { - Some(s) => self.tcx.struct_span_lint_hir(lint, hir_id, s, decorate), - None => self.tcx.struct_lint_node(lint, hir_id, decorate), + Some(s) => self.tcx.struct_span_lint_hir(lint, hir_id, s, msg, decorate), + None => self.tcx.struct_lint_node(lint, hir_id, msg, decorate), } } @@ -1006,9 +1019,12 @@ impl LintContext for EarlyContext<'_> { &self, lint: &'static Lint, span: Option<S>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { - self.builder.struct_lint(lint, span.map(|s| s.into()), decorate) + self.builder.struct_lint(lint, span.map(|s| s.into()), msg, decorate) } fn get_lint_level(&self, lint: &'static Lint) -> Level { diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 96ecd79a69c..f7759bec908 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -43,9 +43,8 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { self.context.lookup_with_diagnostics( lint_id.lint, Some(span), - |lint| { - lint.build(msg).emit(); - }, + msg, + |lint| lint, diagnostic, ); } @@ -59,6 +58,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { F: FnOnce(&mut Self), { let is_crate_node = id == ast::CRATE_NODE_ID; + debug!(?id); let push = self.context.builder.push(attrs, is_crate_node, None); self.check_id(id); diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs index f41ee640499..e8d307814b9 100644 --- a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs +++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs @@ -50,26 +50,24 @@ fn enforce_mem_discriminant( ) { let ty_param = cx.typeck_results().node_substs(func_expr.hir_id).type_at(0); if is_non_enum(ty_param) { - cx.struct_span_lint(ENUM_INTRINSICS_NON_ENUMS, expr_span, |builder| { - builder - .build(fluent::lint::enum_intrinsics_mem_discriminant) - .set_arg("ty_param", ty_param) - .span_note(args_span, fluent::lint::note) - .emit(); - }); + cx.struct_span_lint( + ENUM_INTRINSICS_NON_ENUMS, + expr_span, + fluent::lint::enum_intrinsics_mem_discriminant, + |lint| lint.set_arg("ty_param", ty_param).span_note(args_span, fluent::lint::note), + ); } } fn enforce_mem_variant_count(cx: &LateContext<'_>, func_expr: &hir::Expr<'_>, span: Span) { let ty_param = cx.typeck_results().node_substs(func_expr.hir_id).type_at(0); if is_non_enum(ty_param) { - cx.struct_span_lint(ENUM_INTRINSICS_NON_ENUMS, span, |builder| { - builder - .build(fluent::lint::enum_intrinsics_mem_variant) - .set_arg("ty_param", ty_param) - .note(fluent::lint::note) - .emit(); - }); + cx.struct_span_lint( + ENUM_INTRINSICS_NON_ENUMS, + span, + fluent::lint::enum_intrinsics_mem_variant, + |lint| lint.set_arg("ty_param", ty_param).note(fluent::lint::note), + ); } } diff --git a/compiler/rustc_lint/src/expect.rs b/compiler/rustc_lint/src/expect.rs index 699e8154318..4c3c39734dd 100644 --- a/compiler/rustc_lint/src/expect.rs +++ b/compiler/rustc_lint/src/expect.rs @@ -16,8 +16,10 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) { return; } + let lint_expectations = tcx.lint_expectations(()); let fulfilled_expectations = tcx.sess.diagnostic().steal_fulfilled_expectation_ids(); - let lint_expectations = &tcx.lint_levels(()).lint_expectations; + + tracing::debug!(?lint_expectations, ?fulfilled_expectations); for (id, expectation) in lint_expectations { // This check will always be true, since `lint_expectations` only @@ -43,17 +45,17 @@ fn emit_unfulfilled_expectation_lint( builtin::UNFULFILLED_LINT_EXPECTATIONS, hir_id, expectation.emission_span, - |diag| { - let mut diag = diag.build(fluent::lint::expectation); + fluent::lint::expectation, + |lint| { if let Some(rationale) = expectation.reason { - diag.note(rationale.as_str()); + lint.note(rationale.as_str()); } if expectation.is_unfulfilled_lint_expectations { - diag.note(fluent::lint::note); + lint.note(fluent::lint::note); } - diag.emit(); + lint }, ); } diff --git a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs index 8f22221324a..42557068bd3 100644 --- a/compiler/rustc_lint/src/hidden_unicode_codepoints.rs +++ b/compiler/rustc_lint/src/hidden_unicode_codepoints.rs @@ -60,52 +60,56 @@ impl HiddenUnicodeCodepoints { }) .collect(); - cx.struct_span_lint(TEXT_DIRECTION_CODEPOINT_IN_LITERAL, span, |lint| { - let mut err = lint.build(fluent::lint::hidden_unicode_codepoints); - err.set_arg("label", label); - err.set_arg("count", spans.len()); - err.span_label(span, fluent::lint::label); - err.note(fluent::lint::note); - if point_at_inner_spans { - for (c, span) in &spans { - err.span_label(*span, format!("{:?}", c)); + cx.struct_span_lint( + TEXT_DIRECTION_CODEPOINT_IN_LITERAL, + span, + fluent::lint::hidden_unicode_codepoints, + |lint| { + lint.set_arg("label", label); + lint.set_arg("count", spans.len()); + lint.span_label(span, fluent::lint::label); + lint.note(fluent::lint::note); + if point_at_inner_spans { + for (c, span) in &spans { + lint.span_label(*span, format!("{:?}", c)); + } } - } - if point_at_inner_spans && !spans.is_empty() { - err.multipart_suggestion_with_style( - fluent::lint::suggestion_remove, - spans.iter().map(|(_, span)| (*span, "".to_string())).collect(), - Applicability::MachineApplicable, - SuggestionStyle::HideCodeAlways, - ); - err.multipart_suggestion( - fluent::lint::suggestion_escape, - spans - .into_iter() - .map(|(c, span)| { - let c = format!("{:?}", c); - (span, c[1..c.len() - 1].to_string()) - }) - .collect(), - Applicability::MachineApplicable, - ); - } else { - // FIXME: in other suggestions we've reversed the inner spans of doc comments. We - // should do the same here to provide the same good suggestions as we do for - // literals above. - err.set_arg( - "escaped", - spans - .into_iter() - .map(|(c, _)| format!("{:?}", c)) - .collect::<Vec<String>>() - .join(", "), - ); - err.note(fluent::lint::suggestion_remove); - err.note(fluent::lint::no_suggestion_note_escape); - } - err.emit(); - }); + if point_at_inner_spans && !spans.is_empty() { + lint.multipart_suggestion_with_style( + fluent::lint::suggestion_remove, + spans.iter().map(|(_, span)| (*span, "".to_string())).collect(), + Applicability::MachineApplicable, + SuggestionStyle::HideCodeAlways, + ); + lint.multipart_suggestion( + fluent::lint::suggestion_escape, + spans + .into_iter() + .map(|(c, span)| { + let c = format!("{:?}", c); + (span, c[1..c.len() - 1].to_string()) + }) + .collect(), + Applicability::MachineApplicable, + ); + } else { + // FIXME: in other suggestions we've reversed the inner spans of doc comments. We + // should do the same here to provide the same good suggestions as we do for + // literals above. + lint.set_arg( + "escaped", + spans + .into_iter() + .map(|(c, _)| format!("{:?}", c)) + .collect::<Vec<String>>() + .join(", "), + ); + lint.note(fluent::lint::suggestion_remove); + lint.note(fluent::lint::no_suggestion_note_escape); + } + lint + }, + ); } } impl EarlyLintPass for HiddenUnicodeCodepoints { diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index d8a03024d13..8f5e38fdbcc 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -34,13 +34,16 @@ impl LateLintPass<'_> for DefaultHashTypes { Some(sym::HashSet) => "FxHashSet", _ => return, }; - cx.struct_span_lint(DEFAULT_HASH_TYPES, path.span, |lint| { - lint.build(fluent::lint::default_hash_types) - .set_arg("preferred", replace) - .set_arg("used", cx.tcx.item_name(def_id)) - .note(fluent::lint::note) - .emit(); - }); + cx.struct_span_lint( + DEFAULT_HASH_TYPES, + path.span, + fluent::lint::default_hash_types, + |lint| { + lint.set_arg("preferred", replace) + .set_arg("used", cx.tcx.item_name(def_id)) + .note(fluent::lint::note) + }, + ); } } @@ -80,12 +83,12 @@ impl LateLintPass<'_> for QueryStability { if let Ok(Some(instance)) = ty::Instance::resolve(cx.tcx, cx.param_env, def_id, substs) { let def_id = instance.def_id(); if cx.tcx.has_attr(def_id, sym::rustc_lint_query_instability) { - cx.struct_span_lint(POTENTIAL_QUERY_INSTABILITY, span, |lint| { - lint.build(fluent::lint::query_instability) - .set_arg("query", cx.tcx.item_name(def_id)) - .note(fluent::lint::note) - .emit(); - }) + cx.struct_span_lint( + POTENTIAL_QUERY_INSTABILITY, + span, + fluent::lint::query_instability, + |lint| lint.set_arg("query", cx.tcx.item_name(def_id)).note(fluent::lint::note), + ) } } } @@ -123,15 +126,14 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { let span = path.span.with_hi( segment.args.map_or(segment.ident.span, |a| a.span_ext).hi() ); - cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, |lint| { - lint.build(fluent::lint::tykind_kind) + cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, fluent::lint::tykind_kind, |lint| { + lint .span_suggestion( span, fluent::lint::suggestion, "ty", Applicability::MaybeIncorrect, // ty maybe needs an import ) - .emit(); }); } } @@ -140,76 +142,77 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { match &ty.kind { TyKind::Path(QPath::Resolved(_, path)) => { if lint_ty_kind_usage(cx, &path.res) { - cx.struct_span_lint(USAGE_OF_TY_TYKIND, path.span, |lint| { - let hir = cx.tcx.hir(); - match hir.find(hir.get_parent_node(ty.hir_id)) { - Some(Node::Pat(Pat { - kind: - PatKind::Path(qpath) - | PatKind::TupleStruct(qpath, ..) - | PatKind::Struct(qpath, ..), - .. - })) => { - if let QPath::TypeRelative(qpath_ty, ..) = qpath - && qpath_ty.hir_id == ty.hir_id - { - lint.build(fluent::lint::tykind_kind) - .span_suggestion( - path.span, - fluent::lint::suggestion, - "ty", - Applicability::MaybeIncorrect, // ty maybe needs an import - ) - .emit(); - return; - } + let hir = cx.tcx.hir(); + let span = match hir.find(hir.get_parent_node(ty.hir_id)) { + Some(Node::Pat(Pat { + kind: + PatKind::Path(qpath) + | PatKind::TupleStruct(qpath, ..) + | PatKind::Struct(qpath, ..), + .. + })) => { + if let QPath::TypeRelative(qpath_ty, ..) = qpath + && qpath_ty.hir_id == ty.hir_id + { + Some(path.span) + } else { + None } - Some(Node::Expr(Expr { - kind: ExprKind::Path(qpath), - .. - })) => { - if let QPath::TypeRelative(qpath_ty, ..) = qpath - && qpath_ty.hir_id == ty.hir_id - { - lint.build(fluent::lint::tykind_kind) - .span_suggestion( - path.span, - fluent::lint::suggestion, - "ty", - Applicability::MaybeIncorrect, // ty maybe needs an import - ) - .emit(); - return; - } + } + Some(Node::Expr(Expr { + kind: ExprKind::Path(qpath), + .. + })) => { + if let QPath::TypeRelative(qpath_ty, ..) = qpath + && qpath_ty.hir_id == ty.hir_id + { + Some(path.span) + } else { + None } - // Can't unify these two branches because qpath below is `&&` and above is `&` - // and `A | B` paths don't play well together with adjustments, apparently. - Some(Node::Expr(Expr { - kind: ExprKind::Struct(qpath, ..), - .. - })) => { - if let QPath::TypeRelative(qpath_ty, ..) = qpath - && qpath_ty.hir_id == ty.hir_id - { - lint.build(fluent::lint::tykind_kind) - .span_suggestion( - path.span, - fluent::lint::suggestion, - "ty", - Applicability::MaybeIncorrect, // ty maybe needs an import - ) - .emit(); - return; - } + } + // Can't unify these two branches because qpath below is `&&` and above is `&` + // and `A | B` paths don't play well together with adjustments, apparently. + Some(Node::Expr(Expr { + kind: ExprKind::Struct(qpath, ..), + .. + })) => { + if let QPath::TypeRelative(qpath_ty, ..) = qpath + && qpath_ty.hir_id == ty.hir_id + { + Some(path.span) + } else { + None } - _ => {} } - lint.build(fluent::lint::tykind).help(fluent::lint::help).emit(); - }) + _ => None + }; + + match span { + Some(span) => { + cx.struct_span_lint( + USAGE_OF_TY_TYKIND, + path.span, + fluent::lint::tykind_kind, + |lint| lint.span_suggestion( + span, + fluent::lint::suggestion, + "ty", + Applicability::MaybeIncorrect, // ty maybe needs an import + ) + ) + }, + None => cx.struct_span_lint( + USAGE_OF_TY_TYKIND, + path.span, + fluent::lint::tykind, + |lint| lint.help(fluent::lint::help) + ) + } } else if !ty.span.from_expansion() && let Some(t) = is_ty_or_ty_ctxt(cx, &path) { if path.segments.len() > 1 { - cx.struct_span_lint(USAGE_OF_QUALIFIED_TY, path.span, |lint| { - lint.build(fluent::lint::ty_qualified) + cx.struct_span_lint(USAGE_OF_QUALIFIED_TY, path.span, fluent::lint::ty_qualified, |lint| { + lint .set_arg("ty", t.clone()) .span_suggestion( path.span, @@ -218,7 +221,6 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind { // The import probably needs to be changed Applicability::MaybeIncorrect, ) - .emit(); }) } } @@ -244,7 +246,7 @@ fn is_ty_or_ty_ctxt(cx: &LateContext<'_>, path: &Path<'_>) -> Option<String> { } } // Only lint on `&Ty` and `&TyCtxt` if it is used outside of a trait. - Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => { + Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() { if let Some(name @ (sym::Ty | sym::TyCtxt)) = cx.tcx.get_diagnostic_name(adt.did()) { @@ -308,11 +310,8 @@ impl EarlyLintPass for LintPassImpl { cx.struct_span_lint( LINT_PASS_IMPL_WITHOUT_MACRO, lint_pass.path.span, - |lint| { - lint.build(fluent::lint::lintpass_by_hand) - .help(fluent::lint::help) - .emit(); - }, + fluent::lint::lintpass_by_hand, + |lint| lint.help(fluent::lint::help), ) } } @@ -349,12 +348,12 @@ impl<'tcx> LateLintPass<'tcx> for ExistingDocKeyword { if is_doc_keyword(v) { return; } - cx.struct_span_lint(EXISTING_DOC_KEYWORD, attr.span, |lint| { - lint.build(fluent::lint::non_existant_doc_keyword) - .set_arg("keyword", v) - .help(fluent::lint::help) - .emit(); - }); + cx.struct_span_lint( + EXISTING_DOC_KEYWORD, + attr.span, + fluent::lint::non_existant_doc_keyword, + |lint| lint.set_arg("keyword", v).help(fluent::lint::help), + ); } } } @@ -412,9 +411,12 @@ impl LateLintPass<'_> for Diagnostics { } debug!(?found_impl); if !found_parent_with_attr && !found_impl { - cx.struct_span_lint(DIAGNOSTIC_OUTSIDE_OF_IMPL, span, |lint| { - lint.build(fluent::lint::diag_out_of_impl).emit(); - }) + cx.struct_span_lint( + DIAGNOSTIC_OUTSIDE_OF_IMPL, + span, + fluent::lint::diag_out_of_impl, + |lint| lint, + ) } let mut found_diagnostic_message = false; @@ -430,9 +432,12 @@ impl LateLintPass<'_> for Diagnostics { } debug!(?found_diagnostic_message); if !found_parent_with_attr && !found_diagnostic_message { - cx.struct_span_lint(UNTRANSLATABLE_DIAGNOSTIC, span, |lint| { - lint.build(fluent::lint::untranslatable_diag).emit(); - }) + cx.struct_span_lint( + UNTRANSLATABLE_DIAGNOSTIC, + span, + fluent::lint::untranslatable_diag, + |lint| lint, + ) } } } @@ -464,8 +469,8 @@ impl LateLintPass<'_> for BadOptAccess { let Some(literal) = item.literal() && let ast::LitKind::Str(val, _) = literal.kind { - cx.struct_span_lint(BAD_OPT_ACCESS, expr.span, |lint| { - lint.build(val.as_str()).emit(); } + cx.struct_span_lint(BAD_OPT_ACCESS, expr.span, val.as_str(), |lint| + lint ); } } diff --git a/compiler/rustc_lint/src/let_underscore.rs b/compiler/rustc_lint/src/let_underscore.rs index 7e885e6c51a..78f355ec3d0 100644 --- a/compiler/rustc_lint/src/let_underscore.rs +++ b/compiler/rustc_lint/src/let_underscore.rs @@ -1,5 +1,5 @@ use crate::{LateContext, LateLintPass, LintContext}; -use rustc_errors::{Applicability, LintDiagnosticBuilder, MultiSpan}; +use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan}; use rustc_hir as hir; use rustc_middle::ty; use rustc_span::Symbol; @@ -128,48 +128,41 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore { init.span, "this binding will immediately drop the value assigned to it".to_string(), ); - cx.struct_span_lint(LET_UNDERSCORE_LOCK, span, |lint| { - build_and_emit_lint( - lint, - local, - init.span, - "non-binding let on a synchronization lock", - ) - }) + cx.struct_span_lint( + LET_UNDERSCORE_LOCK, + span, + "non-binding let on a synchronization lock", + |lint| build_lint(lint, local, init.span), + ) } else { - cx.struct_span_lint(LET_UNDERSCORE_DROP, local.span, |lint| { - build_and_emit_lint( - lint, - local, - init.span, - "non-binding let on a type that implements `Drop`", - ); - }) + cx.struct_span_lint( + LET_UNDERSCORE_DROP, + local.span, + "non-binding let on a type that implements `Drop`", + |lint| build_lint(lint, local, init.span), + ) } } } } -fn build_and_emit_lint( - lint: LintDiagnosticBuilder<'_, ()>, +fn build_lint<'a, 'b>( + lint: &'a mut DiagnosticBuilder<'b, ()>, local: &hir::Local<'_>, init_span: rustc_span::Span, - msg: &str, -) { - lint.build(msg) - .span_suggestion_verbose( - local.pat.span, - "consider binding to an unused variable to avoid immediately dropping the value", - "_unused", - Applicability::MachineApplicable, - ) - .multipart_suggestion( - "consider immediately dropping the value", - vec![ - (local.span.until(init_span), "drop(".to_string()), - (init_span.shrink_to_hi(), ")".to_string()), - ], - Applicability::MachineApplicable, - ) - .emit(); +) -> &'a mut DiagnosticBuilder<'b, ()> { + lint.span_suggestion_verbose( + local.pat.span, + "consider binding to an unused variable to avoid immediately dropping the value", + "_unused", + Applicability::MachineApplicable, + ) + .multipart_suggestion( + "consider immediately dropping the value", + vec![ + (local.span.until(init_span), "drop(".to_string()), + (init_span.shrink_to_hi(), ")".to_string()), + ], + Applicability::MachineApplicable, + ) } diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 1e16ac51e9e..be1d7d98aa6 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -3,13 +3,15 @@ use crate::late::unerased_lint_store; use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{Applicability, Diagnostic, LintDiagnosticBuilder, MultiSpan}; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, MultiSpan}; use rustc_hir as hir; -use rustc_hir::{intravisit, HirId}; +use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::HirId; +use rustc_index::vec::IndexVec; use rustc_middle::hir::nested_filter; use rustc_middle::lint::{ - struct_lint_level, LevelAndSource, LintExpectation, LintLevelMap, LintLevelSets, - LintLevelSource, LintSet, LintStackIndex, COMMAND_LINE, + reveal_actual_level, struct_lint_level, LevelAndSource, LintExpectation, LintLevelSource, + ShallowLintLevelMap, }; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{RegisteredTools, TyCtxt}; @@ -27,47 +29,408 @@ use crate::errors::{ UnknownToolInScopedLint, }; -fn lint_levels(tcx: TyCtxt<'_>, (): ()) -> LintLevelMap { - let store = unerased_lint_store(tcx); - let levels = - LintLevelsBuilder::new(tcx.sess, false, &store, &tcx.resolutions(()).registered_tools); - let mut builder = LintLevelMapBuilder { levels, tcx }; - let krate = tcx.hir().krate(); +/// Collection of lint levels for the whole crate. +/// This is used by AST-based lints, which do not +/// wait until we have built HIR to be emitted. +#[derive(Debug)] +struct LintLevelSets { + /// Linked list of specifications. + list: IndexVec<LintStackIndex, LintSet>, +} + +rustc_index::newtype_index! { + struct LintStackIndex { + ENCODABLE = custom, // we don't need encoding + const COMMAND_LINE = 0, + } +} + +/// Specifications found at this position in the stack. This map only represents the lints +/// found for one set of attributes (like `shallow_lint_levels_on` does). +/// +/// We store the level specifications as a linked list. +/// Each `LintSet` represents a set of attributes on the same AST node. +/// The `parent` forms a linked list that matches the AST tree. +/// This way, walking the linked list is equivalent to walking the AST bottom-up +/// to find the specifications for a given lint. +#[derive(Debug)] +struct LintSet { + // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which + // flag. + specs: FxHashMap<LintId, LevelAndSource>, + parent: LintStackIndex, +} + +impl LintLevelSets { + fn new() -> Self { + LintLevelSets { list: IndexVec::new() } + } + + fn get_lint_level( + &self, + lint: &'static Lint, + idx: LintStackIndex, + aux: Option<&FxHashMap<LintId, LevelAndSource>>, + sess: &Session, + ) -> LevelAndSource { + let lint = LintId::of(lint); + let (level, mut src) = self.raw_lint_id_level(lint, idx, aux); + let level = reveal_actual_level(level, &mut src, sess, lint, |id| { + self.raw_lint_id_level(id, idx, aux) + }); + (level, src) + } - builder.levels.id_to_set.reserve(krate.owners.len() + 1); + fn raw_lint_id_level( + &self, + id: LintId, + mut idx: LintStackIndex, + aux: Option<&FxHashMap<LintId, LevelAndSource>>, + ) -> (Option<Level>, LintLevelSource) { + if let Some(specs) = aux { + if let Some(&(level, src)) = specs.get(&id) { + return (Some(level), src); + } + } + loop { + let LintSet { ref specs, parent } = self.list[idx]; + if let Some(&(level, src)) = specs.get(&id) { + return (Some(level), src); + } + if idx == COMMAND_LINE { + return (None, LintLevelSource::Default); + } + idx = parent; + } + } +} - let push = - builder.levels.push(tcx.hir().attrs(hir::CRATE_HIR_ID), true, Some(hir::CRATE_HIR_ID)); +fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExpectation)> { + let store = unerased_lint_store(tcx); - builder.levels.register_id(hir::CRATE_HIR_ID); + let mut builder = LintLevelsBuilder { + sess: tcx.sess, + provider: QueryMapExpectationsWrapper { + tcx, + cur: hir::CRATE_HIR_ID, + specs: ShallowLintLevelMap::default(), + expectations: Vec::new(), + unstable_to_stable_ids: FxHashMap::default(), + empty: FxHashMap::default(), + }, + warn_about_weird_lints: false, + store, + registered_tools: &tcx.resolutions(()).registered_tools, + }; + + builder.add_command_line(); + builder.add_id(hir::CRATE_HIR_ID); tcx.hir().walk_toplevel_module(&mut builder); - builder.levels.pop(push); - builder.levels.update_unstable_expectation_ids(); - builder.levels.build_map() + tcx.sess.diagnostic().update_unstable_expectation_id(&builder.provider.unstable_to_stable_ids); + + builder.provider.expectations } -pub struct LintLevelsBuilder<'s> { - sess: &'s Session, - lint_expectations: Vec<(LintExpectationId, LintExpectation)>, - /// Each expectation has a stable and an unstable identifier. This map - /// is used to map from unstable to stable [`LintExpectationId`]s. - expectation_id_map: FxHashMap<LintExpectationId, LintExpectationId>, +#[instrument(level = "trace", skip(tcx), ret)] +fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLevelMap { + let store = unerased_lint_store(tcx); + let attrs = tcx.hir_attrs(owner); + + let mut levels = LintLevelsBuilder { + sess: tcx.sess, + provider: LintLevelQueryMap { + tcx, + cur: owner.into(), + specs: ShallowLintLevelMap::default(), + empty: FxHashMap::default(), + attrs, + }, + warn_about_weird_lints: false, + store, + registered_tools: &tcx.resolutions(()).registered_tools, + }; + + if owner == hir::CRATE_OWNER_ID { + levels.add_command_line(); + } + + match attrs.map.range(..) { + // There is only something to do if there are attributes at all. + [] => {} + // Most of the time, there is only one attribute. Avoid fetching HIR in that case. + [(local_id, _)] => levels.add_id(HirId { owner, local_id: *local_id }), + // Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do + // a standard visit. + // FIXME(#102522) Just iterate on attrs once that iteration order matches HIR's. + _ => match tcx.hir().expect_owner(owner) { + hir::OwnerNode::Item(item) => levels.visit_item(item), + hir::OwnerNode::ForeignItem(item) => levels.visit_foreign_item(item), + hir::OwnerNode::TraitItem(item) => levels.visit_trait_item(item), + hir::OwnerNode::ImplItem(item) => levels.visit_impl_item(item), + hir::OwnerNode::Crate(mod_) => { + levels.add_id(hir::CRATE_HIR_ID); + levels.visit_mod(mod_, mod_.spans.inner_span, hir::CRATE_HIR_ID) + } + }, + } + + let specs = levels.provider.specs; + + #[cfg(debug_assertions)] + for (_, v) in specs.specs.iter() { + debug_assert!(!v.is_empty()); + } + + specs +} + +pub struct TopDown { sets: LintLevelSets, - id_to_set: FxHashMap<HirId, LintStackIndex>, cur: LintStackIndex, +} + +pub trait LintLevelsProvider { + fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource>; + fn insert(&mut self, id: LintId, lvl: LevelAndSource); + fn get_lint_level(&self, lint: &'static Lint, sess: &Session) -> LevelAndSource; + fn push_expectation(&mut self, _id: LintExpectationId, _expectation: LintExpectation) {} +} + +impl LintLevelsProvider for TopDown { + fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource> { + &self.sets.list[self.cur].specs + } + + fn insert(&mut self, id: LintId, lvl: LevelAndSource) { + self.sets.list[self.cur].specs.insert(id, lvl); + } + + fn get_lint_level(&self, lint: &'static Lint, sess: &Session) -> LevelAndSource { + self.sets.get_lint_level(lint, self.cur, Some(self.current_specs()), sess) + } +} + +struct LintLevelQueryMap<'tcx> { + tcx: TyCtxt<'tcx>, + cur: HirId, + specs: ShallowLintLevelMap, + /// Empty hash map to simplify code. + empty: FxHashMap<LintId, LevelAndSource>, + attrs: &'tcx hir::AttributeMap<'tcx>, +} + +impl LintLevelsProvider for LintLevelQueryMap<'_> { + fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource> { + self.specs.specs.get(&self.cur.local_id).unwrap_or(&self.empty) + } + fn insert(&mut self, id: LintId, lvl: LevelAndSource) { + self.specs.specs.get_mut_or_insert_default(self.cur.local_id).insert(id, lvl); + } + fn get_lint_level(&self, lint: &'static Lint, _: &Session) -> LevelAndSource { + self.specs.lint_level_id_at_node(self.tcx, LintId::of(lint), self.cur) + } +} + +struct QueryMapExpectationsWrapper<'tcx> { + tcx: TyCtxt<'tcx>, + cur: HirId, + specs: ShallowLintLevelMap, + expectations: Vec<(LintExpectationId, LintExpectation)>, + unstable_to_stable_ids: FxHashMap<LintExpectationId, LintExpectationId>, + /// Empty hash map to simplify code. + empty: FxHashMap<LintId, LevelAndSource>, +} + +impl LintLevelsProvider for QueryMapExpectationsWrapper<'_> { + fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource> { + self.specs.specs.get(&self.cur.local_id).unwrap_or(&self.empty) + } + fn insert(&mut self, id: LintId, lvl: LevelAndSource) { + let specs = self.specs.specs.get_mut_or_insert_default(self.cur.local_id); + specs.clear(); + specs.insert(id, lvl); + } + fn get_lint_level(&self, lint: &'static Lint, _: &Session) -> LevelAndSource { + self.specs.lint_level_id_at_node(self.tcx, LintId::of(lint), self.cur) + } + fn push_expectation(&mut self, id: LintExpectationId, expectation: LintExpectation) { + let LintExpectationId::Stable { attr_id: Some(attr_id), hir_id, attr_index, .. } = id else { bug!("unstable expectation id should already be mapped") }; + let key = LintExpectationId::Unstable { attr_id, lint_index: None }; + + if !self.unstable_to_stable_ids.contains_key(&key) { + self.unstable_to_stable_ids.insert( + key, + LintExpectationId::Stable { hir_id, attr_index, lint_index: None, attr_id: None }, + ); + } + + self.expectations.push((id.normalize(), expectation)); + } +} + +impl<'tcx> LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> { + fn add_id(&mut self, hir_id: HirId) { + self.provider.cur = hir_id; + self.add( + self.provider.attrs.get(hir_id.local_id), + hir_id == hir::CRATE_HIR_ID, + Some(hir_id), + ); + } +} + +impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, LintLevelQueryMap<'tcx>> { + type NestedFilter = nested_filter::OnlyBodies; + + fn nested_visit_map(&mut self) -> Self::Map { + self.provider.tcx.hir() + } + + fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { + self.add_id(param.hir_id); + intravisit::walk_param(self, param); + } + + fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) { + self.add_id(it.hir_id()); + intravisit::walk_item(self, it); + } + + fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) { + self.add_id(it.hir_id()); + intravisit::walk_foreign_item(self, it); + } + + fn visit_stmt(&mut self, e: &'tcx hir::Stmt<'tcx>) { + // We will call `add_id` when we walk + // the `StmtKind`. The outer statement itself doesn't + // define the lint levels. + intravisit::walk_stmt(self, e); + } + + fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) { + self.add_id(e.hir_id); + intravisit::walk_expr(self, e); + } + + fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) { + self.add_id(s.hir_id); + intravisit::walk_field_def(self, s); + } + + fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) { + self.add_id(v.id); + intravisit::walk_variant(self, v); + } + + fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) { + self.add_id(l.hir_id); + intravisit::walk_local(self, l); + } + + fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) { + self.add_id(a.hir_id); + intravisit::walk_arm(self, a); + } + + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { + self.add_id(trait_item.hir_id()); + intravisit::walk_trait_item(self, trait_item); + } + + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { + self.add_id(impl_item.hir_id()); + intravisit::walk_impl_item(self, impl_item); + } +} + +impl<'tcx> LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'tcx>> { + fn add_id(&mut self, hir_id: HirId) { + self.provider.cur = hir_id; + self.add(self.provider.tcx.hir().attrs(hir_id), hir_id == hir::CRATE_HIR_ID, Some(hir_id)); + } +} + +impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'tcx>> { + type NestedFilter = nested_filter::All; + + fn nested_visit_map(&mut self) -> Self::Map { + self.provider.tcx.hir() + } + + fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { + self.add_id(param.hir_id); + intravisit::walk_param(self, param); + } + + fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) { + self.add_id(it.hir_id()); + intravisit::walk_item(self, it); + } + + fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) { + self.add_id(it.hir_id()); + intravisit::walk_foreign_item(self, it); + } + + fn visit_stmt(&mut self, e: &'tcx hir::Stmt<'tcx>) { + // We will call `add_id` when we walk + // the `StmtKind`. The outer statement itself doesn't + // define the lint levels. + intravisit::walk_stmt(self, e); + } + + fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) { + self.add_id(e.hir_id); + intravisit::walk_expr(self, e); + } + + fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) { + self.add_id(s.hir_id); + intravisit::walk_field_def(self, s); + } + + fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) { + self.add_id(v.id); + intravisit::walk_variant(self, v); + } + + fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) { + self.add_id(l.hir_id); + intravisit::walk_local(self, l); + } + + fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) { + self.add_id(a.hir_id); + intravisit::walk_arm(self, a); + } + + fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { + self.add_id(trait_item.hir_id()); + intravisit::walk_trait_item(self, trait_item); + } + + fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { + self.add_id(impl_item.hir_id()); + intravisit::walk_impl_item(self, impl_item); + } +} + +pub struct LintLevelsBuilder<'s, P> { + sess: &'s Session, + provider: P, warn_about_weird_lints: bool, store: &'s LintStore, registered_tools: &'s RegisteredTools, } -pub struct BuilderPush { +pub(crate) struct BuilderPush { prev: LintStackIndex, - pub changed: bool, } -impl<'s> LintLevelsBuilder<'s> { - pub fn new( +impl<'s> LintLevelsBuilder<'s, TopDown> { + pub(crate) fn new( sess: &'s Session, warn_about_weird_lints: bool, store: &'s LintStore, @@ -75,20 +438,74 @@ impl<'s> LintLevelsBuilder<'s> { ) -> Self { let mut builder = LintLevelsBuilder { sess, - lint_expectations: Default::default(), - expectation_id_map: Default::default(), - sets: LintLevelSets::new(), - cur: COMMAND_LINE, - id_to_set: Default::default(), + provider: TopDown { sets: LintLevelSets::new(), cur: COMMAND_LINE }, warn_about_weird_lints, store, registered_tools, }; - builder.process_command_line(sess, store); - assert_eq!(builder.sets.list.len(), 1); + builder.process_command_line(); + assert_eq!(builder.provider.sets.list.len(), 1); builder } + fn process_command_line(&mut self) { + self.provider.cur = self + .provider + .sets + .list + .push(LintSet { specs: FxHashMap::default(), parent: COMMAND_LINE }); + self.add_command_line(); + } + + /// Pushes a list of AST lint attributes onto this context. + /// + /// This function will return a `BuilderPush` object which should be passed + /// to `pop` when this scope for the attributes provided is exited. + /// + /// This function will perform a number of tasks: + /// + /// * It'll validate all lint-related attributes in `attrs` + /// * It'll mark all lint-related attributes as used + /// * Lint levels will be updated based on the attributes provided + /// * Lint attributes are validated, e.g., a `#[forbid]` can't be switched to + /// `#[allow]` + /// + /// Don't forget to call `pop`! + pub(crate) fn push( + &mut self, + attrs: &[ast::Attribute], + is_crate_node: bool, + source_hir_id: Option<HirId>, + ) -> BuilderPush { + let prev = self.provider.cur; + self.provider.cur = + self.provider.sets.list.push(LintSet { specs: FxHashMap::default(), parent: prev }); + + self.add(attrs, is_crate_node, source_hir_id); + + if self.provider.current_specs().is_empty() { + self.provider.sets.list.pop(); + self.provider.cur = prev; + } + + BuilderPush { prev } + } + + /// Called after `push` when the scope of a set of attributes are exited. + pub(crate) fn pop(&mut self, push: BuilderPush) { + self.provider.cur = push.prev; + std::mem::forget(push); + } +} + +#[cfg(debug_assertions)] +impl Drop for BuilderPush { + fn drop(&mut self) { + panic!("Found a `push` without a `pop`."); + } +} + +impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { pub(crate) fn sess(&self) -> &Session { self.sess } @@ -98,24 +515,20 @@ impl<'s> LintLevelsBuilder<'s> { } fn current_specs(&self) -> &FxHashMap<LintId, LevelAndSource> { - &self.sets.list[self.cur].specs + self.provider.current_specs() } - fn current_specs_mut(&mut self) -> &mut FxHashMap<LintId, LevelAndSource> { - &mut self.sets.list[self.cur].specs + fn insert(&mut self, id: LintId, lvl: LevelAndSource) { + self.provider.insert(id, lvl) } - fn process_command_line(&mut self, sess: &Session, store: &LintStore) { - self.sets.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); - - self.cur = - self.sets.list.push(LintSet { specs: FxHashMap::default(), parent: COMMAND_LINE }); - for &(ref lint_name, level) in &sess.opts.lint_opts { - store.check_lint_name_cmdline(sess, &lint_name, level, self.registered_tools); + fn add_command_line(&mut self) { + for &(ref lint_name, level) in &self.sess.opts.lint_opts { + self.store.check_lint_name_cmdline(self.sess, &lint_name, level, self.registered_tools); let orig_level = level; let lint_flag_val = Symbol::intern(lint_name); - let Ok(ids) = store.find_lints(&lint_name) else { + let Ok(ids) = self.store.find_lints(&lint_name) else { // errors handled in check_lint_name_cmdline above continue }; @@ -129,7 +542,7 @@ impl<'s> LintLevelsBuilder<'s> { if self.check_gated_lint(id, DUMMY_SP) { let src = LintLevelSource::CommandLine(lint_flag_val, orig_level); - self.current_specs_mut().insert(id, (level, src)); + self.insert(id, (level, src)); } } } @@ -138,9 +551,11 @@ impl<'s> LintLevelsBuilder<'s> { /// Attempts to insert the `id` to `level_src` map entry. If unsuccessful /// (e.g. if a forbid was already inserted on the same scope), then emits a /// diagnostic with no change to `specs`. - fn insert_spec(&mut self, id: LintId, (level, src): LevelAndSource) { - let (old_level, old_src) = - self.sets.get_lint_level(id.lint, self.cur, Some(self.current_specs()), &self.sess); + fn insert_spec(&mut self, id: LintId, (mut level, src): LevelAndSource) { + let (old_level, old_src) = self.provider.get_lint_level(id.lint, &self.sess); + if let Level::Expect(id) = &mut level && let LintExpectationId::Stable { .. } = id { + *id = id.normalize(); + } // Setting to a non-forbid level is an error if the lint previously had // a forbid level. Note that this is not necessarily true even with a // `#[forbid(..)]` attribute present, as that is overridden by `--cap-lints`. @@ -158,7 +573,7 @@ impl<'s> LintLevelsBuilder<'s> { let id_name = id.lint.name_lower(); let fcw_warning = match old_src { LintLevelSource::Default => false, - LintLevelSource::Node(symbol, _, _) => self.store.is_lint_group(symbol), + LintLevelSource::Node { name, .. } => self.store.is_lint_group(name), LintLevelSource::CommandLine(symbol, _) => self.store.is_lint_group(symbol), }; debug!( @@ -178,8 +593,8 @@ impl<'s> LintLevelsBuilder<'s> { id.to_string() )); } - LintLevelSource::Node(_, forbid_source_span, reason) => { - diag.span_label(forbid_source_span, "`forbid` level set here"); + LintLevelSource::Node { span, reason, .. } => { + diag.span_label(span, "`forbid` level set here"); if let Some(rationale) = reason { diag.note(rationale.as_str()); } @@ -199,11 +614,8 @@ impl<'s> LintLevelsBuilder<'s> { LintLevelSource::Default => { OverruledAttributeSub::DefaultSource { id: id.to_string() } } - LintLevelSource::Node(_, forbid_source_span, reason) => { - OverruledAttributeSub::NodeSource { - span: forbid_source_span, - reason, - } + LintLevelSource::Node { span, reason, .. } => { + OverruledAttributeSub::NodeSource { span, reason } } LintLevelSource::CommandLine(_, _) => { OverruledAttributeSub::CommandLineSource @@ -214,14 +626,14 @@ impl<'s> LintLevelsBuilder<'s> { self.struct_lint( FORBIDDEN_LINT_GROUPS, Some(src.span().into()), - |diag_builder| { - let mut diag_builder = diag_builder.build(&format!( - "{}({}) incompatible with previous forbid", - level.as_str(), - src.name(), - )); - decorate_diag(&mut diag_builder); - diag_builder.emit(); + format!( + "{}({}) incompatible with previous forbid", + level.as_str(), + src.name(), + ), + |lint| { + decorate_diag(lint); + lint }, ); } @@ -244,45 +656,21 @@ impl<'s> LintLevelsBuilder<'s> { match (old_level, level) { // If the new level is an expectation store it in `ForceWarn` - (Level::ForceWarn(_), Level::Expect(expectation_id)) => self - .current_specs_mut() - .insert(id, (Level::ForceWarn(Some(expectation_id)), old_src)), - // Keep `ForceWarn` level but drop the expectation - (Level::ForceWarn(_), _) => { - self.current_specs_mut().insert(id, (Level::ForceWarn(None), old_src)) + (Level::ForceWarn(_), Level::Expect(expectation_id)) => { + self.insert(id, (Level::ForceWarn(Some(expectation_id)), old_src)) } + // Keep `ForceWarn` level but drop the expectation + (Level::ForceWarn(_), _) => self.insert(id, (Level::ForceWarn(None), old_src)), // Set the lint level as normal - _ => self.current_specs_mut().insert(id, (level, src)), + _ => self.insert(id, (level, src)), }; } - /// Pushes a list of AST lint attributes onto this context. - /// - /// This function will return a `BuilderPush` object which should be passed - /// to `pop` when this scope for the attributes provided is exited. - /// - /// This function will perform a number of tasks: - /// - /// * It'll validate all lint-related attributes in `attrs` - /// * It'll mark all lint-related attributes as used - /// * Lint levels will be updated based on the attributes provided - /// * Lint attributes are validated, e.g., a `#[forbid]` can't be switched to - /// `#[allow]` - /// - /// Don't forget to call `pop`! - pub(crate) fn push( - &mut self, - attrs: &[ast::Attribute], - is_crate_node: bool, - source_hir_id: Option<HirId>, - ) -> BuilderPush { - let prev = self.cur; - self.cur = self.sets.list.push(LintSet { specs: FxHashMap::default(), parent: prev }); - + fn add(&mut self, attrs: &[ast::Attribute], is_crate_node: bool, source_hir_id: Option<HirId>) { let sess = self.sess; for (attr_index, attr) in attrs.iter().enumerate() { if attr.has_name(sym::automatically_derived) { - self.current_specs_mut().insert( + self.insert( LintId::of(SINGLE_USE_LIFETIMES), (Level::Allow, LintLevelSource::Default), ); @@ -293,7 +681,17 @@ impl<'s> LintLevelsBuilder<'s> { None => continue, // This is the only lint level with a `LintExpectationId` that can be created from an attribute Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => { - let stable_id = self.create_stable_id(unstable_id, hir_id, attr_index); + let LintExpectationId::Unstable { attr_id, lint_index } = unstable_id + else { bug!("stable id Level::from_attr") }; + + let stable_id = LintExpectationId::Stable { + hir_id, + attr_index: attr_index.try_into().unwrap(), + lint_index, + // we pass the previous unstable attr_id such that we can trace the ast id when building a map + // to go from unstable to stable id. + attr_id: Some(attr_id), + }; Level::Expect(stable_id) } @@ -408,7 +806,7 @@ impl<'s> LintLevelsBuilder<'s> { [lint] => *lint == LintId::of(UNFULFILLED_LINT_EXPECTATIONS), _ => false, }; - self.lint_expectations.push(( + self.provider.push_expectation( expect_id, LintExpectation::new( reason, @@ -416,13 +814,19 @@ impl<'s> LintLevelsBuilder<'s> { is_unfulfilled_lint_expectations, tool_name, ), - )); + ); } - let src = LintLevelSource::Node( - meta_item.path.segments.last().expect("empty lint name").ident.name, - sp, + let src = LintLevelSource::Node { + name: meta_item + .path + .segments + .last() + .expect("empty lint name") + .ident + .name, + span: sp, reason, - ); + }; for &id in *ids { if self.check_gated_lint(id, attr.span) { self.insert_spec(id, (level, src)); @@ -435,67 +839,60 @@ impl<'s> LintLevelsBuilder<'s> { Ok(ids) => { let complete_name = &format!("{}::{}", tool_ident.unwrap().name, name); - let src = LintLevelSource::Node( - Symbol::intern(complete_name), - sp, + let src = LintLevelSource::Node { + name: Symbol::intern(complete_name), + span: sp, reason, - ); + }; for &id in ids { if self.check_gated_lint(id, attr.span) { self.insert_spec(id, (level, src)); } } if let Level::Expect(expect_id) = level { - self.lint_expectations.push(( + self.provider.push_expectation( expect_id, LintExpectation::new(reason, sp, false, tool_name), - )); + ); } } Err((Some(ids), ref new_lint_name)) => { let lint = builtin::RENAMED_AND_REMOVED_LINTS; - let (lvl, src) = self.sets.get_lint_level( - lint, - self.cur, - Some(self.current_specs()), - &sess, - ); + let (lvl, src) = self.provider.get_lint_level(lint, &sess); struct_lint_level( self.sess, lint, lvl, src, Some(sp.into()), + format!( + "lint name `{}` is deprecated \ + and may not have an effect in the future.", + name + ), |lint| { - let msg = format!( - "lint name `{}` is deprecated \ - and may not have an effect in the future.", - name - ); - lint.build(&msg) - .span_suggestion( - sp, - "change it to", - new_lint_name, - Applicability::MachineApplicable, - ) - .emit(); + lint.span_suggestion( + sp, + "change it to", + new_lint_name, + Applicability::MachineApplicable, + ) }, ); - let src = LintLevelSource::Node( - Symbol::intern(&new_lint_name), - sp, + let src = LintLevelSource::Node { + name: Symbol::intern(&new_lint_name), + span: sp, reason, - ); + }; for id in ids { self.insert_spec(*id, (level, src)); } if let Level::Expect(expect_id) = level { - self.lint_expectations.push(( + self.provider.push_expectation( expect_id, LintExpectation::new(reason, sp, false, tool_name), - )); + ); } } Err((None, _)) => { @@ -521,57 +918,54 @@ impl<'s> LintLevelsBuilder<'s> { CheckLintNameResult::Warning(msg, renamed) => { let lint = builtin::RENAMED_AND_REMOVED_LINTS; - let (renamed_lint_level, src) = self.sets.get_lint_level( - lint, - self.cur, - Some(self.current_specs()), - &sess, - ); + let (renamed_lint_level, src) = self.provider.get_lint_level(lint, &sess); struct_lint_level( self.sess, lint, renamed_lint_level, src, Some(sp.into()), + msg, |lint| { - let mut err = lint.build(msg); if let Some(new_name) = &renamed { - err.span_suggestion( + lint.span_suggestion( sp, "use the new name", new_name, Applicability::MachineApplicable, ); } - err.emit(); + lint }, ); } CheckLintNameResult::NoLint(suggestion) => { let lint = builtin::UNKNOWN_LINTS; - let (level, src) = self.sets.get_lint_level( - lint, - self.cur, - Some(self.current_specs()), + let (level, src) = self.provider.get_lint_level(lint, self.sess); + let name = if let Some(tool_ident) = tool_ident { + format!("{}::{}", tool_ident.name, name) + } else { + name.to_string() + }; + struct_lint_level( self.sess, + lint, + level, + src, + Some(sp.into()), + format!("unknown lint: `{}`", name), + |lint| { + if let Some(suggestion) = suggestion { + lint.span_suggestion( + sp, + "did you mean", + suggestion, + Applicability::MachineApplicable, + ); + } + lint + }, ); - struct_lint_level(self.sess, lint, level, src, Some(sp.into()), |lint| { - let name = if let Some(tool_ident) = tool_ident { - format!("{}::{}", tool_ident.name, name) - } else { - name.to_string() - }; - let mut db = lint.build(format!("unknown lint: `{}`", name)); - if let Some(suggestion) = suggestion { - db.span_suggestion( - sp, - "did you mean", - suggestion, - Applicability::MachineApplicable, - ); - } - db.emit(); - }); } } // If this lint was renamed, apply the new lint instead of ignoring the attribute. @@ -583,17 +977,21 @@ impl<'s> LintLevelsBuilder<'s> { if let CheckLintNameResult::Ok(ids) = self.store.check_lint_name(&new_name, None, self.registered_tools) { - let src = LintLevelSource::Node(Symbol::intern(&new_name), sp, reason); + let src = LintLevelSource::Node { + name: Symbol::intern(&new_name), + span: sp, + reason, + }; for &id in ids { if self.check_gated_lint(id, attr.span) { self.insert_spec(id, (level, src)); } } if let Level::Expect(expect_id) = level { - self.lint_expectations.push(( + self.provider.push_expectation( expect_id, LintExpectation::new(reason, sp, false, tool_name), - )); + ); } } else { panic!("renamed lint does not exist: {}", new_name); @@ -608,232 +1006,83 @@ impl<'s> LintLevelsBuilder<'s> { continue; } - let LintLevelSource::Node(lint_attr_name, lint_attr_span, _) = *src else { + let LintLevelSource::Node { name: lint_attr_name, span: lint_attr_span, .. } = *src else { continue }; let lint = builtin::UNUSED_ATTRIBUTES; - let (lint_level, lint_src) = - self.sets.get_lint_level(lint, self.cur, Some(self.current_specs()), self.sess); + let (lint_level, lint_src) = self.provider.get_lint_level(lint, &self.sess); struct_lint_level( self.sess, lint, lint_level, lint_src, Some(lint_attr_span.into()), - |lint| { - let mut db = lint.build(&format!( - "{}({}) is ignored unless specified at crate level", - level.as_str(), - lint_attr_name - )); - db.emit(); - }, + format!( + "{}({}) is ignored unless specified at crate level", + level.as_str(), + lint_attr_name + ), + |lint| lint, ); // don't set a separate error for every lint in the group break; } } - - if self.current_specs().is_empty() { - self.sets.list.pop(); - self.cur = prev; - } - - BuilderPush { prev, changed: prev != self.cur } - } - - fn create_stable_id( - &mut self, - unstable_id: LintExpectationId, - hir_id: HirId, - attr_index: usize, - ) -> LintExpectationId { - let stable_id = - LintExpectationId::Stable { hir_id, attr_index: attr_index as u16, lint_index: None }; - - self.expectation_id_map.insert(unstable_id, stable_id); - - stable_id } /// Checks if the lint is gated on a feature that is not enabled. /// /// Returns `true` if the lint's feature is enabled. + // FIXME only emit this once for each attribute, instead of repeating it 4 times for + // pre-expansion lints, post-expansion lints, `shallow_lint_levels_on` and `lint_expectations`. fn check_gated_lint(&self, lint_id: LintId, span: Span) -> bool { if let Some(feature) = lint_id.lint.feature_gate { if !self.sess.features_untracked().enabled(feature) { let lint = builtin::UNKNOWN_LINTS; let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS); - struct_lint_level(self.sess, lint, level, src, Some(span.into()), |lint_db| { - let mut db = - lint_db.build(&format!("unknown lint: `{}`", lint_id.lint.name_lower())); - db.note(&format!("the `{}` lint is unstable", lint_id.lint.name_lower(),)); - add_feature_diagnostics(&mut db, &self.sess.parse_sess, feature); - db.emit(); - }); + struct_lint_level( + self.sess, + lint, + level, + src, + Some(span.into()), + format!("unknown lint: `{}`", lint_id.lint.name_lower()), + |lint| { + lint.note( + &format!("the `{}` lint is unstable", lint_id.lint.name_lower(),), + ); + add_feature_diagnostics(lint, &self.sess.parse_sess, feature); + lint + }, + ); return false; } } true } - /// Called after `push` when the scope of a set of attributes are exited. - pub fn pop(&mut self, push: BuilderPush) { - self.cur = push.prev; - } - /// Find the lint level for a lint. - pub fn lint_level(&self, lint: &'static Lint) -> (Level, LintLevelSource) { - self.sets.get_lint_level(lint, self.cur, None, self.sess) + pub fn lint_level(&self, lint: &'static Lint) -> LevelAndSource { + self.provider.get_lint_level(lint, self.sess) } /// Used to emit a lint-related diagnostic based on the current state of /// this lint context. - pub fn struct_lint( + pub(crate) fn struct_lint( &self, lint: &'static Lint, span: Option<MultiSpan>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { let (level, src) = self.lint_level(lint); - struct_lint_level(self.sess, lint, level, src, span, decorate) - } - - /// Registers the ID provided with the current set of lints stored in - /// this context. - pub fn register_id(&mut self, id: HirId) { - self.id_to_set.insert(id, self.cur); - } - - fn update_unstable_expectation_ids(&self) { - self.sess.diagnostic().update_unstable_expectation_id(&self.expectation_id_map); - } - - pub fn build_map(self) -> LintLevelMap { - LintLevelMap { - sets: self.sets, - id_to_set: self.id_to_set, - lint_expectations: self.lint_expectations, - } - } -} - -struct LintLevelMapBuilder<'tcx> { - levels: LintLevelsBuilder<'tcx>, - tcx: TyCtxt<'tcx>, -} - -impl LintLevelMapBuilder<'_> { - fn with_lint_attrs<F>(&mut self, id: hir::HirId, f: F) - where - F: FnOnce(&mut Self), - { - let is_crate_hir = id == hir::CRATE_HIR_ID; - let attrs = self.tcx.hir().attrs(id); - let push = self.levels.push(attrs, is_crate_hir, Some(id)); - - if push.changed { - self.levels.register_id(id); - } - f(self); - self.levels.pop(push); - } -} - -impl<'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> { - type NestedFilter = nested_filter::All; - - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - - fn visit_param(&mut self, param: &'tcx hir::Param<'tcx>) { - self.with_lint_attrs(param.hir_id, |builder| { - intravisit::walk_param(builder, param); - }); - } - - fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) { - self.with_lint_attrs(it.hir_id(), |builder| { - intravisit::walk_item(builder, it); - }); - } - - fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem<'tcx>) { - self.with_lint_attrs(it.hir_id(), |builder| { - intravisit::walk_foreign_item(builder, it); - }) - } - - fn visit_stmt(&mut self, e: &'tcx hir::Stmt<'tcx>) { - // We will call `with_lint_attrs` when we walk - // the `StmtKind`. The outer statement itself doesn't - // define the lint levels. - intravisit::walk_stmt(self, e); - } - - fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) { - self.with_lint_attrs(e.hir_id, |builder| { - intravisit::walk_expr(builder, e); - }) - } - - fn visit_expr_field(&mut self, field: &'tcx hir::ExprField<'tcx>) { - self.with_lint_attrs(field.hir_id, |builder| { - intravisit::walk_expr_field(builder, field); - }) - } - - fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) { - self.with_lint_attrs(s.hir_id, |builder| { - intravisit::walk_field_def(builder, s); - }) - } - - fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) { - self.with_lint_attrs(v.id, |builder| { - intravisit::walk_variant(builder, v); - }) - } - - fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) { - self.with_lint_attrs(l.hir_id, |builder| { - intravisit::walk_local(builder, l); - }) - } - - fn visit_arm(&mut self, a: &'tcx hir::Arm<'tcx>) { - self.with_lint_attrs(a.hir_id, |builder| { - intravisit::walk_arm(builder, a); - }) - } - - fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { - self.with_lint_attrs(trait_item.hir_id(), |builder| { - intravisit::walk_trait_item(builder, trait_item); - }); - } - - fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { - self.with_lint_attrs(impl_item.hir_id(), |builder| { - intravisit::walk_impl_item(builder, impl_item); - }); - } - - fn visit_pat_field(&mut self, field: &'tcx hir::PatField<'tcx>) { - self.with_lint_attrs(field.hir_id, |builder| { - intravisit::walk_pat_field(builder, field); - }) - } - - fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) { - self.with_lint_attrs(p.hir_id, |builder| { - intravisit::walk_generic_param(builder, p); - }); + struct_lint_level(self.sess, lint, level, src, span, msg, decorate) } } -pub fn provide(providers: &mut Providers) { - providers.lint_levels = lint_levels; +pub(crate) fn provide(providers: &mut Providers) { + *providers = Providers { shallow_lint_levels_on, lint_expectations, ..*providers }; } diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 4408f68dd63..9148c42195f 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -62,6 +62,7 @@ mod non_ascii_idents; mod non_fmt_panic; mod nonstandard_style; mod noop_method_call; +mod opaque_hidden_inferred_bound; mod pass_by_value; mod passes; mod redundant_semicolon; @@ -93,6 +94,7 @@ use non_ascii_idents::*; use non_fmt_panic::NonPanicFmt; use nonstandard_style::*; use noop_method_call::*; +use opaque_hidden_inferred_bound::*; use pass_by_value::*; use redundant_semicolon::*; use traits::*; @@ -223,6 +225,7 @@ macro_rules! late_lint_mod_passes { EnumIntrinsicsNonEnums: EnumIntrinsicsNonEnums, InvalidAtomicOrdering: InvalidAtomicOrdering, NamedAsmLabels: NamedAsmLabels, + OpaqueHiddenInferredBound: OpaqueHiddenInferredBound, ] ); }; diff --git a/compiler/rustc_lint/src/methods.rs b/compiler/rustc_lint/src/methods.rs index 5f7f03480c0..313119637bc 100644 --- a/compiler/rustc_lint/src/methods.rs +++ b/compiler/rustc_lint/src/methods.rs @@ -90,14 +90,17 @@ fn lint_cstring_as_ptr( if cx.tcx.is_diagnostic_item(sym::Result, def.did()) { if let ty::Adt(adt, _) = substs.type_at(0).kind() { if cx.tcx.is_diagnostic_item(sym::cstring_type, adt.did()) { - cx.struct_span_lint(TEMPORARY_CSTRING_AS_PTR, as_ptr_span, |diag| { - diag.build(fluent::lint::cstring_ptr) - .span_label(as_ptr_span, fluent::lint::as_ptr_label) - .span_label(unwrap.span, fluent::lint::unwrap_label) - .note(fluent::lint::note) - .help(fluent::lint::help) - .emit(); - }); + cx.struct_span_lint( + TEMPORARY_CSTRING_AS_PTR, + as_ptr_span, + fluent::lint::cstring_ptr, + |diag| { + diag.span_label(as_ptr_span, fluent::lint::as_ptr_label) + .span_label(unwrap.span, fluent::lint::unwrap_label) + .note(fluent::lint::note) + .help(fluent::lint::help) + }, + ); } } } diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 764003e61a6..b2626efb6d7 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -180,15 +180,21 @@ impl EarlyLintPass for NonAsciiIdents { continue; } has_non_ascii_idents = true; - cx.struct_span_lint(NON_ASCII_IDENTS, sp, |lint| { - lint.build(fluent::lint::identifier_non_ascii_char).emit(); - }); + cx.struct_span_lint( + NON_ASCII_IDENTS, + sp, + fluent::lint::identifier_non_ascii_char, + |lint| lint, + ); if check_uncommon_codepoints && !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed) { - cx.struct_span_lint(UNCOMMON_CODEPOINTS, sp, |lint| { - lint.build(fluent::lint::identifier_uncommon_codepoints).emit(); - }) + cx.struct_span_lint( + UNCOMMON_CODEPOINTS, + sp, + fluent::lint::identifier_uncommon_codepoints, + |lint| lint, + ) } } @@ -216,13 +222,16 @@ impl EarlyLintPass for NonAsciiIdents { .entry(skeleton_sym) .and_modify(|(existing_symbol, existing_span, existing_is_ascii)| { if !*existing_is_ascii || !is_ascii { - cx.struct_span_lint(CONFUSABLE_IDENTS, sp, |lint| { - lint.build(fluent::lint::confusable_identifier_pair) - .set_arg("existing_sym", *existing_symbol) - .set_arg("sym", symbol) - .span_label(*existing_span, fluent::lint::label) - .emit(); - }); + cx.struct_span_lint( + CONFUSABLE_IDENTS, + sp, + fluent::lint::confusable_identifier_pair, + |lint| { + lint.set_arg("existing_sym", *existing_symbol) + .set_arg("sym", symbol) + .span_label(*existing_span, fluent::lint::label) + }, + ); } if *existing_is_ascii && !is_ascii { *existing_symbol = symbol; @@ -322,22 +331,25 @@ impl EarlyLintPass for NonAsciiIdents { } for ((sp, ch_list), script_set) in lint_reports { - cx.struct_span_lint(MIXED_SCRIPT_CONFUSABLES, sp, |lint| { - let mut includes = String::new(); - for (idx, ch) in ch_list.into_iter().enumerate() { - if idx != 0 { - includes += ", "; + cx.struct_span_lint( + MIXED_SCRIPT_CONFUSABLES, + sp, + fluent::lint::mixed_script_confusables, + |lint| { + let mut includes = String::new(); + for (idx, ch) in ch_list.into_iter().enumerate() { + if idx != 0 { + includes += ", "; + } + let char_info = format!("'{}' (U+{:04X})", ch, ch as u32); + includes += &char_info; } - let char_info = format!("'{}' (U+{:04X})", ch, ch as u32); - includes += &char_info; - } - lint.build(fluent::lint::mixed_script_confusables) - .set_arg("set", script_set.to_string()) - .set_arg("includes", includes) - .note(fluent::lint::includes_note) - .note(fluent::lint::note) - .emit(); - }); + lint.set_arg("set", script_set.to_string()) + .set_arg("includes", includes) + .note(fluent::lint::includes_note) + .note(fluent::lint::note) + }, + ); } } } diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index cdad2d2e8f9..9d2a23f2b5f 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -119,21 +119,19 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc arg_span = expn.call_site; } - cx.struct_span_lint(NON_FMT_PANICS, arg_span, |lint| { - let mut l = lint.build(fluent::lint::non_fmt_panic); - l.set_arg("name", symbol); - l.note(fluent::lint::note); - l.note(fluent::lint::more_info_note); + cx.struct_span_lint(NON_FMT_PANICS, arg_span, fluent::lint::non_fmt_panic, |lint| { + lint.set_arg("name", symbol); + lint.note(fluent::lint::note); + lint.note(fluent::lint::more_info_note); if !is_arg_inside_call(arg_span, span) { // No clue where this argument is coming from. - l.emit(); - return; + return lint; } if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) { // A case of `panic!(format!(..))`. - l.note(fluent::lint::supports_fmt_note); + lint.note(fluent::lint::supports_fmt_note); if let Some((open, close, _)) = find_delimiters(cx, arg_span) { - l.multipart_suggestion( + lint.multipart_suggestion( fluent::lint::supports_fmt_suggestion, vec![ (arg_span.until(open.shrink_to_hi()), "".into()), @@ -180,15 +178,15 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc }; if suggest_display { - l.span_suggestion_verbose( + lint.span_suggestion_verbose( arg_span.shrink_to_lo(), fluent::lint::display_suggestion, "\"{}\", ", fmt_applicability, ); } else if suggest_debug { - l.set_arg("ty", ty); - l.span_suggestion_verbose( + lint.set_arg("ty", ty); + lint.span_suggestion_verbose( arg_span.shrink_to_lo(), fluent::lint::debug_suggestion, "\"{:?}\", ", @@ -198,8 +196,8 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc if suggest_panic_any { if let Some((open, close, del)) = find_delimiters(cx, span) { - l.set_arg("already_suggested", suggest_display || suggest_debug); - l.multipart_suggestion( + lint.set_arg("already_suggested", suggest_display || suggest_debug); + lint.multipart_suggestion( fluent::lint::panic_suggestion, if del == '(' { vec![(span.until(open), "std::panic::panic_any".into())] @@ -214,7 +212,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc } } } - l.emit(); + lint }); } @@ -258,26 +256,30 @@ fn check_panic_str<'tcx>( .map(|span| fmt_span.from_inner(InnerSpan::new(span.start, span.end))) .collect(), }; - cx.struct_span_lint(NON_FMT_PANICS, arg_spans, |lint| { - let mut l = lint.build(fluent::lint::non_fmt_panic_unused); - l.set_arg("count", n_arguments); - l.note(fluent::lint::note); - if is_arg_inside_call(arg.span, span) { - l.span_suggestion( - arg.span.shrink_to_hi(), - fluent::lint::add_args_suggestion, - ", ...", - Applicability::HasPlaceholders, - ); - l.span_suggestion( - arg.span.shrink_to_lo(), - fluent::lint::add_fmt_suggestion, - "\"{}\", ", - Applicability::MachineApplicable, - ); - } - l.emit(); - }); + cx.struct_span_lint( + NON_FMT_PANICS, + arg_spans, + fluent::lint::non_fmt_panic_unused, + |lint| { + lint.set_arg("count", n_arguments); + lint.note(fluent::lint::note); + if is_arg_inside_call(arg.span, span) { + lint.span_suggestion( + arg.span.shrink_to_hi(), + fluent::lint::add_args_suggestion, + ", ...", + Applicability::HasPlaceholders, + ); + lint.span_suggestion( + arg.span.shrink_to_lo(), + fluent::lint::add_fmt_suggestion, + "\"{}\", ", + Applicability::MachineApplicable, + ); + } + lint + }, + ); } else { let brace_spans: Option<Vec<_>> = snippet.filter(|s| s.starts_with('"') || s.starts_with("r#")).map(|s| { @@ -287,20 +289,24 @@ fn check_panic_str<'tcx>( .collect() }); let count = brace_spans.as_ref().map(|v| v.len()).unwrap_or(/* any number >1 */ 2); - cx.struct_span_lint(NON_FMT_PANICS, brace_spans.unwrap_or_else(|| vec![span]), |lint| { - let mut l = lint.build(fluent::lint::non_fmt_panic_braces); - l.set_arg("count", count); - l.note(fluent::lint::note); - if is_arg_inside_call(arg.span, span) { - l.span_suggestion( - arg.span.shrink_to_lo(), - fluent::lint::suggestion, - "\"{}\", ", - Applicability::MachineApplicable, - ); - } - l.emit(); - }); + cx.struct_span_lint( + NON_FMT_PANICS, + brace_spans.unwrap_or_else(|| vec![span]), + fluent::lint::non_fmt_panic_braces, + |lint| { + lint.set_arg("count", count); + lint.note(fluent::lint::note); + if is_arg_inside_call(arg.span, span) { + lint.span_suggestion( + arg.span.shrink_to_lo(), + fluent::lint::suggestion, + "\"{}\", ", + Applicability::MachineApplicable, + ); + } + lint + }, + ); } } diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs index 768ad84838b..9f800e9c8c9 100644 --- a/compiler/rustc_lint/src/nonstandard_style.rs +++ b/compiler/rustc_lint/src/nonstandard_style.rs @@ -136,26 +136,30 @@ impl NonCamelCaseTypes { let name = ident.name.as_str(); if !is_camel_case(name) { - cx.struct_span_lint(NON_CAMEL_CASE_TYPES, ident.span, |lint| { - let mut err = lint.build(fluent::lint::non_camel_case_type); - let cc = to_camel_case(name); - // We cannot provide meaningful suggestions - // if the characters are in the category of "Lowercase Letter". - if *name != cc { - err.span_suggestion( - ident.span, - fluent::lint::suggestion, - to_camel_case(name), - Applicability::MaybeIncorrect, - ); - } else { - err.span_label(ident.span, fluent::lint::label); - } + cx.struct_span_lint( + NON_CAMEL_CASE_TYPES, + ident.span, + fluent::lint::non_camel_case_type, + |lint| { + let cc = to_camel_case(name); + // We cannot provide meaningful suggestions + // if the characters are in the category of "Lowercase Letter". + if *name != cc { + lint.span_suggestion( + ident.span, + fluent::lint::suggestion, + to_camel_case(name), + Applicability::MaybeIncorrect, + ); + } else { + lint.span_label(ident.span, fluent::lint::label); + } - err.set_arg("sort", sort); - err.set_arg("name", name); - err.emit(); - }) + lint.set_arg("sort", sort); + lint.set_arg("name", name); + lint + }, + ) } } } @@ -280,9 +284,8 @@ impl NonSnakeCase { let name = ident.name.as_str(); if !is_snake_case(name) { - cx.struct_span_lint(NON_SNAKE_CASE, ident.span, |lint| { + cx.struct_span_lint(NON_SNAKE_CASE, ident.span, fluent::lint::non_snake_case, |lint| { let sc = NonSnakeCase::to_snake_case(name); - let mut err = lint.build(fluent::lint::non_snake_case); // We cannot provide meaningful suggestions // if the characters are in the category of "Uppercase Letter". if name != sc { @@ -297,30 +300,30 @@ impl NonSnakeCase { if sc_ident.name.can_be_raw() { (fluent::lint::rename_or_convert_suggestion, sc_ident.to_string()) } else { - err.note(fluent::lint::cannot_convert_note); + lint.note(fluent::lint::cannot_convert_note); (fluent::lint::rename_suggestion, String::new()) } } else { (fluent::lint::convert_suggestion, sc.clone()) }; - err.span_suggestion( + lint.span_suggestion( ident.span, message, suggestion, Applicability::MaybeIncorrect, ); } else { - err.help(fluent::lint::help); + lint.help(fluent::lint::help); } } else { - err.span_label(ident.span, fluent::lint::label); + lint.span_label(ident.span, fluent::lint::label); } - err.set_arg("sort", sort); - err.set_arg("name", name); - err.set_arg("sc", sc); - err.emit(); + lint.set_arg("sort", sort); + lint.set_arg("name", name); + lint.set_arg("sc", sc); + lint }); } } @@ -478,26 +481,30 @@ impl NonUpperCaseGlobals { fn check_upper_case(cx: &LateContext<'_>, sort: &str, ident: &Ident) { let name = ident.name.as_str(); if name.chars().any(|c| c.is_lowercase()) { - cx.struct_span_lint(NON_UPPER_CASE_GLOBALS, ident.span, |lint| { - let uc = NonSnakeCase::to_snake_case(&name).to_uppercase(); - let mut err = lint.build(fluent::lint::non_upper_case_global); - // We cannot provide meaningful suggestions - // if the characters are in the category of "Lowercase Letter". - if *name != uc { - err.span_suggestion( - ident.span, - fluent::lint::suggestion, - uc, - Applicability::MaybeIncorrect, - ); - } else { - err.span_label(ident.span, fluent::lint::label); - } + cx.struct_span_lint( + NON_UPPER_CASE_GLOBALS, + ident.span, + fluent::lint::non_upper_case_global, + |lint| { + let uc = NonSnakeCase::to_snake_case(&name).to_uppercase(); + // We cannot provide meaningful suggestions + // if the characters are in the category of "Lowercase Letter". + if *name != uc { + lint.span_suggestion( + ident.span, + fluent::lint::suggestion, + uc, + Applicability::MaybeIncorrect, + ); + } else { + lint.span_label(ident.span, fluent::lint::label); + } - err.set_arg("sort", sort); - err.set_arg("name", name); - err.emit(); - }) + lint.set_arg("sort", sort); + lint.set_arg("name", name); + lint + }, + ) } } } diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs index d1449496d33..9a62afd3caf 100644 --- a/compiler/rustc_lint/src/noop_method_call.rs +++ b/compiler/rustc_lint/src/noop_method_call.rs @@ -1,5 +1,4 @@ use crate::context::LintContext; -use crate::rustc_middle::ty::TypeVisitable; use crate::LateContext; use crate::LateLintPass; use rustc_errors::fluent; @@ -46,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { }; // We only care about method calls corresponding to the `Clone`, `Deref` and `Borrow` // traits and ignore any other method call. - let (trait_id, did) = match cx.typeck_results().type_dependent_def(expr.hir_id) { + let did = match cx.typeck_results().type_dependent_def(expr.hir_id) { // Verify we are dealing with a method/associated function. Some((DefKind::AssocFn, did)) => match cx.tcx.trait_of_item(did) { // Check that we're dealing with a trait method for one of the traits we care about. @@ -56,21 +55,17 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { Some(sym::Borrow | sym::Clone | sym::Deref) ) => { - (trait_id, did) + did } _ => return, }, _ => return, }; - let substs = cx.typeck_results().node_substs(expr.hir_id); - if substs.needs_subst() { - // We can't resolve on types that require monomorphization, so we don't handle them if - // we need to perform substitution. - return; - } - let param_env = cx.tcx.param_env(trait_id); + let substs = cx + .tcx + .normalize_erasing_regions(cx.param_env, cx.typeck_results().node_substs(expr.hir_id)); // Resolve the trait method instance. - let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, param_env, did, substs) else { + let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, substs) else { return }; // (Re)check that it implements the noop diagnostic. @@ -90,13 +85,11 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall { } let expr_span = expr.span; let span = expr_span.with_lo(receiver.span.hi()); - cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| { - lint.build(fluent::lint::noop_method_call) - .set_arg("method", call.ident.name) + cx.struct_span_lint(NOOP_METHOD_CALL, span, fluent::lint::noop_method_call, |lint| { + lint.set_arg("method", call.ident.name) .set_arg("receiver_ty", receiver_ty) .span_label(span, fluent::lint::label) .note(fluent::lint::note) - .emit(); }); } } diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs new file mode 100644 index 00000000000..d8ce20db37c --- /dev/null +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -0,0 +1,156 @@ +use rustc_hir as hir; +use rustc_infer::infer::TyCtxtInferExt; +use rustc_macros::LintDiagnostic; +use rustc_middle::ty::{self, fold::BottomUpFolder, Ty, TypeFoldable}; +use rustc_span::Span; +use rustc_trait_selection::traits; +use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; + +use crate::{LateContext, LateLintPass, LintContext}; + +declare_lint! { + /// The `opaque_hidden_inferred_bound` lint detects cases in which nested + /// `impl Trait` in associated type bounds are not written generally enough + /// to satisfy the bounds of the associated type. + /// + /// ### Explanation + /// + /// This functionality was removed in #97346, but then rolled back in #99860 + /// because it caused regressions. + /// + /// We plan on reintroducing this as a hard error, but in the mean time, + /// this lint serves to warn and suggest fixes for any use-cases which rely + /// on this behavior. + /// + /// ### Example + /// + /// ``` + /// trait Trait { + /// type Assoc: Send; + /// } + /// + /// struct Struct; + /// + /// impl Trait for Struct { + /// type Assoc = i32; + /// } + /// + /// fn test() -> impl Trait<Assoc = impl Sized> { + /// Struct + /// } + /// ``` + /// + /// {{produces}} + /// + /// In this example, `test` declares that the associated type `Assoc` for + /// `impl Trait` is `impl Sized`, which does not satisfy the `Send` bound + /// on the associated type. + /// + /// Although the hidden type, `i32` does satisfy this bound, we do not + /// consider the return type to be well-formed with this lint. It can be + /// fixed by changing `impl Sized` into `impl Sized + Send`. + pub OPAQUE_HIDDEN_INFERRED_BOUND, + Warn, + "detects the use of nested `impl Trait` types in associated type bounds that are not general enough" +} + +declare_lint_pass!(OpaqueHiddenInferredBound => [OPAQUE_HIDDEN_INFERRED_BOUND]); + +impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { + let hir::ItemKind::OpaqueTy(_) = &item.kind else { return; }; + let def_id = item.def_id.def_id.to_def_id(); + cx.tcx.infer_ctxt().enter(|ref infcx| { + // For every projection predicate in the opaque type's explicit bounds, + // check that the type that we're assigning actually satisfies the bounds + // of the associated type. + for &(pred, pred_span) in cx.tcx.explicit_item_bounds(def_id) { + // Liberate bound regions in the predicate since we + // don't actually care about lifetimes in this check. + let predicate = cx.tcx.liberate_late_bound_regions( + def_id, + pred.kind(), + ); + let ty::PredicateKind::Projection(proj) = predicate else { + continue; + }; + // Only check types, since those are the only things that may + // have opaques in them anyways. + let Some(proj_term) = proj.term.ty() else { continue }; + + let proj_ty = + cx + .tcx + .mk_projection(proj.projection_ty.item_def_id, proj.projection_ty.substs); + // For every instance of the projection type in the bounds, + // replace them with the term we're assigning to the associated + // type in our opaque type. + let proj_replacer = &mut BottomUpFolder { + tcx: cx.tcx, + ty_op: |ty| if ty == proj_ty { proj_term } else { ty }, + lt_op: |lt| lt, + ct_op: |ct| ct, + }; + // For example, in `impl Trait<Assoc = impl Send>`, for all of the bounds on `Assoc`, + // e.g. `type Assoc: OtherTrait`, replace `<impl Trait as Trait>::Assoc: OtherTrait` + // with `impl Send: OtherTrait`. + for assoc_pred_and_span in cx + .tcx + .bound_explicit_item_bounds(proj.projection_ty.item_def_id) + .transpose_iter() + { + let assoc_pred_span = assoc_pred_and_span.0.1; + let assoc_pred = assoc_pred_and_span + .map_bound(|(pred, _)| *pred) + .subst(cx.tcx, &proj.projection_ty.substs) + .fold_with(proj_replacer); + let Ok(assoc_pred) = traits::fully_normalize(infcx, traits::ObligationCause::dummy(), cx.param_env, assoc_pred) else { + continue; + }; + // If that predicate doesn't hold modulo regions (but passed during type-check), + // then we must've taken advantage of the hack in `project_and_unify_types` where + // we replace opaques with inference vars. Emit a warning! + if !infcx.predicate_must_hold_modulo_regions(&traits::Obligation::new( + traits::ObligationCause::dummy(), + cx.param_env, + assoc_pred, + )) { + // If it's a trait bound and an opaque that doesn't satisfy it, + // then we can emit a suggestion to add the bound. + let (suggestion, suggest_span) = + match (proj_term.kind(), assoc_pred.kind().skip_binder()) { + (ty::Opaque(def_id, _), ty::PredicateKind::Trait(trait_pred)) => ( + format!(" + {}", trait_pred.print_modifiers_and_trait_path()), + Some(cx.tcx.def_span(def_id).shrink_to_hi()), + ), + _ => (String::new(), None), + }; + cx.emit_spanned_lint( + OPAQUE_HIDDEN_INFERRED_BOUND, + pred_span, + OpaqueHiddenInferredBoundLint { + ty: cx.tcx.mk_opaque(def_id, ty::InternalSubsts::identity_for_item(cx.tcx, def_id)), + proj_ty: proj_term, + assoc_pred_span, + suggestion, + suggest_span, + }, + ); + } + } + } + }); + } +} + +#[derive(LintDiagnostic)] +#[diag(lint::opaque_hidden_inferred_bound)] +struct OpaqueHiddenInferredBoundLint<'tcx> { + ty: Ty<'tcx>, + proj_ty: Ty<'tcx>, + #[label(lint::specifically)] + assoc_pred_span: Span, + #[suggestion_verbose(applicability = "machine-applicable", code = "{suggestion}")] + suggest_span: Option<Span>, + suggestion: String, +} diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index af5e5faf1f5..349399b5964 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -29,18 +29,20 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue { } } if let Some(t) = path_for_pass_by_value(cx, &inner_ty) { - cx.struct_span_lint(PASS_BY_VALUE, ty.span, |lint| { - lint.build(fluent::lint::pass_by_value) - .set_arg("ty", t.clone()) - .span_suggestion( + cx.struct_span_lint( + PASS_BY_VALUE, + ty.span, + fluent::lint::pass_by_value, + |lint| { + lint.set_arg("ty", t.clone()).span_suggestion( ty.span, fluent::lint::suggestion, t, // Changing type of function argument Applicability::MaybeIncorrect, ) - .emit(); - }) + }, + ) } } _ => {} @@ -56,7 +58,7 @@ fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option<Stri let path_segment = path.segments.last().unwrap(); return Some(format!("{}{}", name, gen_args(cx, path_segment))); } - Res::SelfTy { trait_: None, alias_to: Some((did, _)) } => { + Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { if let ty::Adt(adt, substs) = cx.tcx.type_of(did).kind() { if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) { return Some(cx.tcx.def_path_str_with_substs(adt.did(), substs)); diff --git a/compiler/rustc_lint/src/redundant_semicolon.rs b/compiler/rustc_lint/src/redundant_semicolon.rs index 26f41345383..46c84550e9f 100644 --- a/compiler/rustc_lint/src/redundant_semicolon.rs +++ b/compiler/rustc_lint/src/redundant_semicolon.rs @@ -48,11 +48,18 @@ fn maybe_lint_redundant_semis(cx: &EarlyContext<'_>, seq: &mut Option<(Span, boo return; } - cx.struct_span_lint(REDUNDANT_SEMICOLONS, span, |lint| { - lint.build(fluent::lint::redundant_semicolons) - .set_arg("multiple", multiple) - .span_suggestion(span, fluent::lint::suggestion, "", Applicability::MaybeIncorrect) - .emit(); - }); + cx.struct_span_lint( + REDUNDANT_SEMICOLONS, + span, + fluent::lint::redundant_semicolons, + |lint| { + lint.set_arg("multiple", multiple).span_suggestion( + span, + fluent::lint::suggestion, + "", + Applicability::MaybeIncorrect, + ) + }, + ); } } diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index df1587c5948..078465bdce6 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -100,15 +100,18 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { if trait_predicate.trait_ref.self_ty().is_impl_trait() { continue; } - cx.struct_span_lint(DROP_BOUNDS, span, |lint| { - let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { - return - }; - lint.build(fluent::lint::drop_trait_constraints) - .set_arg("predicate", predicate) - .set_arg("needs_drop", cx.tcx.def_path_str(needs_drop)) - .emit(); - }); + let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { + continue; + }; + cx.struct_span_lint( + DROP_BOUNDS, + span, + fluent::lint::drop_trait_constraints, + |lint| { + lint.set_arg("predicate", predicate) + .set_arg("needs_drop", cx.tcx.def_path_str(needs_drop)) + }, + ); } } } @@ -119,14 +122,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { }; for bound in &bounds[..] { let def_id = bound.trait_ref.trait_def_id(); - if cx.tcx.lang_items().drop_trait() == def_id { - cx.struct_span_lint(DYN_DROP, bound.span, |lint| { - let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { - return - }; - lint.build(fluent::lint::drop_glue) - .set_arg("needs_drop", cx.tcx.def_path_str(needs_drop)) - .emit(); + if cx.tcx.lang_items().drop_trait() == def_id + && let Some(needs_drop) = cx.tcx.get_diagnostic_item(sym::needs_drop) + { + cx.struct_span_lint(DYN_DROP, bound.span, fluent::lint::drop_glue, |lint| { + lint.set_arg("needs_drop", cx.tcx.def_path_str(needs_drop)) }); } } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 4fb6d65a6e9..b6009bd800a 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -144,12 +144,18 @@ fn lint_overflowing_range_endpoint<'tcx>( // We can suggest using an inclusive range // (`..=`) instead only if it is the `end` that is // overflowing and only by 1. - if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max { - cx.struct_span_lint(OVERFLOWING_LITERALS, struct_expr.span, |lint| { - let mut err = lint.build(fluent::lint::range_endpoint_out_of_range); - err.set_arg("ty", ty); - if let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) { + if eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max + && let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) + { + cx.struct_span_lint( + OVERFLOWING_LITERALS, + struct_expr.span, + fluent::lint::range_endpoint_out_of_range, + |lint| { use ast::{LitIntType, LitKind}; + + lint.set_arg("ty", ty); + // We need to preserve the literal's suffix, // as it may determine typing information. let suffix = match lit.node { @@ -159,16 +165,17 @@ fn lint_overflowing_range_endpoint<'tcx>( _ => bug!(), }; let suggestion = format!("{}..={}{}", start, lit_val - 1, suffix); - err.span_suggestion( + lint.span_suggestion( struct_expr.span, fluent::lint::suggestion, suggestion, Applicability::MachineApplicable, ); - err.emit(); overwritten = true; - } - }); + + lint + }, + ); } overwritten } @@ -221,52 +228,58 @@ fn report_bin_hex_error( negative: bool, ) { let size = Integer::from_attr(&cx.tcx, ty).size(); - cx.struct_span_lint(OVERFLOWING_LITERALS, expr.span, |lint| { - let (t, actually) = match ty { - attr::IntType::SignedInt(t) => { - let actually = if negative { - -(size.sign_extend(val) as i128) - } else { - size.sign_extend(val) as i128 - }; - (t.name_str(), actually.to_string()) - } - attr::IntType::UnsignedInt(t) => { - let actually = size.truncate(val); - (t.name_str(), actually.to_string()) - } - }; - let mut err = lint.build(fluent::lint::overflowing_bin_hex); - if negative { - // If the value is negative, - // emits a note about the value itself, apart from the literal. - err.note(fluent::lint::negative_note); - err.note(fluent::lint::negative_becomes_note); - } else { - err.note(fluent::lint::positive_note); - } - if let Some(sugg_ty) = - get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative) - { - err.set_arg("suggestion_ty", sugg_ty); - if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') { - let (sans_suffix, _) = repr_str.split_at(pos); - err.span_suggestion( - expr.span, - fluent::lint::suggestion, - format!("{}{}", sans_suffix, sugg_ty), - Applicability::MachineApplicable, - ); + cx.struct_span_lint( + OVERFLOWING_LITERALS, + expr.span, + fluent::lint::overflowing_bin_hex, + |lint| { + let (t, actually) = match ty { + attr::IntType::SignedInt(t) => { + let actually = if negative { + -(size.sign_extend(val) as i128) + } else { + size.sign_extend(val) as i128 + }; + (t.name_str(), actually.to_string()) + } + attr::IntType::UnsignedInt(t) => { + let actually = size.truncate(val); + (t.name_str(), actually.to_string()) + } + }; + + if negative { + // If the value is negative, + // emits a note about the value itself, apart from the literal. + lint.note(fluent::lint::negative_note); + lint.note(fluent::lint::negative_becomes_note); } else { - err.help(fluent::lint::help); + lint.note(fluent::lint::positive_note); } - } - err.set_arg("ty", t); - err.set_arg("lit", repr_str); - err.set_arg("dec", val); - err.set_arg("actually", actually); - err.emit(); - }); + if let Some(sugg_ty) = + get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative) + { + lint.set_arg("suggestion_ty", sugg_ty); + if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') { + let (sans_suffix, _) = repr_str.split_at(pos); + lint.span_suggestion( + expr.span, + fluent::lint::suggestion, + format!("{}{}", sans_suffix, sugg_ty), + Applicability::MachineApplicable, + ); + } else { + lint.help(fluent::lint::help); + } + } + lint.set_arg("ty", t) + .set_arg("lit", repr_str) + .set_arg("dec", val) + .set_arg("actually", actually); + + lint + }, + ); } // This function finds the next fitting type and generates a suggestion string. @@ -349,26 +362,27 @@ fn lint_int_literal<'tcx>( return; } - cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { - let mut err = lint.build(fluent::lint::overflowing_int); - err.set_arg("ty", t.name_str()); - err.set_arg( - "lit", - cx.sess() - .source_map() - .span_to_snippet(lit.span) - .expect("must get snippet from literal"), - ); - err.set_arg("min", min); - err.set_arg("max", max); - err.note(fluent::lint::note); + cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, fluent::lint::overflowing_int, |lint| { + lint.set_arg("ty", t.name_str()) + .set_arg( + "lit", + cx.sess() + .source_map() + .span_to_snippet(lit.span) + .expect("must get snippet from literal"), + ) + .set_arg("min", min) + .set_arg("max", max) + .note(fluent::lint::note); + if let Some(sugg_ty) = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative) { - err.set_arg("suggestion_ty", sugg_ty); - err.help(fluent::lint::help); + lint.set_arg("suggestion_ty", sugg_ty); + lint.help(fluent::lint::help); } - err.emit(); + + lint }); } } @@ -393,16 +407,19 @@ fn lint_uint_literal<'tcx>( match par_e.kind { hir::ExprKind::Cast(..) => { if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() { - cx.struct_span_lint(OVERFLOWING_LITERALS, par_e.span, |lint| { - lint.build(fluent::lint::only_cast_u8_to_char) - .span_suggestion( + cx.struct_span_lint( + OVERFLOWING_LITERALS, + par_e.span, + fluent::lint::only_cast_u8_to_char, + |lint| { + lint.span_suggestion( par_e.span, fluent::lint::suggestion, format!("'\\u{{{:X}}}'", lit_val), Applicability::MachineApplicable, ) - .emit(); - }); + }, + ); return; } } @@ -424,9 +441,8 @@ fn lint_uint_literal<'tcx>( ); return; } - cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { - lint.build(fluent::lint::overflowing_uint) - .set_arg("ty", t.name_str()) + cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, fluent::lint::overflowing_uint, |lint| { + lint.set_arg("ty", t.name_str()) .set_arg( "lit", cx.sess() @@ -437,7 +453,6 @@ fn lint_uint_literal<'tcx>( .set_arg("min", min) .set_arg("max", max) .note(fluent::lint::note) - .emit(); }); } } @@ -467,19 +482,22 @@ fn lint_literal<'tcx>( _ => bug!(), }; if is_infinite == Ok(true) { - cx.struct_span_lint(OVERFLOWING_LITERALS, e.span, |lint| { - lint.build(fluent::lint::overflowing_literal) - .set_arg("ty", t.name_str()) - .set_arg( - "lit", - cx.sess() - .source_map() - .span_to_snippet(lit.span) - .expect("must get snippet from literal"), - ) - .note(fluent::lint::note) - .emit(); - }); + cx.struct_span_lint( + OVERFLOWING_LITERALS, + e.span, + fluent::lint::overflowing_literal, + |lint| { + lint.set_arg("ty", t.name_str()) + .set_arg( + "lit", + cx.sess() + .source_map() + .span_to_snippet(lit.span) + .expect("must get snippet from literal"), + ) + .note(fluent::lint::note) + }, + ); } } _ => {} @@ -497,9 +515,12 @@ impl<'tcx> LateLintPass<'tcx> for TypeLimits { } hir::ExprKind::Binary(binop, ref l, ref r) => { if is_comparison(binop) && !check_limits(cx, binop, &l, &r) { - cx.struct_span_lint(UNUSED_COMPARISONS, e.span, |lint| { - lint.build(fluent::lint::unused_comparisons).emit(); - }); + cx.struct_span_lint( + UNUSED_COMPARISONS, + e.span, + fluent::lint::unused_comparisons, + |lint| lint, + ); } } hir::ExprKind::Lit(ref lit) => lint_literal(cx, self, e, lit), @@ -1150,25 +1171,24 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { CItemKind::Definition => IMPROPER_CTYPES_DEFINITIONS, }; - self.cx.struct_span_lint(lint, sp, |lint| { + self.cx.struct_span_lint(lint, sp, fluent::lint::improper_ctypes, |lint| { let item_description = match self.mode { CItemKind::Declaration => "block", CItemKind::Definition => "fn", }; - let mut diag = lint.build(fluent::lint::improper_ctypes); - diag.set_arg("ty", ty); - diag.set_arg("desc", item_description); - diag.span_label(sp, fluent::lint::label); + lint.set_arg("ty", ty); + lint.set_arg("desc", item_description); + lint.span_label(sp, fluent::lint::label); if let Some(help) = help { - diag.help(help); + lint.help(help); } - diag.note(note); + lint.note(note); if let ty::Adt(def, _) = ty.kind() { if let Some(sp) = self.cx.tcx.hir().span_if_local(def.did()) { - diag.span_note(sp, fluent::lint::note); + lint.span_note(sp, fluent::lint::note); } } - diag.emit(); + lint }); } @@ -1381,11 +1401,8 @@ impl<'tcx> LateLintPass<'tcx> for VariantSizeDifferences { cx.struct_span_lint( VARIANT_SIZE_DIFFERENCES, enum_definition.variants[largest_index].span, - |lint| { - lint.build(fluent::lint::variant_size_differences) - .set_arg("largest", largest) - .emit(); - }, + fluent::lint::variant_size_differences, + |lint| lint.set_arg("largest", largest), ); } } @@ -1493,25 +1510,16 @@ impl InvalidAtomicOrdering { fn check_atomic_load_store(cx: &LateContext<'_>, expr: &Expr<'_>) { if let Some((method, args)) = Self::inherent_atomic_method_call(cx, expr, &[sym::load, sym::store]) - && let Some((ordering_arg, invalid_ordering)) = match method { - sym::load => Some((&args[0], sym::Release)), - sym::store => Some((&args[1], sym::Acquire)), + && let Some((ordering_arg, invalid_ordering, msg)) = match method { + sym::load => Some((&args[0], sym::Release, fluent::lint::atomic_ordering_load)), + sym::store => Some((&args[1], sym::Acquire, fluent::lint::atomic_ordering_store)), _ => None, } && let Some(ordering) = Self::match_ordering(cx, ordering_arg) && (ordering == invalid_ordering || ordering == sym::AcqRel) { - cx.struct_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, |diag| { - if method == sym::load { - diag.build(fluent::lint::atomic_ordering_load) - .help(fluent::lint::help) - .emit() - } else { - debug_assert_eq!(method, sym::store); - diag.build(fluent::lint::atomic_ordering_store) - .help(fluent::lint::help) - .emit(); - } + cx.struct_span_lint(INVALID_ATOMIC_ORDERING, ordering_arg.span, msg, |lint| { + lint.help(fluent::lint::help) }); } } @@ -1523,10 +1531,9 @@ impl InvalidAtomicOrdering { && matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::fence | sym::compiler_fence)) && Self::match_ordering(cx, &args[0]) == Some(sym::Relaxed) { - cx.struct_span_lint(INVALID_ATOMIC_ORDERING, args[0].span, |diag| { - diag.build(fluent::lint::atomic_ordering_fence) + cx.struct_span_lint(INVALID_ATOMIC_ORDERING, args[0].span, fluent::lint::atomic_ordering_fence, |lint| { + lint .help(fluent::lint::help) - .emit(); }); } } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 3d426ecbfcb..787c9518b50 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -154,9 +154,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { }; if let Some(must_use_op) = must_use_op { - cx.struct_span_lint(UNUSED_MUST_USE, expr.span, |lint| { - lint.build(fluent::lint::unused_op) - .set_arg("op", must_use_op) + cx.struct_span_lint(UNUSED_MUST_USE, expr.span, fluent::lint::unused_op, |lint| { + lint.set_arg("op", must_use_op) .span_label(expr.span, fluent::lint::label) .span_suggestion_verbose( expr.span.shrink_to_lo(), @@ -164,14 +163,13 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { "let _ = ", Applicability::MachineApplicable, ) - .emit(); }); op_warned = true; } if !(type_permits_lack_of_use || fn_warned || op_warned) { - cx.struct_span_lint(UNUSED_RESULTS, s.span, |lint| { - lint.build(fluent::lint::unused_result).set_arg("ty", ty).emit(); + cx.struct_span_lint(UNUSED_RESULTS, s.span, fluent::lint::unused_result, |lint| { + lint.set_arg("ty", ty) }); } @@ -267,29 +265,35 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } }, ty::Closure(..) => { - cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| { - // FIXME(davidtwco): this isn't properly translatable because of the - // pre/post strings - lint.build(fluent::lint::unused_closure) - .set_arg("count", plural_len) - .set_arg("pre", descr_pre) - .set_arg("post", descr_post) - .note(fluent::lint::note) - .emit(); - }); + cx.struct_span_lint( + UNUSED_MUST_USE, + span, + fluent::lint::unused_closure, + |lint| { + // FIXME(davidtwco): this isn't properly translatable because of the + // pre/post strings + lint.set_arg("count", plural_len) + .set_arg("pre", descr_pre) + .set_arg("post", descr_post) + .note(fluent::lint::note) + }, + ); true } ty::Generator(..) => { - cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| { - // FIXME(davidtwco): this isn't properly translatable because of the - // pre/post strings - lint.build(fluent::lint::unused_generator) - .set_arg("count", plural_len) - .set_arg("pre", descr_pre) - .set_arg("post", descr_post) - .note(fluent::lint::note) - .emit(); - }); + cx.struct_span_lint( + UNUSED_MUST_USE, + span, + fluent::lint::unused_generator, + |lint| { + // FIXME(davidtwco): this isn't properly translatable because of the + // pre/post strings + lint.set_arg("count", plural_len) + .set_arg("pre", descr_pre) + .set_arg("post", descr_post) + .note(fluent::lint::note) + }, + ); true } _ => false, @@ -309,18 +313,17 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { descr_post_path: &str, ) -> bool { if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) { - cx.struct_span_lint(UNUSED_MUST_USE, span, |lint| { + cx.struct_span_lint(UNUSED_MUST_USE, span, fluent::lint::unused_def, |lint| { // FIXME(davidtwco): this isn't properly translatable because of the pre/post // strings - let mut err = lint.build(fluent::lint::unused_def); - err.set_arg("pre", descr_pre_path); - err.set_arg("post", descr_post_path); - err.set_arg("def", cx.tcx.def_path_str(def_id)); + lint.set_arg("pre", descr_pre_path); + lint.set_arg("post", descr_post_path); + lint.set_arg("def", cx.tcx.def_path_str(def_id)); // check for #[must_use = "..."] if let Some(note) = attr.value_str() { - err.note(note.as_str()); + lint.note(note.as_str()); } - err.emit(); + lint }); true } else { @@ -357,25 +360,34 @@ impl<'tcx> LateLintPass<'tcx> for PathStatements { fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) { if let hir::StmtKind::Semi(expr) = s.kind { if let hir::ExprKind::Path(_) = expr.kind { - cx.struct_span_lint(PATH_STATEMENTS, s.span, |lint| { - let ty = cx.typeck_results().expr_ty(expr); - if ty.needs_drop(cx.tcx, cx.param_env) { - let mut lint = lint.build(fluent::lint::path_statement_drop); - if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) { - lint.span_suggestion( - s.span, - fluent::lint::suggestion, - format!("drop({});", snippet), - Applicability::MachineApplicable, - ); - } else { - lint.span_help(s.span, fluent::lint::suggestion); - } - lint.emit(); - } else { - lint.build(fluent::lint::path_statement_no_effect).emit(); - } - }); + let ty = cx.typeck_results().expr_ty(expr); + if ty.needs_drop(cx.tcx, cx.param_env) { + cx.struct_span_lint( + PATH_STATEMENTS, + s.span, + fluent::lint::path_statement_drop, + |lint| { + if let Ok(snippet) = cx.sess().source_map().span_to_snippet(expr.span) { + lint.span_suggestion( + s.span, + fluent::lint::suggestion, + format!("drop({});", snippet), + Applicability::MachineApplicable, + ); + } else { + lint.span_help(s.span, fluent::lint::suggestion); + } + lint + }, + ); + } else { + cx.struct_span_lint( + PATH_STATEMENTS, + s.span, + fluent::lint::path_statement_no_effect, + |lint| lint, + ); + } } } } @@ -545,22 +557,21 @@ trait UnusedDelimLint { } else { MultiSpan::from(value_span) }; - cx.struct_span_lint(self.lint(), primary_span, |lint| { - let mut db = lint.build(fluent::lint::unused_delim); - db.set_arg("delim", Self::DELIM_STR); - db.set_arg("item", msg); + cx.struct_span_lint(self.lint(), primary_span, fluent::lint::unused_delim, |lint| { + lint.set_arg("delim", Self::DELIM_STR); + lint.set_arg("item", msg); if let Some((lo, hi)) = spans { let replacement = vec![ (lo, if keep_space.0 { " ".into() } else { "".into() }), (hi, if keep_space.1 { " ".into() } else { "".into() }), ]; - db.multipart_suggestion( + lint.multipart_suggestion( fluent::lint::suggestion, replacement, Applicability::MachineApplicable, ); } - db.emit(); + lint }); } @@ -1128,9 +1139,12 @@ impl UnusedImportBraces { ast::UseTreeKind::Nested(_) => return, }; - cx.struct_span_lint(UNUSED_IMPORT_BRACES, item.span, |lint| { - lint.build(fluent::lint::unused_import_braces).set_arg("node", node_name).emit(); - }); + cx.struct_span_lint( + UNUSED_IMPORT_BRACES, + item.span, + fluent::lint::unused_import_braces, + |lint| lint.set_arg("node", node_name), + ); } } } @@ -1179,15 +1193,17 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation { for adj in cx.typeck_results().expr_adjustments(e) { if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind { - cx.struct_span_lint(UNUSED_ALLOCATION, e.span, |lint| { - lint.build(match m { + cx.struct_span_lint( + UNUSED_ALLOCATION, + e.span, + match m { adjustment::AutoBorrowMutability::Not => fluent::lint::unused_allocation, adjustment::AutoBorrowMutability::Mut { .. } => { fluent::lint::unused_allocation_mut } - }) - .emit(); - }); + }, + |lint| lint, + ); } } } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 11b2d057a07..cbe7afc8e55 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -92,7 +92,7 @@ pub enum LintExpectationId { /// stable and can be cached. The additional index ensures that nodes with /// several expectations can correctly match diagnostics to the individual /// expectation. - Stable { hir_id: HirId, attr_index: u16, lint_index: Option<u16> }, + Stable { hir_id: HirId, attr_index: u16, lint_index: Option<u16>, attr_id: Option<AttrId> }, } impl LintExpectationId { @@ -116,13 +116,31 @@ impl LintExpectationId { *lint_index = new_lint_index } + + /// Prepares the id for hashing. Removes references to the ast. + /// Should only be called when the id is stable. + pub fn normalize(self) -> Self { + match self { + Self::Stable { hir_id, attr_index, lint_index, .. } => { + Self::Stable { hir_id, attr_index, lint_index, attr_id: None } + } + Self::Unstable { .. } => { + unreachable!("`normalize` called when `ExpectationId` is unstable") + } + } + } } impl<HCX: rustc_hir::HashStableContext> HashStable<HCX> for LintExpectationId { #[inline] fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) { match self { - LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { + LintExpectationId::Stable { + hir_id, + attr_index, + lint_index: Some(lint_index), + attr_id: _, + } => { hir_id.hash_stable(hcx, hasher); attr_index.hash_stable(hcx, hasher); lint_index.hash_stable(hcx, hasher); @@ -142,9 +160,12 @@ impl<HCX: rustc_hir::HashStableContext> ToStableHashKey<HCX> for LintExpectation #[inline] fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType { match self { - LintExpectationId::Stable { hir_id, attr_index, lint_index: Some(lint_index) } => { - (*hir_id, *attr_index, *lint_index) - } + LintExpectationId::Stable { + hir_id, + attr_index, + lint_index: Some(lint_index), + attr_id: _, + } => (*hir_id, *attr_index, *lint_index), _ => { unreachable!("HashStable should only be called for a filled `LintExpectationId`") } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index b9a283552f7..83040a652b1 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -36,7 +36,7 @@ impl<'a> DiagnosticDerive<'a> { span_err(builder.span, "diagnostic slug not specified") .help(&format!( "specify the slug as the first argument to the `#[diag(...)]` \ - attribute, such as `#[diag(typeck::example_error)]`", + attribute, such as `#[diag(hir_analysis::example_error)]`", )) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); @@ -96,38 +96,43 @@ impl<'a> LintDiagnosticDerive<'a> { let body = builder.body(&variant); let diag = &builder.parent.diag; - let init = match builder.slug.value_ref() { + + quote! { + #preamble + #body + #diag + } + }); + + let msg = builder.each_variant(&mut structure, |mut builder, variant| { + // HACK(wafflelapkin): initialize slug (???) + let _preamble = builder.preamble(&variant); + + match builder.slug.value_ref() { None => { span_err(builder.span, "diagnostic slug not specified") .help(&format!( "specify the slug as the first argument to the attribute, such as \ - `#[diag(typeck::example_error)]`", + `#[diag(compiletest::example)]`", )) .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } - Some(slug) => { - quote! { - let mut #diag = #diag.build(rustc_errors::fluent::#slug); - } - } - }; - - quote! { - #init - #preamble - #body - #diag.emit(); + Some(slug) => quote! { rustc_errors::fluent::#slug.into() }, } }); let diag = &builder.diag; structure.gen_impl(quote! { gen impl<'__a> rustc_errors::DecorateLint<'__a, ()> for @Self { - fn decorate_lint(self, #diag: rustc_errors::LintDiagnosticBuilder<'__a, ()>) { + fn decorate_lint<'__b>(self, #diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()>) -> &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()> { use rustc_errors::IntoDiagnosticArg; #implementation } + + fn msg(&self) -> rustc_errors::DiagnosticMessage { + #msg + } } }) } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index dede1b2122a..466da175810 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -223,6 +223,15 @@ provide! { tcx, def_id, other, cdata, fn_arg_names => { table } generator_kind => { table } trait_def => { table } + collect_trait_impl_trait_tys => { + Ok(cdata + .root + .tables + .trait_impl_trait_tys + .get(cdata, def_id.index) + .map(|lazy| lazy.decode((cdata, tcx))) + .process_decoded(tcx, || panic!("{:?} does not have trait_impl_trait_tys", def_id))) + } visibility => { cdata.get_visibility(def_id.index) } adt_def => { cdata.get_adt_def(def_id.index, tcx) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 7cf00ca41fe..1a7a3c65c3b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1059,6 +1059,34 @@ fn should_encode_const(def_kind: DefKind) -> bool { } } +fn should_encode_trait_impl_trait_tys<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { + if tcx.def_kind(def_id) != DefKind::AssocFn { + return false; + } + + let Some(item) = tcx.opt_associated_item(def_id) else { return false; }; + if item.container != ty::AssocItemContainer::ImplContainer { + return false; + } + + let Some(trait_item_def_id) = item.trait_item_def_id else { return false; }; + + // FIXME(RPITIT): This does a somewhat manual walk through the signature + // of the trait fn to look for any RPITITs, but that's kinda doing a lot + // of work. We can probably remove this when we refactor RPITITs to be + // associated types. + tcx.fn_sig(trait_item_def_id).skip_binder().output().walk().any(|arg| { + if let ty::GenericArgKind::Type(ty) = arg.unpack() + && let ty::Projection(data) = ty.kind() + && tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder + { + true + } else { + false + } + }) +} + impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_attrs(&mut self, def_id: LocalDefId) { let mut attrs = self @@ -1128,6 +1156,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if let DefKind::Trait | DefKind::TraitAlias = def_kind { record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id)); } + if should_encode_trait_impl_trait_tys(tcx, def_id) + && let Ok(table) = self.tcx.collect_trait_impl_trait_tys(def_id) + { + record!(self.tables.trait_impl_trait_tys[def_id] <- table); + } } let inherent_impls = tcx.crate_inherent_impls(()); for (def_id, implementations) in inherent_impls.inherent_impls.iter() { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 748b3afec37..6d7345570af 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -1,6 +1,7 @@ use crate::creader::CrateMetadataRef; use decoder::Metadata; use def_path_hash_map::DefPathHashMapRef; +use rustc_data_structures::fx::FxHashMap; use table::TableBuilder; use rustc_ast as ast; @@ -399,6 +400,8 @@ define_tables! { macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>, proc_macro: Table<DefIndex, MacroKind>, module_reexports: Table<DefIndex, LazyArray<ModChild>>, + + trait_impl_trait_tys: Table<DefIndex, LazyValue<FxHashMap<DefId, Ty<'static>>>>, } #[derive(TyEncodable, TyDecodable)] diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index cca17a4eccd..de916ea8c49 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -12,8 +12,6 @@ chalk-ir = "0.80.0" either = "1.5.0" gsgdt = "0.1.2" polonius-engine = "0.13.0" -rand = "0.8.4" -rand_xoshiro = "0.6.0" rustc_apfloat = { path = "../rustc_apfloat" } rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 40b9d73db94..6b556826918 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -62,7 +62,7 @@ use crate::ty::TyCtxt; use rustc_data_structures::fingerprint::Fingerprint; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_hir::definitions::DefPathHash; -use rustc_hir::{HirId, OwnerId}; +use rustc_hir::{HirId, ItemLocalId, OwnerId}; use rustc_query_system::dep_graph::FingerprintStyle; use rustc_span::symbol::Symbol; use std::hash::Hash; @@ -194,7 +194,7 @@ impl DepNodeExt for DepNode { let kind = dep_kind_from_label_string(label)?; match tcx.fingerprint_style(kind) { - FingerprintStyle::Opaque => Err(()), + FingerprintStyle::Opaque | FingerprintStyle::HirId => Err(()), FingerprintStyle::Unit => Ok(DepNode::new_no_params(tcx, kind)), FingerprintStyle::DefPathHash => { Ok(DepNode::from_def_path_hash(tcx, def_path_hash, kind)) @@ -344,7 +344,7 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for (DefId, DefId) { impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId { #[inline(always)] fn fingerprint_style() -> FingerprintStyle { - FingerprintStyle::Opaque + FingerprintStyle::HirId } // We actually would not need to specialize the implementation of this @@ -353,10 +353,36 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId { #[inline(always)] fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint { let HirId { owner, local_id } = *self; - let def_path_hash = tcx.def_path_hash(owner.to_def_id()); - let local_id = Fingerprint::from_smaller_hash(local_id.as_u32().into()); + Fingerprint::new( + // `owner` is local, so is completely defined by the local hash + def_path_hash.local_hash(), + local_id.as_u32().into(), + ) + } - def_path_hash.0.combine(local_id) + #[inline(always)] + fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { + let HirId { owner, local_id } = *self; + format!("{}.{}", tcx.def_path_str(owner.to_def_id()), local_id.as_u32()) + } + + #[inline(always)] + fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> { + if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId { + let (local_hash, local_id) = Fingerprint::from(dep_node.hash).as_value(); + let def_path_hash = DefPathHash::new(tcx.sess.local_stable_crate_id(), local_hash); + let def_id = tcx + .def_path_hash_to_def_id(def_path_hash, &mut || { + panic!("Failed to extract HirId: {:?} {}", dep_node.kind, dep_node.hash) + }) + .expect_local(); + let local_id = local_id + .try_into() + .unwrap_or_else(|_| panic!("local id should be u32, found {:?}", local_id)); + Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) }) + } else { + None + } } } diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index a4ceb494569..e69cb546d15 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -48,3 +48,10 @@ pub struct LimitInvalid<'a> { pub value_span: Span, pub error_str: &'a str, } + +#[derive(Diagnostic)] +#[diag(middle::const_eval_non_int)] +pub struct ConstEvalNonIntError { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index b5f7b26ea7a..b78c3f85596 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -14,7 +14,7 @@ use rustc_index::vec::Idx; use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; #[inline] @@ -61,7 +61,7 @@ pub struct ParentHirIterator<'hir> { } impl<'hir> Iterator for ParentHirIterator<'hir> { - type Item = (HirId, Node<'hir>); + type Item = HirId; fn next(&mut self) -> Option<Self::Item> { if self.current_id == CRATE_HIR_ID { @@ -77,10 +77,7 @@ impl<'hir> Iterator for ParentHirIterator<'hir> { } self.current_id = parent_id; - if let Some(node) = self.map.find(parent_id) { - return Some((parent_id, node)); - } - // If this `HirId` doesn't have an entry, skip it and look for its `parent_id`. + return Some(parent_id); } } } @@ -393,8 +390,8 @@ impl<'hir> Map<'hir> { } pub fn enclosing_body_owner(self, hir_id: HirId) -> LocalDefId { - for (parent, _) in self.parent_iter(hir_id) { - if let Some(body) = self.find(parent).map(associated_body).flatten() { + for (_, node) in self.parent_iter(hir_id) { + if let Some(body) = associated_body(node) { return self.body_owner_def_id(body); } } @@ -635,13 +632,20 @@ impl<'hir> Map<'hir> { /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`. #[inline] - pub fn parent_iter(self, current_id: HirId) -> ParentHirIterator<'hir> { + pub fn parent_id_iter(self, current_id: HirId) -> impl Iterator<Item = HirId> + 'hir { ParentHirIterator { current_id, map: self } } /// Returns an iterator for the nodes in the ancestor tree of the `current_id` /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`. #[inline] + pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> { + self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.find(id)?))) + } + + /// Returns an iterator for the nodes in the ancestor tree of the `current_id` + /// until the crate root is reached. Prefer this over your own loop using `get_parent_node`. + #[inline] pub fn parent_owner_iter(self, current_id: HirId) -> ParentOwnerIterator<'hir> { ParentOwnerIterator { current_id, map: self } } @@ -937,9 +941,19 @@ impl<'hir> Map<'hir> { let span = match self.find(hir_id)? { // Function-like. - Node::Item(Item { kind: ItemKind::Fn(sig, ..), .. }) - | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, ..), .. }) - | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, ..), .. }) => sig.span, + Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. }) + | Node::TraitItem(TraitItem { + kind: TraitItemKind::Fn(sig, ..), + span: outer_span, + .. + }) + | Node::ImplItem(ImplItem { + kind: ImplItemKind::Fn(sig, ..), span: outer_span, .. + }) => { + // Ensure that the returned span has the item's SyntaxContext, and not the + // SyntaxContext of the visibility. + sig.span.find_ancestor_in_same_ctxt(*outer_span).unwrap_or(*outer_span) + } // Constants and Statics. Node::Item(Item { kind: @@ -981,7 +995,11 @@ impl<'hir> Map<'hir> { } // Other cases. Node::Item(item) => match &item.kind { - ItemKind::Use(path, _) => path.span, + ItemKind::Use(path, _) => { + // Ensure that the returned span has the item's SyntaxContext, and not the + // SyntaxContext of the path. + path.span.find_ancestor_in_same_ctxt(item.span).unwrap_or(item.span) + } _ => named_span(item.span, item.ident, item.kind.generics()), }, Node::Variant(variant) => named_span(variant.span, variant.ident, None), @@ -991,11 +1009,17 @@ impl<'hir> Map<'hir> { _ => named_span(item.span, item.ident, None), }, Node::Ctor(_) => return self.opt_span(self.get_parent_node(hir_id)), - Node::Expr(Expr { kind: ExprKind::Closure(Closure { fn_decl_span, .. }), .. }) => { - *fn_decl_span + Node::Expr(Expr { + kind: ExprKind::Closure(Closure { fn_decl_span, .. }), + span, + .. + }) => { + // Ensure that the returned span has the item's SyntaxContext. + fn_decl_span.find_ancestor_in_same_ctxt(*span).unwrap_or(*span) } _ => self.span_with_body(hir_id), }; + debug_assert_eq!(span.ctxt(), self.span_with_body(hir_id).ctxt()); Some(span) } @@ -1131,7 +1155,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { .filter_map(|(def_id, info)| { let _ = info.as_owner()?; let def_path_hash = definitions.def_path_hash(def_id); - let span = resolutions.source_span[def_id]; + let span = resolutions.source_span.get(def_id).unwrap_or(&DUMMY_SP); debug_assert_eq!(span.parent(), None); Some((def_path_hash, span)) }) diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 2f45222de47..d95c5cbd654 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -1,20 +1,20 @@ use std::cmp; use rustc_data_structures::fx::FxHashMap; -use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_errors::{Diagnostic, DiagnosticId, LintDiagnosticBuilder, MultiSpan}; -use rustc_hir::HirId; -use rustc_index::vec::IndexVec; -use rustc_query_system::ich::StableHashingContext; +use rustc_data_structures::sorted_map::SortedMap; +use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, MultiSpan}; +use rustc_hir::{HirId, ItemLocalId}; use rustc_session::lint::{ builtin::{self, FORBIDDEN_LINT_GROUPS}, - FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId, + FutureIncompatibilityReason, Level, Lint, LintId, }; use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::{DesugaringKind, ExpnKind}; use rustc_span::{symbol, Span, Symbol, DUMMY_SP}; +use crate::ty::TyCtxt; + /// How a lint level was set. #[derive(Clone, Copy, PartialEq, Eq, HashStable, Debug)] pub enum LintLevelSource { @@ -23,7 +23,12 @@ pub enum LintLevelSource { Default, /// Lint level was set by an attribute. - Node(Symbol, Span, Option<Symbol> /* RFC 2383 reason */), + Node { + name: Symbol, + span: Span, + /// RFC 2383 reason + reason: Option<Symbol>, + }, /// Lint level was set by a command-line flag. /// The provided `Level` is the level specified on the command line. @@ -35,7 +40,7 @@ impl LintLevelSource { pub fn name(&self) -> Symbol { match *self { LintLevelSource::Default => symbol::kw::Default, - LintLevelSource::Node(name, _, _) => name, + LintLevelSource::Node { name, .. } => name, LintLevelSource::CommandLine(name, _) => name, } } @@ -43,7 +48,7 @@ impl LintLevelSource { pub fn span(&self) -> Span { match *self { LintLevelSource::Default => DUMMY_SP, - LintLevelSource::Node(_, span, _) => span, + LintLevelSource::Node { span, .. } => span, LintLevelSource::CommandLine(_, _) => DUMMY_SP, } } @@ -52,145 +57,137 @@ impl LintLevelSource { /// A tuple of a lint level and its source. pub type LevelAndSource = (Level, LintLevelSource); -#[derive(Debug, HashStable)] -pub struct LintLevelSets { - pub list: IndexVec<LintStackIndex, LintSet>, - pub lint_cap: Level, -} - -rustc_index::newtype_index! { - #[derive(HashStable)] - pub struct LintStackIndex { - const COMMAND_LINE = 0, - } -} - -#[derive(Debug, HashStable)] -pub struct LintSet { - // -A,-W,-D flags, a `Symbol` for the flag itself and `Level` for which - // flag. - pub specs: FxHashMap<LintId, LevelAndSource>, - - pub parent: LintStackIndex, +/// Return type for the `shallow_lint_levels_on` query. +/// +/// This map represents the set of allowed lints and allowance levels given +/// by the attributes for *a single HirId*. +#[derive(Default, Debug, HashStable)] +pub struct ShallowLintLevelMap { + pub specs: SortedMap<ItemLocalId, FxHashMap<LintId, LevelAndSource>>, } -impl LintLevelSets { - pub fn new() -> Self { - LintLevelSets { list: IndexVec::new(), lint_cap: Level::Forbid } - } - - pub fn get_lint_level( - &self, - lint: &'static Lint, - idx: LintStackIndex, - aux: Option<&FxHashMap<LintId, LevelAndSource>>, - sess: &Session, - ) -> LevelAndSource { - let (level, mut src) = self.get_lint_id_level(LintId::of(lint), idx, aux); - - // If `level` is none then we actually assume the default level for this - // lint. - let mut level = level.unwrap_or_else(|| lint.default_level(sess.edition())); - - // If we're about to issue a warning, check at the last minute for any - // directives against the warnings "lint". If, for example, there's an - // `allow(warnings)` in scope then we want to respect that instead. - // - // We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically - // triggers in cases (like #80988) where you have `forbid(warnings)`, - // and so if we turned that into an error, it'd defeat the purpose of the - // future compatibility warning. - if level == Level::Warn && LintId::of(lint) != LintId::of(FORBIDDEN_LINT_GROUPS) { - let (warnings_level, warnings_src) = - self.get_lint_id_level(LintId::of(builtin::WARNINGS), idx, aux); - if let Some(configured_warning_level) = warnings_level { - if configured_warning_level != Level::Warn { - level = configured_warning_level; - src = warnings_src; - } +/// From an initial level and source, verify the effect of special annotations: +/// `warnings` lint level and lint caps. +/// +/// The return of this function is suitable for diagnostics. +pub fn reveal_actual_level( + level: Option<Level>, + src: &mut LintLevelSource, + sess: &Session, + lint: LintId, + probe_for_lint_level: impl FnOnce(LintId) -> (Option<Level>, LintLevelSource), +) -> Level { + // If `level` is none then we actually assume the default level for this lint. + let mut level = level.unwrap_or_else(|| lint.lint.default_level(sess.edition())); + + // If we're about to issue a warning, check at the last minute for any + // directives against the warnings "lint". If, for example, there's an + // `allow(warnings)` in scope then we want to respect that instead. + // + // We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically + // triggers in cases (like #80988) where you have `forbid(warnings)`, + // and so if we turned that into an error, it'd defeat the purpose of the + // future compatibility warning. + if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) { + let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS)); + if let Some(configured_warning_level) = warnings_level { + if configured_warning_level != Level::Warn { + level = configured_warning_level; + *src = warnings_src; } } + } - // Ensure that we never exceed the `--cap-lints` argument - // unless the source is a --force-warn - level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src { - level - } else { - cmp::min(level, self.lint_cap) - }; - - if let Some(driver_level) = sess.driver_lint_caps.get(&LintId::of(lint)) { - // Ensure that we never exceed driver level. - level = cmp::min(*driver_level, level); - } + // Ensure that we never exceed the `--cap-lints` argument unless the source is a --force-warn + level = if let LintLevelSource::CommandLine(_, Level::ForceWarn(_)) = src { + level + } else { + cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid)) + }; - (level, src) + if let Some(driver_level) = sess.driver_lint_caps.get(&lint) { + // Ensure that we never exceed driver level. + level = cmp::min(*driver_level, level); } - pub fn get_lint_id_level( + level +} + +impl ShallowLintLevelMap { + /// Perform a deep probe in the HIR tree looking for the actual level for the lint. + /// This lint level is not usable for diagnostics, it needs to be corrected by + /// `reveal_actual_level` beforehand. + #[instrument(level = "trace", skip(self, tcx), ret)] + fn probe_for_lint_level( &self, + tcx: TyCtxt<'_>, id: LintId, - mut idx: LintStackIndex, - aux: Option<&FxHashMap<LintId, LevelAndSource>>, + start: HirId, ) -> (Option<Level>, LintLevelSource) { - if let Some(specs) = aux { - if let Some(&(level, src)) = specs.get(&id) { - return (Some(level), src); - } + if let Some(map) = self.specs.get(&start.local_id) + && let Some(&(level, src)) = map.get(&id) + { + return (Some(level), src); } - loop { - let LintSet { ref specs, parent } = self.list[idx]; - if let Some(&(level, src)) = specs.get(&id) { - return (Some(level), src); + + let mut owner = start.owner; + let mut specs = &self.specs; + + for parent in tcx.hir().parent_id_iter(start) { + if parent.owner != owner { + owner = parent.owner; + specs = &tcx.shallow_lint_levels_on(owner).specs; } - if idx == COMMAND_LINE { - return (None, LintLevelSource::Default); + if let Some(map) = specs.get(&parent.local_id) + && let Some(&(level, src)) = map.get(&id) + { + return (Some(level), src); } - idx = parent; } - } -} -#[derive(Debug)] -pub struct LintLevelMap { - /// This is a collection of lint expectations as described in RFC 2383, that - /// can be fulfilled during this compilation session. This means that at least - /// one expected lint is currently registered in the lint store. - /// - /// The [`LintExpectationId`] is stored as a part of the [`Expect`](Level::Expect) - /// lint level. - pub lint_expectations: Vec<(LintExpectationId, LintExpectation)>, - pub sets: LintLevelSets, - pub id_to_set: FxHashMap<HirId, LintStackIndex>, -} + (None, LintLevelSource::Default) + } -impl LintLevelMap { - /// If the `id` was previously registered with `register_id` when building - /// this `LintLevelMap` this returns the corresponding lint level and source - /// of the lint level for the lint provided. - /// - /// If the `id` was not previously registered, returns `None`. If `None` is - /// returned then the parent of `id` should be acquired and this function - /// should be called again. - pub fn level_and_source( + /// Fetch and return the user-visible lint level for the given lint at the given HirId. + #[instrument(level = "trace", skip(self, tcx), ret)] + pub fn lint_level_id_at_node( &self, - lint: &'static Lint, - id: HirId, - session: &Session, - ) -> Option<LevelAndSource> { - self.id_to_set.get(&id).map(|idx| self.sets.get_lint_level(lint, *idx, None, session)) + tcx: TyCtxt<'_>, + lint: LintId, + cur: HirId, + ) -> (Level, LintLevelSource) { + let (level, mut src) = self.probe_for_lint_level(tcx, lint, cur); + let level = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| { + self.probe_for_lint_level(tcx, lint, cur) + }); + (level, src) } } -impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap { - #[inline] - fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - let LintLevelMap { ref sets, ref id_to_set, ref lint_expectations } = *self; +impl TyCtxt<'_> { + /// Fetch and return the user-visible lint level for the given lint at the given HirId. + pub fn lint_level_at_node(self, lint: &'static Lint, id: HirId) -> (Level, LintLevelSource) { + self.shallow_lint_levels_on(id.owner).lint_level_id_at_node(self, LintId::of(lint), id) + } - id_to_set.hash_stable(hcx, hasher); - lint_expectations.hash_stable(hcx, hasher); + /// Walks upwards from `id` to find a node which might change lint levels with attributes. + /// It stops at `bound` and just returns it if reached. + pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId { + let hir = self.hir(); + loop { + if id == bound { + return bound; + } - hcx.while_hashing_spans(true, |hcx| sets.hash_stable(hcx, hasher)) + if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) { + return id; + } + let next = hir.get_parent_node(id); + if next == id { + bug!("lint traversal reached the root of the crate"); + } + id = next; + } } } @@ -261,11 +258,11 @@ pub fn explain_lint_level_source( )); } } - LintLevelSource::Node(lint_attr_name, src, reason) => { + LintLevelSource::Node { name: lint_attr_name, span, reason, .. } => { if let Some(rationale) = reason { err.note(rationale.as_str()); } - err.span_note_once(src, "the lint level is defined here"); + err.span_note_once(span, "the lint level is defined here"); if lint_attr_name.as_str() != name { let level_str = level.as_str(); err.note_once(&format!( @@ -277,23 +274,32 @@ pub fn explain_lint_level_source( } } -pub fn struct_lint_level<'s, 'd>( - sess: &'s Session, +pub fn struct_lint_level( + sess: &Session, lint: &'static Lint, level: Level, src: LintLevelSource, span: Option<MultiSpan>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) + 'd, + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to // the "real" work. - fn struct_lint_level_impl<'s, 'd>( - sess: &'s Session, + fn struct_lint_level_impl( + sess: &Session, lint: &'static Lint, level: Level, src: LintLevelSource, span: Option<MultiSpan>, - decorate: Box<dyn for<'b> FnOnce(LintDiagnosticBuilder<'b, ()>) + 'd>, + msg: impl Into<DiagnosticMessage>, + decorate: Box< + dyn '_ + + for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, + >, ) { // Check for future incompatibility lints and issue a stronger warning. let future_incompatible = lint.future_incompatible; @@ -344,6 +350,8 @@ pub fn struct_lint_level<'s, 'd>( (Level::Deny | Level::Forbid, None) => sess.diagnostic().struct_err_lint(""), }; + err.set_is_lint(); + // If this code originates in a foreign macro, aka something that this crate // did not itself author, then it's likely that there's nothing this crate // can do about it. We probably want to skip the lint entirely. @@ -366,6 +374,10 @@ pub fn struct_lint_level<'s, 'd>( } } + // Delay evaluating and setting the primary message until after we've + // suppressed the lint due to macros. + err.set_primary_message(msg); + // Lint diagnostics that are covered by the expect level will not be emitted outside // the compiler. It is therefore not necessary to add any information for the user. // This will therefore directly call the decorate function which will in turn emit @@ -373,12 +385,12 @@ pub fn struct_lint_level<'s, 'd>( if let Level::Expect(_) = level { let name = lint.name_lower(); err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn: false }); - decorate(LintDiagnosticBuilder::new(err)); + + decorate(&mut err); + err.emit(); return; } - explain_lint_level_source(lint, level, src, &mut err); - let name = lint.name_lower(); let is_force_warn = matches!(level, Level::ForceWarn(_)); err.code(DiagnosticId::Lint { name, has_future_breakage, is_force_warn }); @@ -417,10 +429,12 @@ pub fn struct_lint_level<'s, 'd>( } } - // Finally, run `decorate`. This function is also responsible for emitting the diagnostic. - decorate(LintDiagnosticBuilder::new(err)); + // Finally, run `decorate`. + decorate(&mut err); + explain_lint_level_source(lint, level, src, &mut *err); + err.emit() } - struct_lint_level_impl(sess, lint, level, src, span, Box::new(decorate)) + struct_lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate)) } /// Returns whether `span` originates in a foreign crate's external macro. @@ -432,7 +446,9 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool { match expn_data.kind { ExpnKind::Inlined | ExpnKind::Root - | ExpnKind::Desugaring(DesugaringKind::ForLoop | DesugaringKind::WhileLoop) => false, + | ExpnKind::Desugaring( + DesugaringKind::ForLoop | DesugaringKind::WhileLoop | DesugaringKind::OpaqueTy, + ) => false, ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) => true, // well, it's "external" ExpnKind::Macro(MacroKind::Bang, _) => { // Dummy span for the `def_site` means it's an external macro. diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index d182929c400..61bc089e431 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -253,13 +253,12 @@ fn late_report_deprecation( return; } let method_span = method_span.unwrap_or(span); - tcx.struct_span_lint_hir(lint, hir_id, method_span, |lint| { - let mut diag = lint.build(message); + tcx.struct_span_lint_hir(lint, hir_id, method_span, message, |diag| { if let hir::Node::Expr(_) = tcx.hir().get(hir_id) { let kind = tcx.def_kind(def_id).descr(def_id); - deprecation_suggestion(&mut diag, kind, suggestion, method_span); + deprecation_suggestion(diag, kind, suggestion, method_span); } - diag.emit(); + diag }); } @@ -621,9 +620,7 @@ impl<'tcx> TyCtxt<'tcx> { unmarked: impl FnOnce(Span, DefId), ) -> bool { let soft_handler = |lint, span, msg: &_| { - self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| { - lint.build(msg).emit(); - }) + self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |lint| lint) }; let eval_result = self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable); diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 734c31192c7..8f67161420d 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -45,7 +45,7 @@ impl<'tcx> TyCtxt<'tcx> { // // When trying to evaluate constants containing inference variables, // use `Infcx::const_eval_resolve` instead. - if ct.substs.has_infer_types_or_consts() { + if ct.substs.has_non_region_infer() { bug!("did not expect inference variables here"); } @@ -76,7 +76,7 @@ impl<'tcx> TyCtxt<'tcx> { // // When trying to evaluate constants containing inference variables, // use `Infcx::const_eval_resolve` instead. - if ct.substs.has_infer_types_or_consts() { + if ct.substs.has_non_region_infer() { bug!("did not expect inference variables here"); } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 78a16788815..a9ebd783403 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -313,7 +313,7 @@ impl<'tcx> Body<'tcx> { is_polymorphic: false, tainted_by_errors, }; - body.is_polymorphic = body.has_param_types_or_consts(); + body.is_polymorphic = body.has_non_region_param(); body } @@ -339,7 +339,7 @@ impl<'tcx> Body<'tcx> { is_polymorphic: false, tainted_by_errors: None, }; - body.is_polymorphic = body.has_param_types_or_consts(); + body.is_polymorphic = body.has_non_region_param(); body } @@ -2760,7 +2760,7 @@ fn pretty_print_const_value<'tcx>( } // Aggregates, printed as array/tuple/struct/variant construction syntax. // - // NB: the `has_param_types_or_consts` check ensures that we can use + // NB: the `has_non_region_param` check ensures that we can use // the `destructure_const` query with an empty `ty::ParamEnv` without // introducing ICEs (e.g. via `layout_of`) from missing bounds. // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized` @@ -2768,7 +2768,7 @@ fn pretty_print_const_value<'tcx>( // // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the // correct `ty::ParamEnv` to allow printing *all* constant values. - (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => { + (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_non_region_param() => { let ct = tcx.lift(ct).unwrap(); let ty = tcx.lift(ty).unwrap(); if let Some(contents) = tcx.try_destructure_mir_constant( diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index eed44240f83..cf5b365b27c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -274,10 +274,15 @@ rustc_queries! { separate_provide_extern } - query lint_levels(_: ()) -> LintLevelMap { + query shallow_lint_levels_on(key: hir::OwnerId) -> rustc_middle::lint::ShallowLintLevelMap { + eval_always // fetches `resolutions` arena_cache - eval_always - desc { "computing the lint levels for items in this crate" } + desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key.to_def_id()) } + } + + query lint_expectations(_: ()) -> Vec<(LintExpectationId, LintExpectation)> { + arena_cache + desc { "computing `#[expect]`ed lints in this crate" } } query parent_module_from_def_id(key: LocalDefId) -> LocalDefId { @@ -1126,6 +1131,11 @@ rustc_queries! { desc { |tcx| "checking whether `{}` is `doc(hidden)`", tcx.def_path_str(def_id) } } + /// Determines whether an item is annotated with `doc(notable_trait)`. + query is_doc_notable_trait(def_id: DefId) -> bool { + desc { |tcx| "checking whether `{}` is `doc(notable_trait)`", tcx.def_path_str(def_id) } + } + /// Returns the attributes on the item at `def_id`. /// /// Do not use this directly, use `tcx.get_attrs` instead. diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index 641e53f2a15..1aa4df77800 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -71,16 +71,16 @@ impl<'tcx> AbstractConst<'tcx> { walk_abstract_const::<!, _>(tcx, self, |node| { match node.root(tcx) { Node::Leaf(leaf) => { - if leaf.has_infer_types_or_consts() { + if leaf.has_non_region_infer() { failure_kind = FailureKind::MentionsInfer; - } else if leaf.has_param_types_or_consts() { + } else if leaf.has_non_region_param() { failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam); } } Node::Cast(_, _, ty) => { - if ty.has_infer_types_or_consts() { + if ty.has_non_region_infer() { failure_kind = FailureKind::MentionsInfer; - } else if ty.has_param_types_or_consts() { + } else if ty.has_non_region_param() { failure_kind = cmp::min(failure_kind, FailureKind::MentionsParam); } } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 2e596b27527..3c485e26409 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -438,7 +438,8 @@ impl<'tcx> AdtDef<'tcx> { | Res::Def(DefKind::Union, _) | Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::AssocTy, _) - | Res::SelfTy { .. } + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } | Res::SelfCtor(..) => self.non_enum_variant(), _ => bug!("unexpected res {:?} in variant_of_res", res), } @@ -457,11 +458,9 @@ impl<'tcx> AdtDef<'tcx> { Some(Discr { val: b, ty }) } else { info!("invalid enum discriminant: {:#?}", val); - crate::mir::interpret::struct_error( - tcx.at(tcx.def_span(expr_did)), - "constant evaluation of enum discriminant resulted in non-integer", - ) - .emit(); + tcx.sess.emit_err(crate::error::ConstEvalNonIntError { + span: tcx.def_span(expr_did), + }); None } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 4781585b82c..97646003e73 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -4,7 +4,7 @@ use crate::arena::Arena; use crate::dep_graph::{DepGraph, DepKindStruct}; use crate::hir::place::Place as HirPlace; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; -use crate::lint::{struct_lint_level, LintLevelSource}; +use crate::lint::struct_lint_level; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::resolve_lifetime; use crate::middle::stability; @@ -35,7 +35,9 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{self, Lock, Lrc, ReadGuard, RwLock, WorkerLocal}; use rustc_data_structures::vec_map::VecMap; -use rustc_errors::{DecorateLint, ErrorGuaranteed, LintDiagnosticBuilder, MultiSpan}; +use rustc_errors::{ + DecorateLint, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, MultiSpan, +}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; @@ -55,7 +57,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use rustc_session::config::{CrateType, OutputFilenames}; use rustc_session::cstore::CrateStoreDyn; use rustc_session::errors::TargetDataLayoutErrorsWrapper; -use rustc_session::lint::{Level, Lint}; +use rustc_session::lint::Lint; use rustc_session::Limit; use rustc_session::Session; use rustc_span::def_id::{DefPathHash, StableCrateId}; @@ -2810,44 +2812,6 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_bound_variable_kinds(xs)) } - /// Walks upwards from `id` to find a node which might change lint levels with attributes. - /// It stops at `bound` and just returns it if reached. - pub fn maybe_lint_level_root_bounded(self, mut id: HirId, bound: HirId) -> HirId { - let hir = self.hir(); - loop { - if id == bound { - return bound; - } - - if hir.attrs(id).iter().any(|attr| Level::from_attr(attr).is_some()) { - return id; - } - let next = hir.get_parent_node(id); - if next == id { - bug!("lint traversal reached the root of the crate"); - } - id = next; - } - } - - pub fn lint_level_at_node( - self, - lint: &'static Lint, - mut id: hir::HirId, - ) -> (Level, LintLevelSource) { - let sets = self.lint_levels(()); - loop { - if let Some(pair) = sets.level_and_source(lint, id, self.sess) { - return pair; - } - let next = self.hir().get_parent_node(id); - if next == id { - bug!("lint traversal reached the root of the crate"); - } - id = next; - } - } - /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, /// typically generated by `#[derive(LintDiagnostic)]`). pub fn emit_spanned_lint( @@ -2857,7 +2821,9 @@ impl<'tcx> TyCtxt<'tcx> { span: impl Into<MultiSpan>, decorator: impl for<'a> DecorateLint<'a, ()>, ) { - self.struct_span_lint_hir(lint, hir_id, span, |diag| decorator.decorate_lint(diag)) + self.struct_span_lint_hir(lint, hir_id, span, decorator.msg(), |diag| { + decorator.decorate_lint(diag) + }) } pub fn struct_span_lint_hir( @@ -2865,10 +2831,13 @@ impl<'tcx> TyCtxt<'tcx> { lint: &'static Lint, hir_id: HirId, span: impl Into<MultiSpan>, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { let (level, src) = self.lint_level_at_node(lint, hir_id); - struct_lint_level(self.sess, lint, level, src, Some(span.into()), decorate); + struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate); } /// Emit a lint from a lint struct (some type that implements `DecorateLint`, typically @@ -2879,17 +2848,20 @@ impl<'tcx> TyCtxt<'tcx> { id: HirId, decorator: impl for<'a> DecorateLint<'a, ()>, ) { - self.struct_lint_node(lint, id, |diag| decorator.decorate_lint(diag)) + self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag)) } pub fn struct_lint_node( self, lint: &'static Lint, id: HirId, - decorate: impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>), + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'b mut DiagnosticBuilder<'a, ()>, + ) -> &'b mut DiagnosticBuilder<'a, ()>, ) { let (level, src) = self.lint_level_at_node(lint, id); - struct_lint_level(self.sess, lint, level, src, None, decorate); + struct_lint_level(self.sess, lint, level, src, None, msg, decorate); } pub fn in_scope_traits(self, id: HirId) -> Option<&'tcx [TraitCandidate]> { diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 41bb3c71401..3be0bc4defc 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -132,7 +132,7 @@ pub fn simplify_type<'tcx>( // don't unify with anything else as long as they are fully normalized. // // We will have to be careful with lazy normalization here. - TreatParams::AsPlaceholder if !ty.has_infer_types_or_consts() => { + TreatParams::AsPlaceholder if !ty.has_non_region_infer() => { debug!("treating `{}` as a placeholder", ty); Some(PlaceholderSimplifiedType) } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index cc820d9eb2d..5f8729a8ddf 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1,40 +1,23 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; -use crate::mir::{GeneratorLayout, GeneratorSavedLocal}; use crate::ty::normalize_erasing_regions::NormalizationError; -use crate::ty::{ - self, layout_sanity_check::sanity_check_layout, subst::SubstsRef, EarlyBinder, ReprOptions, Ty, - TyCtxt, TypeVisitable, -}; +use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitable}; use rustc_ast as ast; use rustc_attr as attr; +use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_hir::lang_items::LangItem; -use rustc_index::bit_set::BitSet; -use rustc_index::vec::{Idx, IndexVec}; -use rustc_session::{config::OptLevel, DataTypeKind, FieldInfo, SizeKind, VariantInfo}; -use rustc_span::symbol::Symbol; +use rustc_index::vec::Idx; +use rustc_session::config::OptLevel; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::call::{ - ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind, -}; +use rustc_target::abi::call::FnAbi; use rustc_target::abi::*; use rustc_target::spec::{abi::Abi as SpecAbi, HasTargetSpec, PanicStrategy, Target}; -use std::cmp::{self, Ordering}; +use std::cmp::{self}; use std::fmt; -use std::iter; use std::num::NonZeroUsize; use std::ops::Bound; -use rand::{seq::SliceRandom, SeedableRng}; -use rand_xoshiro::Xoshiro128StarStar; - -pub fn provide(providers: &mut ty::query::Providers) { - *providers = - ty::query::Providers { layout_of, fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers }; -} - pub trait IntegerExt { fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>, signed: bool) -> Ty<'tcx>; fn from_attr<C: HasDataLayout>(cx: &C, ity: attr::IntType) -> Integer; @@ -206,6 +189,12 @@ pub enum LayoutError<'tcx> { NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>), } +impl<'a> IntoDiagnostic<'a, !> for LayoutError<'a> { + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, !> { + handler.struct_fatal(self.to_string()) + } +} + impl<'tcx> fmt::Display for LayoutError<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { @@ -223,1814 +212,12 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> { } } -#[instrument(skip(tcx, query), level = "debug")] -fn layout_of<'tcx>( - tcx: TyCtxt<'tcx>, - query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, -) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> { - let (param_env, ty) = query.into_parts(); - debug!(?ty); - - let param_env = param_env.with_reveal_all_normalized(tcx); - let unnormalized_ty = ty; - - // FIXME: We might want to have two different versions of `layout_of`: - // One that can be called after typecheck has completed and can use - // `normalize_erasing_regions` here and another one that can be called - // before typecheck has completed and uses `try_normalize_erasing_regions`. - let ty = match tcx.try_normalize_erasing_regions(param_env, ty) { - Ok(t) => t, - Err(normalization_error) => { - return Err(LayoutError::NormalizationFailure(ty, normalization_error)); - } - }; - - if ty != unnormalized_ty { - // Ensure this layout is also cached for the normalized type. - return tcx.layout_of(param_env.and(ty)); - } - - let cx = LayoutCx { tcx, param_env }; - - let layout = cx.layout_of_uncached(ty)?; - let layout = TyAndLayout { ty, layout }; - - cx.record_layout_for_printing(layout); - - sanity_check_layout(&cx, &layout); - - Ok(layout) -} - #[derive(Clone, Copy)] pub struct LayoutCx<'tcx, C> { pub tcx: C, pub param_env: ty::ParamEnv<'tcx>, } -#[derive(Copy, Clone, Debug)] -enum StructKind { - /// A tuple, closure, or univariant which cannot be coerced to unsized. - AlwaysSized, - /// A univariant, the last field of which may be coerced to unsized. - MaybeUnsized, - /// A univariant, but with a prefix of an arbitrary size & alignment (e.g., enum tag). - Prefixed(Size, Align), -} - -// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`. -// This is used to go between `memory_index` (source field order to memory order) -// and `inverse_memory_index` (memory order to source field order). -// See also `FieldsShape::Arbitrary::memory_index` for more details. -// FIXME(eddyb) build a better abstraction for permutations, if possible. -fn invert_mapping(map: &[u32]) -> Vec<u32> { - let mut inverse = vec![0; map.len()]; - for i in 0..map.len() { - inverse[map[i] as usize] = i as u32; - } - inverse -} - -impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { - fn scalar_pair(&self, a: Scalar, b: Scalar) -> LayoutS<'tcx> { - let dl = self.data_layout(); - let b_align = b.align(dl); - let align = a.align(dl).max(b_align).max(dl.aggregate_align); - let b_offset = a.size(dl).align_to(b_align.abi); - let size = (b_offset + b.size(dl)).align_to(align.abi); - - // HACK(nox): We iter on `b` and then `a` because `max_by_key` - // returns the last maximum. - let largest_niche = Niche::from_scalar(dl, b_offset, b) - .into_iter() - .chain(Niche::from_scalar(dl, Size::ZERO, a)) - .max_by_key(|niche| niche.available(dl)); - - LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Arbitrary { - offsets: vec![Size::ZERO, b_offset], - memory_index: vec![0, 1], - }, - abi: Abi::ScalarPair(a, b), - largest_niche, - align, - size, - } - } - - fn univariant_uninterned( - &self, - ty: Ty<'tcx>, - fields: &[TyAndLayout<'_>], - repr: &ReprOptions, - kind: StructKind, - ) -> Result<LayoutS<'tcx>, LayoutError<'tcx>> { - let dl = self.data_layout(); - let pack = repr.pack; - if pack.is_some() && repr.align.is_some() { - self.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned"); - return Err(LayoutError::Unknown(ty)); - } - - let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; - - let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect(); - - let optimize = !repr.inhibit_struct_field_reordering_opt(); - if optimize { - let end = - if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; - let optimizing = &mut inverse_memory_index[..end]; - let field_align = |f: &TyAndLayout<'_>| { - if let Some(pack) = pack { f.align.abi.min(pack) } else { f.align.abi } - }; - - // If `-Z randomize-layout` was enabled for the type definition we can shuffle - // the field ordering to try and catch some code making assumptions about layouts - // we don't guarantee - if repr.can_randomize_type_layout() { - // `ReprOptions.layout_seed` is a deterministic seed that we can use to - // randomize field ordering with - let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed); - - // Shuffle the ordering of the fields - optimizing.shuffle(&mut rng); - - // Otherwise we just leave things alone and actually optimize the type's fields - } else { - match kind { - StructKind::AlwaysSized | StructKind::MaybeUnsized => { - optimizing.sort_by_key(|&x| { - // Place ZSTs first to avoid "interesting offsets", - // especially with only one or two non-ZST fields. - let f = &fields[x as usize]; - (!f.is_zst(), cmp::Reverse(field_align(f))) - }); - } - - StructKind::Prefixed(..) => { - // Sort in ascending alignment so that the layout stays optimal - // regardless of the prefix - optimizing.sort_by_key(|&x| field_align(&fields[x as usize])); - } - } - - // FIXME(Kixiron): We can always shuffle fields within a given alignment class - // regardless of the status of `-Z randomize-layout` - } - } - - // inverse_memory_index holds field indices by increasing memory offset. - // That is, if field 5 has offset 0, the first element of inverse_memory_index is 5. - // We now write field offsets to the corresponding offset slot; - // field 5 with offset 0 puts 0 in offsets[5]. - // At the bottom of this function, we invert `inverse_memory_index` to - // produce `memory_index` (see `invert_mapping`). - - let mut sized = true; - let mut offsets = vec![Size::ZERO; fields.len()]; - let mut offset = Size::ZERO; - let mut largest_niche = None; - let mut largest_niche_available = 0; - - if let StructKind::Prefixed(prefix_size, prefix_align) = kind { - let prefix_align = - if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align }; - align = align.max(AbiAndPrefAlign::new(prefix_align)); - offset = prefix_size.align_to(prefix_align); - } - - for &i in &inverse_memory_index { - let field = fields[i as usize]; - if !sized { - self.tcx.sess.delay_span_bug( - DUMMY_SP, - &format!( - "univariant: field #{} of `{}` comes after unsized field", - offsets.len(), - ty - ), - ); - } - - if field.is_unsized() { - sized = false; - } - - // Invariant: offset < dl.obj_size_bound() <= 1<<61 - let field_align = if let Some(pack) = pack { - field.align.min(AbiAndPrefAlign::new(pack)) - } else { - field.align - }; - offset = offset.align_to(field_align.abi); - align = align.max(field_align); - - debug!("univariant offset: {:?} field: {:#?}", offset, field); - offsets[i as usize] = offset; - - if let Some(mut niche) = field.largest_niche { - let available = niche.available(dl); - if available > largest_niche_available { - largest_niche_available = available; - niche.offset += offset; - largest_niche = Some(niche); - } - } - - offset = offset.checked_add(field.size, dl).ok_or(LayoutError::SizeOverflow(ty))?; - } - - if let Some(repr_align) = repr.align { - align = align.max(AbiAndPrefAlign::new(repr_align)); - } - - debug!("univariant min_size: {:?}", offset); - let min_size = offset; - - // As stated above, inverse_memory_index holds field indices by increasing offset. - // This makes it an already-sorted view of the offsets vec. - // To invert it, consider: - // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0. - // Field 5 would be the first element, so memory_index is i: - // Note: if we didn't optimize, it's already right. - - let memory_index = - if optimize { invert_mapping(&inverse_memory_index) } else { inverse_memory_index }; - - let size = min_size.align_to(align.abi); - let mut abi = Abi::Aggregate { sized }; - - // Unpack newtype ABIs and find scalar pairs. - if sized && size.bytes() > 0 { - // All other fields must be ZSTs. - let mut non_zst_fields = fields.iter().enumerate().filter(|&(_, f)| !f.is_zst()); - - match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) { - // We have exactly one non-ZST field. - (Some((i, field)), None, None) => { - // Field fills the struct and it has a scalar or scalar pair ABI. - if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size - { - match field.abi { - // For plain scalars, or vectors of them, we can't unpack - // newtypes for `#[repr(C)]`, as that affects C ABIs. - Abi::Scalar(_) | Abi::Vector { .. } if optimize => { - abi = field.abi; - } - // But scalar pairs are Rust-specific and get - // treated as aggregates by C ABIs anyway. - Abi::ScalarPair(..) => { - abi = field.abi; - } - _ => {} - } - } - } - - // Two non-ZST fields, and they're both scalars. - (Some((i, a)), Some((j, b)), None) => { - match (a.abi, b.abi) { - (Abi::Scalar(a), Abi::Scalar(b)) => { - // Order by the memory placement, not source order. - let ((i, a), (j, b)) = if offsets[i] < offsets[j] { - ((i, a), (j, b)) - } else { - ((j, b), (i, a)) - }; - let pair = self.scalar_pair(a, b); - let pair_offsets = match pair.fields { - FieldsShape::Arbitrary { ref offsets, ref memory_index } => { - assert_eq!(memory_index, &[0, 1]); - offsets - } - _ => bug!(), - }; - if offsets[i] == pair_offsets[0] - && offsets[j] == pair_offsets[1] - && align == pair.align - && size == pair.size - { - // We can use `ScalarPair` only when it matches our - // already computed layout (including `#[repr(C)]`). - abi = pair.abi; - } - } - _ => {} - } - } - - _ => {} - } - } - - if fields.iter().any(|f| f.abi.is_uninhabited()) { - abi = Abi::Uninhabited; - } - - Ok(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Arbitrary { offsets, memory_index }, - abi, - largest_niche, - align, - size, - }) - } - - fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<Layout<'tcx>, LayoutError<'tcx>> { - let tcx = self.tcx; - let param_env = self.param_env; - let dl = self.data_layout(); - let scalar_unit = |value: Primitive| { - let size = value.size(dl); - assert!(size.bits() <= 128); - Scalar::Initialized { value, valid_range: WrappingRange::full(size) } - }; - let scalar = - |value: Primitive| tcx.intern_layout(LayoutS::scalar(self, scalar_unit(value))); - - let univariant = |fields: &[TyAndLayout<'_>], repr: &ReprOptions, kind| { - Ok(tcx.intern_layout(self.univariant_uninterned(ty, fields, repr, kind)?)) - }; - debug_assert!(!ty.has_infer_types_or_consts()); - - Ok(match *ty.kind() { - // Basic scalars. - ty::Bool => tcx.intern_layout(LayoutS::scalar( - self, - Scalar::Initialized { - value: Int(I8, false), - valid_range: WrappingRange { start: 0, end: 1 }, - }, - )), - ty::Char => tcx.intern_layout(LayoutS::scalar( - self, - Scalar::Initialized { - value: Int(I32, false), - valid_range: WrappingRange { start: 0, end: 0x10FFFF }, - }, - )), - ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)), - ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)), - ty::Float(fty) => scalar(match fty { - ty::FloatTy::F32 => F32, - ty::FloatTy::F64 => F64, - }), - ty::FnPtr(_) => { - let mut ptr = scalar_unit(Pointer); - ptr.valid_range_mut().start = 1; - tcx.intern_layout(LayoutS::scalar(self, ptr)) - } - - // The never type. - ty::Never => tcx.intern_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Primitive, - abi: Abi::Uninhabited, - largest_niche: None, - align: dl.i8_align, - size: Size::ZERO, - }), - - // Potentially-wide pointers. - ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { - let mut data_ptr = scalar_unit(Pointer); - if !ty.is_unsafe_ptr() { - data_ptr.valid_range_mut().start = 1; - } - - let pointee = tcx.normalize_erasing_regions(param_env, pointee); - if pointee.is_sized(tcx.at(DUMMY_SP), param_env) { - return Ok(tcx.intern_layout(LayoutS::scalar(self, data_ptr))); - } - - let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env); - let metadata = match unsized_part.kind() { - ty::Foreign(..) => { - return Ok(tcx.intern_layout(LayoutS::scalar(self, data_ptr))); - } - ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), - ty::Dynamic(..) => { - let mut vtable = scalar_unit(Pointer); - vtable.valid_range_mut().start = 1; - vtable - } - _ => return Err(LayoutError::Unknown(unsized_part)), - }; - - // Effectively a (ptr, meta) tuple. - tcx.intern_layout(self.scalar_pair(data_ptr, metadata)) - } - - ty::Dynamic(_, _, ty::DynStar) => { - let mut data = scalar_unit(Int(dl.ptr_sized_integer(), false)); - data.valid_range_mut().start = 0; - let mut vtable = scalar_unit(Pointer); - vtable.valid_range_mut().start = 1; - tcx.intern_layout(self.scalar_pair(data, vtable)) - } - - // Arrays and slices. - ty::Array(element, mut count) => { - if count.has_projections() { - count = tcx.normalize_erasing_regions(param_env, count); - if count.has_projections() { - return Err(LayoutError::Unknown(ty)); - } - } - - let count = count.try_eval_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?; - let element = self.layout_of(element)?; - let size = - element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?; - - let abi = - if count != 0 && tcx.conservative_is_privately_uninhabited(param_env.and(ty)) { - Abi::Uninhabited - } else { - Abi::Aggregate { sized: true } - }; - - let largest_niche = if count != 0 { element.largest_niche } else { None }; - - tcx.intern_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Array { stride: element.size, count }, - abi, - largest_niche, - align: element.align, - size, - }) - } - ty::Slice(element) => { - let element = self.layout_of(element)?; - tcx.intern_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Array { stride: element.size, count: 0 }, - abi: Abi::Aggregate { sized: false }, - largest_niche: None, - align: element.align, - size: Size::ZERO, - }) - } - ty::Str => tcx.intern_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, - abi: Abi::Aggregate { sized: false }, - largest_niche: None, - align: dl.i8_align, - size: Size::ZERO, - }), - - // Odd unit types. - ty::FnDef(..) => univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)?, - ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => { - let mut unit = self.univariant_uninterned( - ty, - &[], - &ReprOptions::default(), - StructKind::AlwaysSized, - )?; - match unit.abi { - Abi::Aggregate { ref mut sized } => *sized = false, - _ => bug!(), - } - tcx.intern_layout(unit) - } - - ty::Generator(def_id, substs, _) => self.generator_layout(ty, def_id, substs)?, - - ty::Closure(_, ref substs) => { - let tys = substs.as_closure().upvar_tys(); - univariant( - &tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?, - &ReprOptions::default(), - StructKind::AlwaysSized, - )? - } - - ty::Tuple(tys) => { - let kind = - if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; - - univariant( - &tys.iter().map(|k| self.layout_of(k)).collect::<Result<Vec<_>, _>>()?, - &ReprOptions::default(), - kind, - )? - } - - // SIMD vector types. - ty::Adt(def, substs) if def.repr().simd() => { - if !def.is_struct() { - // Should have yielded E0517 by now. - tcx.sess.delay_span_bug( - DUMMY_SP, - "#[repr(simd)] was applied to an ADT that is not a struct", - ); - return Err(LayoutError::Unknown(ty)); - } - - // Supported SIMD vectors are homogeneous ADTs with at least one field: - // - // * #[repr(simd)] struct S(T, T, T, T); - // * #[repr(simd)] struct S { x: T, y: T, z: T, w: T } - // * #[repr(simd)] struct S([T; 4]) - // - // where T is a primitive scalar (integer/float/pointer). - - // SIMD vectors with zero fields are not supported. - // (should be caught by typeck) - if def.non_enum_variant().fields.is_empty() { - tcx.sess.fatal(&format!("monomorphising SIMD type `{}` of zero length", ty)); - } - - // Type of the first ADT field: - let f0_ty = def.non_enum_variant().fields[0].ty(tcx, substs); - - // Heterogeneous SIMD vectors are not supported: - // (should be caught by typeck) - for fi in &def.non_enum_variant().fields { - if fi.ty(tcx, substs) != f0_ty { - tcx.sess.fatal(&format!("monomorphising heterogeneous SIMD type `{}`", ty)); - } - } - - // The element type and number of elements of the SIMD vector - // are obtained from: - // - // * the element type and length of the single array field, if - // the first field is of array type, or - // - // * the homogeneous field type and the number of fields. - let (e_ty, e_len, is_array) = if let ty::Array(e_ty, _) = f0_ty.kind() { - // First ADT field is an array: - - // SIMD vectors with multiple array fields are not supported: - // (should be caught by typeck) - if def.non_enum_variant().fields.len() != 1 { - tcx.sess.fatal(&format!( - "monomorphising SIMD type `{}` with more than one array field", - ty - )); - } - - // Extract the number of elements from the layout of the array field: - let FieldsShape::Array { count, .. } = self.layout_of(f0_ty)?.layout.fields() else { - return Err(LayoutError::Unknown(ty)); - }; - - (*e_ty, *count, true) - } else { - // First ADT field is not an array: - (f0_ty, def.non_enum_variant().fields.len() as _, false) - }; - - // SIMD vectors of zero length are not supported. - // Additionally, lengths are capped at 2^16 as a fixed maximum backends must - // support. - // - // Can't be caught in typeck if the array length is generic. - if e_len == 0 { - tcx.sess.fatal(&format!("monomorphising SIMD type `{}` of zero length", ty)); - } else if e_len > MAX_SIMD_LANES { - tcx.sess.fatal(&format!( - "monomorphising SIMD type `{}` of length greater than {}", - ty, MAX_SIMD_LANES, - )); - } - - // Compute the ABI of the element type: - let e_ly = self.layout_of(e_ty)?; - let Abi::Scalar(e_abi) = e_ly.abi else { - // This error isn't caught in typeck, e.g., if - // the element type of the vector is generic. - tcx.sess.fatal(&format!( - "monomorphising SIMD type `{}` with a non-primitive-scalar \ - (integer/float/pointer) element type `{}`", - ty, e_ty - )) - }; - - // Compute the size and alignment of the vector: - let size = e_ly.size.checked_mul(e_len, dl).ok_or(LayoutError::SizeOverflow(ty))?; - let align = dl.vector_align(size); - let size = size.align_to(align.abi); - - // Compute the placement of the vector fields: - let fields = if is_array { - FieldsShape::Arbitrary { offsets: vec![Size::ZERO], memory_index: vec![0] } - } else { - FieldsShape::Array { stride: e_ly.size, count: e_len } - }; - - tcx.intern_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields, - abi: Abi::Vector { element: e_abi, count: e_len }, - largest_niche: e_ly.largest_niche, - size, - align, - }) - } - - // ADTs. - ty::Adt(def, substs) => { - // Cache the field layouts. - let variants = def - .variants() - .iter() - .map(|v| { - v.fields - .iter() - .map(|field| self.layout_of(field.ty(tcx, substs))) - .collect::<Result<Vec<_>, _>>() - }) - .collect::<Result<IndexVec<VariantIdx, _>, _>>()?; - - if def.is_union() { - if def.repr().pack.is_some() && def.repr().align.is_some() { - self.tcx.sess.delay_span_bug( - tcx.def_span(def.did()), - "union cannot be packed and aligned", - ); - return Err(LayoutError::Unknown(ty)); - } - - let mut align = - if def.repr().pack.is_some() { dl.i8_align } else { dl.aggregate_align }; - - if let Some(repr_align) = def.repr().align { - align = align.max(AbiAndPrefAlign::new(repr_align)); - } - - let optimize = !def.repr().inhibit_union_abi_opt(); - let mut size = Size::ZERO; - let mut abi = Abi::Aggregate { sized: true }; - let index = VariantIdx::new(0); - for field in &variants[index] { - assert!(!field.is_unsized()); - align = align.max(field.align); - - // If all non-ZST fields have the same ABI, forward this ABI - if optimize && !field.is_zst() { - // Discard valid range information and allow undef - let field_abi = match field.abi { - Abi::Scalar(x) => Abi::Scalar(x.to_union()), - Abi::ScalarPair(x, y) => { - Abi::ScalarPair(x.to_union(), y.to_union()) - } - Abi::Vector { element: x, count } => { - Abi::Vector { element: x.to_union(), count } - } - Abi::Uninhabited | Abi::Aggregate { .. } => { - Abi::Aggregate { sized: true } - } - }; - - if size == Size::ZERO { - // first non ZST: initialize 'abi' - abi = field_abi; - } else if abi != field_abi { - // different fields have different ABI: reset to Aggregate - abi = Abi::Aggregate { sized: true }; - } - } - - size = cmp::max(size, field.size); - } - - if let Some(pack) = def.repr().pack { - align = align.min(AbiAndPrefAlign::new(pack)); - } - - return Ok(tcx.intern_layout(LayoutS { - variants: Variants::Single { index }, - fields: FieldsShape::Union( - NonZeroUsize::new(variants[index].len()) - .ok_or(LayoutError::Unknown(ty))?, - ), - abi, - largest_niche: None, - align, - size: size.align_to(align.abi), - })); - } - - // A variant is absent if it's uninhabited and only has ZST fields. - // Present uninhabited variants only require space for their fields, - // but *not* an encoding of the discriminant (e.g., a tag value). - // See issue #49298 for more details on the need to leave space - // for non-ZST uninhabited data (mostly partial initialization). - let absent = |fields: &[TyAndLayout<'_>]| { - let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited()); - let is_zst = fields.iter().all(|f| f.is_zst()); - uninhabited && is_zst - }; - let (present_first, present_second) = { - let mut present_variants = variants - .iter_enumerated() - .filter_map(|(i, v)| if absent(v) { None } else { Some(i) }); - (present_variants.next(), present_variants.next()) - }; - let present_first = match present_first { - Some(present_first) => present_first, - // Uninhabited because it has no variants, or only absent ones. - None if def.is_enum() => { - return Ok(tcx.layout_of(param_env.and(tcx.types.never))?.layout); - } - // If it's a struct, still compute a layout so that we can still compute the - // field offsets. - None => VariantIdx::new(0), - }; - - let is_struct = !def.is_enum() || - // Only one variant is present. - (present_second.is_none() && - // Representation optimizations are allowed. - !def.repr().inhibit_enum_layout_opt()); - if is_struct { - // Struct, or univariant enum equivalent to a struct. - // (Typechecking will reject discriminant-sizing attrs.) - - let v = present_first; - let kind = if def.is_enum() || variants[v].is_empty() { - StructKind::AlwaysSized - } else { - let param_env = tcx.param_env(def.did()); - let last_field = def.variant(v).fields.last().unwrap(); - let always_sized = - tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env); - if !always_sized { - StructKind::MaybeUnsized - } else { - StructKind::AlwaysSized - } - }; - - let mut st = self.univariant_uninterned(ty, &variants[v], &def.repr(), kind)?; - st.variants = Variants::Single { index: v }; - - if def.is_unsafe_cell() { - let hide_niches = |scalar: &mut _| match scalar { - Scalar::Initialized { value, valid_range } => { - *valid_range = WrappingRange::full(value.size(dl)) - } - // Already doesn't have any niches - Scalar::Union { .. } => {} - }; - match &mut st.abi { - Abi::Uninhabited => {} - Abi::Scalar(scalar) => hide_niches(scalar), - Abi::ScalarPair(a, b) => { - hide_niches(a); - hide_niches(b); - } - Abi::Vector { element, count: _ } => hide_niches(element), - Abi::Aggregate { sized: _ } => {} - } - st.largest_niche = None; - return Ok(tcx.intern_layout(st)); - } - - let (start, end) = self.tcx.layout_scalar_valid_range(def.did()); - match st.abi { - Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => { - // the asserts ensure that we are not using the - // `#[rustc_layout_scalar_valid_range(n)]` - // attribute to widen the range of anything as that would probably - // result in UB somewhere - // FIXME(eddyb) the asserts are probably not needed, - // as larger validity ranges would result in missed - // optimizations, *not* wrongly assuming the inner - // value is valid. e.g. unions enlarge validity ranges, - // because the values may be uninitialized. - if let Bound::Included(start) = start { - // FIXME(eddyb) this might be incorrect - it doesn't - // account for wrap-around (end < start) ranges. - let valid_range = scalar.valid_range_mut(); - assert!(valid_range.start <= start); - valid_range.start = start; - } - if let Bound::Included(end) = end { - // FIXME(eddyb) this might be incorrect - it doesn't - // account for wrap-around (end < start) ranges. - let valid_range = scalar.valid_range_mut(); - assert!(valid_range.end >= end); - valid_range.end = end; - } - - // Update `largest_niche` if we have introduced a larger niche. - let niche = Niche::from_scalar(dl, Size::ZERO, *scalar); - if let Some(niche) = niche { - match st.largest_niche { - Some(largest_niche) => { - // Replace the existing niche even if they're equal, - // because this one is at a lower offset. - if largest_niche.available(dl) <= niche.available(dl) { - st.largest_niche = Some(niche); - } - } - None => st.largest_niche = Some(niche), - } - } - } - _ => assert!( - start == Bound::Unbounded && end == Bound::Unbounded, - "nonscalar layout for layout_scalar_valid_range type {:?}: {:#?}", - def, - st, - ), - } - - return Ok(tcx.intern_layout(st)); - } - - // At this point, we have handled all unions and - // structs. (We have also handled univariant enums - // that allow representation optimization.) - assert!(def.is_enum()); - - // Until we've decided whether to use the tagged or - // niche filling LayoutS, we don't want to intern the - // variant layouts, so we can't store them in the - // overall LayoutS. Store the overall LayoutS - // and the variant LayoutSs here until then. - struct TmpLayout<'tcx> { - layout: LayoutS<'tcx>, - variants: IndexVec<VariantIdx, LayoutS<'tcx>>, - } - - let calculate_niche_filling_layout = - || -> Result<Option<TmpLayout<'tcx>>, LayoutError<'tcx>> { - // The current code for niche-filling relies on variant indices - // instead of actual discriminants, so enums with - // explicit discriminants (RFC #2363) would misbehave. - if def.repr().inhibit_enum_layout_opt() - || def - .variants() - .iter_enumerated() - .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32())) - { - return Ok(None); - } - - if variants.len() < 2 { - return Ok(None); - } - - let mut align = dl.aggregate_align; - let mut variant_layouts = variants - .iter_enumerated() - .map(|(j, v)| { - let mut st = self.univariant_uninterned( - ty, - v, - &def.repr(), - StructKind::AlwaysSized, - )?; - st.variants = Variants::Single { index: j }; - - align = align.max(st.align); - - Ok(st) - }) - .collect::<Result<IndexVec<VariantIdx, _>, _>>()?; - - let largest_variant_index = match variant_layouts - .iter_enumerated() - .max_by_key(|(_i, layout)| layout.size.bytes()) - .map(|(i, _layout)| i) - { - None => return Ok(None), - Some(i) => i, - }; - - let all_indices = VariantIdx::new(0)..=VariantIdx::new(variants.len() - 1); - let needs_disc = |index: VariantIdx| { - index != largest_variant_index && !absent(&variants[index]) - }; - let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap() - ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap(); - - let count = niche_variants.size_hint().1.unwrap() as u128; - - // Find the field with the largest niche - let (field_index, niche, (niche_start, niche_scalar)) = match variants - [largest_variant_index] - .iter() - .enumerate() - .filter_map(|(j, field)| Some((j, field.largest_niche?))) - .max_by_key(|(_, niche)| niche.available(dl)) - .and_then(|(j, niche)| Some((j, niche, niche.reserve(self, count)?))) - { - None => return Ok(None), - Some(x) => x, - }; - - let niche_offset = niche.offset - + variant_layouts[largest_variant_index].fields.offset(field_index); - let niche_size = niche.value.size(dl); - let size = variant_layouts[largest_variant_index].size.align_to(align.abi); - - let all_variants_fit = - variant_layouts.iter_enumerated_mut().all(|(i, layout)| { - if i == largest_variant_index { - return true; - } - - layout.largest_niche = None; - - if layout.size <= niche_offset { - // This variant will fit before the niche. - return true; - } - - // Determine if it'll fit after the niche. - let this_align = layout.align.abi; - let this_offset = (niche_offset + niche_size).align_to(this_align); - - if this_offset + layout.size > size { - return false; - } - - // It'll fit, but we need to make some adjustments. - match layout.fields { - FieldsShape::Arbitrary { ref mut offsets, .. } => { - for (j, offset) in offsets.iter_mut().enumerate() { - if !variants[i][j].is_zst() { - *offset += this_offset; - } - } - } - _ => { - panic!("Layout of fields should be Arbitrary for variants") - } - } - - // It can't be a Scalar or ScalarPair because the offset isn't 0. - if !layout.abi.is_uninhabited() { - layout.abi = Abi::Aggregate { sized: true }; - } - layout.size += this_offset; - - true - }); - - if !all_variants_fit { - return Ok(None); - } - - let largest_niche = Niche::from_scalar(dl, niche_offset, niche_scalar); - - let others_zst = variant_layouts.iter_enumerated().all(|(i, layout)| { - i == largest_variant_index || layout.size == Size::ZERO - }); - let same_size = size == variant_layouts[largest_variant_index].size; - let same_align = align == variant_layouts[largest_variant_index].align; - - let abi = if variant_layouts.iter().all(|v| v.abi.is_uninhabited()) { - Abi::Uninhabited - } else if same_size && same_align && others_zst { - match variant_layouts[largest_variant_index].abi { - // When the total alignment and size match, we can use the - // same ABI as the scalar variant with the reserved niche. - Abi::Scalar(_) => Abi::Scalar(niche_scalar), - Abi::ScalarPair(first, second) => { - // Only the niche is guaranteed to be initialised, - // so use union layouts for the other primitive. - if niche_offset == Size::ZERO { - Abi::ScalarPair(niche_scalar, second.to_union()) - } else { - Abi::ScalarPair(first.to_union(), niche_scalar) - } - } - _ => Abi::Aggregate { sized: true }, - } - } else { - Abi::Aggregate { sized: true } - }; - - let layout = LayoutS { - variants: Variants::Multiple { - tag: niche_scalar, - tag_encoding: TagEncoding::Niche { - untagged_variant: largest_variant_index, - niche_variants, - niche_start, - }, - tag_field: 0, - variants: IndexVec::new(), - }, - fields: FieldsShape::Arbitrary { - offsets: vec![niche_offset], - memory_index: vec![0], - }, - abi, - largest_niche, - size, - align, - }; - - Ok(Some(TmpLayout { layout, variants: variant_layouts })) - }; - - let niche_filling_layout = calculate_niche_filling_layout()?; - - let (mut min, mut max) = (i128::MAX, i128::MIN); - let discr_type = def.repr().discr_type(); - let bits = Integer::from_attr(self, discr_type).size().bits(); - for (i, discr) in def.discriminants(tcx) { - if variants[i].iter().any(|f| f.abi.is_uninhabited()) { - continue; - } - let mut x = discr.val as i128; - if discr_type.is_signed() { - // sign extend the raw representation to be an i128 - x = (x << (128 - bits)) >> (128 - bits); - } - if x < min { - min = x; - } - if x > max { - max = x; - } - } - // We might have no inhabited variants, so pretend there's at least one. - if (min, max) == (i128::MAX, i128::MIN) { - min = 0; - max = 0; - } - assert!(min <= max, "discriminant range is {}...{}", min, max); - let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr(), min, max); - - let mut align = dl.aggregate_align; - let mut size = Size::ZERO; - - // We're interested in the smallest alignment, so start large. - let mut start_align = Align::from_bytes(256).unwrap(); - assert_eq!(Integer::for_align(dl, start_align), None); - - // repr(C) on an enum tells us to make a (tag, union) layout, - // so we need to grow the prefix alignment to be at least - // the alignment of the union. (This value is used both for - // determining the alignment of the overall enum, and the - // determining the alignment of the payload after the tag.) - let mut prefix_align = min_ity.align(dl).abi; - if def.repr().c() { - for fields in &variants { - for field in fields { - prefix_align = prefix_align.max(field.align.abi); - } - } - } - - // Create the set of structs that represent each variant. - let mut layout_variants = variants - .iter_enumerated() - .map(|(i, field_layouts)| { - let mut st = self.univariant_uninterned( - ty, - &field_layouts, - &def.repr(), - StructKind::Prefixed(min_ity.size(), prefix_align), - )?; - st.variants = Variants::Single { index: i }; - // Find the first field we can't move later - // to make room for a larger discriminant. - for field in - st.fields.index_by_increasing_offset().map(|j| field_layouts[j]) - { - if !field.is_zst() || field.align.abi.bytes() != 1 { - start_align = start_align.min(field.align.abi); - break; - } - } - size = cmp::max(size, st.size); - align = align.max(st.align); - Ok(st) - }) - .collect::<Result<IndexVec<VariantIdx, _>, _>>()?; - - // Align the maximum variant size to the largest alignment. - size = size.align_to(align.abi); - - if size.bytes() >= dl.obj_size_bound() { - return Err(LayoutError::SizeOverflow(ty)); - } - - let typeck_ity = Integer::from_attr(dl, def.repr().discr_type()); - if typeck_ity < min_ity { - // It is a bug if Layout decided on a greater discriminant size than typeck for - // some reason at this point (based on values discriminant can take on). Mostly - // because this discriminant will be loaded, and then stored into variable of - // type calculated by typeck. Consider such case (a bug): typeck decided on - // byte-sized discriminant, but layout thinks we need a 16-bit to store all - // discriminant values. That would be a bug, because then, in codegen, in order - // to store this 16-bit discriminant into 8-bit sized temporary some of the - // space necessary to represent would have to be discarded (or layout is wrong - // on thinking it needs 16 bits) - bug!( - "layout decided on a larger discriminant type ({:?}) than typeck ({:?})", - min_ity, - typeck_ity - ); - // However, it is fine to make discr type however large (as an optimisation) - // after this point – we’ll just truncate the value we load in codegen. - } - - // Check to see if we should use a different type for the - // discriminant. We can safely use a type with the same size - // as the alignment of the first field of each variant. - // We increase the size of the discriminant to avoid LLVM copying - // padding when it doesn't need to. This normally causes unaligned - // load/stores and excessive memcpy/memset operations. By using a - // bigger integer size, LLVM can be sure about its contents and - // won't be so conservative. - - // Use the initial field alignment - let mut ity = if def.repr().c() || def.repr().int.is_some() { - min_ity - } else { - Integer::for_align(dl, start_align).unwrap_or(min_ity) - }; - - // If the alignment is not larger than the chosen discriminant size, - // don't use the alignment as the final size. - if ity <= min_ity { - ity = min_ity; - } else { - // Patch up the variants' first few fields. - let old_ity_size = min_ity.size(); - let new_ity_size = ity.size(); - for variant in &mut layout_variants { - match variant.fields { - FieldsShape::Arbitrary { ref mut offsets, .. } => { - for i in offsets { - if *i <= old_ity_size { - assert_eq!(*i, old_ity_size); - *i = new_ity_size; - } - } - // We might be making the struct larger. - if variant.size <= old_ity_size { - variant.size = new_ity_size; - } - } - _ => bug!(), - } - } - } - - let tag_mask = ity.size().unsigned_int_max(); - let tag = Scalar::Initialized { - value: Int(ity, signed), - valid_range: WrappingRange { - start: (min as u128 & tag_mask), - end: (max as u128 & tag_mask), - }, - }; - let mut abi = Abi::Aggregate { sized: true }; - - if layout_variants.iter().all(|v| v.abi.is_uninhabited()) { - abi = Abi::Uninhabited; - } else if tag.size(dl) == size { - // Make sure we only use scalar layout when the enum is entirely its - // own tag (i.e. it has no padding nor any non-ZST variant fields). - abi = Abi::Scalar(tag); - } else { - // Try to use a ScalarPair for all tagged enums. - let mut common_prim = None; - let mut common_prim_initialized_in_all_variants = true; - for (field_layouts, layout_variant) in iter::zip(&variants, &layout_variants) { - let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else { - bug!(); - }; - let mut fields = - iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst()); - let (field, offset) = match (fields.next(), fields.next()) { - (None, None) => { - common_prim_initialized_in_all_variants = false; - continue; - } - (Some(pair), None) => pair, - _ => { - common_prim = None; - break; - } - }; - let prim = match field.abi { - Abi::Scalar(scalar) => { - common_prim_initialized_in_all_variants &= - matches!(scalar, Scalar::Initialized { .. }); - scalar.primitive() - } - _ => { - common_prim = None; - break; - } - }; - if let Some(pair) = common_prim { - // This is pretty conservative. We could go fancier - // by conflating things like i32 and u32, or even - // realising that (u8, u8) could just cohabit with - // u16 or even u32. - if pair != (prim, offset) { - common_prim = None; - break; - } - } else { - common_prim = Some((prim, offset)); - } - } - if let Some((prim, offset)) = common_prim { - let prim_scalar = if common_prim_initialized_in_all_variants { - scalar_unit(prim) - } else { - // Common prim might be uninit. - Scalar::Union { value: prim } - }; - let pair = self.scalar_pair(tag, prim_scalar); - let pair_offsets = match pair.fields { - FieldsShape::Arbitrary { ref offsets, ref memory_index } => { - assert_eq!(memory_index, &[0, 1]); - offsets - } - _ => bug!(), - }; - if pair_offsets[0] == Size::ZERO - && pair_offsets[1] == *offset - && align == pair.align - && size == pair.size - { - // We can use `ScalarPair` only when it matches our - // already computed layout (including `#[repr(C)]`). - abi = pair.abi; - } - } - } - - // If we pick a "clever" (by-value) ABI, we might have to adjust the ABI of the - // variants to ensure they are consistent. This is because a downcast is - // semantically a NOP, and thus should not affect layout. - if matches!(abi, Abi::Scalar(..) | Abi::ScalarPair(..)) { - for variant in &mut layout_variants { - // We only do this for variants with fields; the others are not accessed anyway. - // Also do not overwrite any already existing "clever" ABIs. - if variant.fields.count() > 0 - && matches!(variant.abi, Abi::Aggregate { .. }) - { - variant.abi = abi; - // Also need to bump up the size and alignment, so that the entire value fits in here. - variant.size = cmp::max(variant.size, size); - variant.align.abi = cmp::max(variant.align.abi, align.abi); - } - } - } - - let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag); - - let tagged_layout = LayoutS { - variants: Variants::Multiple { - tag, - tag_encoding: TagEncoding::Direct, - tag_field: 0, - variants: IndexVec::new(), - }, - fields: FieldsShape::Arbitrary { - offsets: vec![Size::ZERO], - memory_index: vec![0], - }, - largest_niche, - abi, - align, - size, - }; - - let tagged_layout = TmpLayout { layout: tagged_layout, variants: layout_variants }; - - let mut best_layout = match (tagged_layout, niche_filling_layout) { - (tl, Some(nl)) => { - // Pick the smaller layout; otherwise, - // pick the layout with the larger niche; otherwise, - // pick tagged as it has simpler codegen. - use Ordering::*; - let niche_size = |tmp_l: &TmpLayout<'_>| { - tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl)) - }; - match ( - tl.layout.size.cmp(&nl.layout.size), - niche_size(&tl).cmp(&niche_size(&nl)), - ) { - (Greater, _) => nl, - (Equal, Less) => nl, - _ => tl, - } - } - (tl, None) => tl, - }; - - // Now we can intern the variant layouts and store them in the enum layout. - best_layout.layout.variants = match best_layout.layout.variants { - Variants::Multiple { tag, tag_encoding, tag_field, .. } => Variants::Multiple { - tag, - tag_encoding, - tag_field, - variants: best_layout - .variants - .into_iter() - .map(|layout| tcx.intern_layout(layout)) - .collect(), - }, - _ => bug!(), - }; - - tcx.intern_layout(best_layout.layout) - } - - // Types with no meaningful known layout. - ty::Projection(_) | ty::Opaque(..) => { - // NOTE(eddyb) `layout_of` query should've normalized these away, - // if that was possible, so there's no reason to try again here. - return Err(LayoutError::Unknown(ty)); - } - - ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Infer(_) => { - bug!("Layout::compute: unexpected type `{}`", ty) - } - - ty::Bound(..) | ty::Param(_) | ty::Error(_) => { - return Err(LayoutError::Unknown(ty)); - } - }) - } -} - -/// Overlap eligibility and variant assignment for each GeneratorSavedLocal. -#[derive(Clone, Debug, PartialEq)] -enum SavedLocalEligibility { - Unassigned, - Assigned(VariantIdx), - // FIXME: Use newtype_index so we aren't wasting bytes - Ineligible(Option<u32>), -} - -// When laying out generators, we divide our saved local fields into two -// categories: overlap-eligible and overlap-ineligible. -// -// Those fields which are ineligible for overlap go in a "prefix" at the -// beginning of the layout, and always have space reserved for them. -// -// Overlap-eligible fields are only assigned to one variant, so we lay -// those fields out for each variant and put them right after the -// prefix. -// -// Finally, in the layout details, we point to the fields from the -// variants they are assigned to. It is possible for some fields to be -// included in multiple variants. No field ever "moves around" in the -// layout; its offset is always the same. -// -// Also included in the layout are the upvars and the discriminant. -// These are included as fields on the "outer" layout; they are not part -// of any variant. -impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { - /// Compute the eligibility and assignment of each local. - fn generator_saved_local_eligibility( - &self, - info: &GeneratorLayout<'tcx>, - ) -> (BitSet<GeneratorSavedLocal>, IndexVec<GeneratorSavedLocal, SavedLocalEligibility>) { - use SavedLocalEligibility::*; - - let mut assignments: IndexVec<GeneratorSavedLocal, SavedLocalEligibility> = - IndexVec::from_elem_n(Unassigned, info.field_tys.len()); - - // The saved locals not eligible for overlap. These will get - // "promoted" to the prefix of our generator. - let mut ineligible_locals = BitSet::new_empty(info.field_tys.len()); - - // Figure out which of our saved locals are fields in only - // one variant. The rest are deemed ineligible for overlap. - for (variant_index, fields) in info.variant_fields.iter_enumerated() { - for local in fields { - match assignments[*local] { - Unassigned => { - assignments[*local] = Assigned(variant_index); - } - Assigned(idx) => { - // We've already seen this local at another suspension - // point, so it is no longer a candidate. - trace!( - "removing local {:?} in >1 variant ({:?}, {:?})", - local, - variant_index, - idx - ); - ineligible_locals.insert(*local); - assignments[*local] = Ineligible(None); - } - Ineligible(_) => {} - } - } - } - - // Next, check every pair of eligible locals to see if they - // conflict. - for local_a in info.storage_conflicts.rows() { - let conflicts_a = info.storage_conflicts.count(local_a); - if ineligible_locals.contains(local_a) { - continue; - } - - for local_b in info.storage_conflicts.iter(local_a) { - // local_a and local_b are storage live at the same time, therefore they - // cannot overlap in the generator layout. The only way to guarantee - // this is if they are in the same variant, or one is ineligible - // (which means it is stored in every variant). - if ineligible_locals.contains(local_b) - || assignments[local_a] == assignments[local_b] - { - continue; - } - - // If they conflict, we will choose one to make ineligible. - // This is not always optimal; it's just a greedy heuristic that - // seems to produce good results most of the time. - let conflicts_b = info.storage_conflicts.count(local_b); - let (remove, other) = - if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) }; - ineligible_locals.insert(remove); - assignments[remove] = Ineligible(None); - trace!("removing local {:?} due to conflict with {:?}", remove, other); - } - } - - // Count the number of variants in use. If only one of them, then it is - // impossible to overlap any locals in our layout. In this case it's - // always better to make the remaining locals ineligible, so we can - // lay them out with the other locals in the prefix and eliminate - // unnecessary padding bytes. - { - let mut used_variants = BitSet::new_empty(info.variant_fields.len()); - for assignment in &assignments { - if let Assigned(idx) = assignment { - used_variants.insert(*idx); - } - } - if used_variants.count() < 2 { - for assignment in assignments.iter_mut() { - *assignment = Ineligible(None); - } - ineligible_locals.insert_all(); - } - } - - // Write down the order of our locals that will be promoted to the prefix. - { - for (idx, local) in ineligible_locals.iter().enumerate() { - assignments[local] = Ineligible(Some(idx as u32)); - } - } - debug!("generator saved local assignments: {:?}", assignments); - - (ineligible_locals, assignments) - } - - /// Compute the full generator layout. - fn generator_layout( - &self, - ty: Ty<'tcx>, - def_id: hir::def_id::DefId, - substs: SubstsRef<'tcx>, - ) -> Result<Layout<'tcx>, LayoutError<'tcx>> { - use SavedLocalEligibility::*; - let tcx = self.tcx; - let subst_field = |ty: Ty<'tcx>| EarlyBinder(ty).subst(tcx, substs); - - let Some(info) = tcx.generator_layout(def_id) else { - return Err(LayoutError::Unknown(ty)); - }; - let (ineligible_locals, assignments) = self.generator_saved_local_eligibility(&info); - - // Build a prefix layout, including "promoting" all ineligible - // locals as part of the prefix. We compute the layout of all of - // these fields at once to get optimal packing. - let tag_index = substs.as_generator().prefix_tys().count(); - - // `info.variant_fields` already accounts for the reserved variants, so no need to add them. - let max_discr = (info.variant_fields.len() - 1) as u128; - let discr_int = Integer::fit_unsigned(max_discr); - let discr_int_ty = discr_int.to_ty(tcx, false); - let tag = Scalar::Initialized { - value: Primitive::Int(discr_int, false), - valid_range: WrappingRange { start: 0, end: max_discr }, - }; - let tag_layout = self.tcx.intern_layout(LayoutS::scalar(self, tag)); - let tag_layout = TyAndLayout { ty: discr_int_ty, layout: tag_layout }; - - let promoted_layouts = ineligible_locals - .iter() - .map(|local| subst_field(info.field_tys[local])) - .map(|ty| tcx.mk_maybe_uninit(ty)) - .map(|ty| self.layout_of(ty)); - let prefix_layouts = substs - .as_generator() - .prefix_tys() - .map(|ty| self.layout_of(ty)) - .chain(iter::once(Ok(tag_layout))) - .chain(promoted_layouts) - .collect::<Result<Vec<_>, _>>()?; - let prefix = self.univariant_uninterned( - ty, - &prefix_layouts, - &ReprOptions::default(), - StructKind::AlwaysSized, - )?; - - let (prefix_size, prefix_align) = (prefix.size, prefix.align); - - // Split the prefix layout into the "outer" fields (upvars and - // discriminant) and the "promoted" fields. Promoted fields will - // get included in each variant that requested them in - // GeneratorLayout. - debug!("prefix = {:#?}", prefix); - let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields { - FieldsShape::Arbitrary { mut offsets, memory_index } => { - let mut inverse_memory_index = invert_mapping(&memory_index); - - // "a" (`0..b_start`) and "b" (`b_start..`) correspond to - // "outer" and "promoted" fields respectively. - let b_start = (tag_index + 1) as u32; - let offsets_b = offsets.split_off(b_start as usize); - let offsets_a = offsets; - - // Disentangle the "a" and "b" components of `inverse_memory_index` - // by preserving the order but keeping only one disjoint "half" each. - // FIXME(eddyb) build a better abstraction for permutations, if possible. - let inverse_memory_index_b: Vec<_> = - inverse_memory_index.iter().filter_map(|&i| i.checked_sub(b_start)).collect(); - inverse_memory_index.retain(|&i| i < b_start); - let inverse_memory_index_a = inverse_memory_index; - - // Since `inverse_memory_index_{a,b}` each only refer to their - // respective fields, they can be safely inverted - let memory_index_a = invert_mapping(&inverse_memory_index_a); - let memory_index_b = invert_mapping(&inverse_memory_index_b); - - let outer_fields = - FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a }; - (outer_fields, offsets_b, memory_index_b) - } - _ => bug!(), - }; - - let mut size = prefix.size; - let mut align = prefix.align; - let variants = info - .variant_fields - .iter_enumerated() - .map(|(index, variant_fields)| { - // Only include overlap-eligible fields when we compute our variant layout. - let variant_only_tys = variant_fields - .iter() - .filter(|local| match assignments[**local] { - Unassigned => bug!(), - Assigned(v) if v == index => true, - Assigned(_) => bug!("assignment does not match variant"), - Ineligible(_) => false, - }) - .map(|local| subst_field(info.field_tys[*local])); - - let mut variant = self.univariant_uninterned( - ty, - &variant_only_tys - .map(|ty| self.layout_of(ty)) - .collect::<Result<Vec<_>, _>>()?, - &ReprOptions::default(), - StructKind::Prefixed(prefix_size, prefix_align.abi), - )?; - variant.variants = Variants::Single { index }; - - let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else { - bug!(); - }; - - // Now, stitch the promoted and variant-only fields back together in - // the order they are mentioned by our GeneratorLayout. - // Because we only use some subset (that can differ between variants) - // of the promoted fields, we can't just pick those elements of the - // `promoted_memory_index` (as we'd end up with gaps). - // So instead, we build an "inverse memory_index", as if all of the - // promoted fields were being used, but leave the elements not in the - // subset as `INVALID_FIELD_IDX`, which we can filter out later to - // obtain a valid (bijective) mapping. - const INVALID_FIELD_IDX: u32 = !0; - let mut combined_inverse_memory_index = - vec![INVALID_FIELD_IDX; promoted_memory_index.len() + memory_index.len()]; - let mut offsets_and_memory_index = iter::zip(offsets, memory_index); - let combined_offsets = variant_fields - .iter() - .enumerate() - .map(|(i, local)| { - let (offset, memory_index) = match assignments[*local] { - Unassigned => bug!(), - Assigned(_) => { - let (offset, memory_index) = - offsets_and_memory_index.next().unwrap(); - (offset, promoted_memory_index.len() as u32 + memory_index) - } - Ineligible(field_idx) => { - let field_idx = field_idx.unwrap() as usize; - (promoted_offsets[field_idx], promoted_memory_index[field_idx]) - } - }; - combined_inverse_memory_index[memory_index as usize] = i as u32; - offset - }) - .collect(); - - // Remove the unused slots and invert the mapping to obtain the - // combined `memory_index` (also see previous comment). - combined_inverse_memory_index.retain(|&i| i != INVALID_FIELD_IDX); - let combined_memory_index = invert_mapping(&combined_inverse_memory_index); - - variant.fields = FieldsShape::Arbitrary { - offsets: combined_offsets, - memory_index: combined_memory_index, - }; - - size = size.max(variant.size); - align = align.max(variant.align); - Ok(tcx.intern_layout(variant)) - }) - .collect::<Result<IndexVec<VariantIdx, _>, _>>()?; - - size = size.align_to(align.abi); - - let abi = - if prefix.abi.is_uninhabited() || variants.iter().all(|v| v.abi().is_uninhabited()) { - Abi::Uninhabited - } else { - Abi::Aggregate { sized: true } - }; - - let layout = tcx.intern_layout(LayoutS { - variants: Variants::Multiple { - tag, - tag_encoding: TagEncoding::Direct, - tag_field: tag_index, - variants, - }, - fields: outer_fields, - abi, - largest_niche: prefix.largest_niche, - size, - align, - }); - debug!("generator layout ({:?}): {:#?}", ty, layout); - Ok(layout) - } - - /// This is invoked by the `layout_of` query to record the final - /// layout of each type. - #[inline(always)] - fn record_layout_for_printing(&self, layout: TyAndLayout<'tcx>) { - // If we are running with `-Zprint-type-sizes`, maybe record layouts - // for dumping later. - if self.tcx.sess.opts.unstable_opts.print_type_sizes { - self.record_layout_for_printing_outlined(layout) - } - } - - fn record_layout_for_printing_outlined(&self, layout: TyAndLayout<'tcx>) { - // Ignore layouts that are done with non-empty environments or - // non-monomorphic layouts, as the user only wants to see the stuff - // resulting from the final codegen session. - if layout.ty.has_param_types_or_consts() || !self.param_env.caller_bounds().is_empty() { - return; - } - - // (delay format until we actually need it) - let record = |kind, packed, opt_discr_size, variants| { - let type_desc = format!("{:?}", layout.ty); - self.tcx.sess.code_stats.record_type_size( - kind, - type_desc, - layout.align.abi, - layout.size, - packed, - opt_discr_size, - variants, - ); - }; - - let adt_def = match *layout.ty.kind() { - ty::Adt(ref adt_def, _) => { - debug!("print-type-size t: `{:?}` process adt", layout.ty); - adt_def - } - - ty::Closure(..) => { - debug!("print-type-size t: `{:?}` record closure", layout.ty); - record(DataTypeKind::Closure, false, None, vec![]); - return; - } - - _ => { - debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty); - return; - } - }; - - let adt_kind = adt_def.adt_kind(); - let adt_packed = adt_def.repr().pack.is_some(); - - let build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| { - let mut min_size = Size::ZERO; - let field_info: Vec<_> = flds - .iter() - .enumerate() - .map(|(i, &name)| { - let field_layout = layout.field(self, i); - let offset = layout.fields.offset(i); - let field_end = offset + field_layout.size; - if min_size < field_end { - min_size = field_end; - } - FieldInfo { - name, - offset: offset.bytes(), - size: field_layout.size.bytes(), - align: field_layout.align.abi.bytes(), - } - }) - .collect(); - - VariantInfo { - name: n, - kind: if layout.is_unsized() { SizeKind::Min } else { SizeKind::Exact }, - align: layout.align.abi.bytes(), - size: if min_size.bytes() == 0 { layout.size.bytes() } else { min_size.bytes() }, - fields: field_info, - } - }; - - match layout.variants { - Variants::Single { index } => { - if !adt_def.variants().is_empty() && layout.fields != FieldsShape::Primitive { - debug!( - "print-type-size `{:#?}` variant {}", - layout, - adt_def.variant(index).name - ); - let variant_def = &adt_def.variant(index); - let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect(); - record( - adt_kind.into(), - adt_packed, - None, - vec![build_variant_info(Some(variant_def.name), &fields, layout)], - ); - } else { - // (This case arises for *empty* enums; so give it - // zero variants.) - record(adt_kind.into(), adt_packed, None, vec![]); - } - } - - Variants::Multiple { tag, ref tag_encoding, .. } => { - debug!( - "print-type-size `{:#?}` adt general variants def {}", - layout.ty, - adt_def.variants().len() - ); - let variant_infos: Vec<_> = adt_def - .variants() - .iter_enumerated() - .map(|(i, variant_def)| { - let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect(); - build_variant_info( - Some(variant_def.name), - &fields, - layout.for_variant(self, i), - ) - }) - .collect(); - record( - adt_kind.into(), - adt_packed, - match tag_encoding { - TagEncoding::Direct => Some(tag.size(self)), - _ => None, - }, - variant_infos, - ); - } - } - } -} - /// Type size "skeleton", i.e., the only information determining a type's size. /// While this is conservative, (aside from constant sizes, only pointers, /// newtypes thereof and null pointer optimized enums are allowed), it is @@ -2057,7 +244,7 @@ impl<'tcx> SizeSkeleton<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Result<SizeSkeleton<'tcx>, LayoutError<'tcx>> { - debug_assert!(!ty.has_infer_types_or_consts()); + debug_assert!(!ty.has_non_region_infer()); // First try computing a static layout. let err = match tcx.layout_of(param_env.and(ty)) { @@ -2073,7 +260,7 @@ impl<'tcx> SizeSkeleton<'tcx> { let tail = tcx.struct_tail_erasing_lifetimes(pointee, param_env); match tail.kind() { ty::Param(_) | ty::Projection(_) => { - debug_assert!(tail.has_param_types_or_consts()); + debug_assert!(tail.has_non_region_param()); Ok(SizeSkeleton::Pointer { non_zero, tail: tcx.erase_regions(tail) }) } _ => bug!( @@ -2747,117 +934,6 @@ where } } -impl<'tcx> ty::Instance<'tcx> { - // NOTE(eddyb) this is private to avoid using it from outside of - // `fn_abi_of_instance` - any other uses are either too high-level - // for `Instance` (e.g. typeck would use `Ty::fn_sig` instead), - // or should go through `FnAbi` instead, to avoid losing any - // adjustments `fn_abi_of_instance` might be performing. - #[tracing::instrument(level = "debug", skip(tcx, param_env))] - fn fn_sig_for_fn_abi( - &self, - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> ty::PolyFnSig<'tcx> { - let ty = self.ty(tcx, param_env); - match *ty.kind() { - ty::FnDef(..) => { - // HACK(davidtwco,eddyb): This is a workaround for polymorphization considering - // parameters unused if they show up in the signature, but not in the `mir::Body` - // (i.e. due to being inside a projection that got normalized, see - // `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping - // track of a polymorphization `ParamEnv` to allow normalizing later. - // - // We normalize the `fn_sig` again after substituting at a later point. - let mut sig = match *ty.kind() { - ty::FnDef(def_id, substs) => tcx - .bound_fn_sig(def_id) - .map_bound(|fn_sig| { - tcx.normalize_erasing_regions(tcx.param_env(def_id), fn_sig) - }) - .subst(tcx, substs), - _ => unreachable!(), - }; - - if let ty::InstanceDef::VTableShim(..) = self.def { - // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. - sig = sig.map_bound(|mut sig| { - let mut inputs_and_output = sig.inputs_and_output.to_vec(); - inputs_and_output[0] = tcx.mk_mut_ptr(inputs_and_output[0]); - sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output); - sig - }); - } - sig - } - ty::Closure(def_id, substs) => { - let sig = substs.as_closure().sig(); - - let bound_vars = tcx.mk_bound_variable_kinds( - sig.bound_vars() - .iter() - .chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), - ); - let br = ty::BoundRegion { - var: ty::BoundVar::from_usize(bound_vars.len() - 1), - kind: ty::BoundRegionKind::BrEnv, - }; - let env_region = ty::ReLateBound(ty::INNERMOST, br); - let env_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap(); - - let sig = sig.skip_binder(); - ty::Binder::bind_with_vars( - tcx.mk_fn_sig( - iter::once(env_ty).chain(sig.inputs().iter().cloned()), - sig.output(), - sig.c_variadic, - sig.unsafety, - sig.abi, - ), - bound_vars, - ) - } - ty::Generator(_, substs, _) => { - let sig = substs.as_generator().poly_sig(); - - let bound_vars = tcx.mk_bound_variable_kinds( - sig.bound_vars() - .iter() - .chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), - ); - let br = ty::BoundRegion { - var: ty::BoundVar::from_usize(bound_vars.len() - 1), - kind: ty::BoundRegionKind::BrEnv, - }; - let env_region = ty::ReLateBound(ty::INNERMOST, br); - let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); - - let pin_did = tcx.require_lang_item(LangItem::Pin, None); - let pin_adt_ref = tcx.adt_def(pin_did); - let pin_substs = tcx.intern_substs(&[env_ty.into()]); - let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs); - - let sig = sig.skip_binder(); - let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); - let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); - let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); - ty::Binder::bind_with_vars( - tcx.mk_fn_sig( - [env_ty, sig.resume_ty].iter(), - &ret_ty, - false, - hir::Unsafety::Normal, - rustc_target::spec::abi::Abi::Rust, - ), - bound_vars, - ) - } - _ => bug!("unexpected type {:?} in Instance::fn_sig", ty), - } - } -} - /// Calculates whether a function's ABI can unwind or not. /// /// This takes two primary parameters: @@ -3000,40 +1076,6 @@ pub fn fn_can_unwind<'tcx>(tcx: TyCtxt<'tcx>, fn_def_id: Option<DefId>, abi: Spe } } -#[inline] -pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv { - use rustc_target::spec::abi::Abi::*; - match tcx.sess.target.adjust_abi(abi) { - RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust, - RustCold => Conv::RustCold, - - // It's the ABI's job to select this, not ours. - System { .. } => bug!("system abi should be selected elsewhere"), - EfiApi => bug!("eficall abi should be selected elsewhere"), - - Stdcall { .. } => Conv::X86Stdcall, - Fastcall { .. } => Conv::X86Fastcall, - Vectorcall { .. } => Conv::X86VectorCall, - Thiscall { .. } => Conv::X86ThisCall, - C { .. } => Conv::C, - Unadjusted => Conv::C, - Win64 { .. } => Conv::X86_64Win64, - SysV64 { .. } => Conv::X86_64SysV, - Aapcs { .. } => Conv::ArmAapcs, - CCmseNonSecureCall => Conv::CCmseNonSecureCall, - PtxKernel => Conv::PtxKernel, - Msp430Interrupt => Conv::Msp430Intr, - X86Interrupt => Conv::X86Intr, - AmdGpuKernel => Conv::AmdGpuKernel, - AvrInterrupt => Conv::AvrInterrupt, - AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt, - Wasm => Conv::C, - - // These API constants ought to be more specific... - Cdecl { .. } => Conv::C, - } -} - /// Error produced by attempting to compute or adjust a `FnAbi`. #[derive(Copy, Clone, Debug, HashStable)] pub enum FnAbiError<'tcx> { @@ -3065,6 +1107,12 @@ impl<'tcx> fmt::Display for FnAbiError<'tcx> { } } +impl<'tcx> IntoDiagnostic<'tcx, !> for FnAbiError<'tcx> { + fn into_diagnostic(self, handler: &'tcx Handler) -> DiagnosticBuilder<'tcx, !> { + handler.struct_fatal(self.to_string()) + } +} + // FIXME(eddyb) maybe use something like this for an unified `fn_abi_of`, not // just for error handling. #[derive(Debug)] @@ -3146,367 +1194,3 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> { } impl<'tcx, C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {} - -fn fn_abi_of_fn_ptr<'tcx>( - tcx: TyCtxt<'tcx>, - query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>, -) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { - let (param_env, (sig, extra_args)) = query.into_parts(); - - LayoutCx { tcx, param_env }.fn_abi_new_uncached(sig, extra_args, None, None, false) -} - -fn fn_abi_of_instance<'tcx>( - tcx: TyCtxt<'tcx>, - query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>, -) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { - let (param_env, (instance, extra_args)) = query.into_parts(); - - let sig = instance.fn_sig_for_fn_abi(tcx, param_env); - - let caller_location = if instance.def.requires_caller_location(tcx) { - Some(tcx.caller_location_ty()) - } else { - None - }; - - LayoutCx { tcx, param_env }.fn_abi_new_uncached( - sig, - extra_args, - caller_location, - Some(instance.def_id()), - matches!(instance.def, ty::InstanceDef::Virtual(..)), - ) -} - -// Handle safe Rust thin and fat pointers. -pub fn adjust_for_rust_scalar<'tcx>( - cx: LayoutCx<'tcx, TyCtxt<'tcx>>, - attrs: &mut ArgAttributes, - scalar: Scalar, - layout: TyAndLayout<'tcx>, - offset: Size, - is_return: bool, -) { - // Booleans are always a noundef i1 that needs to be zero-extended. - if scalar.is_bool() { - attrs.ext(ArgExtension::Zext); - attrs.set(ArgAttribute::NoUndef); - return; - } - - // Scalars which have invalid values cannot be undef. - if !scalar.is_always_valid(&cx) { - attrs.set(ArgAttribute::NoUndef); - } - - // Only pointer types handled below. - let Scalar::Initialized { value: Pointer, valid_range} = scalar else { return }; - - if !valid_range.contains(0) { - attrs.set(ArgAttribute::NonNull); - } - - if let Some(pointee) = layout.pointee_info_at(&cx, offset) { - if let Some(kind) = pointee.safe { - attrs.pointee_align = Some(pointee.align); - - // `Box` (`UniqueBorrowed`) are not necessarily dereferenceable - // for the entire duration of the function as they can be deallocated - // at any time. Same for shared mutable references. If LLVM had a - // way to say "dereferenceable on entry" we could use it here. - attrs.pointee_size = match kind { - PointerKind::UniqueBorrowed - | PointerKind::UniqueBorrowedPinned - | PointerKind::Frozen => pointee.size, - PointerKind::SharedMutable | PointerKind::UniqueOwned => Size::ZERO, - }; - - // `Box`, `&T`, and `&mut T` cannot be undef. - // Note that this only applies to the value of the pointer itself; - // this attribute doesn't make it UB for the pointed-to data to be undef. - attrs.set(ArgAttribute::NoUndef); - - // The aliasing rules for `Box<T>` are still not decided, but currently we emit - // `noalias` for it. This can be turned off using an unstable flag. - // See https://github.com/rust-lang/unsafe-code-guidelines/issues/326 - let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias.unwrap_or(true); - - // `&mut` pointer parameters never alias other parameters, - // or mutable global data - // - // `&T` where `T` contains no `UnsafeCell<U>` is immutable, - // and can be marked as both `readonly` and `noalias`, as - // LLVM's definition of `noalias` is based solely on memory - // dependencies rather than pointer equality - // - // Due to past miscompiles in LLVM, we apply a separate NoAliasMutRef attribute - // for UniqueBorrowed arguments, so that the codegen backend can decide whether - // or not to actually emit the attribute. It can also be controlled with the - // `-Zmutable-noalias` debugging option. - let no_alias = match kind { - PointerKind::SharedMutable - | PointerKind::UniqueBorrowed - | PointerKind::UniqueBorrowedPinned => false, - PointerKind::UniqueOwned => noalias_for_box, - PointerKind::Frozen => !is_return, - }; - if no_alias { - attrs.set(ArgAttribute::NoAlias); - } - - if kind == PointerKind::Frozen && !is_return { - attrs.set(ArgAttribute::ReadOnly); - } - - if kind == PointerKind::UniqueBorrowed && !is_return { - attrs.set(ArgAttribute::NoAliasMutRef); - } - } - } -} - -impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { - // FIXME(eddyb) perhaps group the signature/type-containing (or all of them?) - // arguments of this method, into a separate `struct`. - #[tracing::instrument( - level = "debug", - skip(self, caller_location, fn_def_id, force_thin_self_ptr) - )] - fn fn_abi_new_uncached( - &self, - sig: ty::PolyFnSig<'tcx>, - extra_args: &[Ty<'tcx>], - caller_location: Option<Ty<'tcx>>, - fn_def_id: Option<DefId>, - // FIXME(eddyb) replace this with something typed, like an `enum`. - force_thin_self_ptr: bool, - ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { - let sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, sig); - - let conv = conv_from_spec_abi(self.tcx(), sig.abi); - - let mut inputs = sig.inputs(); - let extra_args = if sig.abi == RustCall { - assert!(!sig.c_variadic && extra_args.is_empty()); - - if let Some(input) = sig.inputs().last() { - if let ty::Tuple(tupled_arguments) = input.kind() { - inputs = &sig.inputs()[0..sig.inputs().len() - 1]; - tupled_arguments - } else { - bug!( - "argument to function with \"rust-call\" ABI \ - is not a tuple" - ); - } - } else { - bug!( - "argument to function with \"rust-call\" ABI \ - is not a tuple" - ); - } - } else { - assert!(sig.c_variadic || extra_args.is_empty()); - extra_args - }; - - let target = &self.tcx.sess.target; - let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc"); - let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu"; - let linux_s390x_gnu_like = - target.os == "linux" && target.arch == "s390x" && target_env_gnu_like; - let linux_sparc64_gnu_like = - target.os == "linux" && target.arch == "sparc64" && target_env_gnu_like; - let linux_powerpc_gnu_like = - target.os == "linux" && target.arch == "powerpc" && target_env_gnu_like; - use SpecAbi::*; - let rust_abi = matches!(sig.abi, RustIntrinsic | PlatformIntrinsic | Rust | RustCall); - - let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> { - let span = tracing::debug_span!("arg_of"); - let _entered = span.enter(); - let is_return = arg_idx.is_none(); - - let layout = self.layout_of(ty)?; - let layout = if force_thin_self_ptr && arg_idx == Some(0) { - // Don't pass the vtable, it's not an argument of the virtual fn. - // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` - // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen - make_thin_self_ptr(self, layout) - } else { - layout - }; - - let mut arg = ArgAbi::new(self, layout, |layout, scalar, offset| { - let mut attrs = ArgAttributes::new(); - adjust_for_rust_scalar(*self, &mut attrs, scalar, *layout, offset, is_return); - attrs - }); - - if arg.layout.is_zst() { - // For some forsaken reason, x86_64-pc-windows-gnu - // doesn't ignore zero-sized struct arguments. - // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc}. - if is_return - || rust_abi - || (!win_x64_gnu - && !linux_s390x_gnu_like - && !linux_sparc64_gnu_like - && !linux_powerpc_gnu_like) - { - arg.mode = PassMode::Ignore; - } - } - - Ok(arg) - }; - - let mut fn_abi = FnAbi { - ret: arg_of(sig.output(), None)?, - args: inputs - .iter() - .copied() - .chain(extra_args.iter().copied()) - .chain(caller_location) - .enumerate() - .map(|(i, ty)| arg_of(ty, Some(i))) - .collect::<Result<_, _>>()?, - c_variadic: sig.c_variadic, - fixed_count: inputs.len() as u32, - conv, - can_unwind: fn_can_unwind(self.tcx(), fn_def_id, sig.abi), - }; - self.fn_abi_adjust_for_abi(&mut fn_abi, sig.abi)?; - debug!("fn_abi_new_uncached = {:?}", fn_abi); - Ok(self.tcx.arena.alloc(fn_abi)) - } - - #[tracing::instrument(level = "trace", skip(self))] - fn fn_abi_adjust_for_abi( - &self, - fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>, - abi: SpecAbi, - ) -> Result<(), FnAbiError<'tcx>> { - if abi == SpecAbi::Unadjusted { - return Ok(()); - } - - if abi == SpecAbi::Rust - || abi == SpecAbi::RustCall - || abi == SpecAbi::RustIntrinsic - || abi == SpecAbi::PlatformIntrinsic - { - let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>| { - if arg.is_ignore() { - return; - } - - match arg.layout.abi { - Abi::Aggregate { .. } => {} - - // This is a fun case! The gist of what this is doing is - // that we want callers and callees to always agree on the - // ABI of how they pass SIMD arguments. If we were to *not* - // make these arguments indirect then they'd be immediates - // in LLVM, which means that they'd used whatever the - // appropriate ABI is for the callee and the caller. That - // means, for example, if the caller doesn't have AVX - // enabled but the callee does, then passing an AVX argument - // across this boundary would cause corrupt data to show up. - // - // This problem is fixed by unconditionally passing SIMD - // arguments through memory between callers and callees - // which should get them all to agree on ABI regardless of - // target feature sets. Some more information about this - // issue can be found in #44367. - // - // Note that the platform intrinsic ABI is exempt here as - // that's how we connect up to LLVM and it's unstable - // anyway, we control all calls to it in libstd. - Abi::Vector { .. } - if abi != SpecAbi::PlatformIntrinsic - && self.tcx.sess.target.simd_types_indirect => - { - arg.make_indirect(); - return; - } - - _ => return, - } - - let size = arg.layout.size; - if arg.layout.is_unsized() || size > Pointer.size(self) { - arg.make_indirect(); - } else { - // We want to pass small aggregates as immediates, but using - // a LLVM aggregate type for this leads to bad optimizations, - // so we pick an appropriately sized integer type instead. - arg.cast_to(Reg { kind: RegKind::Integer, size }); - } - }; - fixup(&mut fn_abi.ret); - for arg in fn_abi.args.iter_mut() { - fixup(arg); - } - } else { - fn_abi.adjust_for_foreign_abi(self, abi)?; - } - - Ok(()) - } -} - -#[tracing::instrument(level = "debug", skip(cx))] -fn make_thin_self_ptr<'tcx>( - cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>), - layout: TyAndLayout<'tcx>, -) -> TyAndLayout<'tcx> { - let tcx = cx.tcx(); - let fat_pointer_ty = if layout.is_unsized() { - // unsized `self` is passed as a pointer to `self` - // FIXME (mikeyhew) change this to use &own if it is ever added to the language - tcx.mk_mut_ptr(layout.ty) - } else { - match layout.abi { - Abi::ScalarPair(..) | Abi::Scalar(..) => (), - _ => bug!("receiver type has unsupported layout: {:?}", layout), - } - - // In the case of Rc<Self>, we need to explicitly pass a *mut RcBox<Self> - // with a Scalar (not ScalarPair) ABI. This is a hack that is understood - // elsewhere in the compiler as a method on a `dyn Trait`. - // To get the type `*mut RcBox<Self>`, we just keep unwrapping newtypes until we - // get a built-in pointer type - let mut fat_pointer_layout = layout; - 'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr() - && !fat_pointer_layout.ty.is_region_ptr() - { - for i in 0..fat_pointer_layout.fields.count() { - let field_layout = fat_pointer_layout.field(cx, i); - - if !field_layout.is_zst() { - fat_pointer_layout = field_layout; - continue 'descend_newtypes; - } - } - - bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout); - } - - fat_pointer_layout.ty - }; - - // we now have a type like `*mut RcBox<dyn Trait>` - // change its layout to that of `*mut ()`, a thin pointer, but keep the same type - // this is understood as a special case elsewhere in the compiler - let unit_ptr_ty = tcx.mk_mut_ptr(tcx.mk_unit()); - - TyAndLayout { - ty: fat_pointer_ty, - - // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing the `Result` - // should always work because the type is always `*mut ()`. - ..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap() - } -} diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 63dd213a085..753d7bffe84 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -130,7 +130,6 @@ mod erase_regions; mod generics; mod impls_ty; mod instance; -mod layout_sanity_check; mod list; mod parameterized; mod rvalue_scopes; @@ -2593,7 +2592,6 @@ pub fn provide(providers: &mut ty::query::Providers) { closure::provide(providers); context::provide(providers); erase_regions::provide(providers); - layout::provide(providers); util::provide(providers); print::provide(providers); super::util::bug::provide(providers); diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index 9c8dc30e2db..0257ca7b29c 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -1,3 +1,4 @@ +use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::{DefId, DefIndex}; use rustc_index::vec::{Idx, IndexVec}; @@ -29,6 +30,10 @@ impl<I: Idx + 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for IndexVe type Value<'tcx> = IndexVec<I, T::Value<'tcx>>; } +impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for FxHashMap<I, T> { + type Value<'tcx> = FxHashMap<I, T::Value<'tcx>>; +} + impl<T: ParameterizedOverTcx> ParameterizedOverTcx for ty::Binder<'static, T> { type Value<'tcx> = ty::Binder<'tcx, T::Value<'tcx>>; } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 70efa748846..82d7c0a97cb 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -927,7 +927,7 @@ pub trait PrettyPrinter<'tcx>: // unless we can find out what generator return type it comes from. let term = if let Some(ty) = term.skip_binder().ty() && let ty::Projection(proj) = ty.kind() - && let assoc = tcx.associated_item(proj.item_def_id) + && let Some(assoc) = tcx.opt_associated_item(proj.item_def_id) && assoc.trait_container(tcx) == tcx.lang_items().gen_trait() && assoc.name == rustc_span::sym::Return { @@ -2173,10 +2173,16 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { let mut region_index = self.region_index; let mut next_name = |this: &Self| { - let name = name_by_region_index(region_index, &mut available_names, num_available); - debug!(?name); - region_index += 1; - assert!(!this.used_region_names.contains(&name)); + let mut name; + + loop { + name = name_by_region_index(region_index, &mut available_names, num_available); + region_index += 1; + + if !this.used_region_names.contains(&name) { + break; + } + } name }; diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 169da348a29..b6cda34c51f 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -1,6 +1,6 @@ use crate::dep_graph; use crate::infer::canonical::{self, Canonical}; -use crate::lint::LintLevelMap; +use crate::lint::LintExpectation; use crate::metadata::ModChild; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; @@ -51,6 +51,7 @@ use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec}; use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion}; use rustc_session::cstore::{CrateDepKind, CrateSource}; use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib}; +use rustc_session::lint::LintExpectationId; use rustc_session::utils::NativeLibKind; use rustc_session::Limits; use rustc_span::symbol::Symbol; diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index a939be32fff..36eb2ab5157 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -492,6 +492,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { } impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List<T> { + #[inline] fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.iter().try_for_each(|t| t.visit_with(visitor)) } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index d93aab04e99..713f9067a85 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1289,12 +1289,24 @@ pub fn is_doc_hidden(tcx: TyCtxt<'_>, def_id: DefId) -> bool { .any(|items| items.iter().any(|item| item.has_name(sym::hidden))) } +/// Determines whether an item is annotated with `doc(notable_trait)`. +pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { + tcx.get_attrs(def_id, sym::doc) + .filter_map(|attr| attr.meta_item_list()) + .any(|items| items.iter().any(|item| item.has_name(sym::notable_trait))) +} + /// Determines whether an item is an intrinsic by Abi. pub fn is_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool { matches!(tcx.fn_sig(def_id).abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic) } pub fn provide(providers: &mut ty::query::Providers) { - *providers = - ty::query::Providers { normalize_opaque_types, is_doc_hidden, is_intrinsic, ..*providers } + *providers = ty::query::Providers { + normalize_opaque_types, + is_doc_hidden, + is_doc_notable_trait, + is_intrinsic, + ..*providers + } } diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 9c3b6a794e1..44efb93a53b 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -104,8 +104,8 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { None } } - fn has_param_types_or_consts(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_PARAM | TypeFlags::HAS_CT_PARAM) + fn has_non_region_param(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_SUBST - TypeFlags::HAS_RE_PARAM) } fn has_infer_regions(&self) -> bool { self.has_type_flags(TypeFlags::HAS_RE_INFER) @@ -113,8 +113,8 @@ pub trait TypeVisitable<'tcx>: fmt::Debug + Clone { fn has_infer_types(&self) -> bool { self.has_type_flags(TypeFlags::HAS_TY_INFER) } - fn has_infer_types_or_consts(&self) -> bool { - self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_CT_INFER) + fn has_non_region_infer(&self) -> bool { + self.has_type_flags(TypeFlags::NEEDS_INFER - TypeFlags::HAS_RE_INFER) } fn needs_infer(&self) -> bool { self.has_type_flags(TypeFlags::NEEDS_INFER) diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 495738ebe1c..5e8ce65daf0 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -89,15 +89,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { UNSAFE_OP_IN_UNSAFE_FN, self.hir_context, span, - |lint| { - lint.build(&format!( - "{} is unsafe and requires unsafe block (error E0133)", - description, - )) - .span_label(span, kind.simple_description()) - .note(note) - .emit(); - }, + format!("{} is unsafe and requires unsafe block (error E0133)", description,), + |lint| lint.span_label(span, kind.simple_description()).note(note), ) } SafetyContext::Safe => { @@ -125,14 +118,13 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { enclosing_unsafe: Option<(Span, &'static str)>, ) { let block_span = self.tcx.sess.source_map().guess_head_span(block_span); - self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, |lint| { - let msg = "unnecessary `unsafe` block"; - let mut db = lint.build(msg); - db.span_label(block_span, msg); + let msg = "unnecessary `unsafe` block"; + self.tcx.struct_span_lint_hir(UNUSED_UNSAFE, hir_id, block_span, msg, |lint| { + lint.span_label(block_span, msg); if let Some((span, kind)) = enclosing_unsafe { - db.span_label(span, format!("because it's nested under this `unsafe` {}", kind)); + lint.span_label(span, format!("because it's nested under this `unsafe` {}", kind)); } - db.emit(); + lint }); } @@ -364,7 +356,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> { // If the called function has target features the calling function hasn't, // the call requires `unsafe`. Don't check this on wasm // targets, though. For more information on wasm see the - // is_like_wasm check in typeck/src/collect.rs + // is_like_wasm check in hir_analysis/src/collect.rs if !self.tcx.sess.target.options.is_like_wasm && !self .tcx diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 54d549fd66c..b21f30efce8 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -36,16 +36,20 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) { let sp = tcx.def_span(def_id); let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - tcx.struct_span_lint_hir(UNCONDITIONAL_RECURSION, hir_id, sp, |lint| { - let mut db = lint.build("function cannot return without recursing"); - db.span_label(sp, "cannot return without recursing"); - // offer some help to the programmer. - for call_span in vis.reachable_recursive_calls { - db.span_label(call_span, "recursive call site"); - } - db.help("a `loop` may express intention better if this is on purpose"); - db.emit(); - }); + tcx.struct_span_lint_hir( + UNCONDITIONAL_RECURSION, + hir_id, + sp, + "function cannot return without recursing", + |lint| { + lint.span_label(sp, "cannot return without recursing"); + // offer some help to the programmer. + for call_span in vis.reachable_recursive_calls { + lint.span_label(call_span, "recursive call site"); + } + lint.help("a `loop` may express intention better if this is on purpose") + }, + ); } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index d45b886903b..8fca94119c2 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -7,7 +7,7 @@ use super::{PatCtxt, PatternError}; use rustc_arena::TypedArena; use rustc_ast::Mutability; use rustc_errors::{ - error_code, pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, + error_code, pluralize, struct_span_err, Applicability, DelayDm, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, }; use rustc_hir as hir; @@ -347,19 +347,23 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { let span_end = affix.last().unwrap().unwrap().0; let span = span_start.to(span_end); let cnt = affix.len(); - cx.tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, top, span, |lint| { - let s = pluralize!(cnt); - let mut diag = lint.build(&format!("{kind} irrefutable pattern{s} in let chain")); - diag.note(&format!( - "{these} pattern{s} will always match", - these = pluralize!("this", cnt), - )); - diag.help(&format!( - "consider moving {} {suggestion}", - if cnt > 1 { "them" } else { "it" } - )); - diag.emit() - }); + let s = pluralize!(cnt); + cx.tcx.struct_span_lint_hir( + IRREFUTABLE_LET_PATTERNS, + top, + span, + format!("{kind} irrefutable pattern{s} in let chain"), + |lint| { + lint.note(format!( + "{these} pattern{s} will always match", + these = pluralize!("this", cnt), + )) + .help(format!( + "consider moving {} {suggestion}", + if cnt > 1 { "them" } else { "it" } + )) + }, + ); }; if let Some(until) = chain_refutabilities.iter().position(|r| !matches!(*r, Some((_, false)))) && until > 0 { // The chain has a non-zero prefix of irrefutable `let` statements. @@ -561,26 +565,28 @@ fn check_for_bindings_named_same_as_variants( BINDINGS_WITH_VARIANT_NAME, p.hir_id, p.span, + DelayDm(|| format!( + "pattern binding `{}` is named the same as one \ + of the variants of the type `{}`", + ident, cx.tcx.def_path_str(edef.did()) + )), |lint| { let ty_path = cx.tcx.def_path_str(edef.did()); - let mut err = lint.build(&format!( - "pattern binding `{}` is named the same as one \ - of the variants of the type `{}`", - ident, ty_path - )); - err.code(error_code!(E0170)); + lint.code(error_code!(E0170)); + // If this is an irrefutable pattern, and there's > 1 variant, // then we can't actually match on this. Applying the below // suggestion would produce code that breaks on `check_irrefutable`. if rf == Refutable || variant_count == 1 { - err.span_suggestion( + lint.span_suggestion( p.span, "to match on the variant, qualify the path", format!("{}::{}", ty_path, ident), Applicability::MachineApplicable, ); } - err.emit(); + + lint }, ) } @@ -598,14 +604,13 @@ fn pat_is_catchall(pat: &DeconstructedPat<'_, '_>) -> bool { } fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option<Span>) { - tcx.struct_span_lint_hir(UNREACHABLE_PATTERNS, id, span, |lint| { - let mut err = lint.build("unreachable pattern"); + tcx.struct_span_lint_hir(UNREACHABLE_PATTERNS, id, span, "unreachable pattern", |lint| { if let Some(catchall) = catchall { // We had a catchall pattern, hint at that. - err.span_label(span, "unreachable pattern"); - err.span_label(catchall, "matches any value"); + lint.span_label(span, "unreachable pattern"); + lint.span_label(catchall, "matches any value"); } - err.emit(); + lint }); } @@ -621,6 +626,11 @@ fn irrefutable_let_patterns( count: usize, span: Span, ) { + let span = match source { + LetSource::LetElse(span) => span, + _ => span, + }; + macro_rules! emit_diag { ( $lint:expr, @@ -630,18 +640,23 @@ fn irrefutable_let_patterns( ) => {{ let s = pluralize!(count); let these = pluralize!("this", count); - let mut diag = $lint.build(&format!("irrefutable {} pattern{s}", $source_name)); - diag.note(&format!("{these} pattern{s} will always match, so the {}", $note_sufix)); - diag.help(concat!("consider ", $help_sufix)); - diag.emit() + tcx.struct_span_lint_hir( + IRREFUTABLE_LET_PATTERNS, + id, + span, + format!("irrefutable {} pattern{s}", $source_name), + |lint| { + lint.note(&format!( + "{these} pattern{s} will always match, so the {}", + $note_sufix + )) + .help(concat!("consider ", $help_sufix)) + }, + ) }}; } - let span = match source { - LetSource::LetElse(span) => span, - _ => span, - }; - tcx.struct_span_lint_hir(IRREFUTABLE_LET_PATTERNS, id, span, |lint| match source { + match source { LetSource::GenericLet => { emit_diag!(lint, "`let`", "`let` is useless", "removing `let`"); } @@ -677,7 +692,7 @@ fn irrefutable_let_patterns( "instead using a `loop { ... }` with a `let` inside it" ); } - }); + }; } fn is_let_irrefutable<'p, 'tcx>( diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index b58685e8958..f2935ca0e3a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,3 +1,4 @@ +use rustc_errors::DelayDm; use rustc_hir as hir; use rustc_index::vec::Idx; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; @@ -205,9 +206,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, self.id, self.span, - |lint| { - lint.build(&msg).emit(); - }, + msg, + |lint| lint, ); } else { debug!( @@ -286,9 +286,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, id, span, - |lint| { - lint.build("floating-point types cannot be used in patterns").emit(); - }, + "floating-point types cannot be used in patterns", + |lint| lint, ); } PatKind::Constant { value: cv } @@ -340,15 +339,15 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, id, span, - |lint| { - let msg = format!( + DelayDm(|| { + format!( "to use a constant of type `{}` in a pattern, \ `{}` must be annotated with `#[derive(PartialEq, Eq)]`", cv.ty(), cv.ty(), - ); - lint.build(&msg).emit(); - }, + ) + }), + |lint| lint, ); } // Since we are behind a reference, we can just bubble the error up so we get a @@ -488,7 +487,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::INDIRECT_STRUCTURAL_MATCH, self.id, self.span, - |lint| {lint.build(&msg).emit();}, + msg, + |lint| lint, ); } PatKind::Constant { value: cv } @@ -556,9 +556,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::POINTER_STRUCTURAL_MATCH, id, span, - |lint| { - lint.build(msg).emit(); - }, + msg, + |lint| lint, ); } PatKind::Constant { value: cv } @@ -594,9 +593,8 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH, id, span, - |lint| { - lint.build(&msg).emit(); - }, + msg, + |lint| lint, ); } diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 5105f059f9b..91ecfccdb5f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -299,10 +299,10 @@ impl IntRange { lint::builtin::OVERLAPPING_RANGE_ENDPOINTS, hir_id, pcx.span, + "multiple patterns overlap on their endpoints", |lint| { - let mut err = lint.build("multiple patterns overlap on their endpoints"); for (int_range, span) in overlaps { - err.span_label( + lint.span_label( span, &format!( "this range overlaps on `{}`...", @@ -310,9 +310,9 @@ impl IntRange { ), ); } - err.span_label(pcx.span, "... with this range"); - err.note("you likely meant to write mutually exclusive ranges"); - err.emit(); + lint.span_label(pcx.span, "... with this range"); + lint.note("you likely meant to write mutually exclusive ranges"); + lint }, ); } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index cd186421bb1..895af80bd7f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -433,7 +433,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { | DefKind::AssocTy, _, ) - | Res::SelfTy { .. } + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } | Res::SelfCtor(..) => PatKind::Leaf { subpatterns }, _ => { let pattern_error = match res { diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 22b58837148..f1279072844 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -754,9 +754,8 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>( hir_id: HirId, witnesses: Vec<DeconstructedPat<'p, 'tcx>>, ) { - cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, |build| { + cx.tcx.struct_span_lint_hir(NON_EXHAUSTIVE_OMITTED_PATTERNS, hir_id, sp, "some variants are not matched explicitly", |lint| { let joined_patterns = joined_uncovered_patterns(cx, &witnesses); - let mut lint = build.build("some variants are not matched explicitly"); lint.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns)); lint.help( "ensure that all variants are matched explicitly by adding the suggested match arms", @@ -765,7 +764,7 @@ fn lint_non_exhaustive_omitted_patterns<'p, 'tcx>( "the matched value is of type `{}` and the `non_exhaustive_omitted_patterns` attribute was found", scrut_ty, )); - lint.emit(); + lint }); } diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs index 8838b14c53a..fa5f392fa74 100644 --- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs +++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs @@ -1,4 +1,4 @@ -use rustc_errors::{DiagnosticBuilder, LintDiagnosticBuilder}; +use rustc_errors::{DiagnosticBuilder, DiagnosticMessage}; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; @@ -63,7 +63,10 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> { place: &Place<'tcx>, const_item: DefId, location: Location, - decorate: impl for<'b> FnOnce(LintDiagnosticBuilder<'b, ()>) -> DiagnosticBuilder<'b, ()>, + msg: impl Into<DiagnosticMessage>, + decorate: impl for<'a, 'b> FnOnce( + &'a mut DiagnosticBuilder<'b, ()>, + ) -> &'a mut DiagnosticBuilder<'b, ()>, ) { // Don't lint on borrowing/assigning when a dereference is involved. // If we 'leave' the temporary via a dereference, we must @@ -84,10 +87,10 @@ impl<'tcx> ConstMutationChecker<'_, 'tcx> { CONST_ITEM_MUTATION, lint_root, source_info.span, + msg, |lint| { decorate(lint) .span_note(self.tcx.def_span(const_item), "`const` item defined here") - .emit(); }, ); } @@ -102,10 +105,8 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { // so emitting a lint would be redundant. if !lhs.projection.is_empty() { if let Some(def_id) = self.is_const_item_without_destructor(lhs.local) { - self.lint_const_item_usage(&lhs, def_id, loc, |lint| { - let mut lint = lint.build("attempting to modify a `const` item"); - lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified"); - lint + self.lint_const_item_usage(&lhs, def_id, loc, "attempting to modify a `const` item",|lint| { + lint.note("each usage of a `const` item creates a new temporary; the original `const` item will not be modified") }) } } @@ -137,8 +138,7 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> { }); let lint_loc = if method_did.is_some() { self.body.terminator_loc(loc.block) } else { loc }; - self.lint_const_item_usage(place, def_id, lint_loc, |lint| { - let mut lint = lint.build("taking a mutable reference to a `const` item"); + self.lint_const_item_usage(place, def_id, lint_loc, "taking a mutable reference to a `const` item", |lint| { lint .note("each usage of a `const` item creates a new temporary") .note("the mutable reference will refer to this temporary, not the original `const` item"); diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs index 3b7ba3f9a67..51abcf51189 100644 --- a/compiler/rustc_mir_transform/src/check_packed_ref.rs +++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs @@ -33,21 +33,27 @@ struct PackedRefChecker<'a, 'tcx> { fn unsafe_derive_on_repr_packed(tcx: TyCtxt<'_>, def_id: LocalDefId) { let lint_hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - tcx.struct_span_lint_hir(UNALIGNED_REFERENCES, lint_hir_id, tcx.def_span(def_id), |lint| { - // FIXME: when we make this a hard error, this should have its - // own error code. - let extra = if tcx.generics_of(def_id).own_requires_monomorphization() { - "with type or const parameters" - } else { - "that does not derive `Copy`" - }; - let message = format!( - "`{}` can't be derived on this `#[repr(packed)]` struct {}", - tcx.item_name(tcx.trait_id_of_impl(def_id.to_def_id()).expect("derived trait name")), - extra - ); - lint.build(message).emit(); - }); + // FIXME: when we make this a hard error, this should have its + // own error code. + + let extra = if tcx.generics_of(def_id).own_requires_monomorphization() { + "with type or const parameters" + } else { + "that does not derive `Copy`" + }; + let message = format!( + "`{}` can't be derived on this `#[repr(packed)]` struct {}", + tcx.item_name(tcx.trait_id_of_impl(def_id.to_def_id()).expect("derived trait name")), + extra + ); + + tcx.struct_span_lint_hir( + UNALIGNED_REFERENCES, + lint_hir_id, + tcx.def_span(def_id), + message, + |lint| lint, + ); } impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { @@ -86,8 +92,9 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { UNALIGNED_REFERENCES, lint_root, source_info.span, + "reference to packed field is unaligned", |lint| { - lint.build("reference to packed field is unaligned") + lint .note( "fields of packed structs are not properly aligned, and creating \ a misaligned reference is undefined behavior (even if that \ @@ -98,7 +105,6 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> { reference with a raw pointer and use `read_unaligned`/`write_unaligned` \ (loads and stores via `*p` must be properly aligned even when using raw pointers)" ) - .emit(); }, ); } diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index beff19a3ab2..4730be1244b 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -489,21 +489,20 @@ fn unsafety_check_result<'tcx>( fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) { let span = tcx.sess.source_map().guess_head_span(tcx.hir().span(id)); - tcx.struct_span_lint_hir(UNUSED_UNSAFE, id, span, |lint| { - let msg = "unnecessary `unsafe` block"; - let mut db = lint.build(msg); - db.span_label(span, msg); + let msg = "unnecessary `unsafe` block"; + tcx.struct_span_lint_hir(UNUSED_UNSAFE, id, span, msg, |lint| { + lint.span_label(span, msg); match kind { UnusedUnsafe::Unused => {} UnusedUnsafe::InUnsafeBlock(id) => { - db.span_label( + lint.span_label( tcx.sess.source_map().guess_head_span(tcx.hir().span(id)), "because it's nested under this `unsafe` block", ); } } - db.emit(); + lint }); } @@ -543,15 +542,8 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { UNSAFE_OP_IN_UNSAFE_FN, lint_root, source_info.span, - |lint| { - lint.build(&format!( - "{} is unsafe and requires unsafe block (error E0133)", - description, - )) - .span_label(source_info.span, description) - .note(note) - .emit(); - }, + format!("{} is unsafe and requires unsafe block (error E0133)", description,), + |lint| lint.span_label(source_info.span, description).note(note), ), } } diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 973f55437ee..cda3702c83d 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -347,10 +347,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { panic: AssertKind<impl std::fmt::Debug>, ) { if let Some(lint_root) = self.lint_root(source_info) { - self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, |lint| { - let mut err = lint.build(message); - err.span_label(source_info.span, format!("{:?}", panic)); - err.emit(); + self.tcx.struct_span_lint_hir(lint, lint_root, source_info.span, message, |lint| { + lint.span_label(source_info.span, format!("{:?}", panic)) }); } } diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index 7522a50a8c6..1244c18020d 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -106,14 +106,12 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { .lint_root; let span = terminator.source_info.span; - tcx.struct_span_lint_hir(FFI_UNWIND_CALLS, lint_root, span, |lint| { - let msg = match fn_def_id { - Some(_) => "call to foreign function with FFI-unwind ABI", - None => "call to function pointer with FFI-unwind ABI", - }; - let mut db = lint.build(msg); - db.span_label(span, msg); - db.emit(); + let msg = match fn_def_id { + Some(_) => "call to foreign function with FFI-unwind ABI", + None => "call to function pointer with FFI-unwind ABI", + }; + tcx.struct_span_lint_hir(FFI_UNWIND_CALLS, lint_root, span, msg, |lint| { + lint.span_label(span, msg) }); tainted = true; diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs index 0568eb2ffa6..469566694a3 100644 --- a/compiler/rustc_mir_transform/src/function_item_references.rs +++ b/compiler/rustc_mir_transform/src/function_item_references.rs @@ -179,11 +179,15 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { let num_args = fn_sig.inputs().map_bound(|inputs| inputs.len()).skip_binder(); let variadic = if fn_sig.c_variadic() { ", ..." } else { "" }; let ret = if fn_sig.output().skip_binder().is_unit() { "" } else { " -> _" }; - self.tcx.struct_span_lint_hir(FUNCTION_ITEM_REFERENCES, lint_root, span, |lint| { - lint.build("taking a reference to a function item does not give a function pointer") - .span_suggestion( + self.tcx.struct_span_lint_hir( + FUNCTION_ITEM_REFERENCES, + lint_root, + span, + "taking a reference to a function item does not give a function pointer", + |lint| { + lint.span_suggestion( span, - &format!("cast `{}` to obtain a function pointer", ident), + format!("cast `{}` to obtain a function pointer", ident), format!( "{} as {}{}fn({}{}){}", if params.is_empty() { ident } else { format!("{}::<{}>", ident, params) }, @@ -195,7 +199,7 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> { ), Applicability::Unspecified, ) - .emit(); - }); + }, + ); } } diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index b7e3ca571e1..a93f6a60114 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -290,7 +290,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> { - if !c.has_param_types_or_consts() { + if !c.has_non_region_param() { return ControlFlow::CONTINUE; } @@ -311,7 +311,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { } fn visit_mir_const(&mut self, constant: ConstantKind<'tcx>) -> ControlFlow<Self::BreakTy> { - if !constant.has_param_types_or_consts() { + if !constant.has_non_region_param() { return ControlFlow::CONTINUE; } @@ -336,7 +336,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for MarkUsedGenericParams<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - if !ty.has_param_types_or_consts() { + if !ty.has_non_region_param() { return ControlFlow::CONTINUE; } @@ -373,7 +373,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> { #[instrument(level = "debug", skip(self))] fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> { - if !c.has_param_types_or_consts() { + if !c.has_non_region_param() { return ControlFlow::CONTINUE; } @@ -391,7 +391,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for HasUsedGenericParams<'a> { #[instrument(level = "debug", skip(self))] fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - if !ty.has_param_types_or_consts() { + if !ty.has_non_region_param() { return ControlFlow::CONTINUE; } diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index bcd078a8967..88540e13ef2 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -52,7 +52,7 @@ pub(crate) fn parse_token_trees<'a>( let cursor = Cursor::new(src); let string_reader = StringReader { sess, start_pos, pos: start_pos, src, cursor, override_span }; - tokentrees::TokenTreesReader::parse_token_trees(string_reader) + tokentrees::TokenTreesReader::parse_all_token_trees(string_reader) } struct StringReader<'a> { diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 364753154db..b2701817d48 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -27,7 +27,7 @@ pub(super) struct TokenTreesReader<'a> { } impl<'a> TokenTreesReader<'a> { - pub(super) fn parse_token_trees( + pub(super) fn parse_all_token_trees( string_reader: StringReader<'a>, ) -> (PResult<'a, TokenStream>, Vec<UnmatchedBrace>) { let mut tt_reader = TokenTreesReader { @@ -40,36 +40,51 @@ impl<'a> TokenTreesReader<'a> { last_delim_empty_block_spans: FxHashMap::default(), matching_block_spans: Vec::new(), }; - let res = tt_reader.parse_all_token_trees(); + let res = tt_reader.parse_token_trees(/* is_delimited */ false); (res, tt_reader.unmatched_braces) } - // Parse a stream of tokens into a list of `TokenTree`s, up to an `Eof`. - fn parse_all_token_trees(&mut self) -> PResult<'a, TokenStream> { + // Parse a stream of tokens into a list of `TokenTree`s. + fn parse_token_trees(&mut self, is_delimited: bool) -> PResult<'a, TokenStream> { self.token = self.string_reader.next_token().0; - let mut buf = TokenStreamBuilder::default(); + let mut buf = Vec::new(); loop { match self.token.kind { token::OpenDelim(delim) => buf.push(self.parse_token_tree_open_delim(delim)), - token::CloseDelim(delim) => return Err(self.close_delim_err(delim)), - token::Eof => return Ok(buf.into_token_stream()), - _ => buf.push(self.parse_token_tree_non_delim_non_eof()), - } - } - } - - // Parse a stream of tokens into a list of `TokenTree`s, up to a `CloseDelim`. - fn parse_token_trees_until_close_delim(&mut self) -> TokenStream { - let mut buf = TokenStreamBuilder::default(); - loop { - match self.token.kind { - token::OpenDelim(delim) => buf.push(self.parse_token_tree_open_delim(delim)), - token::CloseDelim(..) => return buf.into_token_stream(), + token::CloseDelim(delim) => { + return if is_delimited { + Ok(TokenStream::new(buf)) + } else { + Err(self.close_delim_err(delim)) + }; + } token::Eof => { - self.eof_err().emit(); - return buf.into_token_stream(); + if is_delimited { + self.eof_err().emit(); + } + return Ok(TokenStream::new(buf)); + } + _ => { + // Get the next normal token. This might require getting multiple adjacent + // single-char tokens and joining them together. + let (this_spacing, next_tok) = loop { + let (next_tok, is_next_tok_preceded_by_whitespace) = + self.string_reader.next_token(); + if !is_next_tok_preceded_by_whitespace { + if let Some(glued) = self.token.glue(&next_tok) { + self.token = glued; + } else { + let this_spacing = + if next_tok.is_op() { Spacing::Joint } else { Spacing::Alone }; + break (this_spacing, next_tok); + } + } else { + break (Spacing::Alone, next_tok); + } + }; + let this_tok = std::mem::replace(&mut self.token, next_tok); + buf.push(TokenTree::Token(this_tok, this_spacing)); } - _ => buf.push(self.parse_token_tree_non_delim_non_eof()), } } } @@ -113,14 +128,12 @@ impl<'a> TokenTreesReader<'a> { // The span for beginning of the delimited section let pre_span = self.token.span; - // Move past the open delimiter. self.open_braces.push((open_delim, self.token.span)); - self.token = self.string_reader.next_token().0; // Parse the token trees within the delimiters. // We stop at any delimiter so we can try to recover if the user // uses an incorrect delimiter. - let tts = self.parse_token_trees_until_close_delim(); + let tts = self.parse_token_trees(/* is_delimited */ true).unwrap(); // Expand to cover the entire delimited token tree let delim_span = DelimSpan::from_pair(pre_span, self.token.span); @@ -242,43 +255,4 @@ impl<'a> TokenTreesReader<'a> { err.span_label(self.token.span, "unexpected closing delimiter"); err } - - #[inline] - fn parse_token_tree_non_delim_non_eof(&mut self) -> TokenTree { - // `this_spacing` for the returned token refers to whether the token is - // immediately followed by another op token. It is determined by the - // next token: its kind and its `preceded_by_whitespace` status. - let (next_tok, is_next_tok_preceded_by_whitespace) = self.string_reader.next_token(); - let this_spacing = if is_next_tok_preceded_by_whitespace || !next_tok.is_op() { - Spacing::Alone - } else { - Spacing::Joint - }; - let this_tok = std::mem::replace(&mut self.token, next_tok); - TokenTree::Token(this_tok, this_spacing) - } -} - -#[derive(Default)] -struct TokenStreamBuilder { - buf: Vec<TokenTree>, -} - -impl TokenStreamBuilder { - #[inline(always)] - fn push(&mut self, tree: TokenTree) { - if let Some(TokenTree::Token(prev_token, Spacing::Joint)) = self.buf.last() - && let TokenTree::Token(token, joint) = &tree - && let Some(glued) = prev_token.glue(token) - { - self.buf.pop(); - self.buf.push(TokenTree::Token(glued, *joint)); - } else { - self.buf.push(tree) - } - } - - fn into_token_stream(self) -> TokenStream { - TokenStream::new(self.buf) - } } diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 86c386b94c8..0dc05475ce9 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -32,11 +32,6 @@ pub struct AttrWrapper { start_pos: usize, } -// This struct is passed around very frequently, -// so make sure it doesn't accidentally get larger -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(AttrWrapper, 16); - impl AttrWrapper { pub(super) fn new(attrs: AttrVec, start_pos: usize) -> AttrWrapper { AttrWrapper { attrs, start_pos } @@ -96,9 +91,6 @@ struct LazyAttrTokenStreamImpl { replace_ranges: Box<[ReplaceRange]>, } -#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(LazyAttrTokenStreamImpl, 144); - impl ToAttrTokenStream for LazyAttrTokenStreamImpl { fn to_attr_token_stream(&self) -> AttrTokenStream { // The token produced by the final call to `{,inlined_}next` was not @@ -461,3 +453,13 @@ fn make_token_stream( } AttrTokenStream::new(final_buf.inner) } + +// Some types are used a lot. Make sure they don't unintentionally get bigger. +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +mod size_asserts { + use super::*; + use rustc_data_structures::static_assert_size; + // These are in alphabetical order, which is easy to maintain. + static_assert_size!(AttrWrapper, 16); + static_assert_size!(LazyAttrTokenStreamImpl, 144); +} diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index b512f26335f..f57bd9cec19 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -33,6 +33,7 @@ use rustc_errors::{ fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult, }; use rustc_errors::{pluralize, Diagnostic, ErrorGuaranteed, IntoDiagnostic}; +use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{Span, SpanSnippetError, DUMMY_SP}; @@ -2049,7 +2050,7 @@ impl<'a> Parser<'a> { let mut err = self.struct_span_err(span, &msg); let sp = self.sess.source_map().start_point(self.token.span); if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) { - self.sess.expr_parentheses_needed(&mut err, *sp); + err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } err.span_label(span, "expected expression"); err diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 8b328e593ae..11301f03e48 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1310,7 +1310,7 @@ impl<'a> Parser<'a> { // If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }` // then suggest parens around the lhs. if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&lo) { - self.sess.expr_parentheses_needed(&mut err, *sp); + err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } err }) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index b7454d7bfc1..25425fbb2c6 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -760,8 +760,8 @@ impl<'a> Parser<'a> { ) .span_label(self.token.span, "this doc comment doesn't document anything") .help( - "doc comments must come before what they document, maybe a \ - comment was intended with `//`?", + "doc comments must come before what they document, if a comment was \ + intended use `//`", ) .emit(); self.bump(); @@ -1753,18 +1753,24 @@ impl<'a> Parser<'a> { }; // We use `parse_fn` to get a span for the function let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; - if let Err(mut db) = - self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis) - { - db.delay_as_bug(); + match self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis) { + Ok(_) => { + let mut err = self.struct_span_err( + lo.to(self.prev_token.span), + &format!("functions are not allowed in {adt_ty} definitions"), + ); + err.help( + "unlike in C++, Java, and C#, functions are declared in `impl` blocks", + ); + err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information"); + err + } + Err(err) => { + err.cancel(); + self.restore_snapshot(snapshot); + self.expected_ident_found() + } } - let mut err = self.struct_span_err( - lo.to(self.prev_token.span), - &format!("functions are not allowed in {adt_ty} definitions"), - ); - err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks"); - err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information"); - err } else if self.eat_keyword(kw::Struct) { match self.parse_item_struct() { Ok((ident, _)) => { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 2aebaf7c3af..b934e087608 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -302,7 +302,10 @@ impl TokenCursor { fn desugar(&mut self, attr_style: AttrStyle, data: Symbol, span: Span) -> (Token, Spacing) { // Searches for the occurrences of `"#*` and returns the minimum number of `#`s - // required to wrap the text. + // required to wrap the text. E.g. + // - `abc d` is wrapped as `r"abc d"` (num_of_hashes = 0) + // - `abc "d"` is wrapped as `r#"abc "d""#` (num_of_hashes = 1) + // - `abc "##d##"` is wrapped as `r###"abc "d""###` (num_of_hashes = 3) let mut num_of_hashes = 0; let mut count = 0; for ch in data.as_str().chars() { @@ -314,6 +317,7 @@ impl TokenCursor { num_of_hashes = cmp::max(num_of_hashes, count); } + // `/// foo` becomes `doc = r"foo". let delim_span = DelimSpan::from_single(span); let body = TokenTree::Delimited( delim_span, diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 542a1ac5dc6..0250b518243 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -10,6 +10,7 @@ use rustc_ast::{ }; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; +use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::{respan, Span, Spanned}; use rustc_span::symbol::{kw, sym, Ident}; @@ -693,7 +694,7 @@ impl<'a> Parser<'a> { let sp = self.sess.source_map().start_point(self.token.span); if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) { - self.sess.expr_parentheses_needed(&mut err, *sp); + err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } Err(err) diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index a9e502016aa..df22d79f82e 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -224,7 +224,7 @@ impl<'a> Iterator for Parser<'a> { '{' => { let curr_last_brace = self.last_opening_brace; let byte_pos = self.to_span_index(pos); - let lbrace_end = InnerOffset(byte_pos.0 + 1); + let lbrace_end = self.to_span_index(pos + 1); self.last_opening_brace = Some(byte_pos.to(lbrace_end)); self.cur.next(); if self.consume('{') { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 897a0db930c..87433538512 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -370,10 +370,13 @@ impl CheckAttrVisitor<'_> { b.push_str(&(allowed_target.to_string() + "s")); b }); - self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { - lint.build(&format!("`#[{name}]` only has an effect on {}", supported_names)) - .emit(); - }); + self.tcx.struct_span_lint_hir( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + &format!("`#[{name}]` only has an effect on {}", supported_names), + |lint| lint, + ); } } @@ -877,25 +880,31 @@ impl CheckAttrVisitor<'_> { hir_id: HirId, ) -> bool { if hir_id != CRATE_HIR_ID { - self.tcx.struct_span_lint_hir(INVALID_DOC_ATTRIBUTES, hir_id, meta.span(), |lint| { - let mut err = lint.build(fluent::passes::attr_crate_level); - if attr.style == AttrStyle::Outer - && self.tcx.hir().get_parent_item(hir_id) == CRATE_OWNER_ID - { - if let Ok(mut src) = self.tcx.sess.source_map().span_to_snippet(attr.span) { - src.insert(1, '!'); - err.span_suggestion_verbose( - attr.span, - fluent::passes::suggestion, - src, - Applicability::MaybeIncorrect, - ); - } else { - err.span_help(attr.span, fluent::passes::help); + self.tcx.struct_span_lint_hir( + INVALID_DOC_ATTRIBUTES, + hir_id, + meta.span(), + fluent::passes::attr_crate_level, + |err| { + if attr.style == AttrStyle::Outer + && self.tcx.hir().get_parent_item(hir_id) == CRATE_OWNER_ID + { + if let Ok(mut src) = self.tcx.sess.source_map().span_to_snippet(attr.span) { + src.insert(1, '!'); + err.span_suggestion_verbose( + attr.span, + fluent::passes::suggestion, + src, + Applicability::MaybeIncorrect, + ); + } else { + err.span_help(attr.span, fluent::passes::help); + } } - } - err.note(fluent::passes::note).emit(); - }); + err.note(fluent::passes::note); + err + }, + ); return false; } true diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 4062862ad74..e502b9b54e3 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -191,32 +191,6 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { self.tcx.hir() } - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - let tcx = self.tcx; - if let hir::ItemKind::Impl(hir::Impl { - constness: hir::Constness::Const, - of_trait: Some(trait_ref), - .. - }) = item.kind - { - let def_id = trait_ref.trait_def_id().unwrap(); - let source_map = tcx.sess.source_map(); - if !tcx.has_attr(def_id, sym::const_trait) { - tcx.sess - .struct_span_err( - source_map.guess_head_span(item.span), - "const `impl`s must be for traits marked with `#[const_trait]`", - ) - .span_note( - source_map.guess_head_span(tcx.def_span(def_id)), - "this trait must be annotated with `#[const_trait]`", - ) - .emit(); - } - } - intravisit::walk_item(self, item); - } - fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) { let kind = Some(hir::ConstContext::Const); self.recurse_into(kind, None, |this| intravisit::walk_anon_const(this, anon)); diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index e9d71bc93ac..08f704da62c 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -4,7 +4,7 @@ use itertools::Itertools; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, Applicability, MultiSpan}; +use rustc_errors::{pluralize, Applicability, DelayDm, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -102,14 +102,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } } Res::Def(_, def_id) => self.check_def_id(def_id), - Res::SelfTy { trait_: t, alias_to: i } => { - if let Some(t) = t { - self.check_def_id(t); - } - if let Some((i, _)) = i { - self.check_def_id(i); - } - } + Res::SelfTyParam { trait_: t } => self.check_def_id(t), + Res::SelfTyAlias { alias_to: i, .. } => self.check_def_id(i), Res::ToolMod | Res::NonMacroAttr(..) | Res::Err => {} } } @@ -190,13 +184,14 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { lint::builtin::DEAD_CODE, assign.hir_id, assign.span, - |lint| { - lint.build(&format!( + DelayDm(|| format!( "useless assignment of {} of type `{}` to itself", if is_field_assign { "field" } else { "variable" }, self.typeck_results().expr_ty(lhs), - )) - .emit(); + )), + |lint| { + lint + }, ) } @@ -723,6 +718,26 @@ impl<'tcx> DeadVisitor<'tcx> { }) .collect(); + let descr = tcx.def_kind(first_id).descr(first_id.to_def_id()); + let span_len = dead_codes.len(); + let names = match &names[..] { + _ if span_len > 6 => String::new(), + [name] => format!("`{name}` "), + [names @ .., last] => { + format!( + "{} and `{last}` ", + names.iter().map(|name| format!("`{name}`")).join(", ") + ) + } + [] => unreachable!(), + }; + let msg = format!( + "{these}{descr}{s} {names}{are} never {participle}", + these = if span_len > 6 { "multiple " } else { "" }, + s = pluralize!(span_len), + are = pluralize!("is", span_len), + ); + tcx.struct_span_lint_hir( if is_positional { lint::builtin::UNUSED_TUPLE_STRUCT_FIELDS @@ -731,27 +746,8 @@ impl<'tcx> DeadVisitor<'tcx> { }, tcx.hir().local_def_id_to_hir_id(first_id), MultiSpan::from_spans(spans.clone()), - |lint| { - let descr = tcx.def_kind(first_id).descr(first_id.to_def_id()); - let span_len = dead_codes.len(); - let names = match &names[..] { - _ if span_len > 6 => String::new(), - [name] => format!("`{name}` "), - [names @ .., last] => { - format!( - "{} and `{last}` ", - names.iter().map(|name| format!("`{name}`")).join(", ") - ) - } - [] => unreachable!(), - }; - let mut err = lint.build(&format!( - "{these}{descr}{s} {names}{are} never {participle}", - these = if span_len > 6 { "multiple " } else { "" }, - s = pluralize!(span_len), - are = pluralize!("is", span_len), - )); - + msg, + |err| { if is_positional { err.multipart_suggestion( &format!( @@ -797,7 +793,7 @@ impl<'tcx> DeadVisitor<'tcx> { ); err.note(&msg); } - err.emit(); + err }, ); } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 6a4cd79cde7..c6fe40f72fc 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1319,14 +1319,14 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // that we do not emit the same warning twice if the uninhabited type // is indeed `!`. + let msg = format!("unreachable {}", descr); self.ir.tcx.struct_span_lint_hir( lint::builtin::UNREACHABLE_CODE, expr_id, expr_span, - |lint| { - let msg = format!("unreachable {}", descr); - lint.build(&msg) - .span_label(expr_span, &msg) + &msg, + |diag| { + diag.span_label(expr_span, &msg) .span_label(orig_span, "any code following this expression is unreachable") .span_note( orig_span, @@ -1335,7 +1335,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { orig_ty ), ) - .emit(); }, ); } @@ -1491,14 +1490,8 @@ impl<'tcx> Liveness<'_, 'tcx> { lint::builtin::UNUSED_ASSIGNMENTS, var_hir_id, vec![span], - |lint| { - lint.build(&format!( - "value captured by `{}` is never read", - name - )) - .help("did you mean to capture by reference instead?") - .emit(); - }, + format!("value captured by `{}` is never read", name), + |lint| lint.help("did you mean to capture by reference instead?"), ); } } @@ -1508,11 +1501,8 @@ impl<'tcx> Liveness<'_, 'tcx> { lint::builtin::UNUSED_VARIABLES, var_hir_id, vec![span], - |lint| { - lint.build(&format!("unused variable: `{}`", name)) - .help("did you mean to capture by reference instead?") - .emit(); - }, + format!("unused variable: `{}`", name), + |lint| lint.help("did you mean to capture by reference instead?"), ); } } @@ -1601,20 +1591,17 @@ impl<'tcx> Liveness<'_, 'tcx> { .into_iter() .map(|(_, _, ident_span)| ident_span) .collect::<Vec<_>>(), - |lint| { - lint.build(&format!("variable `{}` is assigned to, but never used", name)) - .note(&format!("consider using `_{}` instead", name)) - .emit(); - }, + format!("variable `{}` is assigned to, but never used", name), + |lint| lint.note(&format!("consider using `_{}` instead", name)), ) } else if can_remove { self.ir.tcx.struct_span_lint_hir( lint::builtin::UNUSED_VARIABLES, first_hir_id, hir_ids_and_spans.iter().map(|(_, pat_span, _)| *pat_span).collect::<Vec<_>>(), + format!("unused variable: `{}`", name), |lint| { - let mut err = lint.build(&format!("unused variable: `{}`", name)); - err.multipart_suggestion( + lint.multipart_suggestion( "try removing the field", hir_ids_and_spans .iter() @@ -1629,8 +1616,7 @@ impl<'tcx> Liveness<'_, 'tcx> { }) .collect(), Applicability::MachineApplicable, - ); - err.emit(); + ) }, ); } else { @@ -1661,14 +1647,13 @@ impl<'tcx> Liveness<'_, 'tcx> { .iter() .map(|(_, pat_span, _)| *pat_span) .collect::<Vec<_>>(), + format!("unused variable: `{}`", name), |lint| { - let mut err = lint.build(&format!("unused variable: `{}`", name)); - err.multipart_suggestion( + lint.multipart_suggestion( "try ignoring the field", shorthands, Applicability::MachineApplicable, - ); - err.emit(); + ) }, ); } else { @@ -1684,17 +1669,16 @@ impl<'tcx> Liveness<'_, 'tcx> { .iter() .map(|(_, _, ident_span)| *ident_span) .collect::<Vec<_>>(), + format!("unused variable: `{}`", name), |lint| { - let mut err = lint.build(&format!("unused variable: `{}`", name)); - if self.has_added_lit_match_name_span(&name, opt_body, &mut err) { - err.span_label(pat.span, "unused variable"); + if self.has_added_lit_match_name_span(&name, opt_body, lint) { + lint.span_label(pat.span, "unused variable"); } - err.multipart_suggestion( + lint.multipart_suggestion( "if this is intentional, prefix it with an underscore", non_shorthands, Applicability::MachineApplicable, - ); - err.emit(); + ) }, ); } @@ -1758,11 +1742,8 @@ impl<'tcx> Liveness<'_, 'tcx> { lint::builtin::UNUSED_ASSIGNMENTS, hir_id, spans, - |lint| { - lint.build(&message(&name)) - .help("maybe it is overwritten before being read?") - .emit(); - }, + message(&name), + |lint| lint.help("maybe it is overwritten before being read?"), ) } } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 607973446fc..2690be66c21 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -65,9 +65,13 @@ fn check_abi(tcx: TyCtxt<'_>, def_id: LocalDefId, abi: Abi) { if abi == Abi::Rust { let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); let span = tcx.def_span(def_id); - tcx.struct_span_lint_hir(UNDEFINED_NAKED_FUNCTION_ABI, hir_id, span, |lint| { - lint.build("Rust ABI is unsupported in naked functions").emit(); - }); + tcx.struct_span_lint_hir( + UNDEFINED_NAKED_FUNCTION_ABI, + hir_id, + span, + "Rust ABI is unsupported in naked functions", + |lint| lint, + ); } } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index e50beb27d2a..34fa80228df 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -752,10 +752,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { INEFFECTIVE_UNSTABLE_TRAIT_IMPL, item.hir_id(), span, - |lint| {lint - .build("an `#[unstable]` annotation here has no effect") - .note("see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information") - .emit();} + "an `#[unstable]` annotation here has no effect", + |lint| lint.note("see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information") ); } } @@ -1081,11 +1079,16 @@ fn unnecessary_partially_stable_feature_lint( implies: Symbol, since: Symbol, ) { - tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, |lint| { - lint.build(&format!( + tcx.struct_span_lint_hir( + lint::builtin::STABLE_FEATURES, + hir::CRATE_HIR_ID, + span, + format!( "the feature `{feature}` has been partially stabilized since {since} and is succeeded \ by the feature `{implies}`" - )) + ), + |lint| { + lint .span_suggestion( span, &format!( @@ -1100,8 +1103,8 @@ fn unnecessary_partially_stable_feature_lint( "", Applicability::MaybeIncorrect, ) - .emit(); - }); + }, + ); } fn unnecessary_stable_feature_lint( @@ -1113,12 +1116,8 @@ fn unnecessary_stable_feature_lint( if since.as_str() == VERSION_PLACEHOLDER { since = rust_version_symbol(); } - tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, |lint| { - lint.build(&format!( - "the feature `{feature}` has been stable since {since} and no longer requires an \ - attribute to enable", - )) - .emit(); + tcx.struct_span_lint_hir(lint::builtin::STABLE_FEATURES, hir::CRATE_HIR_ID, span, format!("the feature `{feature}` has been stable since {since} and no longer requires an attribute to enable"), |lint| { + lint }); } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 7ab07a671c4..841e3ebb2a1 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1422,7 +1422,9 @@ struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> { impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { fn path_is_private_type(&self, path: &hir::Path<'_>) -> bool { let did = match path.res { - Res::PrimTy(..) | Res::SelfTy { .. } | Res::Err => return false, + Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => { + return false; + } res => res.def_id(), }; diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs index 47762440e29..cdbf734cdbe 100644 --- a/compiler/rustc_query_impl/src/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -1,7 +1,7 @@ //! Defines the set of legal keys that can be used in queries. use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; -use rustc_hir::hir_id::OwnerId; +use rustc_hir::hir_id::{HirId, OwnerId}; use rustc_middle::infer::canonical::Canonical; use rustc_middle::mir; use rustc_middle::traits; @@ -557,3 +557,19 @@ impl<'tcx> Key for (Ty<'tcx>, ty::ValTree<'tcx>) { DUMMY_SP } } + +impl Key for HirId { + #[inline(always)] + fn query_crate_is_local(&self) -> bool { + true + } + + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + tcx.hir().span(*self) + } + + #[inline(always)] + fn key_as_def_id(&self) -> Option<DefId> { + None + } +} diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 5003a14b910..da2075fd5aa 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -94,6 +94,8 @@ impl<T: DepContext> HasDepContext for T { pub enum FingerprintStyle { /// The fingerprint is actually a DefPathHash. DefPathHash, + /// The fingerprint is actually a HirId. + HirId, /// Query key was `()` or equivalent, so fingerprint is just zero. Unit, /// Some opaque hash. @@ -104,7 +106,9 @@ impl FingerprintStyle { #[inline] pub fn reconstructible(self) -> bool { match self { - FingerprintStyle::DefPathHash | FingerprintStyle::Unit => true, + FingerprintStyle::DefPathHash | FingerprintStyle::Unit | FingerprintStyle::HirId => { + true + } FingerprintStyle::Opaque => false, } } diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index 8140c243453..148eabb38e2 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -12,7 +12,7 @@ use rustc_session::cstore::CrateStore; use rustc_session::Session; use rustc_span::source_map::SourceMap; use rustc_span::symbol::Symbol; -use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData}; +use rustc_span::{BytePos, CachingSourceMapView, SourceFile, Span, SpanData, DUMMY_SP}; /// This is the context state available during incr. comp. hashing. It contains /// enough information to transform `DefId`s and `HirId`s into stable `DefPath`s (i.e., @@ -185,7 +185,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { #[inline] fn def_span(&self, def_id: LocalDefId) -> Span { - self.source_span[def_id] + *self.source_span.get(def_id).unwrap_or(&DUMMY_SP) } #[inline] diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 81b67b758f7..29aab416ae9 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1010,7 +1010,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { _, ) | Res::Local(..) - | Res::SelfTy { .. } + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } | Res::SelfCtor(..) | Res::Err => bug!("unexpected resolution: {:?}", res), } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 7e83f2a7221..38a3c9dd71a 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -285,21 +285,6 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { fn visit_ty(&mut self, ty: &'a Ty) { match ty.kind { TyKind::MacCall(..) => self.visit_macro_invoc(ty.id), - TyKind::ImplTrait(node_id, _) => { - let parent_def = match self.impl_trait_context { - ImplTraitContext::Universal(item_def) => self.resolver.create_def( - item_def, - node_id, - DefPathData::ImplTrait, - self.expansion.to_expn_id(), - ty.span, - ), - ImplTraitContext::Existential => { - self.create_def(node_id, DefPathData::ImplTrait, ty.span) - } - }; - self.with_parent(parent_def, |this| visit::walk_ty(this, ty)) - } _ => visit::walk_ty(self, ty), } } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index ab71fa0bc1d..b6778804a99 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -511,24 +511,18 @@ impl<'a> Resolver<'a> { let sm = self.session.source_map(); let def_id = match outer_res { - Res::SelfTy { trait_: maybe_trait_defid, alias_to: maybe_impl_defid } => { - if let Some(impl_span) = - maybe_impl_defid.and_then(|(def_id, _)| self.opt_span(def_id)) - { + Res::SelfTyParam { .. } => { + err.span_label(span, "can't use `Self` here"); + return err; + } + Res::SelfTyAlias { alias_to: def_id, .. } => { + if let Some(impl_span) = self.opt_span(def_id) { err.span_label( reduce_impl_span_to_impl_keyword(sm, impl_span), "`Self` type implicitly declared here, by this `impl`", ); } - match (maybe_trait_defid, maybe_impl_defid) { - (Some(_), None) => { - err.span_label(span, "can't use `Self` here"); - } - (_, Some(_)) => { - err.span_label(span, "use a type here instead"); - } - (None, None) => bug!("`impl` without trait nor type?"), - } + err.span_label(span, "use a type here instead"); return err; } Res::Def(DefKind::TyParam, def_id) => { @@ -545,8 +539,9 @@ impl<'a> Resolver<'a> { } _ => { bug!( - "GenericParamsFromOuterFunction should only be used with Res::SelfTy, \ - DefKind::TyParam or DefKind::ConstParam" + "GenericParamsFromOuterFunction should only be used with \ + Res::SelfTyParam, Res::SelfTyAlias, DefKind::TyParam or \ + DefKind::ConstParam" ); } }; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 2287aa1eb25..e0542d5479f 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1162,7 +1162,7 @@ impl<'a> Resolver<'a> { return Res::Err; } } - Res::Def(DefKind::TyParam, _) | Res::SelfTy { .. } => { + Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => { for rib in ribs { let has_generic_params: HasGenericParams = match rib.kind { NormalRibKind @@ -1182,11 +1182,21 @@ impl<'a> Resolver<'a> { if !(trivial == ConstantHasGenerics::Yes || features.generic_const_exprs) { - // HACK(min_const_generics): If we encounter `Self` in an anonymous constant - // we can't easily tell if it's generic at this stage, so we instead remember - // this and then enforce the self type to be concrete later on. - if let Res::SelfTy { trait_, alias_to: Some((def, _)) } = res { - res = Res::SelfTy { trait_, alias_to: Some((def, true)) } + // HACK(min_const_generics): If we encounter `Self` in an anonymous + // constant we can't easily tell if it's generic at this stage, so + // we instead remember this and then enforce the self type to be + // concrete later on. + if let Res::SelfTyAlias { + alias_to: def, + forbid_generic: _, + is_trait_impl, + } = res + { + res = Res::SelfTyAlias { + alias_to: def, + forbid_generic: true, + is_trait_impl, + } } else { if let Some(span) = finalize { self.report_error( diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 558db003867..72029488cb1 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -19,7 +19,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_errors::DiagnosticId; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS}; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate}; use rustc_middle::middle::resolve_lifetime::Set1; use rustc_middle::ty::DefIdTree; @@ -414,7 +414,8 @@ impl<'a> PathSource<'a> { | DefKind::ForeignTy, _, ) | Res::PrimTy(..) - | Res::SelfTy { .. } + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } ), PathSource::Trait(AliasPossibility::No) => matches!(res, Res::Def(DefKind::Trait, _)), PathSource::Trait(AliasPossibility::Maybe) => { @@ -448,7 +449,8 @@ impl<'a> PathSource<'a> { | DefKind::TyAlias | DefKind::AssocTy, _, - ) | Res::SelfTy { .. } + ) | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } ), PathSource::TraitItem(ns) => match res { Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) if ns == ValueNS => true, @@ -1929,7 +1931,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { TyKind::ImplicitSelf => true, TyKind::Path(None, _) => { let path_res = self.r.partial_res_map[&ty.id].base_res(); - if let Res::SelfTy { .. } = path_res { + if let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path_res { return true; } Some(path_res) == self.impl_self @@ -2050,7 +2052,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { |this| { let item_def_id = this.r.local_def_id(item.id).to_def_id(); this.with_self_rib( - Res::SelfTy { trait_: None, alias_to: Some((item_def_id, false)) }, + Res::SelfTyAlias { + alias_to: item_def_id, + forbid_generic: false, + is_trait_impl: false, + }, |this| { visit::walk_item(this, item); }, @@ -2164,14 +2170,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }, |this| { let local_def_id = this.r.local_def_id(item.id).to_def_id(); - this.with_self_rib( - Res::SelfTy { trait_: Some(local_def_id), alias_to: None }, - |this| { - this.visit_generics(generics); - walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits); - this.resolve_trait_items(items); - }, - ); + this.with_self_rib(Res::SelfTyParam { trait_: local_def_id }, |this| { + this.visit_generics(generics); + walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits); + this.resolve_trait_items(items); + }); }, ); } @@ -2188,13 +2191,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }, |this| { let local_def_id = this.r.local_def_id(item.id).to_def_id(); - this.with_self_rib( - Res::SelfTy { trait_: Some(local_def_id), alias_to: None }, - |this| { - this.visit_generics(generics); - walk_list!(this, visit_param_bound, bounds, BoundKind::Bound); - }, - ); + this.with_self_rib(Res::SelfTyParam { trait_: local_def_id }, |this| { + this.visit_generics(generics); + walk_list!(this, visit_param_bound, bounds, BoundKind::Bound); + }); }, ); } @@ -2576,7 +2576,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }, |this| { // Dummy self type for better errors if `Self` is used in the trait path. - this.with_self_rib(Res::SelfTy { trait_: None, alias_to: None }, |this| { + this.with_self_rib(Res::SelfTyParam { trait_: LOCAL_CRATE.as_def_id() }, |this| { this.with_lifetime_rib( LifetimeRibKind::AnonymousCreateParameter { binder: item_id, @@ -2600,9 +2600,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } let item_def_id = item_def_id.to_def_id(); - let res = Res::SelfTy { - trait_: trait_id, - alias_to: Some((item_def_id, false)), + let res = Res::SelfTyAlias { + alias_to: item_def_id, + forbid_generic: false, + is_trait_impl: trait_id.is_some() }; this.with_self_rib(res, |this| { if let Some(trait_ref) = opt_trait_reference.as_ref() { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3c276a9ada9..2d339a4d070 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -130,6 +130,16 @@ pub(super) enum LifetimeElisionCandidate { Missing(MissingLifetime), } +/// Only used for diagnostics. +struct BaseError { + msg: String, + fallback_label: String, + span: Span, + span_label: Option<(Span, &'static str)>, + could_be_expr: bool, + suggestion: Option<(Span, &'static str, String)>, +} + impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { fn def_span(&self, def_id: DefId) -> Option<Span> { match def_id.krate { @@ -138,35 +148,18 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } - /// Handles error reporting for `smart_resolve_path_fragment` function. - /// Creates base error and amends it with one short label and possibly some longer helps/notes. - pub(crate) fn smart_resolve_report_errors( + fn make_base_error( &mut self, path: &[Segment], span: Span, source: PathSource<'_>, res: Option<Res>, - ) -> (DiagnosticBuilder<'a, ErrorGuaranteed>, Vec<ImportSuggestion>) { - let ident_span = path.last().map_or(span, |ident| ident.ident.span); - let ns = source.namespace(); - let is_expected = &|res| source.is_expected(res); - let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _)); - - debug!(?res, ?source); - + ) -> BaseError { // Make the base error. - struct BaseError<'a> { - msg: String, - fallback_label: String, - span: Span, - span_label: Option<(Span, &'a str)>, - could_be_expr: bool, - suggestion: Option<(Span, &'a str, String)>, - } let mut expected = source.descr_expected(); let path_str = Segment::names_to_string(path); let item_str = path.last().unwrap().ident; - let base_error = if let Some(res) = res { + if let Some(res) = res { BaseError { msg: format!("expected {}, found {} `{}`", expected, res.descr(), path_str), fallback_label: format!("not a {expected}"), @@ -277,8 +270,20 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { could_be_expr: false, suggestion, } - }; + } + } + /// Handles error reporting for `smart_resolve_path_fragment` function. + /// Creates base error and amends it with one short label and possibly some longer helps/notes. + pub(crate) fn smart_resolve_report_errors( + &mut self, + path: &[Segment], + span: Span, + source: PathSource<'_>, + res: Option<Res>, + ) -> (DiagnosticBuilder<'a, ErrorGuaranteed>, Vec<ImportSuggestion>) { + debug!(?res, ?source); + let base_error = self.make_base_error(path, span, source, res); let code = source.error_code(res.is_some()); let mut err = self.r.session.struct_span_err_with_code(base_error.span, &base_error.msg, code); @@ -289,41 +294,79 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_label(span, label); } - if let Some(sugg) = base_error.suggestion { - err.span_suggestion_verbose(sugg.0, sugg.1, sugg.2, Applicability::MaybeIncorrect); + if let Some(ref sugg) = base_error.suggestion { + err.span_suggestion_verbose(sugg.0, sugg.1, &sugg.2, Applicability::MaybeIncorrect); } - if let Some(span) = self.diagnostic_metadata.current_block_could_be_bare_struct_literal { - err.multipart_suggestion( - "you might have meant to write a `struct` literal", - vec![ - (span.shrink_to_lo(), "{ SomeStruct ".to_string()), - (span.shrink_to_hi(), "}".to_string()), - ], - Applicability::HasPlaceholders, - ); + self.suggest_bare_struct_literal(&mut err); + self.suggest_pattern_match_with_let(&mut err, source, span); + + self.suggest_self_or_self_ref(&mut err, path, span); + self.detect_assoct_type_constraint_meant_as_path(&mut err, &base_error); + if self.suggest_self_ty(&mut err, source, path, span) + || self.suggest_self_value(&mut err, source, path, span) + { + return (err, Vec::new()); } - match (source, self.diagnostic_metadata.in_if_condition) { - ( - PathSource::Expr(_), - Some(Expr { span: expr_span, kind: ExprKind::Assign(lhs, _, _), .. }), - ) => { - // Icky heuristic so we don't suggest: - // `if (i + 2) = 2` => `if let (i + 2) = 2` (approximately pattern) - // `if 2 = i` => `if let 2 = i` (lhs needs to contain error span) - if lhs.is_approximately_pattern() && lhs.span.contains(span) { - err.span_suggestion_verbose( - expr_span.shrink_to_lo(), - "you might have meant to use pattern matching", - "let ", - Applicability::MaybeIncorrect, - ); + + let (found, candidates) = + self.try_lookup_name_relaxed(&mut err, source, path, span, res, &base_error); + if found { + return (err, candidates); + } + + if !self.type_ascription_suggestion(&mut err, base_error.span) { + let mut fallback = + self.suggest_trait_and_bounds(&mut err, source, res, span, &base_error); + fallback |= self.suggest_typo(&mut err, source, path, span, &base_error); + if fallback { + // Fallback label. + err.span_label(base_error.span, &base_error.fallback_label); + } + } + self.err_code_special_cases(&mut err, source, path, span); + + (err, candidates) + } + + fn detect_assoct_type_constraint_meant_as_path( + &self, + err: &mut Diagnostic, + base_error: &BaseError, + ) { + let Some(ty) = self.diagnostic_metadata.current_type_path else { return; }; + let TyKind::Path(_, path) = &ty.kind else { return; }; + for segment in &path.segments { + let Some(params) = &segment.args else { continue; }; + let ast::GenericArgs::AngleBracketed(ref params) = params.deref() else { continue; }; + for param in ¶ms.args { + let ast::AngleBracketedArg::Constraint(constraint) = param else { continue; }; + let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else { + continue; + }; + for bound in bounds { + let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None) + = bound else + { + continue; + }; + if base_error.span == trait_ref.span { + err.span_suggestion_verbose( + constraint.ident.span.between(trait_ref.span), + "you might have meant to write a path instead of an associated type bound", + "::", + Applicability::MachineApplicable, + ); + } } } - _ => {} } + } + fn suggest_self_or_self_ref(&mut self, err: &mut Diagnostic, path: &[Segment], span: Span) { let is_assoc_fn = self.self_type_is_available(); + let Some(path_last_segment) = path.last() else { return }; + let item_str = path_last_segment.ident; // Emit help message for fake-self from other languages (e.g., `this` in Javascript). if ["this", "my"].contains(&item_str.as_str()) && is_assoc_fn { err.span_suggestion_short( @@ -358,96 +401,25 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } } + } - self.detect_assoct_type_constraint_meant_as_path(base_error.span, &mut err); - - // Emit special messages for unresolved `Self` and `self`. - if is_self_type(path, ns) { - err.code(rustc_errors::error_code!(E0411)); - err.span_label( - span, - "`Self` is only available in impls, traits, and type definitions".to_string(), - ); - if let Some(item_kind) = self.diagnostic_metadata.current_item { - err.span_label( - item_kind.ident.span, - format!( - "`Self` not allowed in {} {}", - item_kind.kind.article(), - item_kind.kind.descr() - ), - ); - } - return (err, Vec::new()); - } - if is_self_value(path, ns) { - debug!("smart_resolve_path_fragment: E0424, source={:?}", source); - - err.code(rustc_errors::error_code!(E0424)); - err.span_label(span, match source { - PathSource::Pat => "`self` value is a keyword and may not be bound to variables or shadowed", - _ => "`self` value is a keyword only available in methods with a `self` parameter", - }); - if let Some((fn_kind, span)) = &self.diagnostic_metadata.current_function { - // The current function has a `self' parameter, but we were unable to resolve - // a reference to `self`. This can only happen if the `self` identifier we - // are resolving came from a different hygiene context. - if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) { - err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters"); - } else { - let doesnt = if is_assoc_fn { - let (span, sugg) = fn_kind - .decl() - .inputs - .get(0) - .map(|p| (p.span.shrink_to_lo(), "&self, ")) - .unwrap_or_else(|| { - // Try to look for the "(" after the function name, if possible. - // This avoids placing the suggestion into the visibility specifier. - let span = fn_kind - .ident() - .map_or(*span, |ident| span.with_lo(ident.span.hi())); - ( - self.r - .session - .source_map() - .span_through_char(span, '(') - .shrink_to_hi(), - "&self", - ) - }); - err.span_suggestion_verbose( - span, - "add a `self` receiver parameter to make the associated `fn` a method", - sugg, - Applicability::MaybeIncorrect, - ); - "doesn't" - } else { - "can't" - }; - if let Some(ident) = fn_kind.ident() { - err.span_label( - ident.span, - &format!("this function {} have a `self` parameter", doesnt), - ); - } - } - } else if let Some(item_kind) = self.diagnostic_metadata.current_item { - err.span_label( - item_kind.ident.span, - format!( - "`self` not allowed in {} {}", - item_kind.kind.article(), - item_kind.kind.descr() - ), - ); - } - return (err, Vec::new()); - } - + fn try_lookup_name_relaxed( + &mut self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + source: PathSource<'_>, + path: &[Segment], + span: Span, + res: Option<Res>, + base_error: &BaseError, + ) -> (bool, Vec<ImportSuggestion>) { // Try to lookup name in more relaxed fashion for better error reporting. let ident = path.last().unwrap().ident; + let is_expected = &|res| source.is_expected(res); + let ns = source.namespace(); + let is_enum_variant = &|res| matches!(res, Res::Def(DefKind::Variant, _)); + let path_str = Segment::names_to_string(path); + let ident_span = path.last().map_or(span, |ident| ident.ident.span); + let mut candidates = self .r .lookup_import_candidates(ident, ns, &self.parent_scope, is_expected) @@ -494,7 +466,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { { // Already reported this issue on the lhs of the type ascription. err.delay_as_bug(); - return (err, candidates); + return (true, candidates); } } @@ -522,8 +494,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ); } } + // Try Levenshtein algorithm. - let typo_sugg = self.lookup_typo_candidate(path, ns, is_expected); + let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected); if path.len() == 1 && self.self_type_is_available() { if let Some(candidate) = self.lookup_assoc_candidate(ident, ns, is_expected) { let self_is_available = self.self_value_is_available(path[0].ident.span); @@ -560,8 +533,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ); } } - self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span); - return (err, candidates); + self.r.add_typo_suggestion(err, typo_sugg, ident_span); + return (true, candidates); } // If the first argument in call is `self` suggest calling a method. @@ -579,14 +552,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { format!("self.{path_str}({args_snippet})"), Applicability::MachineApplicable, ); - return (err, candidates); + return (true, candidates); } } // Try context-dependent help if relaxed lookup didn't work. if let Some(res) = res { if self.smart_resolve_context_dependent_help( - &mut err, + err, span, source, res, @@ -594,106 +567,135 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { &base_error.fallback_label, ) { // We do this to avoid losing a secondary span when we override the main error span. - self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span); - return (err, candidates); + self.r.add_typo_suggestion(err, typo_sugg, ident_span); + return (true, candidates); } } + return (false, candidates); + } + fn suggest_trait_and_bounds( + &mut self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + source: PathSource<'_>, + res: Option<Res>, + span: Span, + base_error: &BaseError, + ) -> bool { let is_macro = base_error.span.from_expansion() && base_error.span.desugaring_kind().is_none(); - if !self.type_ascription_suggestion(&mut err, base_error.span) { - let mut fallback = false; - if let ( - PathSource::Trait(AliasPossibility::Maybe), - Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)), - false, - ) = (source, res, is_macro) - { - if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object { - fallback = true; - let spans: Vec<Span> = bounds - .iter() - .map(|bound| bound.span()) - .filter(|&sp| sp != base_error.span) - .collect(); + let mut fallback = false; - let start_span = bounds[0].span(); - // `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><) - let end_span = bounds.last().unwrap().span(); - // `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar) - let last_bound_span = spans.last().cloned().unwrap(); - let mut multi_span: MultiSpan = spans.clone().into(); - for sp in spans { - let msg = if sp == last_bound_span { - format!( - "...because of {these} bound{s}", - these = pluralize!("this", bounds.len() - 1), - s = pluralize!(bounds.len() - 1), - ) - } else { - String::new() - }; - multi_span.push_span_label(sp, msg); - } - multi_span - .push_span_label(base_error.span, "expected this type to be a trait..."); - err.span_help( - multi_span, - "`+` is used to constrain a \"trait object\" type with lifetimes or \ - auto-traits; structs and enums can't be bound in that way", - ); - if bounds.iter().all(|bound| match bound { - ast::GenericBound::Outlives(_) => true, - ast::GenericBound::Trait(tr, _) => tr.span == base_error.span, - }) { - let mut sugg = vec![]; - if base_error.span != start_span { - sugg.push((start_span.until(base_error.span), String::new())); - } - if base_error.span != end_span { - sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new())); - } + if let ( + PathSource::Trait(AliasPossibility::Maybe), + Some(Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, _)), + false, + ) = (source, res, is_macro) + { + if let Some(bounds @ [_, .., _]) = self.diagnostic_metadata.current_trait_object { + fallback = true; + let spans: Vec<Span> = bounds + .iter() + .map(|bound| bound.span()) + .filter(|&sp| sp != base_error.span) + .collect(); - err.multipart_suggestion( - "if you meant to use a type and not a trait here, remove the bounds", - sugg, - Applicability::MaybeIncorrect, - ); + let start_span = bounds[0].span(); + // `end_span` is the end of the poly trait ref (Foo + 'baz + Bar><) + let end_span = bounds.last().unwrap().span(); + // `last_bound_span` is the last bound of the poly trait ref (Foo + >'baz< + Bar) + let last_bound_span = spans.last().cloned().unwrap(); + let mut multi_span: MultiSpan = spans.clone().into(); + for sp in spans { + let msg = if sp == last_bound_span { + format!( + "...because of {these} bound{s}", + these = pluralize!("this", bounds.len() - 1), + s = pluralize!(bounds.len() - 1), + ) + } else { + String::new() + }; + multi_span.push_span_label(sp, msg); + } + multi_span.push_span_label(base_error.span, "expected this type to be a trait..."); + err.span_help( + multi_span, + "`+` is used to constrain a \"trait object\" type with lifetimes or \ + auto-traits; structs and enums can't be bound in that way", + ); + if bounds.iter().all(|bound| match bound { + ast::GenericBound::Outlives(_) => true, + ast::GenericBound::Trait(tr, _) => tr.span == base_error.span, + }) { + let mut sugg = vec![]; + if base_error.span != start_span { + sugg.push((start_span.until(base_error.span), String::new())); } + if base_error.span != end_span { + sugg.push((base_error.span.shrink_to_hi().to(end_span), String::new())); + } + + err.multipart_suggestion( + "if you meant to use a type and not a trait here, remove the bounds", + sugg, + Applicability::MaybeIncorrect, + ); } } + } - fallback |= self.restrict_assoc_type_in_where_clause(span, &mut err); + fallback |= self.restrict_assoc_type_in_where_clause(span, err); + fallback + } - if !self.r.add_typo_suggestion(&mut err, typo_sugg, ident_span) { - fallback = true; - match self.diagnostic_metadata.current_let_binding { - Some((pat_sp, Some(ty_sp), None)) - if ty_sp.contains(base_error.span) && base_error.could_be_expr => - { - err.span_suggestion_short( - pat_sp.between(ty_sp), - "use `=` if you meant to assign", - " = ", - Applicability::MaybeIncorrect, - ); - } - _ => {} + fn suggest_typo( + &mut self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + source: PathSource<'_>, + path: &[Segment], + span: Span, + base_error: &BaseError, + ) -> bool { + let is_expected = &|res| source.is_expected(res); + let ident_span = path.last().map_or(span, |ident| ident.ident.span); + let typo_sugg = self.lookup_typo_candidate(path, source.namespace(), is_expected); + let mut fallback = false; + if !self.r.add_typo_suggestion(err, typo_sugg, ident_span) { + fallback = true; + match self.diagnostic_metadata.current_let_binding { + Some((pat_sp, Some(ty_sp), None)) + if ty_sp.contains(base_error.span) && base_error.could_be_expr => + { + err.span_suggestion_short( + pat_sp.between(ty_sp), + "use `=` if you meant to assign", + " = ", + Applicability::MaybeIncorrect, + ); } - - // If the trait has a single item (which wasn't matched by Levenshtein), suggest it - let suggestion = self.get_single_associated_item(&path, &source, is_expected); - self.r.add_typo_suggestion(&mut err, suggestion, ident_span); - } - if fallback { - // Fallback label. - err.span_label(base_error.span, base_error.fallback_label); + _ => {} } + + // If the trait has a single item (which wasn't matched by Levenshtein), suggest it + let suggestion = self.get_single_associated_item(&path, &source, is_expected); + self.r.add_typo_suggestion(err, suggestion, ident_span); } + fallback + } + + fn err_code_special_cases( + &mut self, + err: &mut DiagnosticBuilder<'_, ErrorGuaranteed>, + source: PathSource<'_>, + path: &[Segment], + span: Span, + ) { if let Some(err_code) = &err.code { if err_code == &rustc_errors::error_code!(E0425) { for label_rib in &self.label_ribs { for (label_ident, node_id) in &label_rib.bindings { + let ident = path.last().unwrap().ident; if format!("'{}", ident) == label_ident.to_string() { err.span_label(label_ident.span, "a label with a similar name exists"); if let PathSource::Expr(Some(Expr { @@ -724,38 +726,116 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } } + } - (err, candidates) + /// Emit special messages for unresolved `Self` and `self`. + fn suggest_self_ty( + &mut self, + err: &mut Diagnostic, + source: PathSource<'_>, + path: &[Segment], + span: Span, + ) -> bool { + if !is_self_type(path, source.namespace()) { + return false; + } + err.code(rustc_errors::error_code!(E0411)); + err.span_label( + span, + "`Self` is only available in impls, traits, and type definitions".to_string(), + ); + if let Some(item_kind) = self.diagnostic_metadata.current_item { + err.span_label( + item_kind.ident.span, + format!( + "`Self` not allowed in {} {}", + item_kind.kind.article(), + item_kind.kind.descr() + ), + ); + } + true } - fn detect_assoct_type_constraint_meant_as_path(&self, base_span: Span, err: &mut Diagnostic) { - let Some(ty) = self.diagnostic_metadata.current_type_path else { return; }; - let TyKind::Path(_, path) = &ty.kind else { return; }; - for segment in &path.segments { - let Some(params) = &segment.args else { continue; }; - let ast::GenericArgs::AngleBracketed(ref params) = params.deref() else { continue; }; - for param in ¶ms.args { - let ast::AngleBracketedArg::Constraint(constraint) = param else { continue; }; - let ast::AssocConstraintKind::Bound { bounds } = &constraint.kind else { - continue; + fn suggest_self_value( + &mut self, + err: &mut Diagnostic, + source: PathSource<'_>, + path: &[Segment], + span: Span, + ) -> bool { + if !is_self_value(path, source.namespace()) { + return false; + } + + debug!("smart_resolve_path_fragment: E0424, source={:?}", source); + err.code(rustc_errors::error_code!(E0424)); + err.span_label( + span, + match source { + PathSource::Pat => { + "`self` value is a keyword and may not be bound to variables or shadowed" + } + _ => "`self` value is a keyword only available in methods with a `self` parameter", + }, + ); + let is_assoc_fn = self.self_type_is_available(); + if let Some((fn_kind, span)) = &self.diagnostic_metadata.current_function { + // The current function has a `self' parameter, but we were unable to resolve + // a reference to `self`. This can only happen if the `self` identifier we + // are resolving came from a different hygiene context. + if fn_kind.decl().inputs.get(0).map_or(false, |p| p.is_self()) { + err.span_label(*span, "this function has a `self` parameter, but a macro invocation can only access identifiers it receives from parameters"); + } else { + let doesnt = if is_assoc_fn { + let (span, sugg) = fn_kind + .decl() + .inputs + .get(0) + .map(|p| (p.span.shrink_to_lo(), "&self, ")) + .unwrap_or_else(|| { + // Try to look for the "(" after the function name, if possible. + // This avoids placing the suggestion into the visibility specifier. + let span = fn_kind + .ident() + .map_or(*span, |ident| span.with_lo(ident.span.hi())); + ( + self.r + .session + .source_map() + .span_through_char(span, '(') + .shrink_to_hi(), + "&self", + ) + }); + err.span_suggestion_verbose( + span, + "add a `self` receiver parameter to make the associated `fn` a method", + sugg, + Applicability::MaybeIncorrect, + ); + "doesn't" + } else { + "can't" }; - for bound in bounds { - let ast::GenericBound::Trait(trait_ref, ast::TraitBoundModifier::None) - = bound else - { - continue; - }; - if base_span == trait_ref.span { - err.span_suggestion_verbose( - constraint.ident.span.between(trait_ref.span), - "you might have meant to write a path instead of an associated type bound", - "::", - Applicability::MachineApplicable, - ); - } + if let Some(ident) = fn_kind.ident() { + err.span_label( + ident.span, + &format!("this function {} have a `self` parameter", doesnt), + ); } } + } else if let Some(item_kind) = self.diagnostic_metadata.current_item { + err.span_label( + item_kind.ident.span, + format!( + "`self` not allowed in {} {}", + item_kind.kind.article(), + item_kind.kind.descr() + ), + ); } + true } fn suggest_swapping_misplaced_self_ty_and_trait( @@ -787,6 +867,45 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } } + fn suggest_bare_struct_literal(&mut self, err: &mut Diagnostic) { + if let Some(span) = self.diagnostic_metadata.current_block_could_be_bare_struct_literal { + err.multipart_suggestion( + "you might have meant to write a `struct` literal", + vec![ + (span.shrink_to_lo(), "{ SomeStruct ".to_string()), + (span.shrink_to_hi(), "}".to_string()), + ], + Applicability::HasPlaceholders, + ); + } + } + + fn suggest_pattern_match_with_let( + &mut self, + err: &mut Diagnostic, + source: PathSource<'_>, + span: Span, + ) { + if let PathSource::Expr(_) = source && + let Some(Expr { + span: expr_span, + kind: ExprKind::Assign(lhs, _, _), + .. + }) = self.diagnostic_metadata.in_if_condition { + // Icky heuristic so we don't suggest: + // `if (i + 2) = 2` => `if let (i + 2) = 2` (approximately pattern) + // `if 2 = i` => `if let 2 = i` (lhs needs to contain error span) + if lhs.is_approximately_pattern() && lhs.span.contains(span) { + err.span_suggestion_verbose( + expr_span.shrink_to_lo(), + "you might have meant to use pattern matching", + "let ", + Applicability::MaybeIncorrect, + ); + } + } + } + fn get_single_associated_item( &mut self, path: &[Segment], @@ -1330,7 +1449,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { Applicability::HasPlaceholders, ); } - (Res::SelfTy { .. }, _) if ns == ValueNS => { + (Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }, _) if ns == ValueNS => { err.span_label(span, fallback_label); err.note("can't use `Self` as a constructor, you must use the implemented struct"); } diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 9fb1af20ac9..0c29ff364dc 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -326,6 +326,7 @@ fn convert_named_region_map(named_region_map: NamedRegionMap) -> ResolveLifetime } debug!(?rl.defs); + debug!(?rl.late_bound_vars); rl } @@ -507,7 +508,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }) .unzip(); - self.map.late_bound_vars.insert(e.hir_id, binders); + self.record_late_bound_vars(e.hir_id, binders); let scope = Scope::Binder { hir_id: e.hir_id, lifetimes, @@ -531,7 +532,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { match &item.kind { hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => { if let Some(of_trait) = of_trait { - self.map.late_bound_vars.insert(of_trait.hir_ref_id, Vec::default()); + self.record_late_bound_vars(of_trait.hir_ref_id, Vec::default()); } } _ => {} @@ -583,7 +584,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { resolved_lifetimes.late_bound_vars.iter() { late_bound_vars.iter().for_each(|(&local_id, late_bound_vars)| { - self.map.late_bound_vars.insert( + self.record_late_bound_vars( hir::HirId { owner, local_id }, late_bound_vars.clone(), ); @@ -614,7 +615,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, }) .collect(); - self.map.late_bound_vars.insert(item.hir_id(), vec![]); + self.record_late_bound_vars(item.hir_id(), vec![]); let scope = Scope::Binder { hir_id: item.hir_id(), lifetimes, @@ -663,7 +664,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { (pair, r) }) .unzip(); - self.map.late_bound_vars.insert(ty.hir_id, binders); + self.record_late_bound_vars(ty.hir_id, binders); let scope = Scope::Binder { hir_id: ty.hir_id, lifetimes, @@ -817,7 +818,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {} } } - self.map.late_bound_vars.insert(ty.hir_id, vec![]); + self.record_late_bound_vars(ty.hir_id, vec![]); let scope = Scope::Binder { hir_id: ty.hir_id, @@ -861,7 +862,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None, }) .collect(); - self.map.late_bound_vars.insert(trait_item.hir_id(), vec![]); + self.record_late_bound_vars(trait_item.hir_id(), vec![]); let scope = Scope::Binder { hir_id: trait_item.hir_id(), lifetimes, @@ -909,9 +910,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => None, }) .collect(); - self.map.late_bound_vars.insert(ty.hir_id, vec![]); + self.record_late_bound_vars(impl_item.hir_id(), vec![]); let scope = Scope::Binder { - hir_id: ty.hir_id, + hir_id: impl_item.hir_id(), lifetimes, s: self.scope, scope_type: BinderScopeType::Normal, @@ -995,13 +996,14 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { for predicate in generics.predicates { match predicate { &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate { + hir_id, ref bounded_ty, bounds, ref bound_generic_params, origin, .. }) => { - let (lifetimes, binders): (FxIndexMap<LocalDefId, Region>, Vec<_>) = + let lifetimes: FxIndexMap<LocalDefId, Region> = bound_generic_params .iter() .filter(|param| { @@ -1009,19 +1011,23 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { }) .enumerate() .map(|(late_bound_idx, param)| { - let pair = - Region::late(late_bound_idx as u32, this.tcx.hir(), param); - let r = late_region_as_bound_region(this.tcx, &pair.1); - (pair, r) + Region::late(late_bound_idx as u32, this.tcx.hir(), param) + }) + .collect(); + let binders: Vec<_> = + lifetimes + .iter() + .map(|(_, region)| { + late_region_as_bound_region(this.tcx, region) }) - .unzip(); - this.map.late_bound_vars.insert(bounded_ty.hir_id, binders.clone()); + .collect(); + this.record_late_bound_vars(hir_id, binders.clone()); // Even if there are no lifetimes defined here, we still wrap it in a binder // scope. If there happens to be a nested poly trait ref (an error), that // will be `Concatenating` anyways, so we don't have to worry about the depth // being wrong. let scope = Scope::Binder { - hir_id: bounded_ty.hir_id, + hir_id, lifetimes, s: this.scope, scope_type: BinderScopeType::Normal, @@ -1089,7 +1095,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // imagine there's a better way to go about this. let (binders, scope_type) = self.poly_trait_ref_binder_info(); - self.map.late_bound_vars.insert(*hir_id, binders); + self.record_late_bound_vars(*hir_id, binders); let scope = Scope::Binder { hir_id: *hir_id, lifetimes: FxIndexMap::default(), @@ -1127,7 +1133,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { binders.extend(binders_iter); debug!(?binders); - self.map.late_bound_vars.insert(trait_ref.trait_ref.hir_ref_id, binders); + self.record_late_bound_vars(trait_ref.trait_ref.hir_ref_id, binders); // Always introduce a scope here, even if this is in a where clause and // we introduced the binders around the bounded Ty. In that case, we @@ -1211,6 +1217,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } + fn record_late_bound_vars(&mut self, hir_id: hir::HirId, binder: Vec<ty::BoundVariableKind>) { + if let Some(old) = self.map.late_bound_vars.insert(hir_id, binder) { + bug!( + "overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}", + self.map.late_bound_vars[&hir_id] + ) + } + } + /// Visits self by adding a scope and handling recursive walk over the contents with `walk`. /// /// Handles visiting fns and methods. These are a bit complicated because we must distinguish @@ -1268,7 +1283,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { late_region_as_bound_region(self.tcx, &pair.1) }) .collect(); - self.map.late_bound_vars.insert(hir_id, binders); + self.record_late_bound_vars(hir_id, binders); let scope = Scope::Binder { hir_id, lifetimes, diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index adbc119387d..ecb09f0c4b7 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -913,7 +913,8 @@ impl<'tcx> DumpVisitor<'tcx> { | HirDefKind::AssocTy, _, ) - | Res::SelfTy { .. } => { + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } => { self.dump_path_segment_ref( id, &hir::PathSegment::new(ident, hir::HirId::INVALID, Res::Err), diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index ad7aca3cb94..aa000b7067b 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -740,7 +740,8 @@ impl<'tcx> SaveContext<'tcx> { _, ) | Res::PrimTy(..) - | Res::SelfTy { .. } + | Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } | Res::ToolMod | Res::NonMacroAttr(..) | Res::SelfCtor(..) @@ -805,7 +806,7 @@ impl<'tcx> SaveContext<'tcx> { fn lookup_def_id(&self, ref_id: hir::HirId) -> Option<DefId> { match self.get_path_res(ref_id) { - Res::PrimTy(_) | Res::SelfTy { .. } | Res::Err => None, + Res::PrimTy(_) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => None, def => def.opt_def_id(), } } diff --git a/compiler/rustc_save_analysis/src/sig.rs b/compiler/rustc_save_analysis/src/sig.rs index bae1828cd18..62e9f6520fb 100644 --- a/compiler/rustc_save_analysis/src/sig.rs +++ b/compiler/rustc_save_analysis/src/sig.rs @@ -579,7 +579,7 @@ impl<'hir> Sig for hir::Path<'hir> { let res = scx.get_path_res(id.ok_or("Missing id for Path")?); let (name, start, end) = match res { - Res::PrimTy(..) | Res::SelfTy { .. } | Res::Err => { + Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => { return Ok(Signature { text: path_to_string(self), defs: vec![], refs: vec![] }); } Res::Def(DefKind::AssocConst | DefKind::Variant | DefKind::Ctor(..), _) => { diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index d97e1df2a16..2c3d8d5283b 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -2,9 +2,7 @@ //! It also serves as an input to the parser itself. use crate::config::CheckCfg; -use crate::errors::{ - ExprParenthesesNeeded, FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError, -}; +use crate::errors::{FeatureDiagnosticForIssue, FeatureDiagnosticHelp, FeatureGateError}; use crate::lint::{ builtin::UNSTABLE_SYNTAX_PRE_EXPANSION, BufferedEarlyLint, BuiltinLintDiagnostics, Lint, LintId, }; @@ -13,8 +11,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{emitter::SilentEmitter, ColorConfig, Handler}; use rustc_errors::{ - fallback_fluent_bundle, AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticId, - DiagnosticMessage, EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey, + fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticId, DiagnosticMessage, + EmissionGuarantee, ErrorGuaranteed, IntoDiagnostic, MultiSpan, StashKey, }; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; @@ -324,12 +322,6 @@ impl ParseSess { }); } - /// Extend an error with a suggestion to wrap an expression with parentheses to allow the - /// parser to continue parsing the following operation as part of the same expression. - pub fn expr_parentheses_needed(&self, err: &mut Diagnostic, span: Span) { - ExprParenthesesNeeded::surrounding(span).add_to_diagnostic(err); - } - pub fn save_proc_macro_span(&self, span: Span) -> usize { let mut spans = self.proc_macro_quoted_spans.lock(); spans.push(span); diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 37b8371a8fe..bbeabdb55a7 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -218,7 +218,9 @@ impl<D: Decoder> Decodable<D> for DefIndex { /// index and a def index. /// /// You can create a `DefId` from a `LocalDefId` using `local_def_id.to_def_id()`. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy)] +#[derive(Clone, PartialEq, Eq, Copy)] +// Don't derive order on 64-bit big-endian, so we can be consistent regardless of field order. +#[cfg_attr(not(all(target_pointer_width = "64", target_endian = "big")), derive(PartialOrd, Ord))] // On below-64 bit systems we can simply use the derived `Hash` impl #[cfg_attr(not(target_pointer_width = "64"), derive(Hash))] #[repr(C)] @@ -260,6 +262,22 @@ impl Hash for DefId { } } +// Implement the same comparison as derived with the other field order. +#[cfg(all(target_pointer_width = "64", target_endian = "big"))] +impl Ord for DefId { + #[inline] + fn cmp(&self, other: &DefId) -> std::cmp::Ordering { + Ord::cmp(&(self.index, self.krate), &(other.index, other.krate)) + } +} +#[cfg(all(target_pointer_width = "64", target_endian = "big"))] +impl PartialOrd for DefId { + #[inline] + fn partial_cmp(&self, other: &DefId) -> Option<std::cmp::Ordering> { + Some(Ord::cmp(self, other)) + } +} + impl DefId { /// Makes a local `DefId` from the given `DefIndex`. #[inline] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 07f3656d086..8cb7d147d02 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1296,6 +1296,7 @@ symbols! { rustc_reallocator, rustc_regions, rustc_reservation_impl, + rustc_safe_intrinsic, rustc_serialize, rustc_skip_array_during_method_dispatch, rustc_specialization_trait, @@ -1703,6 +1704,7 @@ impl Ident { /// macro (e.g., `macro` or `macro_rules!` items) and stay different if they came from different /// non-transparent macros. /// Technically, this operation strips all transparent marks from ident's syntactic context. + #[inline] pub fn normalize_to_macro_rules(self) -> Ident { Ident::new(self.name, self.span.normalize_to_macro_rules()) } @@ -1718,6 +1720,7 @@ impl Ident { } impl PartialEq for Ident { + #[inline] fn eq(&self, rhs: &Self) -> bool { self.name == rhs.name && self.span.eq_ctxt(rhs.span) } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 18e7e74741a..ecfe6861e84 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -301,7 +301,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { // Encode impl generic params if the substitutions contain parameters (implying // polymorphization is enabled) and this isn't an inherent impl. - if impl_trait_ref.is_some() && substs.iter().any(|a| a.has_param_types_or_consts()) { + if impl_trait_ref.is_some() && substs.iter().any(|a| a.has_non_region_param()) { self = self.path_generic_args( |this| { this.path_append_ns( diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index ec334e5887a..7171ca7bf89 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1392,7 +1392,7 @@ pub struct PointeeInfo { #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum InitKind { Zero, - Uninit, + UninitMitigated0x01Fill, } /// Trait that needs to be implemented by the higher-level type representation @@ -1498,72 +1498,4 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Abi::Aggregate { sized } => sized && self.size.bytes() == 0, } } - - /// Determines if this type permits "raw" initialization by just transmuting some - /// memory into an instance of `T`. - /// - /// `init_kind` indicates if the memory is zero-initialized or left uninitialized. - /// - /// This code is intentionally conservative, and will not detect - /// * zero init of an enum whose 0 variant does not allow zero initialization - /// * making uninitialized types who have a full valid range (ints, floats, raw pointers) - /// * Any form of invalid value being made inside an array (unless the value is uninhabited) - /// - /// A strict form of these checks that uses const evaluation exists in - /// `rustc_const_eval::might_permit_raw_init`, and a tracking issue for making these checks - /// stricter is <https://github.com/rust-lang/rust/issues/66151>. - /// - /// FIXME: Once all the conservatism is removed from here, and the checks are ran by default, - /// we can use the const evaluation checks always instead. - pub fn might_permit_raw_init<C>(self, cx: &C, init_kind: InitKind) -> bool - where - Self: Copy, - Ty: TyAbiInterface<'a, C>, - C: HasDataLayout, - { - let scalar_allows_raw_init = move |s: Scalar| -> bool { - match init_kind { - InitKind::Zero => { - // The range must contain 0. - s.valid_range(cx).contains(0) - } - InitKind::Uninit => { - // The range must include all values. - s.is_always_valid(cx) - } - } - }; - - // Check the ABI. - let valid = match self.abi { - Abi::Uninhabited => false, // definitely UB - Abi::Scalar(s) => scalar_allows_raw_init(s), - Abi::ScalarPair(s1, s2) => scalar_allows_raw_init(s1) && scalar_allows_raw_init(s2), - Abi::Vector { element: s, count } => count == 0 || scalar_allows_raw_init(s), - Abi::Aggregate { .. } => true, // Fields are checked below. - }; - if !valid { - // This is definitely not okay. - return false; - } - - // If we have not found an error yet, we need to recursively descend into fields. - match &self.fields { - FieldsShape::Primitive | FieldsShape::Union { .. } => {} - FieldsShape::Array { .. } => { - // FIXME(#66151): For now, we are conservative and do not check arrays by default. - } - FieldsShape::Arbitrary { offsets, .. } => { - for idx in 0..offsets.len() { - if !self.field(cx, idx).might_permit_raw_init(cx, init_kind) { - // We found a field that is unhappy with this kind of initialization. - return false; - } - } - } - } - - // FIXME(#66151): For now, we are conservative and do not check `self.variants`. - true - } } diff --git a/compiler/rustc_target/src/spec/i386_apple_ios.rs b/compiler/rustc_target/src/spec/i386_apple_ios.rs index 8b6266c5800..b85214a9c6b 100644 --- a/compiler/rustc_target/src/spec/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/i386_apple_ios.rs @@ -14,8 +14,7 @@ pub fn target() -> Target { arch: "x86".into(), options: TargetOptions { max_atomic_width: Some(64), - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - stack_probes: StackProbeType::Call, + stack_probes: StackProbeType::X86, ..base }, } diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index 5e9ceb844f7..99b9d88e642 100644 --- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs @@ -7,8 +7,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.frame_pointer = FramePointer::Always; // Clang automatically chooses a more specific target based on diff --git a/compiler/rustc_target/src/spec/i686_linux_android.rs b/compiler/rustc_target/src/spec/i686_linux_android.rs index bdaf5c99069..c7c30c23901 100644 --- a/compiler/rustc_target/src/spec/i686_linux_android.rs +++ b/compiler/rustc_target/src/spec/i686_linux_android.rs @@ -11,8 +11,7 @@ pub fn target() -> Target { // https://developer.android.com/ndk/guides/abis.html#x86 base.cpu = "pentiumpro".into(); base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".into(); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "i686-linux-android".into(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs index aff284bf2bc..7d201245006 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-znotext"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "i686-unknown-freebsd".into(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs index 87aa74e406c..357cc547fa0 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "i686-unknown-haiku".into(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs index f62029c9067..bb7b5680298 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs @@ -6,8 +6,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.supported_sanitizers = SanitizerSet::ADDRESS; base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "i686-unknown-linux-gnu".into(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs index d9492804349..f6047919674 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-melf_i386"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; // The unwinder used by i686-unknown-linux-musl, the LLVM libunwind // implementation, apparently relies on frame pointers existing... somehow. diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs index 8de698b51f0..0fd2d1231df 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "i686-unknown-netbsdelf".into(), diff --git a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs index 7f25a1a16c1..2952c043daa 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-fuse-ld=lld"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "i686-unknown-openbsd".into(), diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs index f62404e8279..4a0d98efd82 100644 --- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "i686-unknown-linux-gnu".into(), diff --git a/compiler/rustc_target/src/spec/linux_kernel_base.rs b/compiler/rustc_target/src/spec/linux_kernel_base.rs index 0f5d85205f8..f41533a9548 100644 --- a/compiler/rustc_target/src/spec/linux_kernel_base.rs +++ b/compiler/rustc_target/src/spec/linux_kernel_base.rs @@ -6,8 +6,7 @@ pub fn opts() -> TargetOptions { env: "gnu".into(), disable_redzone: true, panic_strategy: PanicStrategy::Abort, - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - stack_probes: StackProbeType::Call, + stack_probes: StackProbeType::X86, frame_pointer: FramePointer::Always, position_independent_executables: true, needs_plt: true, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 35b4cce50a0..af85e2f4feb 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -635,6 +635,10 @@ pub enum StackProbeType { } impl StackProbeType { + // LLVM X86 targets (ix86 and x86_64) can use inline-asm stack probes starting with LLVM 16. + // Notable past issues were rust#83139 (fixed in 14) and rust#84667 (fixed in 16). + const X86: Self = Self::InlineOrCall { min_llvm_version_for_inline: (16, 0, 0) }; + fn from_json(json: &Json) -> Result<Self, String> { let object = json.as_object().ok_or_else(|| "expected a JSON object")?; let kind = object diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs index 803453c4ac4..9f4cc3d80f1 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs @@ -1,11 +1,12 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "ppc64".into(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc64-unknown-freebsd".into(), diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs index 1cb9ce40cb1..21955a616c2 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs @@ -1,11 +1,12 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "ppc64".into(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc64-unknown-linux-gnu".into(), diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs index 159335eb607..bbf86e4ff41 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs @@ -1,11 +1,12 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "ppc64".into(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc64-unknown-linux-musl".into(), diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs index 9cb3a67dc58..bfa61a21fb3 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs @@ -1,11 +1,12 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.cpu = "ppc64".into(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc64-unknown-openbsd".into(), diff --git a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs index b7420d232ca..4ebf342ad22 100644 --- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs @@ -1,11 +1,12 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "ppc64".into(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc64-unknown-linux-gnu".into(), diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs index a3d18004371..a7ab9078531 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs @@ -1,10 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "ppc64le".into(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc64le-unknown-freebsd".into(), diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs index e18ff3be448..69fd6be6dc0 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs @@ -1,10 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "ppc64le".into(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc64le-unknown-linux-gnu".into(), diff --git a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs index b84943d23a9..ae3a8b54519 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs @@ -1,10 +1,11 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "ppc64le".into(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); base.max_atomic_width = Some(64); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc64le-unknown-linux-musl".into(), diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs index 75ac66c276d..b5d4e5de05e 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs @@ -1,11 +1,12 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); // Extra hint to linker that we are generating secure-PLT code. base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--target=powerpc-unknown-freebsd13.0"]); base.max_atomic_width = Some(32); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc-unknown-freebsd13.0".into(), diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs index 6686a0bbf04..0ceb66c327b 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs @@ -1,10 +1,11 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); base.max_atomic_width = Some(32); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc-unknown-linux-gnu".into(), diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs index 6a250f4b51c..716090f39ca 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs @@ -1,10 +1,11 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe"]); base.max_atomic_width = Some(32); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc-unknown-linux-gnuspe".into(), diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs index 34200c67906..d8cd158584a 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs @@ -1,10 +1,11 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); base.max_atomic_width = Some(32); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc-unknown-linux-musl".into(), diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs index 60661ef9b5d..7053e4b9c26 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs @@ -1,10 +1,11 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); base.max_atomic_width = Some(32); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc-unknown-netbsd".into(), diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs index ad2c3d40f35..dec85f9961b 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_openbsd.rs @@ -1,10 +1,11 @@ use crate::abi::Endian; -use crate::spec::Target; +use crate::spec::{StackProbeType, Target}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.endian = Endian::Big; base.max_atomic_width = Some(32); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc-unknown-openbsd".into(), diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs index 3f24966e06e..e0c5db6eacf 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs @@ -1,10 +1,11 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--secure-plt"]); base.max_atomic_width = Some(32); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc-unknown-linux-gnu".into(), diff --git a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs index 0f04f41f9e5..c7f41b1da87 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs @@ -1,10 +1,11 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe", "--secure-plt"]); base.max_atomic_width = Some(32); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "powerpc-unknown-linux-gnuspe".into(), diff --git a/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs index 8757bbed8ad..cda88de0ea4 100644 --- a/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/s390x_unknown_linux_gnu.rs @@ -1,22 +1,23 @@ use crate::abi::Endian; -use crate::spec::Target; +use crate::spec::{StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.endian = Endian::Big; // z10 is the oldest CPU supported by LLVM base.cpu = "z10".into(); - // FIXME: The data_layout string below and the ABI implementation in - // cabi_s390x.rs are for now hard-coded to assume the no-vector ABI. - // Pass the -vector feature string to LLVM to respect this assumption. + // FIXME: The ABI implementation in cabi_s390x.rs is for now hard-coded to assume the no-vector + // ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we + // also strip v128 from the data_layout below to match the older LLVM's expectation. base.features = "-vector".into(); base.max_atomic_width = Some(64); base.min_global_align = Some(16); + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "s390x-unknown-linux-gnu".into(), pointer_width: 64, - data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".into(), + data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(), arch: "s390x".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs index 4c855271a2a..91e63aee5e4 100644 --- a/compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/s390x_unknown_linux_musl.rs @@ -1,23 +1,24 @@ use crate::abi::Endian; -use crate::spec::Target; +use crate::spec::{StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.endian = Endian::Big; // z10 is the oldest CPU supported by LLVM base.cpu = "z10".into(); - // FIXME: The data_layout string below and the ABI implementation in - // cabi_s390x.rs are for now hard-coded to assume the no-vector ABI. - // Pass the -vector feature string to LLVM to respect this assumption. + // FIXME: The ABI implementation in cabi_s390x.rs is for now hard-coded to assume the no-vector + // ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we + // also strip v128 from the data_layout below to match the older LLVM's expectation. base.features = "-vector".into(); base.max_atomic_width = Some(64); base.min_global_align = Some(16); base.static_position_independent_executables = true; + base.stack_probes = StackProbeType::Inline; Target { llvm_target: "s390x-unknown-linux-musl".into(), pointer_width: 64, - data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".into(), + data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(), arch: "s390x".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index 176c9dd6b76..ad96923320c 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -9,8 +9,7 @@ pub fn target() -> Target { base.frame_pointer = FramePointer::Always; base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs index 5e64ed0cff6..e6143025d6d 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs @@ -13,8 +13,7 @@ pub fn target() -> Target { arch: "x86_64".into(), options: TargetOptions { max_atomic_width: Some(64), - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - stack_probes: StackProbeType::Call, + stack_probes: StackProbeType::X86, ..base }, } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index 2122bcd37fc..61591dacf45 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -15,8 +15,7 @@ pub fn target() -> Target { arch: "x86_64".into(), options: TargetOptions { max_atomic_width: Some(64), - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - stack_probes: StackProbeType::Call, + stack_probes: StackProbeType::X86, ..base }, } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs index a848c5a0aff..3d54da0867c 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs @@ -10,8 +10,7 @@ pub fn target() -> Target { arch: "x86_64".into(), options: TargetOptions { max_atomic_width: Some(64), - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - stack_probes: StackProbeType::Call, + stack_probes: StackProbeType::X86, ..base }, } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs index 4dff3c2f209..e499b1985e7 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs @@ -15,8 +15,7 @@ pub fn target() -> Target { arch: "x86_64".into(), options: TargetOptions { max_atomic_width: Some(64), - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - stack_probes: StackProbeType::Call, + stack_probes: StackProbeType::X86, forces_embed_bitcode: true, // Taken from a clang build on Xcode 11.4.1. // These arguments are not actually invoked - they just have diff --git a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs index 4f88fc3500b..532dd6d0742 100644 --- a/compiler/rustc_target/src/spec/x86_64_fuchsia.rs +++ b/compiler/rustc_target/src/spec/x86_64_fuchsia.rs @@ -4,8 +4,7 @@ pub fn target() -> Target { let mut base = super::fuchsia_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs index 6d19cf26574..4db5ec7fd28 100644 --- a/compiler/rustc_target/src/spec/x86_64_linux_android.rs +++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs @@ -7,8 +7,7 @@ pub fn target() -> Target { base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "x86_64-linux-android".into(), diff --git a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs index 0550b221fd9..974359a138b 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs @@ -6,8 +6,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.vendor = "pc".into(); base.max_atomic_width = Some(64); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs index cbe87589a70..a2fe371a2b8 100644 --- a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs @@ -6,8 +6,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.vendor = "sun".into(); base.max_atomic_width = Some(64); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "x86_64-pc-solaris".into(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs index 746f6478178..989e6432b66 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "x86_64-unknown-dragonfly".into(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs index b30784ed692..24b5b4beebc 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::MEMORY | SanitizerSet::THREAD; diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs index d6d03362982..e3f14aeeea9 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; // This option is required to build executables on Haiku x86_64 base.position_independent_executables = true; diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs index d315301615b..fb1af33f80a 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.features = "+rdrnd,+rdseed".into(); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "x86_64-unknown-hermit".into(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs index 956be0353fa..34e20544da6 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.static_position_independent_executables = true; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs index 140882747c2..23a1f5d80f2 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs @@ -6,8 +6,7 @@ pub fn target() -> Target { base.abi = "x32".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-mx32"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.has_thread_local = false; // BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI // breaks code gen. See LLVM bug 36743 diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs index 87e7784d1f9..179f0995456 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.static_position_independent_executables = true; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs index d3a67619aa8..ac77dfb6415 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs index b9a345127e3..871cdd02078 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs @@ -11,8 +11,7 @@ pub fn target() -> Target { let opts = TargetOptions { cpu: "x86-64".into(), max_atomic_width: Some(64), - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - stack_probes: StackProbeType::Call, + stack_probes: StackProbeType::X86, position_independent_executables: true, static_position_independent_executables: true, relro_level: RelroLevel::Full, diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs index f50c6bceec9..b8084d513f7 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "x86_64-unknown-openbsd".into(), diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs index 668ae905417..a2a143f856d 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; Target { llvm_target: "x86_64-unknown-redox".into(), diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs index 1298974952f..187027d3889 100644 --- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs @@ -5,8 +5,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); - // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved - base.stack_probes = StackProbeType::Call; + base.stack_probes = StackProbeType::X86; base.disable_redzone = true; Target { diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index dc585fca34f..911d1cf8bdf 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -235,14 +235,18 @@ pub fn is_const_evaluatable<'cx, 'tcx>( .emit() } - Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() { - NotConstEvaluatable::MentionsInfer - } else if uv.has_param_types_or_consts() { - NotConstEvaluatable::MentionsParam - } else { - let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?")); - NotConstEvaluatable::Error(guar) - }), + Err(ErrorHandled::TooGeneric) => { + let err = if uv.has_non_region_infer() { + NotConstEvaluatable::MentionsInfer + } else if uv.has_non_region_param() { + NotConstEvaluatable::MentionsParam + } else { + let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?")); + NotConstEvaluatable::Error(guar) + }; + + Err(err) + }, Err(ErrorHandled::Linted) => { let reported = infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint"); @@ -250,23 +254,23 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), Ok(_) => { - if uv.substs.has_param_types_or_consts() { - assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst)); - let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def); + if uv.substs.has_non_region_param() { + assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst)); + let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def); - if mir_body.is_polymorphic { - let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) }; - tcx.struct_span_lint_hir( - lint::builtin::CONST_EVALUATABLE_UNCHECKED, - tcx.hir().local_def_id_to_hir_id(local_def_id), - span, - |err| { - err.build("cannot use constants which depend on generic parameters in types").emit(); - }) - } - } + if mir_body.is_polymorphic { + let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) }; + tcx.struct_span_lint_hir( + lint::builtin::CONST_EVALUATABLE_UNCHECKED, + tcx.hir().local_def_id_to_hir_id(local_def_id), + span, + "cannot use constants which depend on generic parameters in types", + |err| err + ) + } + } - Ok(()) + Ok(()) }, } } 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 b0cabc6275f..6dcf9c4d261 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -661,7 +661,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ); } } - } else if !trait_ref.has_infer_types_or_consts() + } else if !trait_ref.has_non_region_infer() && self.predicate_can_apply(obligation.param_env, trait_ref) { // If a where-clause may be useful, remind the @@ -2093,7 +2093,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { // Pick the first substitution that still contains inference variables as the one // we're going to emit an error for. If there are none (see above), fall back to // a more general error. - let subst = data.trait_ref.substs.iter().find(|s| s.has_infer_types_or_consts()); + let subst = data.trait_ref.substs.iter().find(|s| s.has_non_region_infer()); let mut err = if let Some(subst) = subst { self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283, true) @@ -2263,13 +2263,22 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { trait_impls.non_blanket_impls().len() ) }; - + let mut suggestions = vec![( + trait_path_segment.ident.span.shrink_to_lo(), + format!("<{} as ", self.tcx.type_of(impl_def_id)) + )]; + if let Some(generic_arg) = trait_path_segment.args { + let between_span = trait_path_segment.ident.span.between(generic_arg.span_ext); + // get rid of :: between Trait and <type> + // must be '::' between them, otherwise the parser won't accept the code + suggestions.push((between_span, "".to_string(),)); + suggestions.push((generic_arg.span_ext.shrink_to_hi(), format!(">"))); + } else { + suggestions.push((trait_path_segment.ident.span.shrink_to_hi(), format!(">"))); + } err.multipart_suggestion( message, - vec![ - (trait_path_segment.ident.span.shrink_to_lo(), format!("<{} as ", self.tcx.def_path(impl_def_id).to_string_no_crate_verbose())), - (trait_path_segment.ident.span.shrink_to_hi(), format!(">")) - ], + suggestions, Applicability::MaybeIncorrect ); } @@ -2314,7 +2323,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { .substs .iter() .chain(Some(data.term.into_arg())) - .find(|g| g.has_infer_types_or_consts()); + .find(|g| g.has_non_region_infer()); if let Some(subst) = subst { let mut err = self.emit_inference_failure_err( body_id, @@ -2343,7 +2352,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> { if predicate.references_error() || self.is_tainted_by_errors() { return; } - let subst = data.substs.iter().find(|g| g.has_infer_types_or_consts()); + let subst = data.substs.iter().find(|g| g.has_non_region_infer()); if let Some(subst) = subst { let err = self.emit_inference_failure_err( body_id, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index fff26547be0..7aae014af60 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1231,7 +1231,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { return; } let trait_pred = self.resolve_vars_if_possible(trait_pred); - if trait_pred.has_infer_types_or_consts() { + if trait_pred.has_non_region_infer() { // Do not ICE while trying to find if a reborrow would succeed on a trait with // unresolved bindings. return; @@ -1425,7 +1425,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let mut spans_and_needs_box = vec![]; match liberated_sig.output().kind() { - ty::Dynamic(predicates, _, _) => { + ty::Dynamic(predicates, _, ty::Dyn) => { let cause = ObligationCause::misc(ret_ty.span, fn_hir_id); let param_env = ty::ParamEnv::empty(); diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index f13736a76b2..5802f038e89 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -279,7 +279,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { debug!(?obligation, "pre-resolve"); - if obligation.predicate.has_infer_types_or_consts() { + if obligation.predicate.has_non_region_infer() { obligation.predicate = self.selcx.infcx().resolve_vars_if_possible(obligation.predicate); } @@ -569,7 +569,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ) } (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { - if c1.has_infer_types_or_consts() || c2.has_infer_types_or_consts() { + if c1.has_non_region_infer() || c2.has_non_region_infer() { ProcessResult::Unchanged } else { // Two different constants using generic parameters ~> error. @@ -726,11 +726,11 @@ fn substs_infer_vars<'a, 'tcx>( .resolve_vars_if_possible(substs) .skip_binder() // ok because this check doesn't care about regions .iter() - .filter(|arg| arg.has_infer_types_or_consts()) + .filter(|arg| arg.has_non_region_infer()) .flat_map(|arg| { let mut walker = arg.walk(); while let Some(c) = walker.next() { - if !c.has_infer_types_or_consts() { + if !c.has_non_region_infer() { walker.visited.remove(&c); walker.skip_current_subtree(); } diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index e1bd48ba8ac..41b742734cd 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -57,7 +57,7 @@ pub fn can_type_implement_copy<'tcx>( // to begin with, and point to the bad field's span instead. let cause = if field .ty(tcx, traits::InternalSubsts::identity_for_item(tcx, adt.did())) - .has_param_types_or_consts() + .has_non_region_param() { parent_cause.clone() } else { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 8da68c225d8..659ffc178aa 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -170,7 +170,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>( result ); - if result && ty.has_infer_types_or_consts() { + if result && ty.has_non_region_infer() { // Because of inference "guessing", selection can sometimes claim // to succeed while the success requires a guess. To ensure // this function's result remains infallible, we must confirm diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 2773b61e9ba..8f87a7fdeba 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -14,7 +14,7 @@ use crate::infer::TyCtxtInferExt; use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, Obligation, ObligationCause}; use hir::def::DefKind; -use rustc_errors::{FatalError, MultiSpan}; +use rustc_errors::{DelayDm, FatalError, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::abstract_const::{walk_abstract_const, AbstractConst}; @@ -164,37 +164,42 @@ fn lint_object_unsafe_trait( ) { // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id. // It's also hard to get a use site span, so we use the method definition span. - tcx.struct_span_lint_hir(WHERE_CLAUSES_OBJECT_SAFETY, hir::CRATE_HIR_ID, span, |lint| { - let mut err = lint.build(&format!( - "the trait `{}` cannot be made into an object", - tcx.def_path_str(trait_def_id) - )); - let node = tcx.hir().get_if_local(trait_def_id); - let mut spans = MultiSpan::from_span(span); - if let Some(hir::Node::Item(item)) = node { - spans.push_span_label(item.ident.span, "this trait cannot be made into an object..."); - spans.push_span_label(span, format!("...because {}", violation.error_msg())); - } else { - spans.push_span_label( - span, - format!( - "the trait cannot be made into an object because {}", - violation.error_msg() - ), + tcx.struct_span_lint_hir( + WHERE_CLAUSES_OBJECT_SAFETY, + hir::CRATE_HIR_ID, + span, + DelayDm(|| format!("the trait `{}` cannot be made into an object", tcx.def_path_str(trait_def_id))), + |err| { + let node = tcx.hir().get_if_local(trait_def_id); + let mut spans = MultiSpan::from_span(span); + if let Some(hir::Node::Item(item)) = node { + spans.push_span_label( + item.ident.span, + "this trait cannot be made into an object...", + ); + spans.push_span_label(span, format!("...because {}", violation.error_msg())); + } else { + spans.push_span_label( + span, + format!( + "the trait cannot be made into an object because {}", + violation.error_msg() + ), + ); + }; + err.span_note( + spans, + "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \ + call to be resolvable dynamically; for more information visit \ + <https://doc.rust-lang.org/reference/items/traits.html#object-safety>", ); - }; - err.span_note( - spans, - "for a trait to be \"object safe\" it needs to allow building a vtable to allow the \ - call to be resolvable dynamically; for more information visit \ - <https://doc.rust-lang.org/reference/items/traits.html#object-safety>", - ); - if node.is_some() { - // Only provide the help if its a local trait, otherwise it's not - violation.solution(&mut err); - } - err.emit(); - }); + if node.is_some() { + // Only provide the help if its a local trait, otherwise it's not + violation.solution(err); + } + err + }, + ); } fn sized_trait_bound_spans<'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 07b65a9748d..085045bcdcb 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1488,7 +1488,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>( candidate_set.push_candidate(ctor(data)); if potentially_unnormalized_candidates - && !obligation.predicate.has_infer_types_or_consts() + && !obligation.predicate.has_non_region_infer() { // HACK: Pick the first trait def candidate for a fully // inferred predicate. This is to allow duplicates that @@ -2146,10 +2146,10 @@ fn confirm_impl_candidate<'cx, 'tcx>( } else { ty.map_bound(|ty| ty.into()) }; - if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() { + if !check_substs_compatible(tcx, &assoc_ty.item, substs) { let err = tcx.ty_error_with_message( obligation.cause.span, - "impl item and trait item have different parameter counts", + "impl item and trait item have different parameters", ); Progress { term: err.into(), obligations: nested } } else { @@ -2158,6 +2158,44 @@ fn confirm_impl_candidate<'cx, 'tcx>( } } +// Verify that the trait item and its implementation have compatible substs lists +fn check_substs_compatible<'tcx>( + tcx: TyCtxt<'tcx>, + assoc_ty: &ty::AssocItem, + substs: ty::SubstsRef<'tcx>, +) -> bool { + fn check_substs_compatible_inner<'tcx>( + tcx: TyCtxt<'tcx>, + generics: &'tcx ty::Generics, + args: &'tcx [ty::GenericArg<'tcx>], + ) -> bool { + if generics.count() != args.len() { + return false; + } + + let (parent_args, own_args) = args.split_at(generics.parent_count); + + if let Some(parent) = generics.parent + && let parent_generics = tcx.generics_of(parent) + && !check_substs_compatible_inner(tcx, parent_generics, parent_args) { + return false; + } + + for (param, arg) in std::iter::zip(&generics.params, own_args) { + match (¶m.kind, arg.unpack()) { + (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_)) + | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_)) + | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {} + _ => return false, + } + } + + true + } + + check_substs_compatible_inner(tcx, tcx.generics_of(assoc_ty.def_id), substs.as_slice()) +} + fn confirm_impl_trait_in_trait_candidate<'tcx>( selcx: &mut SelectionContext<'_, 'tcx>, obligation: &ProjectionTyObligation<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 451427a6980..9a8331614b0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -6,6 +6,7 @@ //! //! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly use hir::LangItem; +use rustc_errors::DelayDm; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::traits::ObligationCause; @@ -173,7 +174,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len()); - let needs_infer = stack.obligation.predicate.has_infer_types_or_consts(); + let needs_infer = stack.obligation.predicate.has_non_region_infer(); // If there are STILL multiple candidates, we can further // reduce the list by dropping duplicates -- including @@ -825,13 +826,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { DEREF_INTO_DYN_SUPERTRAIT, obligation.cause.body_id, obligation.cause.span, - |lint| { - lint.build(&format!( - "`{}` implements `Deref` with supertrait `{}` as output", - source, - deref_output_ty - )).emit(); - }, + DelayDm(|| format!( + "`{}` implements `Deref` with supertrait `{}` as output", + source, deref_output_ty + )), + |lint| lint, ); return; } @@ -890,11 +889,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - if obligation.has_param_types_or_consts() { + if obligation.has_non_region_param() { return; } - if obligation.has_infer_types_or_consts() { + if obligation.has_non_region_infer() { candidates.ambiguous = true; return; } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index dd49dcecf77..5c8a76401d2 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -11,9 +11,10 @@ use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::GrowableBitSet; use rustc_infer::infer::InferOk; use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; -use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt}; -use rustc_middle::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; -use rustc_middle::ty::{ToPolyTraitRef, ToPredicate}; +use rustc_middle::ty::{ + self, GenericArg, GenericArgKind, GenericParamDefKind, InternalSubsts, SubstsRef, + ToPolyTraitRef, ToPredicate, Ty, TyCtxt, +}; use rustc_span::def_id::DefId; use crate::traits::project::{normalize_with_depth, normalize_with_depth_to}; @@ -289,8 +290,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let scope = type_at(2).skip_binder(); - let assume = - rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, const_at(3)); + let Some(assume) = + rustc_transmute::Assume::from_const(self.infcx.tcx, obligation.param_env, const_at(3)) else { + return Err(Unimplemented); + }; let cause = obligation.cause.clone(); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 5e32a27cdb1..8f2a6f337ba 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -35,7 +35,6 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::fold::BottomUpFolder; -use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::SubstsRef; use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate}; @@ -729,7 +728,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) } (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { - if c1.has_infer_types_or_consts() || c2.has_infer_types_or_consts() { + if c1.has_non_region_infer() || c2.has_non_region_infer() { Ok(EvaluatedToAmbig) } else { // Two different constants using generic parameters ~> error. @@ -914,38 +913,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let unbound_input_types = stack.fresh_trait_pred.skip_binder().trait_ref.substs.types().any(|ty| ty.is_fresh()); - if stack.obligation.polarity() != ty::ImplPolarity::Negative { - // This check was an imperfect workaround for a bug in the old - // intercrate mode; it should be removed when that goes away. - if unbound_input_types && self.intercrate { - debug!("evaluate_stack --> unbound argument, intercrate --> ambiguous",); - // Heuristics: show the diagnostics when there are no candidates in crate. - if self.intercrate_ambiguity_causes.is_some() { - debug!("evaluate_stack: intercrate_ambiguity_causes is some"); - if let Ok(candidate_set) = self.assemble_candidates(stack) { - if !candidate_set.ambiguous && candidate_set.vec.is_empty() { - let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; - let self_ty = trait_ref.self_ty(); - let cause = with_no_trimmed_paths!({ - IntercrateAmbiguityCause::DownstreamCrate { - trait_desc: trait_ref.print_only_trait_path().to_string(), - self_desc: if self_ty.has_concrete_skeleton() { - Some(self_ty.to_string()) - } else { - None - }, - } - }); - - debug!(?cause, "evaluate_stack: pushing cause"); - self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause); - } - } - } - return Ok(EvaluatedToAmbig); - } - } - if unbound_input_types && stack.iter().skip(1).any(|prev| { stack.obligation.param_env == prev.obligation.param_env @@ -1553,7 +1520,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if !generics.params.is_empty() && obligation.predicate.substs[generics.parent_count..] .iter() - .any(|&p| p.has_infer_types_or_consts() && self.infcx.shallow_resolve(p) != p) + .any(|&p| p.has_non_region_infer() && self.infcx.shallow_resolve(p) != p) { ProjectionMatchesProjection::Ambiguous } else { @@ -1737,12 +1704,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { (&ImplCandidate(other_def), &ImplCandidate(victim_def)) => { // See if we can toss out `victim` based on specialization. - // This requires us to know *for sure* that the `other` impl applies - // i.e., `EvaluatedToOk`. + // While this requires us to know *for sure* that the `other` impl applies + // we still use modulo regions here. // - // FIXME(@lcnr): Using `modulo_regions` here seems kind of scary - // to me but is required for `std` to compile, so I didn't change it - // for now. + // This is fine as specialization currently assumes that specializing + // impls have to be always applicable, meaning that the only allowed + // region constraints may be constraints also present on the default impl. let tcx = self.tcx(); if other.evaluation.must_apply_modulo_regions() { if tcx.specializes((other_def, victim_def)) { diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 56a88749c46..eac3f0f30e8 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -17,7 +17,7 @@ use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause}; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder}; +use rustc_errors::{struct_span_err, DiagnosticBuilder, EmissionGuarantee}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::{self, ImplSubject, TyCtxt}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; @@ -350,26 +350,12 @@ fn report_conflicting_impls( // Work to be done after we've built the DiagnosticBuilder. We have to define it // now because the struct_lint methods don't return back the DiagnosticBuilder // that's passed in. - fn decorate<G: EmissionGuarantee>( + fn decorate<'a, 'b, G: EmissionGuarantee>( tcx: TyCtxt<'_>, overlap: OverlapError, - used_to_be_allowed: Option<FutureCompatOverlapErrorKind>, impl_span: Span, - err: LintDiagnosticBuilder<'_, G>, - ) -> G { - let msg = format!( - "conflicting implementations of trait `{}`{}{}", - overlap.trait_desc, - overlap - .self_desc - .clone() - .map_or_else(String::new, |ty| { format!(" for type `{}`", ty) }), - match used_to_be_allowed { - Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)", - _ => "", - } - ); - let mut err = err.build(&msg); + err: &'b mut DiagnosticBuilder<'a, G>, + ) -> &'b mut DiagnosticBuilder<'a, G> { match tcx.span_of_impl(overlap.with_impl) { Ok(span) => { err.span_label(span, "first implementation here"); @@ -384,7 +370,9 @@ fn report_conflicting_impls( } Err(cname) => { let msg = match to_pretty_impl_header(tcx, overlap.with_impl) { - Some(s) => format!("conflicting implementation in crate `{}`:\n- {}", cname, s), + Some(s) => { + format!("conflicting implementation in crate `{}`:\n- {}", cname, s) + } None => format!("conflicting implementation in crate `{}`", cname), }; err.note(&msg); @@ -392,28 +380,33 @@ fn report_conflicting_impls( } for cause in &overlap.intercrate_ambiguity_causes { - cause.add_intercrate_ambiguity_hint(&mut err); + cause.add_intercrate_ambiguity_hint(err); } if overlap.involves_placeholder { - coherence::add_placeholder_note(&mut err); + coherence::add_placeholder_note(err); } - err.emit() + err } + let msg = format!( + "conflicting implementations of trait `{}`{}{}", + overlap.trait_desc, + overlap.self_desc.as_deref().map_or_else(String::new, |ty| format!(" for type `{ty}`")), + match used_to_be_allowed { + Some(FutureCompatOverlapErrorKind::Issue33140) => ": (E0119)", + _ => "", + } + ); + match used_to_be_allowed { None => { let reported = if overlap.with_impl.is_local() || tcx.orphan_check_impl(impl_def_id).is_ok() { - let err = struct_span_err!(tcx.sess, impl_span, E0119, ""); - Some(decorate( - tcx, - overlap, - used_to_be_allowed, - impl_span, - LintDiagnosticBuilder::new(err), - )) + let mut err = struct_span_err!(tcx.sess, impl_span, E0119, "{msg}",); + decorate(tcx, overlap, impl_span, &mut err); + Some(err.emit()) } else { Some(tcx.sess.delay_span_bug(impl_span, "impl should have failed the orphan check")) }; @@ -428,9 +421,8 @@ fn report_conflicting_impls( lint, tcx.hir().local_def_id_to_hir_id(impl_def_id), impl_span, - |ldb| { - decorate(tcx, overlap, used_to_be_allowed, impl_span, ldb); - }, + msg, + |err| decorate(tcx, overlap, impl_span, err), ); } }; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 9722b48a68a..5f901d6995e 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -308,6 +308,32 @@ impl<'tcx> WfPredicates<'tcx> { let obligations = if trait_pred.constness == ty::BoundConstness::NotConst { self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.substs) } else { + if !tcx.has_attr(trait_ref.def_id, rustc_span::sym::const_trait) { + if let Some(item) = self.item && + let hir::ItemKind::Impl(impl_) = item.kind && + let Some(trait_) = &impl_.of_trait && + let Some(def_id) = trait_.trait_def_id() && + def_id == trait_ref.def_id + { + let trait_name = tcx.item_name(def_id); + let mut err = tcx.sess.struct_span_err( + self.span, + &format!("const `impl` for trait `{trait_name}` which is not marked with `#[const_trait]`"), + ); + if def_id.is_local() { + let sp = tcx.def_span(def_id).shrink_to_lo(); + err.span_suggestion(sp, &format!("mark `{trait_name}` as const"), "#[const_trait]", rustc_errors::Applicability::MachineApplicable); + } + err.note("marking a trait with `#[const_trait]` ensures all default method bodies are `const`"); + err.note("adding a non-const method body in the future would be a breaking change"); + err.emit(); + } else { + tcx.sess.span_err( + self.span, + "~const can only be applied to `#[const_trait]` traits", + ); + } + } self.nominal_obligations(trait_ref.def_id, trait_ref.substs) }; diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 32aca4a8a3f..e540ee1664d 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -79,7 +79,7 @@ fn compute_implied_outlives_bounds<'tcx>( // implied bounds in some cases, mostly when dealing with projections. fulfill_cx.register_predicate_obligations( infcx, - obligations.iter().filter(|o| o.predicate.has_infer_types_or_consts()).cloned(), + obligations.iter().filter(|o| o.predicate.has_non_region_infer()).cloned(), ); // From the full set of obligations, just filter down to the diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 64cd70d3678..51f2eb8606a 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -115,7 +115,7 @@ mod rustc { tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, c: Const<'tcx>, - ) -> Self { + ) -> Option<Self> { use rustc_middle::ty::ScalarInt; use rustc_middle::ty::TypeVisitable; use rustc_span::symbol::sym; @@ -123,10 +123,15 @@ mod rustc { let c = c.eval(tcx, param_env); if let Some(err) = c.error_reported() { - return Self { alignment: true, lifetimes: true, safety: true, validity: true }; + return Some(Self { + alignment: true, + lifetimes: true, + safety: true, + validity: true, + }); } - let adt_def = c.ty().ty_adt_def().expect("The given `Const` must be an ADT."); + let adt_def = c.ty().ty_adt_def()?; assert_eq!( tcx.require_lang_item(LangItem::TransmuteOpts, None), @@ -148,12 +153,12 @@ mod rustc { fields[field_idx].unwrap_leaf() == ScalarInt::TRUE }; - Self { + Some(Self { alignment: get_field(sym::alignment), lifetimes: get_field(sym::lifetimes), safety: get_field(sym::safety), validity: get_field(sym::validity), - } + }) } } } diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 52fbd3ae047..5e4ba473061 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -4,6 +4,8 @@ version = "0.0.0" edition = "2021" [dependencies] +rand = "0.8.4" +rand_xoshiro = "0.6.0" tracing = "0.1" rustc_middle = { path = "../rustc_middle" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs new file mode 100644 index 00000000000..6e34ee21082 --- /dev/null +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -0,0 +1,518 @@ +use rustc_hir as hir; +use rustc_hir::lang_items::LangItem; +use rustc_middle::ty::layout::{ + fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout, +}; +use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::def_id::DefId; +use rustc_target::abi::call::{ + ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, Conv, FnAbi, PassMode, Reg, RegKind, +}; +use rustc_target::abi::*; +use rustc_target::spec::abi::Abi as SpecAbi; + +use std::iter; + +pub fn provide(providers: &mut ty::query::Providers) { + *providers = ty::query::Providers { fn_abi_of_fn_ptr, fn_abi_of_instance, ..*providers }; +} + +// NOTE(eddyb) this is private to avoid using it from outside of +// `fn_abi_of_instance` - any other uses are either too high-level +// for `Instance` (e.g. typeck would use `Ty::fn_sig` instead), +// or should go through `FnAbi` instead, to avoid losing any +// adjustments `fn_abi_of_instance` might be performing. +#[tracing::instrument(level = "debug", skip(tcx, param_env))] +fn fn_sig_for_fn_abi<'tcx>( + tcx: TyCtxt<'tcx>, + instance: ty::Instance<'tcx>, + param_env: ty::ParamEnv<'tcx>, +) -> ty::PolyFnSig<'tcx> { + let ty = instance.ty(tcx, param_env); + match *ty.kind() { + ty::FnDef(..) => { + // HACK(davidtwco,eddyb): This is a workaround for polymorphization considering + // parameters unused if they show up in the signature, but not in the `mir::Body` + // (i.e. due to being inside a projection that got normalized, see + // `src/test/ui/polymorphization/normalized_sig_types.rs`), and codegen not keeping + // track of a polymorphization `ParamEnv` to allow normalizing later. + // + // We normalize the `fn_sig` again after substituting at a later point. + let mut sig = match *ty.kind() { + ty::FnDef(def_id, substs) => tcx + .bound_fn_sig(def_id) + .map_bound(|fn_sig| { + tcx.normalize_erasing_regions(tcx.param_env(def_id), fn_sig) + }) + .subst(tcx, substs), + _ => unreachable!(), + }; + + if let ty::InstanceDef::VTableShim(..) = instance.def { + // Modify `fn(self, ...)` to `fn(self: *mut Self, ...)`. + sig = sig.map_bound(|mut sig| { + let mut inputs_and_output = sig.inputs_and_output.to_vec(); + inputs_and_output[0] = tcx.mk_mut_ptr(inputs_and_output[0]); + sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output); + sig + }); + } + sig + } + ty::Closure(def_id, substs) => { + let sig = substs.as_closure().sig(); + + let bound_vars = tcx.mk_bound_variable_kinds( + sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), + ); + let br = ty::BoundRegion { + var: ty::BoundVar::from_usize(bound_vars.len() - 1), + kind: ty::BoundRegionKind::BrEnv, + }; + let env_region = ty::ReLateBound(ty::INNERMOST, br); + let env_ty = tcx.closure_env_ty(def_id, substs, env_region).unwrap(); + + let sig = sig.skip_binder(); + ty::Binder::bind_with_vars( + tcx.mk_fn_sig( + iter::once(env_ty).chain(sig.inputs().iter().cloned()), + sig.output(), + sig.c_variadic, + sig.unsafety, + sig.abi, + ), + bound_vars, + ) + } + ty::Generator(_, substs, _) => { + let sig = substs.as_generator().poly_sig(); + + let bound_vars = tcx.mk_bound_variable_kinds( + sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), + ); + let br = ty::BoundRegion { + var: ty::BoundVar::from_usize(bound_vars.len() - 1), + kind: ty::BoundRegionKind::BrEnv, + }; + let env_region = ty::ReLateBound(ty::INNERMOST, br); + let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty); + + let pin_did = tcx.require_lang_item(LangItem::Pin, None); + let pin_adt_ref = tcx.adt_def(pin_did); + let pin_substs = tcx.intern_substs(&[env_ty.into()]); + let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs); + + let sig = sig.skip_binder(); + let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); + let state_adt_ref = tcx.adt_def(state_did); + let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); + let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); + ty::Binder::bind_with_vars( + tcx.mk_fn_sig( + [env_ty, sig.resume_ty].iter(), + &ret_ty, + false, + hir::Unsafety::Normal, + rustc_target::spec::abi::Abi::Rust, + ), + bound_vars, + ) + } + _ => bug!("unexpected type {:?} in Instance::fn_sig", ty), + } +} + +#[inline] +fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv { + use rustc_target::spec::abi::Abi::*; + match tcx.sess.target.adjust_abi(abi) { + RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust, + RustCold => Conv::RustCold, + + // It's the ABI's job to select this, not ours. + System { .. } => bug!("system abi should be selected elsewhere"), + EfiApi => bug!("eficall abi should be selected elsewhere"), + + Stdcall { .. } => Conv::X86Stdcall, + Fastcall { .. } => Conv::X86Fastcall, + Vectorcall { .. } => Conv::X86VectorCall, + Thiscall { .. } => Conv::X86ThisCall, + C { .. } => Conv::C, + Unadjusted => Conv::C, + Win64 { .. } => Conv::X86_64Win64, + SysV64 { .. } => Conv::X86_64SysV, + Aapcs { .. } => Conv::ArmAapcs, + CCmseNonSecureCall => Conv::CCmseNonSecureCall, + PtxKernel => Conv::PtxKernel, + Msp430Interrupt => Conv::Msp430Intr, + X86Interrupt => Conv::X86Intr, + AmdGpuKernel => Conv::AmdGpuKernel, + AvrInterrupt => Conv::AvrInterrupt, + AvrNonBlockingInterrupt => Conv::AvrNonBlockingInterrupt, + Wasm => Conv::C, + + // These API constants ought to be more specific... + Cdecl { .. } => Conv::C, + } +} + +fn fn_abi_of_fn_ptr<'tcx>( + tcx: TyCtxt<'tcx>, + query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>)>, +) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { + let (param_env, (sig, extra_args)) = query.into_parts(); + + let cx = LayoutCx { tcx, param_env }; + fn_abi_new_uncached(&cx, sig, extra_args, None, None, false) +} + +fn fn_abi_of_instance<'tcx>( + tcx: TyCtxt<'tcx>, + query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>)>, +) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { + let (param_env, (instance, extra_args)) = query.into_parts(); + + let sig = fn_sig_for_fn_abi(tcx, instance, param_env); + + let caller_location = if instance.def.requires_caller_location(tcx) { + Some(tcx.caller_location_ty()) + } else { + None + }; + + fn_abi_new_uncached( + &LayoutCx { tcx, param_env }, + sig, + extra_args, + caller_location, + Some(instance.def_id()), + matches!(instance.def, ty::InstanceDef::Virtual(..)), + ) +} + +// Handle safe Rust thin and fat pointers. +fn adjust_for_rust_scalar<'tcx>( + cx: LayoutCx<'tcx, TyCtxt<'tcx>>, + attrs: &mut ArgAttributes, + scalar: Scalar, + layout: TyAndLayout<'tcx>, + offset: Size, + is_return: bool, +) { + // Booleans are always a noundef i1 that needs to be zero-extended. + if scalar.is_bool() { + attrs.ext(ArgExtension::Zext); + attrs.set(ArgAttribute::NoUndef); + return; + } + + // Scalars which have invalid values cannot be undef. + if !scalar.is_always_valid(&cx) { + attrs.set(ArgAttribute::NoUndef); + } + + // Only pointer types handled below. + let Scalar::Initialized { value: Pointer, valid_range} = scalar else { return }; + + if !valid_range.contains(0) { + attrs.set(ArgAttribute::NonNull); + } + + if let Some(pointee) = layout.pointee_info_at(&cx, offset) { + if let Some(kind) = pointee.safe { + attrs.pointee_align = Some(pointee.align); + + // `Box` (`UniqueBorrowed`) are not necessarily dereferenceable + // for the entire duration of the function as they can be deallocated + // at any time. Same for shared mutable references. If LLVM had a + // way to say "dereferenceable on entry" we could use it here. + attrs.pointee_size = match kind { + PointerKind::UniqueBorrowed + | PointerKind::UniqueBorrowedPinned + | PointerKind::Frozen => pointee.size, + PointerKind::SharedMutable | PointerKind::UniqueOwned => Size::ZERO, + }; + + // `Box`, `&T`, and `&mut T` cannot be undef. + // Note that this only applies to the value of the pointer itself; + // this attribute doesn't make it UB for the pointed-to data to be undef. + attrs.set(ArgAttribute::NoUndef); + + // The aliasing rules for `Box<T>` are still not decided, but currently we emit + // `noalias` for it. This can be turned off using an unstable flag. + // See https://github.com/rust-lang/unsafe-code-guidelines/issues/326 + let noalias_for_box = cx.tcx.sess.opts.unstable_opts.box_noalias.unwrap_or(true); + + // `&mut` pointer parameters never alias other parameters, + // or mutable global data + // + // `&T` where `T` contains no `UnsafeCell<U>` is immutable, + // and can be marked as both `readonly` and `noalias`, as + // LLVM's definition of `noalias` is based solely on memory + // dependencies rather than pointer equality + // + // Due to past miscompiles in LLVM, we apply a separate NoAliasMutRef attribute + // for UniqueBorrowed arguments, so that the codegen backend can decide whether + // or not to actually emit the attribute. It can also be controlled with the + // `-Zmutable-noalias` debugging option. + let no_alias = match kind { + PointerKind::SharedMutable + | PointerKind::UniqueBorrowed + | PointerKind::UniqueBorrowedPinned => false, + PointerKind::UniqueOwned => noalias_for_box, + PointerKind::Frozen => !is_return, + }; + if no_alias { + attrs.set(ArgAttribute::NoAlias); + } + + if kind == PointerKind::Frozen && !is_return { + attrs.set(ArgAttribute::ReadOnly); + } + + if kind == PointerKind::UniqueBorrowed && !is_return { + attrs.set(ArgAttribute::NoAliasMutRef); + } + } + } +} + +// FIXME(eddyb) perhaps group the signature/type-containing (or all of them?) +// arguments of this method, into a separate `struct`. +#[tracing::instrument(level = "debug", skip(cx, caller_location, fn_def_id, force_thin_self_ptr))] +fn fn_abi_new_uncached<'tcx>( + cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, + sig: ty::PolyFnSig<'tcx>, + extra_args: &[Ty<'tcx>], + caller_location: Option<Ty<'tcx>>, + fn_def_id: Option<DefId>, + // FIXME(eddyb) replace this with something typed, like an `enum`. + force_thin_self_ptr: bool, +) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { + let sig = cx.tcx.normalize_erasing_late_bound_regions(cx.param_env, sig); + + let conv = conv_from_spec_abi(cx.tcx(), sig.abi); + + let mut inputs = sig.inputs(); + let extra_args = if sig.abi == RustCall { + assert!(!sig.c_variadic && extra_args.is_empty()); + + if let Some(input) = sig.inputs().last() { + if let ty::Tuple(tupled_arguments) = input.kind() { + inputs = &sig.inputs()[0..sig.inputs().len() - 1]; + tupled_arguments + } else { + bug!( + "argument to function with \"rust-call\" ABI \ + is not a tuple" + ); + } + } else { + bug!( + "argument to function with \"rust-call\" ABI \ + is not a tuple" + ); + } + } else { + assert!(sig.c_variadic || extra_args.is_empty()); + extra_args + }; + + let target = &cx.tcx.sess.target; + let target_env_gnu_like = matches!(&target.env[..], "gnu" | "musl" | "uclibc"); + let win_x64_gnu = target.os == "windows" && target.arch == "x86_64" && target.env == "gnu"; + let linux_s390x_gnu_like = + target.os == "linux" && target.arch == "s390x" && target_env_gnu_like; + let linux_sparc64_gnu_like = + target.os == "linux" && target.arch == "sparc64" && target_env_gnu_like; + let linux_powerpc_gnu_like = + target.os == "linux" && target.arch == "powerpc" && target_env_gnu_like; + use SpecAbi::*; + let rust_abi = matches!(sig.abi, RustIntrinsic | PlatformIntrinsic | Rust | RustCall); + + let arg_of = |ty: Ty<'tcx>, arg_idx: Option<usize>| -> Result<_, FnAbiError<'tcx>> { + let span = tracing::debug_span!("arg_of"); + let _entered = span.enter(); + let is_return = arg_idx.is_none(); + + let layout = cx.layout_of(ty)?; + let layout = if force_thin_self_ptr && arg_idx == Some(0) { + // Don't pass the vtable, it's not an argument of the virtual fn. + // Instead, pass just the data pointer, but give it the type `*const/mut dyn Trait` + // or `&/&mut dyn Trait` because this is special-cased elsewhere in codegen + make_thin_self_ptr(cx, layout) + } else { + layout + }; + + let mut arg = ArgAbi::new(cx, layout, |layout, scalar, offset| { + let mut attrs = ArgAttributes::new(); + adjust_for_rust_scalar(*cx, &mut attrs, scalar, *layout, offset, is_return); + attrs + }); + + if arg.layout.is_zst() { + // For some forsaken reason, x86_64-pc-windows-gnu + // doesn't ignore zero-sized struct arguments. + // The same is true for {s390x,sparc64,powerpc}-unknown-linux-{gnu,musl,uclibc}. + if is_return + || rust_abi + || (!win_x64_gnu + && !linux_s390x_gnu_like + && !linux_sparc64_gnu_like + && !linux_powerpc_gnu_like) + { + arg.mode = PassMode::Ignore; + } + } + + Ok(arg) + }; + + let mut fn_abi = FnAbi { + ret: arg_of(sig.output(), None)?, + args: inputs + .iter() + .copied() + .chain(extra_args.iter().copied()) + .chain(caller_location) + .enumerate() + .map(|(i, ty)| arg_of(ty, Some(i))) + .collect::<Result<_, _>>()?, + c_variadic: sig.c_variadic, + fixed_count: inputs.len() as u32, + conv, + can_unwind: fn_can_unwind(cx.tcx(), fn_def_id, sig.abi), + }; + fn_abi_adjust_for_abi(cx, &mut fn_abi, sig.abi)?; + debug!("fn_abi_new_uncached = {:?}", fn_abi); + Ok(cx.tcx.arena.alloc(fn_abi)) +} + +#[tracing::instrument(level = "trace", skip(cx))] +fn fn_abi_adjust_for_abi<'tcx>( + cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, + fn_abi: &mut FnAbi<'tcx, Ty<'tcx>>, + abi: SpecAbi, +) -> Result<(), FnAbiError<'tcx>> { + if abi == SpecAbi::Unadjusted { + return Ok(()); + } + + if abi == SpecAbi::Rust + || abi == SpecAbi::RustCall + || abi == SpecAbi::RustIntrinsic + || abi == SpecAbi::PlatformIntrinsic + { + let fixup = |arg: &mut ArgAbi<'tcx, Ty<'tcx>>| { + if arg.is_ignore() { + return; + } + + match arg.layout.abi { + Abi::Aggregate { .. } => {} + + // This is a fun case! The gist of what this is doing is + // that we want callers and callees to always agree on the + // ABI of how they pass SIMD arguments. If we were to *not* + // make these arguments indirect then they'd be immediates + // in LLVM, which means that they'd used whatever the + // appropriate ABI is for the callee and the caller. That + // means, for example, if the caller doesn't have AVX + // enabled but the callee does, then passing an AVX argument + // across this boundary would cause corrupt data to show up. + // + // This problem is fixed by unconditionally passing SIMD + // arguments through memory between callers and callees + // which should get them all to agree on ABI regardless of + // target feature sets. Some more information about this + // issue can be found in #44367. + // + // Note that the platform intrinsic ABI is exempt here as + // that's how we connect up to LLVM and it's unstable + // anyway, we control all calls to it in libstd. + Abi::Vector { .. } + if abi != SpecAbi::PlatformIntrinsic + && cx.tcx.sess.target.simd_types_indirect => + { + arg.make_indirect(); + return; + } + + _ => return, + } + + let size = arg.layout.size; + if arg.layout.is_unsized() || size > Pointer.size(cx) { + arg.make_indirect(); + } else { + // We want to pass small aggregates as immediates, but using + // a LLVM aggregate type for this leads to bad optimizations, + // so we pick an appropriately sized integer type instead. + arg.cast_to(Reg { kind: RegKind::Integer, size }); + } + }; + fixup(&mut fn_abi.ret); + for arg in fn_abi.args.iter_mut() { + fixup(arg); + } + } else { + fn_abi.adjust_for_foreign_abi(cx, abi)?; + } + + Ok(()) +} + +#[tracing::instrument(level = "debug", skip(cx))] +fn make_thin_self_ptr<'tcx>( + cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>), + layout: TyAndLayout<'tcx>, +) -> TyAndLayout<'tcx> { + let tcx = cx.tcx(); + let fat_pointer_ty = if layout.is_unsized() { + // unsized `self` is passed as a pointer to `self` + // FIXME (mikeyhew) change this to use &own if it is ever added to the language + tcx.mk_mut_ptr(layout.ty) + } else { + match layout.abi { + Abi::ScalarPair(..) | Abi::Scalar(..) => (), + _ => bug!("receiver type has unsupported layout: {:?}", layout), + } + + // In the case of Rc<Self>, we need to explicitly pass a *mut RcBox<Self> + // with a Scalar (not ScalarPair) ABI. This is a hack that is understood + // elsewhere in the compiler as a method on a `dyn Trait`. + // To get the type `*mut RcBox<Self>`, we just keep unwrapping newtypes until we + // get a built-in pointer type + let mut fat_pointer_layout = layout; + 'descend_newtypes: while !fat_pointer_layout.ty.is_unsafe_ptr() + && !fat_pointer_layout.ty.is_region_ptr() + { + for i in 0..fat_pointer_layout.fields.count() { + let field_layout = fat_pointer_layout.field(cx, i); + + if !field_layout.is_zst() { + fat_pointer_layout = field_layout; + continue 'descend_newtypes; + } + } + + bug!("receiver has no non-zero-sized fields {:?}", fat_pointer_layout); + } + + fat_pointer_layout.ty + }; + + // we now have a type like `*mut RcBox<dyn Trait>` + // change its layout to that of `*mut ()`, a thin pointer, but keep the same type + // this is understood as a special case elsewhere in the compiler + let unit_ptr_ty = tcx.mk_mut_ptr(tcx.mk_unit()); + + TyAndLayout { + ty: fat_pointer_ty, + + // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing the `Result` + // should always work because the type is always `*mut ()`. + ..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap() + } +} diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 493ef335113..e057bb66825 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -135,30 +135,30 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> { impl<'a, 'tcx> IsThirPolymorphic<'a, 'tcx> { fn expr_is_poly(&mut self, expr: &thir::Expr<'tcx>) -> bool { - if expr.ty.has_param_types_or_consts() { + if expr.ty.has_non_region_param() { return true; } match expr.kind { - thir::ExprKind::NamedConst { substs, .. } => substs.has_param_types_or_consts(), + thir::ExprKind::NamedConst { substs, .. } => substs.has_non_region_param(), thir::ExprKind::ConstParam { .. } => true, thir::ExprKind::Repeat { value, count } => { self.visit_expr(&self.thir()[value]); - count.has_param_types_or_consts() + count.has_non_region_param() } _ => false, } } fn pat_is_poly(&mut self, pat: &thir::Pat<'tcx>) -> bool { - if pat.ty.has_param_types_or_consts() { + if pat.ty.has_non_region_param() { return true; } match pat.kind { - thir::PatKind::Constant { value } => value.has_param_types_or_consts(), + thir::PatKind::Constant { value } => value.has_non_region_param(), thir::PatKind::Range(box thir::PatRange { lo, hi, .. }) => { - lo.has_param_types_or_consts() || hi.has_param_types_or_consts() + lo.has_non_region_param() || hi.has_non_region_param() } _ => false, } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index fa1dc90e4a2..81ca8b646ff 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -171,9 +171,13 @@ fn resolve_associated_item<'tcx>( return Ok(None); } - // If the item does not have a value, then we cannot return an instance. + // Any final impl is required to define all associated items. if !leaf_def.item.defaultness(tcx).has_value() { - return Ok(None); + let guard = tcx.sess.delay_span_bug( + tcx.def_span(leaf_def.item.def_id), + "missing value for assoc item in impl", + ); + return Err(guard); } let substs = tcx.erase_regions(substs); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs new file mode 100644 index 00000000000..345911f4309 --- /dev/null +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -0,0 +1,1804 @@ +use rustc_hir as hir; +use rustc_index::bit_set::BitSet; +use rustc_index::vec::{Idx, IndexVec}; +use rustc_middle::mir::{GeneratorLayout, GeneratorSavedLocal}; +use rustc_middle::ty::layout::{ + IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, +}; +use rustc_middle::ty::{ + self, subst::SubstsRef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable, +}; +use rustc_session::{DataTypeKind, FieldInfo, SizeKind, VariantInfo}; +use rustc_span::symbol::Symbol; +use rustc_span::DUMMY_SP; +use rustc_target::abi::*; + +use std::cmp::{self, Ordering}; +use std::iter; +use std::num::NonZeroUsize; +use std::ops::Bound; + +use rand::{seq::SliceRandom, SeedableRng}; +use rand_xoshiro::Xoshiro128StarStar; + +use crate::layout_sanity_check::sanity_check_layout; + +pub fn provide(providers: &mut ty::query::Providers) { + *providers = ty::query::Providers { layout_of, ..*providers }; +} + +#[instrument(skip(tcx, query), level = "debug")] +fn layout_of<'tcx>( + tcx: TyCtxt<'tcx>, + query: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, +) -> Result<TyAndLayout<'tcx>, LayoutError<'tcx>> { + let (param_env, ty) = query.into_parts(); + debug!(?ty); + + let param_env = param_env.with_reveal_all_normalized(tcx); + let unnormalized_ty = ty; + + // FIXME: We might want to have two different versions of `layout_of`: + // One that can be called after typecheck has completed and can use + // `normalize_erasing_regions` here and another one that can be called + // before typecheck has completed and uses `try_normalize_erasing_regions`. + let ty = match tcx.try_normalize_erasing_regions(param_env, ty) { + Ok(t) => t, + Err(normalization_error) => { + return Err(LayoutError::NormalizationFailure(ty, normalization_error)); + } + }; + + if ty != unnormalized_ty { + // Ensure this layout is also cached for the normalized type. + return tcx.layout_of(param_env.and(ty)); + } + + let cx = LayoutCx { tcx, param_env }; + + let layout = layout_of_uncached(&cx, ty)?; + let layout = TyAndLayout { ty, layout }; + + record_layout_for_printing(&cx, layout); + + sanity_check_layout(&cx, &layout); + + Ok(layout) +} + +#[derive(Copy, Clone, Debug)] +enum StructKind { + /// A tuple, closure, or univariant which cannot be coerced to unsized. + AlwaysSized, + /// A univariant, the last field of which may be coerced to unsized. + MaybeUnsized, + /// A univariant, but with a prefix of an arbitrary size & alignment (e.g., enum tag). + Prefixed(Size, Align), +} + +// Invert a bijective mapping, i.e. `invert(map)[y] = x` if `map[x] = y`. +// This is used to go between `memory_index` (source field order to memory order) +// and `inverse_memory_index` (memory order to source field order). +// See also `FieldsShape::Arbitrary::memory_index` for more details. +// FIXME(eddyb) build a better abstraction for permutations, if possible. +fn invert_mapping(map: &[u32]) -> Vec<u32> { + let mut inverse = vec![0; map.len()]; + for i in 0..map.len() { + inverse[map[i] as usize] = i as u32; + } + inverse +} + +fn scalar_pair<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, a: Scalar, b: Scalar) -> LayoutS<'tcx> { + let dl = cx.data_layout(); + let b_align = b.align(dl); + let align = a.align(dl).max(b_align).max(dl.aggregate_align); + let b_offset = a.size(dl).align_to(b_align.abi); + let size = (b_offset + b.size(dl)).align_to(align.abi); + + // HACK(nox): We iter on `b` and then `a` because `max_by_key` + // returns the last maximum. + let largest_niche = Niche::from_scalar(dl, b_offset, b) + .into_iter() + .chain(Niche::from_scalar(dl, Size::ZERO, a)) + .max_by_key(|niche| niche.available(dl)); + + LayoutS { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Arbitrary { + offsets: vec![Size::ZERO, b_offset], + memory_index: vec![0, 1], + }, + abi: Abi::ScalarPair(a, b), + largest_niche, + align, + size, + } +} + +fn univariant_uninterned<'tcx>( + cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, + ty: Ty<'tcx>, + fields: &[TyAndLayout<'_>], + repr: &ReprOptions, + kind: StructKind, +) -> Result<LayoutS<'tcx>, LayoutError<'tcx>> { + let dl = cx.data_layout(); + let pack = repr.pack; + if pack.is_some() && repr.align.is_some() { + cx.tcx.sess.delay_span_bug(DUMMY_SP, "struct cannot be packed and aligned"); + return Err(LayoutError::Unknown(ty)); + } + + let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align }; + + let mut inverse_memory_index: Vec<u32> = (0..fields.len() as u32).collect(); + + let optimize = !repr.inhibit_struct_field_reordering_opt(); + if optimize { + let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; + let optimizing = &mut inverse_memory_index[..end]; + let field_align = |f: &TyAndLayout<'_>| { + if let Some(pack) = pack { f.align.abi.min(pack) } else { f.align.abi } + }; + + // If `-Z randomize-layout` was enabled for the type definition we can shuffle + // the field ordering to try and catch some code making assumptions about layouts + // we don't guarantee + if repr.can_randomize_type_layout() { + // `ReprOptions.layout_seed` is a deterministic seed that we can use to + // randomize field ordering with + let mut rng = Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed); + + // Shuffle the ordering of the fields + optimizing.shuffle(&mut rng); + + // Otherwise we just leave things alone and actually optimize the type's fields + } else { + match kind { + StructKind::AlwaysSized | StructKind::MaybeUnsized => { + optimizing.sort_by_key(|&x| { + // Place ZSTs first to avoid "interesting offsets", + // especially with only one or two non-ZST fields. + let f = &fields[x as usize]; + (!f.is_zst(), cmp::Reverse(field_align(f))) + }); + } + + StructKind::Prefixed(..) => { + // Sort in ascending alignment so that the layout stays optimal + // regardless of the prefix + optimizing.sort_by_key(|&x| field_align(&fields[x as usize])); + } + } + + // FIXME(Kixiron): We can always shuffle fields within a given alignment class + // regardless of the status of `-Z randomize-layout` + } + } + + // inverse_memory_index holds field indices by increasing memory offset. + // That is, if field 5 has offset 0, the first element of inverse_memory_index is 5. + // We now write field offsets to the corresponding offset slot; + // field 5 with offset 0 puts 0 in offsets[5]. + // At the bottom of this function, we invert `inverse_memory_index` to + // produce `memory_index` (see `invert_mapping`). + + let mut sized = true; + let mut offsets = vec![Size::ZERO; fields.len()]; + let mut offset = Size::ZERO; + let mut largest_niche = None; + let mut largest_niche_available = 0; + + if let StructKind::Prefixed(prefix_size, prefix_align) = kind { + let prefix_align = + if let Some(pack) = pack { prefix_align.min(pack) } else { prefix_align }; + align = align.max(AbiAndPrefAlign::new(prefix_align)); + offset = prefix_size.align_to(prefix_align); + } + + for &i in &inverse_memory_index { + let field = fields[i as usize]; + if !sized { + cx.tcx.sess.delay_span_bug( + DUMMY_SP, + &format!( + "univariant: field #{} of `{}` comes after unsized field", + offsets.len(), + ty + ), + ); + } + + if field.is_unsized() { + sized = false; + } + + // Invariant: offset < dl.obj_size_bound() <= 1<<61 + let field_align = if let Some(pack) = pack { + field.align.min(AbiAndPrefAlign::new(pack)) + } else { + field.align + }; + offset = offset.align_to(field_align.abi); + align = align.max(field_align); + + debug!("univariant offset: {:?} field: {:#?}", offset, field); + offsets[i as usize] = offset; + + if let Some(mut niche) = field.largest_niche { + let available = niche.available(dl); + if available > largest_niche_available { + largest_niche_available = available; + niche.offset += offset; + largest_niche = Some(niche); + } + } + + offset = offset.checked_add(field.size, dl).ok_or(LayoutError::SizeOverflow(ty))?; + } + + if let Some(repr_align) = repr.align { + align = align.max(AbiAndPrefAlign::new(repr_align)); + } + + debug!("univariant min_size: {:?}", offset); + let min_size = offset; + + // As stated above, inverse_memory_index holds field indices by increasing offset. + // This makes it an already-sorted view of the offsets vec. + // To invert it, consider: + // If field 5 has offset 0, offsets[0] is 5, and memory_index[5] should be 0. + // Field 5 would be the first element, so memory_index is i: + // Note: if we didn't optimize, it's already right. + + let memory_index = + if optimize { invert_mapping(&inverse_memory_index) } else { inverse_memory_index }; + + let size = min_size.align_to(align.abi); + let mut abi = Abi::Aggregate { sized }; + + // Unpack newtype ABIs and find scalar pairs. + if sized && size.bytes() > 0 { + // All other fields must be ZSTs. + let mut non_zst_fields = fields.iter().enumerate().filter(|&(_, f)| !f.is_zst()); + + match (non_zst_fields.next(), non_zst_fields.next(), non_zst_fields.next()) { + // We have exactly one non-ZST field. + (Some((i, field)), None, None) => { + // Field fills the struct and it has a scalar or scalar pair ABI. + if offsets[i].bytes() == 0 && align.abi == field.align.abi && size == field.size { + match field.abi { + // For plain scalars, or vectors of them, we can't unpack + // newtypes for `#[repr(C)]`, as that affects C ABIs. + Abi::Scalar(_) | Abi::Vector { .. } if optimize => { + abi = field.abi; + } + // But scalar pairs are Rust-specific and get + // treated as aggregates by C ABIs anyway. + Abi::ScalarPair(..) => { + abi = field.abi; + } + _ => {} + } + } + } + + // Two non-ZST fields, and they're both scalars. + (Some((i, a)), Some((j, b)), None) => { + match (a.abi, b.abi) { + (Abi::Scalar(a), Abi::Scalar(b)) => { + // Order by the memory placement, not source order. + let ((i, a), (j, b)) = if offsets[i] < offsets[j] { + ((i, a), (j, b)) + } else { + ((j, b), (i, a)) + }; + let pair = scalar_pair(cx, a, b); + let pair_offsets = match pair.fields { + FieldsShape::Arbitrary { ref offsets, ref memory_index } => { + assert_eq!(memory_index, &[0, 1]); + offsets + } + _ => bug!(), + }; + if offsets[i] == pair_offsets[0] + && offsets[j] == pair_offsets[1] + && align == pair.align + && size == pair.size + { + // We can use `ScalarPair` only when it matches our + // already computed layout (including `#[repr(C)]`). + abi = pair.abi; + } + } + _ => {} + } + } + + _ => {} + } + } + + if fields.iter().any(|f| f.abi.is_uninhabited()) { + abi = Abi::Uninhabited; + } + + Ok(LayoutS { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Arbitrary { offsets, memory_index }, + abi, + largest_niche, + align, + size, + }) +} + +fn layout_of_uncached<'tcx>( + cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, + ty: Ty<'tcx>, +) -> Result<Layout<'tcx>, LayoutError<'tcx>> { + let tcx = cx.tcx; + let param_env = cx.param_env; + let dl = cx.data_layout(); + let scalar_unit = |value: Primitive| { + let size = value.size(dl); + assert!(size.bits() <= 128); + Scalar::Initialized { value, valid_range: WrappingRange::full(size) } + }; + let scalar = |value: Primitive| tcx.intern_layout(LayoutS::scalar(cx, scalar_unit(value))); + + let univariant = |fields: &[TyAndLayout<'_>], repr: &ReprOptions, kind| { + Ok(tcx.intern_layout(univariant_uninterned(cx, ty, fields, repr, kind)?)) + }; + debug_assert!(!ty.has_non_region_infer()); + + Ok(match *ty.kind() { + // Basic scalars. + ty::Bool => tcx.intern_layout(LayoutS::scalar( + cx, + Scalar::Initialized { + value: Int(I8, false), + valid_range: WrappingRange { start: 0, end: 1 }, + }, + )), + ty::Char => tcx.intern_layout(LayoutS::scalar( + cx, + Scalar::Initialized { + value: Int(I32, false), + valid_range: WrappingRange { start: 0, end: 0x10FFFF }, + }, + )), + ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)), + ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)), + ty::Float(fty) => scalar(match fty { + ty::FloatTy::F32 => F32, + ty::FloatTy::F64 => F64, + }), + ty::FnPtr(_) => { + let mut ptr = scalar_unit(Pointer); + ptr.valid_range_mut().start = 1; + tcx.intern_layout(LayoutS::scalar(cx, ptr)) + } + + // The never type. + ty::Never => tcx.intern_layout(LayoutS { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Primitive, + abi: Abi::Uninhabited, + largest_niche: None, + align: dl.i8_align, + size: Size::ZERO, + }), + + // Potentially-wide pointers. + ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { + let mut data_ptr = scalar_unit(Pointer); + if !ty.is_unsafe_ptr() { + data_ptr.valid_range_mut().start = 1; + } + + let pointee = tcx.normalize_erasing_regions(param_env, pointee); + if pointee.is_sized(tcx.at(DUMMY_SP), param_env) { + return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); + } + + let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env); + let metadata = match unsized_part.kind() { + ty::Foreign(..) => { + return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); + } + ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), + ty::Dynamic(..) => { + let mut vtable = scalar_unit(Pointer); + vtable.valid_range_mut().start = 1; + vtable + } + _ => return Err(LayoutError::Unknown(unsized_part)), + }; + + // Effectively a (ptr, meta) tuple. + tcx.intern_layout(scalar_pair(cx, data_ptr, metadata)) + } + + ty::Dynamic(_, _, ty::DynStar) => { + let mut data = scalar_unit(Int(dl.ptr_sized_integer(), false)); + data.valid_range_mut().start = 0; + let mut vtable = scalar_unit(Pointer); + vtable.valid_range_mut().start = 1; + tcx.intern_layout(scalar_pair(cx, data, vtable)) + } + + // Arrays and slices. + ty::Array(element, mut count) => { + if count.has_projections() { + count = tcx.normalize_erasing_regions(param_env, count); + if count.has_projections() { + return Err(LayoutError::Unknown(ty)); + } + } + + let count = count.try_eval_usize(tcx, param_env).ok_or(LayoutError::Unknown(ty))?; + let element = cx.layout_of(element)?; + let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?; + + let abi = if count != 0 && tcx.conservative_is_privately_uninhabited(param_env.and(ty)) + { + Abi::Uninhabited + } else { + Abi::Aggregate { sized: true } + }; + + let largest_niche = if count != 0 { element.largest_niche } else { None }; + + tcx.intern_layout(LayoutS { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Array { stride: element.size, count }, + abi, + largest_niche, + align: element.align, + size, + }) + } + ty::Slice(element) => { + let element = cx.layout_of(element)?; + tcx.intern_layout(LayoutS { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Array { stride: element.size, count: 0 }, + abi: Abi::Aggregate { sized: false }, + largest_niche: None, + align: element.align, + size: Size::ZERO, + }) + } + ty::Str => tcx.intern_layout(LayoutS { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, + abi: Abi::Aggregate { sized: false }, + largest_niche: None, + align: dl.i8_align, + size: Size::ZERO, + }), + + // Odd unit types. + ty::FnDef(..) => univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)?, + ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => { + let mut unit = univariant_uninterned( + cx, + ty, + &[], + &ReprOptions::default(), + StructKind::AlwaysSized, + )?; + match unit.abi { + Abi::Aggregate { ref mut sized } => *sized = false, + _ => bug!(), + } + tcx.intern_layout(unit) + } + + ty::Generator(def_id, substs, _) => generator_layout(cx, ty, def_id, substs)?, + + ty::Closure(_, ref substs) => { + let tys = substs.as_closure().upvar_tys(); + univariant( + &tys.map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?, + &ReprOptions::default(), + StructKind::AlwaysSized, + )? + } + + ty::Tuple(tys) => { + let kind = + if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized }; + + univariant( + &tys.iter().map(|k| cx.layout_of(k)).collect::<Result<Vec<_>, _>>()?, + &ReprOptions::default(), + kind, + )? + } + + // SIMD vector types. + ty::Adt(def, substs) if def.repr().simd() => { + if !def.is_struct() { + // Should have yielded E0517 by now. + tcx.sess.delay_span_bug( + DUMMY_SP, + "#[repr(simd)] was applied to an ADT that is not a struct", + ); + return Err(LayoutError::Unknown(ty)); + } + + // Supported SIMD vectors are homogeneous ADTs with at least one field: + // + // * #[repr(simd)] struct S(T, T, T, T); + // * #[repr(simd)] struct S { x: T, y: T, z: T, w: T } + // * #[repr(simd)] struct S([T; 4]) + // + // where T is a primitive scalar (integer/float/pointer). + + // SIMD vectors with zero fields are not supported. + // (should be caught by typeck) + if def.non_enum_variant().fields.is_empty() { + tcx.sess.fatal(&format!("monomorphising SIMD type `{}` of zero length", ty)); + } + + // Type of the first ADT field: + let f0_ty = def.non_enum_variant().fields[0].ty(tcx, substs); + + // Heterogeneous SIMD vectors are not supported: + // (should be caught by typeck) + for fi in &def.non_enum_variant().fields { + if fi.ty(tcx, substs) != f0_ty { + tcx.sess.fatal(&format!("monomorphising heterogeneous SIMD type `{}`", ty)); + } + } + + // The element type and number of elements of the SIMD vector + // are obtained from: + // + // * the element type and length of the single array field, if + // the first field is of array type, or + // + // * the homogeneous field type and the number of fields. + let (e_ty, e_len, is_array) = if let ty::Array(e_ty, _) = f0_ty.kind() { + // First ADT field is an array: + + // SIMD vectors with multiple array fields are not supported: + // (should be caught by typeck) + if def.non_enum_variant().fields.len() != 1 { + tcx.sess.fatal(&format!( + "monomorphising SIMD type `{}` with more than one array field", + ty + )); + } + + // Extract the number of elements from the layout of the array field: + let FieldsShape::Array { count, .. } = cx.layout_of(f0_ty)?.layout.fields() else { + return Err(LayoutError::Unknown(ty)); + }; + + (*e_ty, *count, true) + } else { + // First ADT field is not an array: + (f0_ty, def.non_enum_variant().fields.len() as _, false) + }; + + // SIMD vectors of zero length are not supported. + // Additionally, lengths are capped at 2^16 as a fixed maximum backends must + // support. + // + // Can't be caught in typeck if the array length is generic. + if e_len == 0 { + tcx.sess.fatal(&format!("monomorphising SIMD type `{}` of zero length", ty)); + } else if e_len > MAX_SIMD_LANES { + tcx.sess.fatal(&format!( + "monomorphising SIMD type `{}` of length greater than {}", + ty, MAX_SIMD_LANES, + )); + } + + // Compute the ABI of the element type: + let e_ly = cx.layout_of(e_ty)?; + let Abi::Scalar(e_abi) = e_ly.abi else { + // This error isn't caught in typeck, e.g., if + // the element type of the vector is generic. + tcx.sess.fatal(&format!( + "monomorphising SIMD type `{}` with a non-primitive-scalar \ + (integer/float/pointer) element type `{}`", + ty, e_ty + )) + }; + + // Compute the size and alignment of the vector: + let size = e_ly.size.checked_mul(e_len, dl).ok_or(LayoutError::SizeOverflow(ty))?; + let align = dl.vector_align(size); + let size = size.align_to(align.abi); + + // Compute the placement of the vector fields: + let fields = if is_array { + FieldsShape::Arbitrary { offsets: vec![Size::ZERO], memory_index: vec![0] } + } else { + FieldsShape::Array { stride: e_ly.size, count: e_len } + }; + + tcx.intern_layout(LayoutS { + variants: Variants::Single { index: VariantIdx::new(0) }, + fields, + abi: Abi::Vector { element: e_abi, count: e_len }, + largest_niche: e_ly.largest_niche, + size, + align, + }) + } + + // ADTs. + ty::Adt(def, substs) => { + // Cache the field layouts. + let variants = def + .variants() + .iter() + .map(|v| { + v.fields + .iter() + .map(|field| cx.layout_of(field.ty(tcx, substs))) + .collect::<Result<Vec<_>, _>>() + }) + .collect::<Result<IndexVec<VariantIdx, _>, _>>()?; + + if def.is_union() { + if def.repr().pack.is_some() && def.repr().align.is_some() { + cx.tcx.sess.delay_span_bug( + tcx.def_span(def.did()), + "union cannot be packed and aligned", + ); + return Err(LayoutError::Unknown(ty)); + } + + let mut align = + if def.repr().pack.is_some() { dl.i8_align } else { dl.aggregate_align }; + + if let Some(repr_align) = def.repr().align { + align = align.max(AbiAndPrefAlign::new(repr_align)); + } + + let optimize = !def.repr().inhibit_union_abi_opt(); + let mut size = Size::ZERO; + let mut abi = Abi::Aggregate { sized: true }; + let index = VariantIdx::new(0); + for field in &variants[index] { + assert!(!field.is_unsized()); + align = align.max(field.align); + + // If all non-ZST fields have the same ABI, forward this ABI + if optimize && !field.is_zst() { + // Discard valid range information and allow undef + let field_abi = match field.abi { + Abi::Scalar(x) => Abi::Scalar(x.to_union()), + Abi::ScalarPair(x, y) => Abi::ScalarPair(x.to_union(), y.to_union()), + Abi::Vector { element: x, count } => { + Abi::Vector { element: x.to_union(), count } + } + Abi::Uninhabited | Abi::Aggregate { .. } => { + Abi::Aggregate { sized: true } + } + }; + + if size == Size::ZERO { + // first non ZST: initialize 'abi' + abi = field_abi; + } else if abi != field_abi { + // different fields have different ABI: reset to Aggregate + abi = Abi::Aggregate { sized: true }; + } + } + + size = cmp::max(size, field.size); + } + + if let Some(pack) = def.repr().pack { + align = align.min(AbiAndPrefAlign::new(pack)); + } + + return Ok(tcx.intern_layout(LayoutS { + variants: Variants::Single { index }, + fields: FieldsShape::Union( + NonZeroUsize::new(variants[index].len()).ok_or(LayoutError::Unknown(ty))?, + ), + abi, + largest_niche: None, + align, + size: size.align_to(align.abi), + })); + } + + // A variant is absent if it's uninhabited and only has ZST fields. + // Present uninhabited variants only require space for their fields, + // but *not* an encoding of the discriminant (e.g., a tag value). + // See issue #49298 for more details on the need to leave space + // for non-ZST uninhabited data (mostly partial initialization). + let absent = |fields: &[TyAndLayout<'_>]| { + let uninhabited = fields.iter().any(|f| f.abi.is_uninhabited()); + let is_zst = fields.iter().all(|f| f.is_zst()); + uninhabited && is_zst + }; + let (present_first, present_second) = { + let mut present_variants = variants + .iter_enumerated() + .filter_map(|(i, v)| if absent(v) { None } else { Some(i) }); + (present_variants.next(), present_variants.next()) + }; + let present_first = match present_first { + Some(present_first) => present_first, + // Uninhabited because it has no variants, or only absent ones. + None if def.is_enum() => { + return Ok(tcx.layout_of(param_env.and(tcx.types.never))?.layout); + } + // If it's a struct, still compute a layout so that we can still compute the + // field offsets. + None => VariantIdx::new(0), + }; + + let is_struct = !def.is_enum() || + // Only one variant is present. + (present_second.is_none() && + // Representation optimizations are allowed. + !def.repr().inhibit_enum_layout_opt()); + if is_struct { + // Struct, or univariant enum equivalent to a struct. + // (Typechecking will reject discriminant-sizing attrs.) + + let v = present_first; + let kind = if def.is_enum() || variants[v].is_empty() { + StructKind::AlwaysSized + } else { + let param_env = tcx.param_env(def.did()); + let last_field = def.variant(v).fields.last().unwrap(); + let always_sized = + tcx.type_of(last_field.did).is_sized(tcx.at(DUMMY_SP), param_env); + if !always_sized { StructKind::MaybeUnsized } else { StructKind::AlwaysSized } + }; + + let mut st = univariant_uninterned(cx, ty, &variants[v], &def.repr(), kind)?; + st.variants = Variants::Single { index: v }; + + if def.is_unsafe_cell() { + let hide_niches = |scalar: &mut _| match scalar { + Scalar::Initialized { value, valid_range } => { + *valid_range = WrappingRange::full(value.size(dl)) + } + // Already doesn't have any niches + Scalar::Union { .. } => {} + }; + match &mut st.abi { + Abi::Uninhabited => {} + Abi::Scalar(scalar) => hide_niches(scalar), + Abi::ScalarPair(a, b) => { + hide_niches(a); + hide_niches(b); + } + Abi::Vector { element, count: _ } => hide_niches(element), + Abi::Aggregate { sized: _ } => {} + } + st.largest_niche = None; + return Ok(tcx.intern_layout(st)); + } + + let (start, end) = cx.tcx.layout_scalar_valid_range(def.did()); + match st.abi { + Abi::Scalar(ref mut scalar) | Abi::ScalarPair(ref mut scalar, _) => { + // the asserts ensure that we are not using the + // `#[rustc_layout_scalar_valid_range(n)]` + // attribute to widen the range of anything as that would probably + // result in UB somewhere + // FIXME(eddyb) the asserts are probably not needed, + // as larger validity ranges would result in missed + // optimizations, *not* wrongly assuming the inner + // value is valid. e.g. unions enlarge validity ranges, + // because the values may be uninitialized. + if let Bound::Included(start) = start { + // FIXME(eddyb) this might be incorrect - it doesn't + // account for wrap-around (end < start) ranges. + let valid_range = scalar.valid_range_mut(); + assert!(valid_range.start <= start); + valid_range.start = start; + } + if let Bound::Included(end) = end { + // FIXME(eddyb) this might be incorrect - it doesn't + // account for wrap-around (end < start) ranges. + let valid_range = scalar.valid_range_mut(); + assert!(valid_range.end >= end); + valid_range.end = end; + } + + // Update `largest_niche` if we have introduced a larger niche. + let niche = Niche::from_scalar(dl, Size::ZERO, *scalar); + if let Some(niche) = niche { + match st.largest_niche { + Some(largest_niche) => { + // Replace the existing niche even if they're equal, + // because this one is at a lower offset. + if largest_niche.available(dl) <= niche.available(dl) { + st.largest_niche = Some(niche); + } + } + None => st.largest_niche = Some(niche), + } + } + } + _ => assert!( + start == Bound::Unbounded && end == Bound::Unbounded, + "nonscalar layout for layout_scalar_valid_range type {:?}: {:#?}", + def, + st, + ), + } + + return Ok(tcx.intern_layout(st)); + } + + // At this point, we have handled all unions and + // structs. (We have also handled univariant enums + // that allow representation optimization.) + assert!(def.is_enum()); + + // Until we've decided whether to use the tagged or + // niche filling LayoutS, we don't want to intern the + // variant layouts, so we can't store them in the + // overall LayoutS. Store the overall LayoutS + // and the variant LayoutSs here until then. + struct TmpLayout<'tcx> { + layout: LayoutS<'tcx>, + variants: IndexVec<VariantIdx, LayoutS<'tcx>>, + } + + let calculate_niche_filling_layout = + || -> Result<Option<TmpLayout<'tcx>>, LayoutError<'tcx>> { + // The current code for niche-filling relies on variant indices + // instead of actual discriminants, so enums with + // explicit discriminants (RFC #2363) would misbehave. + if def.repr().inhibit_enum_layout_opt() + || def + .variants() + .iter_enumerated() + .any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32())) + { + return Ok(None); + } + + if variants.len() < 2 { + return Ok(None); + } + + let mut align = dl.aggregate_align; + let mut variant_layouts = variants + .iter_enumerated() + .map(|(j, v)| { + let mut st = univariant_uninterned( + cx, + ty, + v, + &def.repr(), + StructKind::AlwaysSized, + )?; + st.variants = Variants::Single { index: j }; + + align = align.max(st.align); + + Ok(st) + }) + .collect::<Result<IndexVec<VariantIdx, _>, _>>()?; + + let largest_variant_index = match variant_layouts + .iter_enumerated() + .max_by_key(|(_i, layout)| layout.size.bytes()) + .map(|(i, _layout)| i) + { + None => return Ok(None), + Some(i) => i, + }; + + let all_indices = VariantIdx::new(0)..=VariantIdx::new(variants.len() - 1); + let needs_disc = |index: VariantIdx| { + index != largest_variant_index && !absent(&variants[index]) + }; + let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap() + ..=all_indices.rev().find(|v| needs_disc(*v)).unwrap(); + + let count = niche_variants.size_hint().1.unwrap() as u128; + + // Find the field with the largest niche + let (field_index, niche, (niche_start, niche_scalar)) = match variants + [largest_variant_index] + .iter() + .enumerate() + .filter_map(|(j, field)| Some((j, field.largest_niche?))) + .max_by_key(|(_, niche)| niche.available(dl)) + .and_then(|(j, niche)| Some((j, niche, niche.reserve(cx, count)?))) + { + None => return Ok(None), + Some(x) => x, + }; + + let niche_offset = niche.offset + + variant_layouts[largest_variant_index].fields.offset(field_index); + let niche_size = niche.value.size(dl); + let size = variant_layouts[largest_variant_index].size.align_to(align.abi); + + let all_variants_fit = + variant_layouts.iter_enumerated_mut().all(|(i, layout)| { + if i == largest_variant_index { + return true; + } + + layout.largest_niche = None; + + if layout.size <= niche_offset { + // This variant will fit before the niche. + return true; + } + + // Determine if it'll fit after the niche. + let this_align = layout.align.abi; + let this_offset = (niche_offset + niche_size).align_to(this_align); + + if this_offset + layout.size > size { + return false; + } + + // It'll fit, but we need to make some adjustments. + match layout.fields { + FieldsShape::Arbitrary { ref mut offsets, .. } => { + for (j, offset) in offsets.iter_mut().enumerate() { + if !variants[i][j].is_zst() { + *offset += this_offset; + } + } + } + _ => { + panic!("Layout of fields should be Arbitrary for variants") + } + } + + // It can't be a Scalar or ScalarPair because the offset isn't 0. + if !layout.abi.is_uninhabited() { + layout.abi = Abi::Aggregate { sized: true }; + } + layout.size += this_offset; + + true + }); + + if !all_variants_fit { + return Ok(None); + } + + let largest_niche = Niche::from_scalar(dl, niche_offset, niche_scalar); + + let others_zst = variant_layouts + .iter_enumerated() + .all(|(i, layout)| i == largest_variant_index || layout.size == Size::ZERO); + let same_size = size == variant_layouts[largest_variant_index].size; + let same_align = align == variant_layouts[largest_variant_index].align; + + let abi = if variant_layouts.iter().all(|v| v.abi.is_uninhabited()) { + Abi::Uninhabited + } else if same_size && same_align && others_zst { + match variant_layouts[largest_variant_index].abi { + // When the total alignment and size match, we can use the + // same ABI as the scalar variant with the reserved niche. + Abi::Scalar(_) => Abi::Scalar(niche_scalar), + Abi::ScalarPair(first, second) => { + // Only the niche is guaranteed to be initialised, + // so use union layouts for the other primitive. + if niche_offset == Size::ZERO { + Abi::ScalarPair(niche_scalar, second.to_union()) + } else { + Abi::ScalarPair(first.to_union(), niche_scalar) + } + } + _ => Abi::Aggregate { sized: true }, + } + } else { + Abi::Aggregate { sized: true } + }; + + let layout = LayoutS { + variants: Variants::Multiple { + tag: niche_scalar, + tag_encoding: TagEncoding::Niche { + untagged_variant: largest_variant_index, + niche_variants, + niche_start, + }, + tag_field: 0, + variants: IndexVec::new(), + }, + fields: FieldsShape::Arbitrary { + offsets: vec![niche_offset], + memory_index: vec![0], + }, + abi, + largest_niche, + size, + align, + }; + + Ok(Some(TmpLayout { layout, variants: variant_layouts })) + }; + + let niche_filling_layout = calculate_niche_filling_layout()?; + + let (mut min, mut max) = (i128::MAX, i128::MIN); + let discr_type = def.repr().discr_type(); + let bits = Integer::from_attr(cx, discr_type).size().bits(); + for (i, discr) in def.discriminants(tcx) { + if variants[i].iter().any(|f| f.abi.is_uninhabited()) { + continue; + } + let mut x = discr.val as i128; + if discr_type.is_signed() { + // sign extend the raw representation to be an i128 + x = (x << (128 - bits)) >> (128 - bits); + } + if x < min { + min = x; + } + if x > max { + max = x; + } + } + // We might have no inhabited variants, so pretend there's at least one. + if (min, max) == (i128::MAX, i128::MIN) { + min = 0; + max = 0; + } + assert!(min <= max, "discriminant range is {}...{}", min, max); + let (min_ity, signed) = Integer::repr_discr(tcx, ty, &def.repr(), min, max); + + let mut align = dl.aggregate_align; + let mut size = Size::ZERO; + + // We're interested in the smallest alignment, so start large. + let mut start_align = Align::from_bytes(256).unwrap(); + assert_eq!(Integer::for_align(dl, start_align), None); + + // repr(C) on an enum tells us to make a (tag, union) layout, + // so we need to grow the prefix alignment to be at least + // the alignment of the union. (This value is used both for + // determining the alignment of the overall enum, and the + // determining the alignment of the payload after the tag.) + let mut prefix_align = min_ity.align(dl).abi; + if def.repr().c() { + for fields in &variants { + for field in fields { + prefix_align = prefix_align.max(field.align.abi); + } + } + } + + // Create the set of structs that represent each variant. + let mut layout_variants = variants + .iter_enumerated() + .map(|(i, field_layouts)| { + let mut st = univariant_uninterned( + cx, + ty, + &field_layouts, + &def.repr(), + StructKind::Prefixed(min_ity.size(), prefix_align), + )?; + st.variants = Variants::Single { index: i }; + // Find the first field we can't move later + // to make room for a larger discriminant. + for field in st.fields.index_by_increasing_offset().map(|j| field_layouts[j]) { + if !field.is_zst() || field.align.abi.bytes() != 1 { + start_align = start_align.min(field.align.abi); + break; + } + } + size = cmp::max(size, st.size); + align = align.max(st.align); + Ok(st) + }) + .collect::<Result<IndexVec<VariantIdx, _>, _>>()?; + + // Align the maximum variant size to the largest alignment. + size = size.align_to(align.abi); + + if size.bytes() >= dl.obj_size_bound() { + return Err(LayoutError::SizeOverflow(ty)); + } + + let typeck_ity = Integer::from_attr(dl, def.repr().discr_type()); + if typeck_ity < min_ity { + // It is a bug if Layout decided on a greater discriminant size than typeck for + // some reason at this point (based on values discriminant can take on). Mostly + // because this discriminant will be loaded, and then stored into variable of + // type calculated by typeck. Consider such case (a bug): typeck decided on + // byte-sized discriminant, but layout thinks we need a 16-bit to store all + // discriminant values. That would be a bug, because then, in codegen, in order + // to store this 16-bit discriminant into 8-bit sized temporary some of the + // space necessary to represent would have to be discarded (or layout is wrong + // on thinking it needs 16 bits) + bug!( + "layout decided on a larger discriminant type ({:?}) than typeck ({:?})", + min_ity, + typeck_ity + ); + // However, it is fine to make discr type however large (as an optimisation) + // after this point – we’ll just truncate the value we load in codegen. + } + + // Check to see if we should use a different type for the + // discriminant. We can safely use a type with the same size + // as the alignment of the first field of each variant. + // We increase the size of the discriminant to avoid LLVM copying + // padding when it doesn't need to. This normally causes unaligned + // load/stores and excessive memcpy/memset operations. By using a + // bigger integer size, LLVM can be sure about its contents and + // won't be so conservative. + + // Use the initial field alignment + let mut ity = if def.repr().c() || def.repr().int.is_some() { + min_ity + } else { + Integer::for_align(dl, start_align).unwrap_or(min_ity) + }; + + // If the alignment is not larger than the chosen discriminant size, + // don't use the alignment as the final size. + if ity <= min_ity { + ity = min_ity; + } else { + // Patch up the variants' first few fields. + let old_ity_size = min_ity.size(); + let new_ity_size = ity.size(); + for variant in &mut layout_variants { + match variant.fields { + FieldsShape::Arbitrary { ref mut offsets, .. } => { + for i in offsets { + if *i <= old_ity_size { + assert_eq!(*i, old_ity_size); + *i = new_ity_size; + } + } + // We might be making the struct larger. + if variant.size <= old_ity_size { + variant.size = new_ity_size; + } + } + _ => bug!(), + } + } + } + + let tag_mask = ity.size().unsigned_int_max(); + let tag = Scalar::Initialized { + value: Int(ity, signed), + valid_range: WrappingRange { + start: (min as u128 & tag_mask), + end: (max as u128 & tag_mask), + }, + }; + let mut abi = Abi::Aggregate { sized: true }; + + if layout_variants.iter().all(|v| v.abi.is_uninhabited()) { + abi = Abi::Uninhabited; + } else if tag.size(dl) == size { + // Make sure we only use scalar layout when the enum is entirely its + // own tag (i.e. it has no padding nor any non-ZST variant fields). + abi = Abi::Scalar(tag); + } else { + // Try to use a ScalarPair for all tagged enums. + let mut common_prim = None; + let mut common_prim_initialized_in_all_variants = true; + for (field_layouts, layout_variant) in iter::zip(&variants, &layout_variants) { + let FieldsShape::Arbitrary { ref offsets, .. } = layout_variant.fields else { + bug!(); + }; + let mut fields = iter::zip(field_layouts, offsets).filter(|p| !p.0.is_zst()); + let (field, offset) = match (fields.next(), fields.next()) { + (None, None) => { + common_prim_initialized_in_all_variants = false; + continue; + } + (Some(pair), None) => pair, + _ => { + common_prim = None; + break; + } + }; + let prim = match field.abi { + Abi::Scalar(scalar) => { + common_prim_initialized_in_all_variants &= + matches!(scalar, Scalar::Initialized { .. }); + scalar.primitive() + } + _ => { + common_prim = None; + break; + } + }; + if let Some(pair) = common_prim { + // This is pretty conservative. We could go fancier + // by conflating things like i32 and u32, or even + // realising that (u8, u8) could just cohabit with + // u16 or even u32. + if pair != (prim, offset) { + common_prim = None; + break; + } + } else { + common_prim = Some((prim, offset)); + } + } + if let Some((prim, offset)) = common_prim { + let prim_scalar = if common_prim_initialized_in_all_variants { + scalar_unit(prim) + } else { + // Common prim might be uninit. + Scalar::Union { value: prim } + }; + let pair = scalar_pair(cx, tag, prim_scalar); + let pair_offsets = match pair.fields { + FieldsShape::Arbitrary { ref offsets, ref memory_index } => { + assert_eq!(memory_index, &[0, 1]); + offsets + } + _ => bug!(), + }; + if pair_offsets[0] == Size::ZERO + && pair_offsets[1] == *offset + && align == pair.align + && size == pair.size + { + // We can use `ScalarPair` only when it matches our + // already computed layout (including `#[repr(C)]`). + abi = pair.abi; + } + } + } + + // If we pick a "clever" (by-value) ABI, we might have to adjust the ABI of the + // variants to ensure they are consistent. This is because a downcast is + // semantically a NOP, and thus should not affect layout. + if matches!(abi, Abi::Scalar(..) | Abi::ScalarPair(..)) { + for variant in &mut layout_variants { + // We only do this for variants with fields; the others are not accessed anyway. + // Also do not overwrite any already existing "clever" ABIs. + if variant.fields.count() > 0 && matches!(variant.abi, Abi::Aggregate { .. }) { + variant.abi = abi; + // Also need to bump up the size and alignment, so that the entire value fits in here. + variant.size = cmp::max(variant.size, size); + variant.align.abi = cmp::max(variant.align.abi, align.abi); + } + } + } + + let largest_niche = Niche::from_scalar(dl, Size::ZERO, tag); + + let tagged_layout = LayoutS { + variants: Variants::Multiple { + tag, + tag_encoding: TagEncoding::Direct, + tag_field: 0, + variants: IndexVec::new(), + }, + fields: FieldsShape::Arbitrary { offsets: vec![Size::ZERO], memory_index: vec![0] }, + largest_niche, + abi, + align, + size, + }; + + let tagged_layout = TmpLayout { layout: tagged_layout, variants: layout_variants }; + + let mut best_layout = match (tagged_layout, niche_filling_layout) { + (tl, Some(nl)) => { + // Pick the smaller layout; otherwise, + // pick the layout with the larger niche; otherwise, + // pick tagged as it has simpler codegen. + use Ordering::*; + let niche_size = |tmp_l: &TmpLayout<'_>| { + tmp_l.layout.largest_niche.map_or(0, |n| n.available(dl)) + }; + match ( + tl.layout.size.cmp(&nl.layout.size), + niche_size(&tl).cmp(&niche_size(&nl)), + ) { + (Greater, _) => nl, + (Equal, Less) => nl, + _ => tl, + } + } + (tl, None) => tl, + }; + + // Now we can intern the variant layouts and store them in the enum layout. + best_layout.layout.variants = match best_layout.layout.variants { + Variants::Multiple { tag, tag_encoding, tag_field, .. } => Variants::Multiple { + tag, + tag_encoding, + tag_field, + variants: best_layout + .variants + .into_iter() + .map(|layout| tcx.intern_layout(layout)) + .collect(), + }, + _ => bug!(), + }; + + tcx.intern_layout(best_layout.layout) + } + + // Types with no meaningful known layout. + ty::Projection(_) | ty::Opaque(..) => { + // NOTE(eddyb) `layout_of` query should've normalized these away, + // if that was possible, so there's no reason to try again here. + return Err(LayoutError::Unknown(ty)); + } + + ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Infer(_) => { + bug!("Layout::compute: unexpected type `{}`", ty) + } + + ty::Bound(..) | ty::Param(_) | ty::Error(_) => { + return Err(LayoutError::Unknown(ty)); + } + }) +} + +/// Overlap eligibility and variant assignment for each GeneratorSavedLocal. +#[derive(Clone, Debug, PartialEq)] +enum SavedLocalEligibility { + Unassigned, + Assigned(VariantIdx), + // FIXME: Use newtype_index so we aren't wasting bytes + Ineligible(Option<u32>), +} + +// When laying out generators, we divide our saved local fields into two +// categories: overlap-eligible and overlap-ineligible. +// +// Those fields which are ineligible for overlap go in a "prefix" at the +// beginning of the layout, and always have space reserved for them. +// +// Overlap-eligible fields are only assigned to one variant, so we lay +// those fields out for each variant and put them right after the +// prefix. +// +// Finally, in the layout details, we point to the fields from the +// variants they are assigned to. It is possible for some fields to be +// included in multiple variants. No field ever "moves around" in the +// layout; its offset is always the same. +// +// Also included in the layout are the upvars and the discriminant. +// These are included as fields on the "outer" layout; they are not part +// of any variant. + +/// Compute the eligibility and assignment of each local. +fn generator_saved_local_eligibility<'tcx>( + info: &GeneratorLayout<'tcx>, +) -> (BitSet<GeneratorSavedLocal>, IndexVec<GeneratorSavedLocal, SavedLocalEligibility>) { + use SavedLocalEligibility::*; + + let mut assignments: IndexVec<GeneratorSavedLocal, SavedLocalEligibility> = + IndexVec::from_elem_n(Unassigned, info.field_tys.len()); + + // The saved locals not eligible for overlap. These will get + // "promoted" to the prefix of our generator. + let mut ineligible_locals = BitSet::new_empty(info.field_tys.len()); + + // Figure out which of our saved locals are fields in only + // one variant. The rest are deemed ineligible for overlap. + for (variant_index, fields) in info.variant_fields.iter_enumerated() { + for local in fields { + match assignments[*local] { + Unassigned => { + assignments[*local] = Assigned(variant_index); + } + Assigned(idx) => { + // We've already seen this local at another suspension + // point, so it is no longer a candidate. + trace!( + "removing local {:?} in >1 variant ({:?}, {:?})", + local, + variant_index, + idx + ); + ineligible_locals.insert(*local); + assignments[*local] = Ineligible(None); + } + Ineligible(_) => {} + } + } + } + + // Next, check every pair of eligible locals to see if they + // conflict. + for local_a in info.storage_conflicts.rows() { + let conflicts_a = info.storage_conflicts.count(local_a); + if ineligible_locals.contains(local_a) { + continue; + } + + for local_b in info.storage_conflicts.iter(local_a) { + // local_a and local_b are storage live at the same time, therefore they + // cannot overlap in the generator layout. The only way to guarantee + // this is if they are in the same variant, or one is ineligible + // (which means it is stored in every variant). + if ineligible_locals.contains(local_b) || assignments[local_a] == assignments[local_b] { + continue; + } + + // If they conflict, we will choose one to make ineligible. + // This is not always optimal; it's just a greedy heuristic that + // seems to produce good results most of the time. + let conflicts_b = info.storage_conflicts.count(local_b); + let (remove, other) = + if conflicts_a > conflicts_b { (local_a, local_b) } else { (local_b, local_a) }; + ineligible_locals.insert(remove); + assignments[remove] = Ineligible(None); + trace!("removing local {:?} due to conflict with {:?}", remove, other); + } + } + + // Count the number of variants in use. If only one of them, then it is + // impossible to overlap any locals in our layout. In this case it's + // always better to make the remaining locals ineligible, so we can + // lay them out with the other locals in the prefix and eliminate + // unnecessary padding bytes. + { + let mut used_variants = BitSet::new_empty(info.variant_fields.len()); + for assignment in &assignments { + if let Assigned(idx) = assignment { + used_variants.insert(*idx); + } + } + if used_variants.count() < 2 { + for assignment in assignments.iter_mut() { + *assignment = Ineligible(None); + } + ineligible_locals.insert_all(); + } + } + + // Write down the order of our locals that will be promoted to the prefix. + { + for (idx, local) in ineligible_locals.iter().enumerate() { + assignments[local] = Ineligible(Some(idx as u32)); + } + } + debug!("generator saved local assignments: {:?}", assignments); + + (ineligible_locals, assignments) +} + +/// Compute the full generator layout. +fn generator_layout<'tcx>( + cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, + ty: Ty<'tcx>, + def_id: hir::def_id::DefId, + substs: SubstsRef<'tcx>, +) -> Result<Layout<'tcx>, LayoutError<'tcx>> { + use SavedLocalEligibility::*; + let tcx = cx.tcx; + let subst_field = |ty: Ty<'tcx>| EarlyBinder(ty).subst(tcx, substs); + + let Some(info) = tcx.generator_layout(def_id) else { + return Err(LayoutError::Unknown(ty)); + }; + let (ineligible_locals, assignments) = generator_saved_local_eligibility(&info); + + // Build a prefix layout, including "promoting" all ineligible + // locals as part of the prefix. We compute the layout of all of + // these fields at once to get optimal packing. + let tag_index = substs.as_generator().prefix_tys().count(); + + // `info.variant_fields` already accounts for the reserved variants, so no need to add them. + let max_discr = (info.variant_fields.len() - 1) as u128; + let discr_int = Integer::fit_unsigned(max_discr); + let discr_int_ty = discr_int.to_ty(tcx, false); + let tag = Scalar::Initialized { + value: Primitive::Int(discr_int, false), + valid_range: WrappingRange { start: 0, end: max_discr }, + }; + let tag_layout = cx.tcx.intern_layout(LayoutS::scalar(cx, tag)); + let tag_layout = TyAndLayout { ty: discr_int_ty, layout: tag_layout }; + + let promoted_layouts = ineligible_locals + .iter() + .map(|local| subst_field(info.field_tys[local])) + .map(|ty| tcx.mk_maybe_uninit(ty)) + .map(|ty| cx.layout_of(ty)); + let prefix_layouts = substs + .as_generator() + .prefix_tys() + .map(|ty| cx.layout_of(ty)) + .chain(iter::once(Ok(tag_layout))) + .chain(promoted_layouts) + .collect::<Result<Vec<_>, _>>()?; + let prefix = univariant_uninterned( + cx, + ty, + &prefix_layouts, + &ReprOptions::default(), + StructKind::AlwaysSized, + )?; + + let (prefix_size, prefix_align) = (prefix.size, prefix.align); + + // Split the prefix layout into the "outer" fields (upvars and + // discriminant) and the "promoted" fields. Promoted fields will + // get included in each variant that requested them in + // GeneratorLayout. + debug!("prefix = {:#?}", prefix); + let (outer_fields, promoted_offsets, promoted_memory_index) = match prefix.fields { + FieldsShape::Arbitrary { mut offsets, memory_index } => { + let mut inverse_memory_index = invert_mapping(&memory_index); + + // "a" (`0..b_start`) and "b" (`b_start..`) correspond to + // "outer" and "promoted" fields respectively. + let b_start = (tag_index + 1) as u32; + let offsets_b = offsets.split_off(b_start as usize); + let offsets_a = offsets; + + // Disentangle the "a" and "b" components of `inverse_memory_index` + // by preserving the order but keeping only one disjoint "half" each. + // FIXME(eddyb) build a better abstraction for permutations, if possible. + let inverse_memory_index_b: Vec<_> = + inverse_memory_index.iter().filter_map(|&i| i.checked_sub(b_start)).collect(); + inverse_memory_index.retain(|&i| i < b_start); + let inverse_memory_index_a = inverse_memory_index; + + // Since `inverse_memory_index_{a,b}` each only refer to their + // respective fields, they can be safely inverted + let memory_index_a = invert_mapping(&inverse_memory_index_a); + let memory_index_b = invert_mapping(&inverse_memory_index_b); + + let outer_fields = + FieldsShape::Arbitrary { offsets: offsets_a, memory_index: memory_index_a }; + (outer_fields, offsets_b, memory_index_b) + } + _ => bug!(), + }; + + let mut size = prefix.size; + let mut align = prefix.align; + let variants = info + .variant_fields + .iter_enumerated() + .map(|(index, variant_fields)| { + // Only include overlap-eligible fields when we compute our variant layout. + let variant_only_tys = variant_fields + .iter() + .filter(|local| match assignments[**local] { + Unassigned => bug!(), + Assigned(v) if v == index => true, + Assigned(_) => bug!("assignment does not match variant"), + Ineligible(_) => false, + }) + .map(|local| subst_field(info.field_tys[*local])); + + let mut variant = univariant_uninterned( + cx, + ty, + &variant_only_tys.map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?, + &ReprOptions::default(), + StructKind::Prefixed(prefix_size, prefix_align.abi), + )?; + variant.variants = Variants::Single { index }; + + let FieldsShape::Arbitrary { offsets, memory_index } = variant.fields else { + bug!(); + }; + + // Now, stitch the promoted and variant-only fields back together in + // the order they are mentioned by our GeneratorLayout. + // Because we only use some subset (that can differ between variants) + // of the promoted fields, we can't just pick those elements of the + // `promoted_memory_index` (as we'd end up with gaps). + // So instead, we build an "inverse memory_index", as if all of the + // promoted fields were being used, but leave the elements not in the + // subset as `INVALID_FIELD_IDX`, which we can filter out later to + // obtain a valid (bijective) mapping. + const INVALID_FIELD_IDX: u32 = !0; + let mut combined_inverse_memory_index = + vec![INVALID_FIELD_IDX; promoted_memory_index.len() + memory_index.len()]; + let mut offsets_and_memory_index = iter::zip(offsets, memory_index); + let combined_offsets = variant_fields + .iter() + .enumerate() + .map(|(i, local)| { + let (offset, memory_index) = match assignments[*local] { + Unassigned => bug!(), + Assigned(_) => { + let (offset, memory_index) = offsets_and_memory_index.next().unwrap(); + (offset, promoted_memory_index.len() as u32 + memory_index) + } + Ineligible(field_idx) => { + let field_idx = field_idx.unwrap() as usize; + (promoted_offsets[field_idx], promoted_memory_index[field_idx]) + } + }; + combined_inverse_memory_index[memory_index as usize] = i as u32; + offset + }) + .collect(); + + // Remove the unused slots and invert the mapping to obtain the + // combined `memory_index` (also see previous comment). + combined_inverse_memory_index.retain(|&i| i != INVALID_FIELD_IDX); + let combined_memory_index = invert_mapping(&combined_inverse_memory_index); + + variant.fields = FieldsShape::Arbitrary { + offsets: combined_offsets, + memory_index: combined_memory_index, + }; + + size = size.max(variant.size); + align = align.max(variant.align); + Ok(tcx.intern_layout(variant)) + }) + .collect::<Result<IndexVec<VariantIdx, _>, _>>()?; + + size = size.align_to(align.abi); + + let abi = if prefix.abi.is_uninhabited() || variants.iter().all(|v| v.abi().is_uninhabited()) { + Abi::Uninhabited + } else { + Abi::Aggregate { sized: true } + }; + + let layout = tcx.intern_layout(LayoutS { + variants: Variants::Multiple { + tag, + tag_encoding: TagEncoding::Direct, + tag_field: tag_index, + variants, + }, + fields: outer_fields, + abi, + largest_niche: prefix.largest_niche, + size, + align, + }); + debug!("generator layout ({:?}): {:#?}", ty, layout); + Ok(layout) +} + +/// This is invoked by the `layout_of` query to record the final +/// layout of each type. +#[inline(always)] +fn record_layout_for_printing<'tcx>(cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, layout: TyAndLayout<'tcx>) { + // If we are running with `-Zprint-type-sizes`, maybe record layouts + // for dumping later. + if cx.tcx.sess.opts.unstable_opts.print_type_sizes { + record_layout_for_printing_outlined(cx, layout) + } +} + +fn record_layout_for_printing_outlined<'tcx>( + cx: &LayoutCx<'tcx, TyCtxt<'tcx>>, + layout: TyAndLayout<'tcx>, +) { + // Ignore layouts that are done with non-empty environments or + // non-monomorphic layouts, as the user only wants to see the stuff + // resulting from the final codegen session. + if layout.ty.has_non_region_param() || !cx.param_env.caller_bounds().is_empty() { + return; + } + + // (delay format until we actually need it) + let record = |kind, packed, opt_discr_size, variants| { + let type_desc = format!("{:?}", layout.ty); + cx.tcx.sess.code_stats.record_type_size( + kind, + type_desc, + layout.align.abi, + layout.size, + packed, + opt_discr_size, + variants, + ); + }; + + let adt_def = match *layout.ty.kind() { + ty::Adt(ref adt_def, _) => { + debug!("print-type-size t: `{:?}` process adt", layout.ty); + adt_def + } + + ty::Closure(..) => { + debug!("print-type-size t: `{:?}` record closure", layout.ty); + record(DataTypeKind::Closure, false, None, vec![]); + return; + } + + _ => { + debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty); + return; + } + }; + + let adt_kind = adt_def.adt_kind(); + let adt_packed = adt_def.repr().pack.is_some(); + + let build_variant_info = |n: Option<Symbol>, flds: &[Symbol], layout: TyAndLayout<'tcx>| { + let mut min_size = Size::ZERO; + let field_info: Vec<_> = flds + .iter() + .enumerate() + .map(|(i, &name)| { + let field_layout = layout.field(cx, i); + let offset = layout.fields.offset(i); + let field_end = offset + field_layout.size; + if min_size < field_end { + min_size = field_end; + } + FieldInfo { + name, + offset: offset.bytes(), + size: field_layout.size.bytes(), + align: field_layout.align.abi.bytes(), + } + }) + .collect(); + + VariantInfo { + name: n, + kind: if layout.is_unsized() { SizeKind::Min } else { SizeKind::Exact }, + align: layout.align.abi.bytes(), + size: if min_size.bytes() == 0 { layout.size.bytes() } else { min_size.bytes() }, + fields: field_info, + } + }; + + match layout.variants { + Variants::Single { index } => { + if !adt_def.variants().is_empty() && layout.fields != FieldsShape::Primitive { + debug!("print-type-size `{:#?}` variant {}", layout, adt_def.variant(index).name); + let variant_def = &adt_def.variant(index); + let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect(); + record( + adt_kind.into(), + adt_packed, + None, + vec![build_variant_info(Some(variant_def.name), &fields, layout)], + ); + } else { + // (This case arises for *empty* enums; so give it + // zero variants.) + record(adt_kind.into(), adt_packed, None, vec![]); + } + } + + Variants::Multiple { tag, ref tag_encoding, .. } => { + debug!( + "print-type-size `{:#?}` adt general variants def {}", + layout.ty, + adt_def.variants().len() + ); + let variant_infos: Vec<_> = adt_def + .variants() + .iter_enumerated() + .map(|(i, variant_def)| { + let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect(); + build_variant_info(Some(variant_def.name), &fields, layout.for_variant(cx, i)) + }) + .collect(); + record( + adt_kind.into(), + adt_packed, + match tag_encoding { + TagEncoding::Direct => Some(tag.size(cx)), + _ => None, + }, + variant_infos, + ); + } + } +} diff --git a/compiler/rustc_middle/src/ty/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs index 87c85dcfff3..100926ad446 100644 --- a/compiler/rustc_middle/src/ty/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs @@ -1,4 +1,4 @@ -use crate::ty::{ +use rustc_middle::ty::{ layout::{LayoutCx, TyAndLayout}, TyCtxt, }; diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 10c18789f74..f97fc4c199d 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -9,8 +9,6 @@ #![feature(never_type)] #![feature(box_patterns)] #![recursion_limit = "256"] -#![deny(rustc::untranslatable_diagnostic)] -#![deny(rustc::diagnostic_outside_of_impl)] #[macro_use] extern crate rustc_middle; @@ -19,21 +17,26 @@ extern crate tracing; use rustc_middle::ty::query::Providers; +mod abi; mod assoc; mod common_traits; mod consts; mod errors; mod implied_bounds; pub mod instance; +mod layout; +mod layout_sanity_check; mod needs_drop; pub mod representability; mod ty; pub fn provide(providers: &mut Providers) { + abi::provide(providers); assoc::provide(providers); common_traits::provide(providers); consts::provide(providers); implied_bounds::provide(providers); + layout::provide(providers); needs_drop::provide(providers); ty::provide(providers); instance::provide(providers); diff --git a/config.toml.example b/config.toml.example index a967d881b02..1f5747456e9 100644 --- a/config.toml.example +++ b/config.toml.example @@ -291,6 +291,10 @@ changelog-seen = 2 # on this runtime, such as `-C profile-generate` or `-C instrument-coverage`). #profiler = false +# Use the optimized LLVM C intrinsics for `compiler_builtins`, rather than Rust intrinsics. +# Requires the LLVM submodule to be managed by bootstrap (i.e. not external). +#optimized-compiler-builtins = false + # Indicates whether the native libraries linked into Cargo will be statically # linked or not. #cargo-native-static = false @@ -521,6 +525,12 @@ changelog-seen = 2 # A descriptive string to be appended to `rustc --version` output, which is # also used in places like debuginfo `DW_AT_producer`. This may be useful for # supplementary build information, like distro-specific package versions. +# +# The Rust compiler will differentiate between versions of itself, including +# based on this string, which means that if you wish to be compatible with +# upstream Rust you need to set this to "". However, note that if you are not +# actually compatible -- for example if you've backported patches that change +# behavior -- this may lead to miscompilations or other bugs. #description = <none> (string) # The root location of the musl installation directory. The library directory diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 3018d1c9125..3687f84b1bd 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -2392,7 +2392,11 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_btree_len", issue = "71835")] + #[rustc_const_unstable( + feature = "const_btree_len", + issue = "71835", + implied_by = "const_btree_new" + )] pub const fn len(&self) -> usize { self.length } @@ -2413,7 +2417,11 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_btree_len", issue = "71835")] + #[rustc_const_unstable( + feature = "const_btree_len", + issue = "71835", + implied_by = "const_btree_new" + )] pub const fn is_empty(&self) -> bool { self.len() == 0 } diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 3caaf521240..5783d836e10 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1174,7 +1174,11 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_btree_len", issue = "71835")] + #[rustc_const_unstable( + feature = "const_btree_len", + issue = "71835", + implied_by = "const_btree_new" + )] pub const fn len(&self) -> usize { self.map.len() } @@ -1193,7 +1197,11 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> { /// ``` #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_btree_len", issue = "71835")] + #[rustc_const_unstable( + feature = "const_btree_len", + issue = "71835", + implied_by = "const_btree_new" + )] pub const fn is_empty(&self) -> bool { self.len() == 0 } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index a5322953d49..df315dad893 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -3,6 +3,10 @@ //! Thread-safe reference-counting pointers. //! //! See the [`Arc<T>`][Arc] documentation for more details. +//! +//! **Note**: This module is only available on platforms that support atomic +//! loads and stores of pointers. This may be detected at compile time using +//! `#[cfg(target_has_atomic = "ptr")]`. use core::any::Any; use core::borrow; @@ -82,6 +86,11 @@ macro_rules! acquire { /// [`Mutex`][mutex], [`RwLock`][rwlock], or one of the [`Atomic`][atomic] /// types. /// +/// **Note**: This type is only available on platforms that support atomic +/// loads and stores of pointers, which includes all platforms that support +/// the `std` crate but not all those which only support [`alloc`](crate). +/// This may be detected at compile time using `#[cfg(target_has_atomic = "ptr")]`. +/// /// ## Thread Safety /// /// Unlike [`Rc<T>`], `Arc<T>` uses atomic operations for its reference @@ -1980,33 +1989,26 @@ impl<T: ?Sized> Weak<T> { // We use a CAS loop to increment the strong count instead of a // fetch_add as this function should never take the reference count // from zero to one. - let inner = self.inner()?; - - // Relaxed load because any write of 0 that we can observe - // leaves the field in a permanently zero state (so a - // "stale" read of 0 is fine), and any other value is - // confirmed via the CAS below. - let mut n = inner.strong.load(Relaxed); - - loop { - if n == 0 { - return None; - } - - // See comments in `Arc::clone` for why we do this (for `mem::forget`). - if n > MAX_REFCOUNT { - abort(); - } - + self.inner()? + .strong // Relaxed is fine for the failure case because we don't have any expectations about the new state. // Acquire is necessary for the success case to synchronise with `Arc::new_cyclic`, when the inner // value can be initialized after `Weak` references have already been created. In that case, we // expect to observe the fully initialized value. - match inner.strong.compare_exchange_weak(n, n + 1, Acquire, Relaxed) { - Ok(_) => return Some(unsafe { Arc::from_inner(self.ptr) }), // null checked above - Err(old) => n = old, - } - } + .fetch_update(Acquire, Relaxed, |n| { + // Any write of 0 we can observe leaves the field in permanently zero state. + if n == 0 { + return None; + } + // See comments in `Arc::clone` for why we do this (for `mem::forget`). + if n > MAX_REFCOUNT { + abort(); + } + Some(n + 1) + }) + .ok() + // null checked above + .map(|_| unsafe { Arc::from_inner(self.ptr) }) } /// Gets the number of strong (`Arc`) pointers pointing to this allocation. diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index 528ee4ff154..9d8e309a978 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -1,5 +1,11 @@ #![stable(feature = "wake_trait", since = "1.51.0")] + //! Types and Traits for working with asynchronous tasks. +//! +//! **Note**: This module is only available on platforms that support atomic +//! loads and stores of pointers. This may be detected at compile time using +//! `#[cfg(target_has_atomic = "ptr")]`. + use core::mem::ManuallyDrop; use core::task::{RawWaker, RawWakerVTable, Waker}; diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index a3f8fe40fd5..87d61deb1eb 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -55,6 +55,9 @@ //! This is handled by the [`InPlaceDrop`] guard for sink items (`U`) and by //! [`vec::IntoIter::forget_allocation_drop_remaining()`] for remaining source items (`T`). //! +//! If dropping any remaining source item (`T`) panics then [`InPlaceDstBufDrop`] will handle dropping +//! the already collected sink items (`U`) and freeing the allocation. +//! //! [`vec::IntoIter::forget_allocation_drop_remaining()`]: super::IntoIter::forget_allocation_drop_remaining() //! //! # O(1) collect @@ -138,7 +141,7 @@ use core::iter::{InPlaceIterable, SourceIter, TrustedRandomAccessNoCoerce}; use core::mem::{self, ManuallyDrop, SizedTypeProperties}; use core::ptr::{self}; -use super::{InPlaceDrop, SpecFromIter, SpecFromIterNested, Vec}; +use super::{InPlaceDrop, InPlaceDstBufDrop, SpecFromIter, SpecFromIterNested, Vec}; /// Specialization marker for collecting an iterator pipeline into a Vec while reusing the /// source allocation, i.e. executing the pipeline in place. @@ -191,14 +194,17 @@ where ); } - // Drop any remaining values at the tail of the source but prevent drop of the allocation - // itself once IntoIter goes out of scope. - // If the drop panics then we also leak any elements collected into dst_buf. + // The ownership of the allocation and the new `T` values is temporarily moved into `dst_guard`. + // This is safe because `forget_allocation_drop_remaining` immediately forgets the allocation + // before any panic can occur in order to avoid any double free, and then proceeds to drop + // any remaining values at the tail of the source. // // Note: This access to the source wouldn't be allowed by the TrustedRandomIteratorNoCoerce // contract (used by SpecInPlaceCollect below). But see the "O(1) collect" section in the // module documenttation why this is ok anyway. + let dst_guard = InPlaceDstBufDrop { ptr: dst_buf, len, cap }; src.forget_allocation_drop_remaining(); + mem::forget(dst_guard); let vec = unsafe { Vec::from_raw_parts(dst_buf, len, cap) }; diff --git a/library/alloc/src/vec/in_place_drop.rs b/library/alloc/src/vec/in_place_drop.rs index 1b1ef9130fa..25ca33c6a7b 100644 --- a/library/alloc/src/vec/in_place_drop.rs +++ b/library/alloc/src/vec/in_place_drop.rs @@ -22,3 +22,18 @@ impl<T> Drop for InPlaceDrop<T> { } } } + +// A helper struct for in-place collection that drops the destination allocation and elements, +// to avoid leaking them if some other destructor panics. +pub(super) struct InPlaceDstBufDrop<T> { + pub(super) ptr: *mut T, + pub(super) len: usize, + pub(super) cap: usize, +} + +impl<T> Drop for InPlaceDstBufDrop<T> { + #[inline] + fn drop(&mut self) { + unsafe { super::Vec::from_raw_parts(self.ptr, self.len, self.cap) }; + } +} diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index d74e77637bd..73d7c90cf78 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -95,13 +95,16 @@ impl<T, A: Allocator> IntoIter<T, A> { } /// Drops remaining elements and relinquishes the backing allocation. + /// This method guarantees it won't panic before relinquishing + /// the backing allocation. /// /// This is roughly equivalent to the following, but more efficient /// /// ``` /// # let mut into_iter = Vec::<u8>::with_capacity(10).into_iter(); + /// let mut into_iter = std::mem::replace(&mut into_iter, Vec::new().into_iter()); /// (&mut into_iter).for_each(core::mem::drop); - /// unsafe { core::ptr::write(&mut into_iter, Vec::new().into_iter()); } + /// std::mem::forget(into_iter); /// ``` /// /// This method is used by in-place iteration, refer to the vec::in_place_collect @@ -118,6 +121,8 @@ impl<T, A: Allocator> IntoIter<T, A> { self.ptr = self.buf.as_ptr(); self.end = self.buf.as_ptr(); + // Dropping the remaining elements can panic, so this needs to be + // done only after updating the other fields. unsafe { ptr::drop_in_place(remaining); } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index d6d986905e6..0332047e6b6 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -125,7 +125,7 @@ use self::set_len_on_drop::SetLenOnDrop; mod set_len_on_drop; #[cfg(not(no_global_oom_handling))] -use self::in_place_drop::InPlaceDrop; +use self::in_place_drop::{InPlaceDrop, InPlaceDstBufDrop}; #[cfg(not(no_global_oom_handling))] mod in_place_drop; @@ -483,15 +483,13 @@ impl<T> Vec<T> { Self::with_capacity_in(capacity, Global) } - /// Creates a `Vec<T>` directly from the raw components of another vector. + /// Creates a `Vec<T>` directly from a pointer, a capacity, and a length. /// /// # Safety /// /// This is highly unsafe, due to the number of invariants that aren't /// checked: /// - /// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>` - /// (at least, it's highly likely to be incorrect if it wasn't). /// * `T` needs to have the same alignment as what `ptr` was allocated with. /// (`T` having a less strict alignment is not sufficient, the alignment really /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be @@ -500,6 +498,14 @@ impl<T> Vec<T> { /// to be the same size as the pointer was allocated with. (Because similar to /// alignment, [`dealloc`] must be called with the same layout `size`.) /// * `length` needs to be less than or equal to `capacity`. + /// * The first `length` values must be properly initialized values of type `T`. + /// * `capacity` needs to be the capacity that the pointer was allocated with. + /// * The allocated size in bytes must be no larger than `isize::MAX`. + /// See the safety documentation of [`pointer::offset`]. + /// + /// These requirements are always upheld by any `ptr` that has been allocated + /// via `Vec<T>`. Other allocation sources are allowed if the invariants are + /// upheld. /// /// Violating these may cause problems like corrupting the allocator's /// internal data structures. For example it is normally **not** safe @@ -551,6 +557,32 @@ impl<T> Vec<T> { /// assert_eq!(rebuilt, [4, 5, 6]); /// } /// ``` + /// + /// Using memory that was allocated elsewhere: + /// + /// ```rust + /// #![feature(allocator_api)] + /// + /// use std::alloc::{AllocError, Allocator, Global, Layout}; + /// + /// fn main() { + /// let layout = Layout::array::<u32>(16).expect("overflow cannot happen"); + /// + /// let vec = unsafe { + /// let mem = match Global.allocate(layout) { + /// Ok(mem) => mem.cast::<u32>().as_ptr(), + /// Err(AllocError) => return, + /// }; + /// + /// mem.write(1_000_000); + /// + /// Vec::from_raw_parts_in(mem, 1, 16, Global) + /// }; + /// + /// assert_eq!(vec, &[1_000_000]); + /// assert_eq!(vec.capacity(), 16); + /// } + /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self { @@ -641,21 +673,30 @@ impl<T, A: Allocator> Vec<T, A> { Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 } } - /// Creates a `Vec<T, A>` directly from the raw components of another vector. + /// Creates a `Vec<T, A>` directly from a pointer, a capacity, a length, + /// and an allocator. /// /// # Safety /// /// This is highly unsafe, due to the number of invariants that aren't /// checked: /// - /// * `ptr` needs to have been previously allocated via [`String`]/`Vec<T>` - /// (at least, it's highly likely to be incorrect if it wasn't). - /// * `T` needs to have the same size and alignment as what `ptr` was allocated with. + /// * `T` needs to have the same alignment as what `ptr` was allocated with. /// (`T` having a less strict alignment is not sufficient, the alignment really /// needs to be equal to satisfy the [`dealloc`] requirement that memory must be /// allocated and deallocated with the same layout.) + /// * The size of `T` times the `capacity` (ie. the allocated size in bytes) needs + /// to be the same size as the pointer was allocated with. (Because similar to + /// alignment, [`dealloc`] must be called with the same layout `size`.) /// * `length` needs to be less than or equal to `capacity`. - /// * `capacity` needs to be the capacity that the pointer was allocated with. + /// * The first `length` values must be properly initialized values of type `T`. + /// * `capacity` needs to [*fit*] the layout size that the pointer was allocated with. + /// * The allocated size in bytes must be no larger than `isize::MAX`. + /// See the safety documentation of [`pointer::offset`]. + /// + /// These requirements are always upheld by any `ptr` that has been allocated + /// via `Vec<T, A>`. Other allocation sources are allowed if the invariants are + /// upheld. /// /// Violating these may cause problems like corrupting the allocator's /// internal data structures. For example it is **not** safe @@ -673,6 +714,7 @@ impl<T, A: Allocator> Vec<T, A> { /// /// [`String`]: crate::string::String /// [`dealloc`]: crate::alloc::GlobalAlloc::dealloc + /// [*fit*]: crate::alloc::Allocator#memory-fitting /// /// # Examples /// @@ -711,6 +753,29 @@ impl<T, A: Allocator> Vec<T, A> { /// assert_eq!(rebuilt, [4, 5, 6]); /// } /// ``` + /// + /// Using memory that was allocated elsewhere: + /// + /// ```rust + /// use std::alloc::{alloc, Layout}; + /// + /// fn main() { + /// let layout = Layout::array::<u32>(16).expect("overflow cannot happen"); + /// let vec = unsafe { + /// let mem = alloc(layout).cast::<u32>(); + /// if mem.is_null() { + /// return; + /// } + /// + /// mem.write(1_000_000); + /// + /// Vec::from_raw_parts(mem, 1, 16) + /// }; + /// + /// assert_eq!(vec, &[1_000_000]); + /// assert_eq!(vec.capacity(), 16); + /// } + /// ``` #[inline] #[unstable(feature = "allocator_api", issue = "32838")] pub unsafe fn from_raw_parts_in(ptr: *mut T, length: usize, capacity: usize, alloc: A) -> Self { diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index f140fc4143f..e0271187044 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1191,48 +1191,53 @@ fn test_from_iter_specialization_panic_during_iteration_drops() { } #[test] -fn test_from_iter_specialization_panic_during_drop_leaks() { - static mut DROP_COUNTER: usize = 0; +fn test_from_iter_specialization_panic_during_drop_doesnt_leak() { + static mut DROP_COUNTER_OLD: [usize; 5] = [0; 5]; + static mut DROP_COUNTER_NEW: [usize; 2] = [0; 2]; #[derive(Debug)] - enum Droppable { - DroppedTwice(Box<i32>), - PanicOnDrop, - } + struct Old(usize); - impl Drop for Droppable { + impl Drop for Old { fn drop(&mut self) { - match self { - Droppable::DroppedTwice(_) => { - unsafe { - DROP_COUNTER += 1; - } - println!("Dropping!") - } - Droppable::PanicOnDrop => { - if !std::thread::panicking() { - panic!(); - } - } + unsafe { + DROP_COUNTER_OLD[self.0] += 1; + } + + if self.0 == 3 { + panic!(); } + + println!("Dropped Old: {}", self.0); } } - let mut to_free: *mut Droppable = core::ptr::null_mut(); - let mut cap = 0; + #[derive(Debug)] + struct New(usize); + + impl Drop for New { + fn drop(&mut self) { + unsafe { + DROP_COUNTER_NEW[self.0] += 1; + } + + println!("Dropped New: {}", self.0); + } + } let _ = std::panic::catch_unwind(AssertUnwindSafe(|| { - let mut v = vec![Droppable::DroppedTwice(Box::new(123)), Droppable::PanicOnDrop]; - to_free = v.as_mut_ptr(); - cap = v.capacity(); - let _ = v.into_iter().take(0).collect::<Vec<_>>(); + let v = vec![Old(0), Old(1), Old(2), Old(3), Old(4)]; + let _ = v.into_iter().map(|x| New(x.0)).take(2).collect::<Vec<_>>(); })); - assert_eq!(unsafe { DROP_COUNTER }, 1); - // clean up the leak to keep miri happy - unsafe { - drop(Vec::from_raw_parts(to_free, 0, cap)); - } + assert_eq!(unsafe { DROP_COUNTER_OLD[0] }, 1); + assert_eq!(unsafe { DROP_COUNTER_OLD[1] }, 1); + assert_eq!(unsafe { DROP_COUNTER_OLD[2] }, 1); + assert_eq!(unsafe { DROP_COUNTER_OLD[3] }, 1); + assert_eq!(unsafe { DROP_COUNTER_OLD[4] }, 1); + + assert_eq!(unsafe { DROP_COUNTER_NEW[0] }, 1); + assert_eq!(unsafe { DROP_COUNTER_NEW[1] }, 1); } // regression test for issue #85322. Peekable previously implemented InPlaceIterable, diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 288cab1ef39..4474b673a95 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -405,6 +405,7 @@ impl<T> Cell<T> { /// assert_eq!(cell.replace(10), 5); /// assert_eq!(cell.get(), 10); /// ``` + #[inline] #[stable(feature = "move_cell", since = "1.17.0")] pub fn replace(&self, val: T) -> T { // SAFETY: This can cause data races if called from a separate thread, diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs index b7a63b7c675..224bc9effe6 100644 --- a/library/core/src/char/methods.rs +++ b/library/core/src/char/methods.rs @@ -1444,6 +1444,38 @@ impl char { matches!(*self, '0'..='9') } + /// Checks if the value is an ASCII octal digit: + /// U+0030 '0' ..= U+0037 '7'. + /// + /// # Examples + /// + /// ``` + /// #![feature(is_ascii_octdigit)] + /// + /// let uppercase_a = 'A'; + /// let a = 'a'; + /// let zero = '0'; + /// let seven = '7'; + /// let nine = '9'; + /// let percent = '%'; + /// let lf = '\n'; + /// + /// assert!(!uppercase_a.is_ascii_octdigit()); + /// assert!(!a.is_ascii_octdigit()); + /// assert!(zero.is_ascii_octdigit()); + /// assert!(seven.is_ascii_octdigit()); + /// assert!(!nine.is_ascii_octdigit()); + /// assert!(!percent.is_ascii_octdigit()); + /// assert!(!lf.is_ascii_octdigit()); + /// ``` + #[must_use] + #[unstable(feature = "is_ascii_octdigit", issue = "101288")] + #[rustc_const_unstable(feature = "is_ascii_octdigit", issue = "101288")] + #[inline] + pub const fn is_ascii_octdigit(&self) -> bool { + matches!(*self, '0'..='7') + } + /// Checks if the value is an ASCII hexadecimal digit: /// /// - U+0030 '0' ..= U+0039 '9', or diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs index d2e80e8e7e5..9e9c02093be 100644 --- a/library/core/src/const_closure.rs +++ b/library/core/src/const_closure.rs @@ -16,15 +16,18 @@ use crate::marker::Destruct; /// assert!(7 == cl(2)); /// assert!(8 == cl(1)); /// ``` -pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> { - data: &'a mut CapturedData, - func: Function, +pub(crate) struct ConstFnMutClosure<CapturedData, Function> { + /// The Data captured by the Closure. + /// Must be either a (mutable) reference or a tuple of (mutable) references. + pub data: CapturedData, + /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn + pub func: Function, } - -impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Function> { +impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<&'a mut CapturedData, Function> { /// Function for creating a new closure. /// /// `data` is the a mutable borrow of data that is captured from the environment. + /// If you want Data to be a tuple of mutable Borrows, the struct must be constructed manually. /// /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure /// and return the return value of the closure. @@ -39,25 +42,36 @@ impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Fun } } -impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const - FnOnce<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function> -where - Function: - ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct, -{ - type Output = ClosureReturnValue; +macro_rules! impl_fn_mut_tuple { + ($($var:ident)*) => { + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const + FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct, + { + type Output = ClosureReturnValue; - extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { - self.call_mut(args) - } -} - -impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const - FnMut<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function> -where - Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue, -{ - extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { - (self.func)(self.data, args) - } + extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output { + self.call_mut(args) + } + } + #[allow(unused_parens)] + impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const + FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function> + where + Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue, + { + extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output { + #[allow(non_snake_case)] + let ($($var),*) = &mut self.data; + (self.func)(($($var),*), args) + } + } + }; } +impl_fn_mut_tuple!(A); +impl_fn_mut_tuple!(A B); +impl_fn_mut_tuple!(A B C); +impl_fn_mut_tuple!(A B C D); +impl_fn_mut_tuple!(A B C D E); diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index c42adda8da5..33493964bad 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -25,6 +25,7 @@ //! # Generic Implementations //! //! - [`AsRef`] and [`AsMut`] auto-dereference if the inner type is a reference +//! (but not generally for all [dereferenceable types][core::ops::Deref]) //! - [`From`]`<U> for T` implies [`Into`]`<T> for U` //! - [`TryFrom`]`<U> for T` implies [`TryInto`]`<T> for U` //! - [`From`] and [`Into`] are reflexive, which means that all types can @@ -109,10 +110,12 @@ pub const fn identity<T>(x: T) -> T { /// If you need to do a costly conversion it is better to implement [`From`] with type /// `&T` or write a custom function. /// +/// # Relation to `Borrow` +/// /// `AsRef` has the same signature as [`Borrow`], but [`Borrow`] is different in a few aspects: /// /// - Unlike `AsRef`, [`Borrow`] has a blanket impl for any `T`, and can be used to accept either -/// a reference or a value. +/// a reference or a value. (See also note on `AsRef`'s reflexibility below.) /// - [`Borrow`] also requires that [`Hash`], [`Eq`] and [`Ord`] for a borrowed value are /// equivalent to those of the owned value. For this reason, if you want to /// borrow only a single field of a struct you can implement `AsRef`, but not [`Borrow`]. @@ -122,9 +125,66 @@ pub const fn identity<T>(x: T) -> T { /// /// # Generic Implementations /// -/// - `AsRef` auto-dereferences if the inner type is a reference or a mutable -/// reference (e.g.: `foo.as_ref()` will work the same if `foo` has type -/// `&mut Foo` or `&&mut Foo`) +/// `AsRef` auto-dereferences if the inner type is a reference or a mutable reference +/// (e.g.: `foo.as_ref()` will work the same if `foo` has type `&mut Foo` or `&&mut Foo`). +/// +/// Note that due to historic reasons, the above currently does not hold generally for all +/// [dereferenceable types], e.g. `foo.as_ref()` will *not* work the same as +/// `Box::new(foo).as_ref()`. Instead, many smart pointers provide an `as_ref` implementation which +/// simply returns a reference to the [pointed-to value] (but do not perform a cheap +/// reference-to-reference conversion for that value). However, [`AsRef::as_ref`] should not be +/// used for the sole purpose of dereferencing; instead ['`Deref` coercion'] can be used: +/// +/// [dereferenceable types]: core::ops::Deref +/// [pointed-to value]: core::ops::Deref::Target +/// ['`Deref` coercion']: core::ops::Deref#more-on-deref-coercion +/// +/// ``` +/// let x = Box::new(5i32); +/// // Avoid this: +/// // let y: &i32 = x.as_ref(); +/// // Better just write: +/// let y: &i32 = &x; +/// ``` +/// +/// Types which implement [`Deref`] should consider implementing `AsRef<T>` as follows: +/// +/// [`Deref`]: core::ops::Deref +/// +/// ``` +/// # use core::ops::Deref; +/// # struct SomeType; +/// # impl Deref for SomeType { +/// # type Target = [u8]; +/// # fn deref(&self) -> &[u8] { +/// # &[] +/// # } +/// # } +/// impl<T> AsRef<T> for SomeType +/// where +/// T: ?Sized, +/// <SomeType as Deref>::Target: AsRef<T>, +/// { +/// fn as_ref(&self) -> &T { +/// self.deref().as_ref() +/// } +/// } +/// ``` +/// +/// # Reflexivity +/// +/// Ideally, `AsRef` would be reflexive, i.e. there would be an `impl<T: ?Sized> AsRef<T> for T` +/// with [`as_ref`] simply returning its argument unchanged. +/// Such a blanket implementation is currently *not* provided due to technical restrictions of +/// Rust's type system (it would be overlapping with another existing blanket implementation for +/// `&T where T: AsRef<U>` which allows `AsRef` to auto-dereference, see "Generic Implementations" +/// above). +/// +/// [`as_ref`]: AsRef::as_ref +/// +/// A trivial implementation of `AsRef<T> for T` must be added explicitly for a particular type `T` +/// where needed or desired. Note, however, that not all types from `std` contain such an +/// implementation, and those cannot be added by external code due to orphan rules. /// /// # Examples /// @@ -172,29 +232,138 @@ pub trait AsRef<T: ?Sized> { /// /// # Generic Implementations /// -/// - `AsMut` auto-dereferences if the inner type is a mutable reference -/// (e.g.: `foo.as_mut()` will work the same if `foo` has type `&mut Foo` -/// or `&mut &mut Foo`) +/// `AsMut` auto-dereferences if the inner type is a mutable reference +/// (e.g.: `foo.as_mut()` will work the same if `foo` has type `&mut Foo` or `&mut &mut Foo`). +/// +/// Note that due to historic reasons, the above currently does not hold generally for all +/// [mutably dereferenceable types], e.g. `foo.as_mut()` will *not* work the same as +/// `Box::new(foo).as_mut()`. Instead, many smart pointers provide an `as_mut` implementation which +/// simply returns a reference to the [pointed-to value] (but do not perform a cheap +/// reference-to-reference conversion for that value). However, [`AsMut::as_mut`] should not be +/// used for the sole purpose of mutable dereferencing; instead ['`Deref` coercion'] can be used: +/// +/// [mutably dereferenceable types]: core::ops::DerefMut +/// [pointed-to value]: core::ops::Deref::Target +/// ['`Deref` coercion']: core::ops::DerefMut#more-on-deref-coercion +/// +/// ``` +/// let mut x = Box::new(5i32); +/// // Avoid this: +/// // let y: &mut i32 = x.as_mut(); +/// // Better just write: +/// let y: &mut i32 = &mut x; +/// ``` +/// +/// Types which implement [`DerefMut`] should consider to add an implementation of `AsMut<T>` as +/// follows: +/// +/// [`DerefMut`]: core::ops::DerefMut +/// +/// ``` +/// # use core::ops::{Deref, DerefMut}; +/// # struct SomeType; +/// # impl Deref for SomeType { +/// # type Target = [u8]; +/// # fn deref(&self) -> &[u8] { +/// # &[] +/// # } +/// # } +/// # impl DerefMut for SomeType { +/// # fn deref_mut(&mut self) -> &mut [u8] { +/// # &mut [] +/// # } +/// # } +/// impl<T> AsMut<T> for SomeType +/// where +/// <SomeType as Deref>::Target: AsMut<T>, +/// { +/// fn as_mut(&mut self) -> &mut T { +/// self.deref_mut().as_mut() +/// } +/// } +/// ``` +/// +/// # Reflexivity +/// +/// Ideally, `AsMut` would be reflexive, i.e. there would be an `impl<T: ?Sized> AsMut<T> for T` +/// with [`as_mut`] simply returning its argument unchanged. +/// Such a blanket implementation is currently *not* provided due to technical restrictions of +/// Rust's type system (it would be overlapping with another existing blanket implementation for +/// `&mut T where T: AsMut<U>` which allows `AsMut` to auto-dereference, see "Generic +/// Implementations" above). +/// +/// [`as_mut`]: AsMut::as_mut +/// +/// A trivial implementation of `AsMut<T> for T` must be added explicitly for a particular type `T` +/// where needed or desired. Note, however, that not all types from `std` contain such an +/// implementation, and those cannot be added by external code due to orphan rules. /// /// # Examples /// -/// Using `AsMut` as trait bound for a generic function we can accept all mutable references -/// that can be converted to type `&mut T`. Because [`Box<T>`] implements `AsMut<T>` we can -/// write a function `add_one` that takes all arguments that can be converted to `&mut u64`. -/// Because [`Box<T>`] implements `AsMut<T>`, `add_one` accepts arguments of type -/// `&mut Box<u64>` as well: +/// Using `AsMut` as trait bound for a generic function, we can accept all mutable references that +/// can be converted to type `&mut T`. Unlike [dereference], which has a single [target type], +/// there can be multiple implementations of `AsMut` for a type. In particular, `Vec<T>` implements +/// both `AsMut<Vec<T>>` and `AsMut<[T]>`. +/// +/// In the following, the example functions `caesar` and `null_terminate` provide a generic +/// interface which work with any type that can be converted by cheap mutable-to-mutable conversion +/// into a byte slice (`[u8]`) or byte vector (`Vec<u8>`), respectively. +/// +/// [dereference]: core::ops::DerefMut +/// [target type]: core::ops::Deref::Target /// /// ``` -/// fn add_one<T: AsMut<u64>>(num: &mut T) { -/// *num.as_mut() += 1; +/// struct Document { +/// info: String, +/// content: Vec<u8>, /// } /// -/// let mut boxed_num = Box::new(0); -/// add_one(&mut boxed_num); -/// assert_eq!(*boxed_num, 1); +/// impl<T: ?Sized> AsMut<T> for Document +/// where +/// Vec<u8>: AsMut<T>, +/// { +/// fn as_mut(&mut self) -> &mut T { +/// self.content.as_mut() +/// } +/// } +/// +/// fn caesar<T: AsMut<[u8]>>(data: &mut T, key: u8) { +/// for byte in data.as_mut() { +/// *byte = byte.wrapping_add(key); +/// } +/// } +/// +/// fn null_terminate<T: AsMut<Vec<u8>>>(data: &mut T) { +/// // Using a non-generic inner function, which contains most of the +/// // functionality, helps to minimize monomorphization overhead. +/// fn doit(data: &mut Vec<u8>) { +/// let len = data.len(); +/// if len == 0 || data[len-1] != 0 { +/// data.push(0); +/// } +/// } +/// doit(data.as_mut()); +/// } +/// +/// fn main() { +/// let mut v: Vec<u8> = vec![1, 2, 3]; +/// caesar(&mut v, 5); +/// assert_eq!(v, [6, 7, 8]); +/// null_terminate(&mut v); +/// assert_eq!(v, [6, 7, 8, 0]); +/// let mut doc = Document { +/// info: String::from("Example"), +/// content: vec![17, 19, 8], +/// }; +/// caesar(&mut doc, 1); +/// assert_eq!(doc.content, [18, 20, 9]); +/// null_terminate(&mut doc); +/// assert_eq!(doc.content, [18, 20, 9, 0]); +/// } /// ``` /// -/// [`Box<T>`]: ../../std/boxed/struct.Box.html +/// Note, however, that APIs don't need to be generic. In many cases taking a `&mut [u8]` or +/// `&mut Vec<u8>`, for example, is the better choice (callers need to pass the correct type then). #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "AsMut")] #[const_trait] @@ -376,7 +545,7 @@ pub trait From<T>: Sized { #[lang = "from"] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] - fn from(_: T) -> Self; + fn from(value: T) -> Self; } /// An attempted conversion that consumes `self`, which may or may not be @@ -440,7 +609,7 @@ pub trait TryInto<T>: Sized { /// /// fn try_from(value: i32) -> Result<Self, Self::Error> { /// if value <= 0 { -/// Err("GreaterThanZero only accepts value superior than zero!") +/// Err("GreaterThanZero only accepts values greater than zero!") /// } else { /// Ok(GreaterThanZero(value)) /// } diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 372439f14ec..c8d28550567 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2610,7 +2610,7 @@ impl Debug for () { #[stable(feature = "rust1", since = "1.0.0")] impl<T: ?Sized> Debug for PhantomData<T> { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - f.debug_struct("PhantomData").finish() + write!(f, "PhantomData<{}>", crate::any::type_name::<T>()) } } diff --git a/library/core/src/future/ready.rs b/library/core/src/future/ready.rs index 48f20f90a32..a07b63fb62b 100644 --- a/library/core/src/future/ready.rs +++ b/library/core/src/future/ready.rs @@ -24,6 +24,30 @@ impl<T> Future for Ready<T> { } } +impl<T> Ready<T> { + /// Consumes the `Ready`, returning the wrapped value. + /// + /// # Panics + /// + /// Will panic if this [`Ready`] was already polled to completion. + /// + /// # Examples + /// + /// ``` + /// #![feature(ready_into_inner)] + /// use std::future; + /// + /// let a = future::ready(1); + /// assert_eq!(a.into_inner(), 1); + /// ``` + #[unstable(feature = "ready_into_inner", issue = "101196")] + #[must_use] + #[inline] + pub fn into_inner(self) -> T { + self.0.expect("Called `into_inner()` on `Ready` after completion") + } +} + /// Creates a future that is immediately ready with a value. /// /// Futures created through this function are functionally similar to those diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 12b43da5a42..15ee14398b6 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -788,6 +788,7 @@ extern "rust-intrinsic" { /// uninitialized at that point in the control flow. /// /// This intrinsic should not be used outside of the compiler. + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn rustc_peek<T>(_: T) -> T; /// Aborts the execution of the process. @@ -805,6 +806,7 @@ extern "rust-intrinsic" { /// On Unix, the /// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or /// `SIGBUS`. The precise behaviour is not guaranteed and not stable. + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn abort() -> !; /// Informs the optimizer that this point in the code is not reachable, @@ -843,6 +845,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_likely", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn likely(b: bool) -> bool; /// Hints to the compiler that branch condition is likely to be false. @@ -857,6 +860,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_likely", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn unlikely(b: bool) -> bool; /// Executes a breakpoint trap, for inspection by a debugger. @@ -876,6 +880,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::mem::size_of`]. #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn size_of<T>() -> usize; /// The minimum alignment of a type. @@ -887,6 +892,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::mem::align_of`]. #[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn min_align_of<T>() -> usize; /// The preferred alignment of a type. /// @@ -915,6 +921,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::any::type_name`]. #[rustc_const_unstable(feature = "const_type_name", issue = "63084")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn type_name<T: ?Sized>() -> &'static str; /// Gets an identifier which is globally unique to the specified type. This @@ -928,6 +935,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::any::TypeId::of`]. #[rustc_const_unstable(feature = "const_type_id", issue = "77125")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn type_id<T: ?Sized + 'static>() -> u64; /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited: @@ -935,6 +943,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_stable(feature = "const_assert_type", since = "1.59.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn assert_inhabited<T>(); /// A guard for unsafe functions that cannot ever be executed if `T` does not permit @@ -942,6 +951,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_assert_type2", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn assert_zero_valid<T>(); /// A guard for unsafe functions that cannot ever be executed if `T` has invalid @@ -949,6 +959,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_assert_type2", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn assert_uninit_valid<T>(); /// Gets a reference to a static `Location` indicating where it was called. @@ -960,6 +971,7 @@ extern "rust-intrinsic" { /// /// Consider using [`core::panic::Location::caller`] instead. #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn caller_location() -> &'static crate::panic::Location<'static>; /// Moves a value out of scope without running drop glue. @@ -972,6 +984,7 @@ extern "rust-intrinsic" { /// Therefore, implementations must not require the user to uphold /// any safety invariants. #[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn forget<T: ?Sized>(_: T); /// Reinterprets the bits of a value of one type as another type. @@ -1251,6 +1264,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop). #[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn needs_drop<T: ?Sized>() -> bool; /// Calculates the offset from a pointer. @@ -1295,6 +1309,7 @@ extern "rust-intrinsic" { /// any safety invariants. /// /// Consider using [`pointer::mask`] instead. + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T; /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with @@ -1486,6 +1501,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f32::min`] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn minnumf32(x: f32, y: f32) -> f32; /// Returns the minimum of two `f64` values. /// @@ -1496,6 +1512,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f64::min`] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn minnumf64(x: f64, y: f64) -> f64; /// Returns the maximum of two `f32` values. /// @@ -1506,6 +1523,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f32::max`] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn maxnumf32(x: f32, y: f32) -> f32; /// Returns the maximum of two `f64` values. /// @@ -1516,6 +1534,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f64::max`] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn maxnumf64(x: f64, y: f64) -> f64; /// Copies the sign from `y` to `x` for `f32` values. @@ -1636,6 +1655,7 @@ extern "rust-intrinsic" { /// primitives via the `count_ones` method. For example, /// [`u32::count_ones`] #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn ctpop<T: Copy>(x: T) -> T; /// Returns the number of leading unset bits (zeroes) in an integer type `T`. @@ -1673,6 +1693,7 @@ extern "rust-intrinsic" { /// assert_eq!(num_leading, 16); /// ``` #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn ctlz<T: Copy>(x: T) -> T; /// Like `ctlz`, but extra-unsafe as it returns `undef` when @@ -1729,6 +1750,7 @@ extern "rust-intrinsic" { /// assert_eq!(num_trailing, 16); /// ``` #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn cttz<T: Copy>(x: T) -> T; /// Like `cttz`, but extra-unsafe as it returns `undef` when @@ -1761,6 +1783,7 @@ extern "rust-intrinsic" { /// primitives via the `swap_bytes` method. For example, /// [`u32::swap_bytes`] #[rustc_const_stable(feature = "const_bswap", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn bswap<T: Copy>(x: T) -> T; /// Reverses the bits in an integer type `T`. @@ -1774,6 +1797,7 @@ extern "rust-intrinsic" { /// primitives via the `reverse_bits` method. For example, /// [`u32::reverse_bits`] #[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn bitreverse<T: Copy>(x: T) -> T; /// Performs checked integer addition. @@ -1787,6 +1811,7 @@ extern "rust-intrinsic" { /// primitives via the `overflowing_add` method. For example, /// [`u32::overflowing_add`] #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool); /// Performs checked integer subtraction @@ -1800,6 +1825,7 @@ extern "rust-intrinsic" { /// primitives via the `overflowing_sub` method. For example, /// [`u32::overflowing_sub`] #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn sub_with_overflow<T: Copy>(x: T, y: T) -> (T, bool); /// Performs checked integer multiplication @@ -1813,6 +1839,7 @@ extern "rust-intrinsic" { /// primitives via the `overflowing_mul` method. For example, /// [`u32::overflowing_mul`] #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool); /// Performs an exact division, resulting in undefined behavior where @@ -1887,6 +1914,7 @@ extern "rust-intrinsic" { /// primitives via the `rotate_left` method. For example, /// [`u32::rotate_left`] #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn rotate_left<T: Copy>(x: T, y: T) -> T; /// Performs rotate right. @@ -1900,6 +1928,7 @@ extern "rust-intrinsic" { /// primitives via the `rotate_right` method. For example, /// [`u32::rotate_right`] #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn rotate_right<T: Copy>(x: T, y: T) -> T; /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits. @@ -1913,6 +1942,7 @@ extern "rust-intrinsic" { /// primitives via the `wrapping_add` method. For example, /// [`u32::wrapping_add`] #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn wrapping_add<T: Copy>(a: T, b: T) -> T; /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits. /// @@ -1925,6 +1955,7 @@ extern "rust-intrinsic" { /// primitives via the `wrapping_sub` method. For example, /// [`u32::wrapping_sub`] #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn wrapping_sub<T: Copy>(a: T, b: T) -> T; /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits. /// @@ -1937,6 +1968,7 @@ extern "rust-intrinsic" { /// primitives via the `wrapping_mul` method. For example, /// [`u32::wrapping_mul`] #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn wrapping_mul<T: Copy>(a: T, b: T) -> T; /// Computes `a + b`, saturating at numeric bounds. @@ -1950,6 +1982,7 @@ extern "rust-intrinsic" { /// primitives via the `saturating_add` method. For example, /// [`u32::saturating_add`] #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn saturating_add<T: Copy>(a: T, b: T) -> T; /// Computes `a - b`, saturating at numeric bounds. /// @@ -1962,6 +1995,7 @@ extern "rust-intrinsic" { /// primitives via the `saturating_sub` method. For example, /// [`u32::saturating_sub`] #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn saturating_sub<T: Copy>(a: T, b: T) -> T; /// Returns the value of the discriminant for the variant in 'v'; @@ -1974,6 +2008,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::mem::discriminant`]. #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant; /// Returns the number of variants of the type `T` cast to a `usize`; @@ -1986,6 +2021,7 @@ extern "rust-intrinsic" { /// /// The to-be-stabilized version of this intrinsic is [`mem::variant_count`]. #[rustc_const_unstable(feature = "variant_count", issue = "73662")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn variant_count<T>() -> usize; /// Rust's "try catch" construct which invokes the function pointer `try_fn` @@ -2019,6 +2055,7 @@ extern "rust-intrinsic" { /// Therefore, implementations must not require the user to uphold /// any safety invariants. #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8; /// Allocates a block of memory at compile time. @@ -2069,6 +2106,7 @@ extern "rust-intrinsic" { /// /// [`std::hint::black_box`]: crate::hint::black_box #[rustc_const_unstable(feature = "const_black_box", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn black_box<T>(dummy: T) -> T; /// `ptr` must point to a vtable. diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index e598a54b4f1..e099700e3e7 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -264,7 +264,7 @@ pub trait IntoIterator { #[rustc_const_unstable(feature = "const_intoiterator_identity", issue = "90603")] #[stable(feature = "rust1", since = "1.0.0")] -impl<I: ~const Iterator> const IntoIterator for I { +impl<I: Iterator> const IntoIterator for I { type Item = I::Item; type IntoIter = I; diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index e26920b25cc..f6e6732b0e3 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2431,22 +2431,13 @@ pub trait Iterator { /// /// # Example /// - /// Find the maximum value: - /// /// ``` - /// fn find_max<I>(iter: I) -> Option<I::Item> - /// where I: Iterator, - /// I::Item: Ord, - /// { - /// iter.reduce(|accum, item| { - /// if accum >= item { accum } else { item } - /// }) - /// } - /// let a = [10, 20, 5, -23, 0]; - /// let b: [u32; 0] = []; + /// let reduced: i32 = (1..10).reduce(|acc, e| acc + e).unwrap(); + /// assert_eq!(reduced, 45); /// - /// assert_eq!(find_max(a.iter()), Some(&20)); - /// assert_eq!(find_max(b.iter()), None); + /// // Which is equivalent to doing it with `fold`: + /// let folded: i32 = (1..10).fold(0, |acc, e| acc + e); + /// assert_eq!(reduced, folded); /// ``` #[inline] #[stable(feature = "iterator_fold_self", since = "1.51.0")] diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c3df0d4f9b9..ca02ae90fde 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -164,6 +164,7 @@ #![feature(const_slice_index)] #![feature(const_is_char_boundary)] #![feature(const_cstr_methods)] +#![feature(is_ascii_octdigit)] // // Language features: #![feature(abi_unadjusted)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 5cb5e4458cc..d5ed52124e2 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -799,6 +799,7 @@ impl<T: ?Sized> Unpin for *mut T {} #[unstable(feature = "const_trait_impl", issue = "67792")] #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] +#[const_trait] pub trait Destruct {} /// A marker for tuple types. diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index c0be235c120..311c5fa5b68 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -622,6 +622,38 @@ impl u8 { matches!(*self, b'0'..=b'9') } + /// Checks if the value is an ASCII octal digit: + /// U+0030 '0' ..= U+0037 '7'. + /// + /// # Examples + /// + /// ``` + /// #![feature(is_ascii_octdigit)] + /// + /// let uppercase_a = b'A'; + /// let a = b'a'; + /// let zero = b'0'; + /// let seven = b'7'; + /// let nine = b'9'; + /// let percent = b'%'; + /// let lf = b'\n'; + /// + /// assert!(!uppercase_a.is_ascii_octdigit()); + /// assert!(!a.is_ascii_octdigit()); + /// assert!(zero.is_ascii_octdigit()); + /// assert!(seven.is_ascii_octdigit()); + /// assert!(!nine.is_ascii_octdigit()); + /// assert!(!percent.is_ascii_octdigit()); + /// assert!(!lf.is_ascii_octdigit()); + /// ``` + #[must_use] + #[unstable(feature = "is_ascii_octdigit", issue = "101288")] + #[rustc_const_unstable(feature = "is_ascii_octdigit", issue = "101288")] + #[inline] + pub const fn is_ascii_octdigit(&self) -> bool { + matches!(*self, b'0'..=b'7') + } + /// Checks if the value is an ASCII hexadecimal digit: /// /// - U+0030 '0' ..= U+0039 '9', or @@ -976,8 +1008,8 @@ impl usize { /// assert_eq!(num.classify(), FpCategory::Normal); /// assert_eq!(inf.classify(), FpCategory::Infinite); /// assert_eq!(zero.classify(), FpCategory::Zero); -/// assert_eq!(nan.classify(), FpCategory::Nan); /// assert_eq!(sub.classify(), FpCategory::Subnormal); +/// assert_eq!(nan.classify(), FpCategory::Nan); /// ``` #[derive(Copy, Clone, PartialEq, Eq, Debug)] #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 532a09736a7..da402d66502 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -721,6 +721,160 @@ macro_rules! nonzero_signed_operations { // SAFETY: absolute value of nonzero cannot yield zero values. unsafe { $Uty::new_unchecked(self.get().unsigned_abs()) } } + + /// Returns `true` if `self` is negative and `false` if the + /// number is positive. + /// + /// # Example + /// + /// ``` + /// #![feature(nonzero_negation_ops)] + /// + #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] + /// + /// assert!(neg_five.is_negative()); + /// assert!(!pos_five.is_negative()); + /// # Some(()) + /// # } + /// ``` + #[must_use] + #[inline] + #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + pub const fn is_negative(self) -> bool { + self.get().is_negative() + } + + /// Checked negation. Computes `-self`, returning `None` if `self == i32::MIN`. + /// + /// # Example + /// + /// ``` + /// #![feature(nonzero_negation_ops)] + /// + #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::new(", + stringify!($Int), "::MIN)?;")] + /// + /// assert_eq!(pos_five.checked_neg(), Some(neg_five)); + /// assert_eq!(min.checked_neg(), None); + /// # Some(()) + /// # } + /// ``` + #[inline] + #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + pub const fn checked_neg(self) -> Option<$Ty> { + if let Some(result) = self.get().checked_neg() { + // SAFETY: negation of nonzero cannot yield zero values. + return Some(unsafe { $Ty::new_unchecked(result) }); + } + None + } + + /// Negates self, overflowing if this is equal to the minimum value. + /// + #[doc = concat!("See [`", stringify!($Int), "::overflowing_neg`]")] + /// for documentation on overflow behaviour. + /// + /// # Example + /// + /// ``` + /// #![feature(nonzero_negation_ops)] + /// + #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::new(", + stringify!($Int), "::MIN)?;")] + /// + /// assert_eq!(pos_five.overflowing_neg(), (neg_five, false)); + /// assert_eq!(min.overflowing_neg(), (min, true)); + /// # Some(()) + /// # } + /// ``` + #[inline] + #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + pub const fn overflowing_neg(self) -> ($Ty, bool) { + let (result, overflow) = self.get().overflowing_neg(); + // SAFETY: negation of nonzero cannot yield zero values. + ((unsafe { $Ty::new_unchecked(result) }), overflow) + } + + /// Saturating negation. Computes `-self`, returning `MAX` if + /// `self == i32::MIN` instead of overflowing. + /// + /// # Example + /// + /// ``` + /// #![feature(nonzero_negation_ops)] + /// + #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::new(", + stringify!($Int), "::MIN)?;")] + #[doc = concat!("let min_plus_one = ", stringify!($Ty), "::new(", + stringify!($Int), "::MIN + 1)?;")] + #[doc = concat!("let max = ", stringify!($Ty), "::new(", + stringify!($Int), "::MAX)?;")] + /// + /// assert_eq!(pos_five.saturating_neg(), neg_five); + /// assert_eq!(min.saturating_neg(), max); + /// assert_eq!(max.saturating_neg(), min_plus_one); + /// # Some(()) + /// # } + /// ``` + #[inline] + #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + pub const fn saturating_neg(self) -> $Ty { + if let Some(result) = self.checked_neg() { + return result; + } + $Ty::MAX + } + + /// Wrapping (modular) negation. Computes `-self`, wrapping around at the boundary + /// of the type. + /// + #[doc = concat!("See [`", stringify!($Int), "::wrapping_neg`]")] + /// for documentation on overflow behaviour. + /// + /// # Example + /// + /// ``` + /// #![feature(nonzero_negation_ops)] + /// + #[doc = concat!("# use std::num::", stringify!($Ty), ";")] + /// # fn main() { test().unwrap(); } + /// # fn test() -> Option<()> { + #[doc = concat!("let pos_five = ", stringify!($Ty), "::new(5)?;")] + #[doc = concat!("let neg_five = ", stringify!($Ty), "::new(-5)?;")] + #[doc = concat!("let min = ", stringify!($Ty), "::new(", + stringify!($Int), "::MIN)?;")] + /// + /// assert_eq!(pos_five.wrapping_neg(), neg_five); + /// assert_eq!(min.wrapping_neg(), min); + /// # Some(()) + /// # } + /// ``` + #[inline] + #[unstable(feature = "nonzero_negation_ops", issue = "102443")] + pub const fn wrapping_neg(self) -> $Ty { + let result = self.get().wrapping_neg(); + // SAFETY: negation of nonzero cannot yield zero values. + unsafe { $Ty::new_unchecked(result) } + } } )+ } diff --git a/library/core/src/ops/try_trait.rs b/library/core/src/ops/try_trait.rs index 33df9e6c5cd..84a69046807 100644 --- a/library/core/src/ops/try_trait.rs +++ b/library/core/src/ops/try_trait.rs @@ -379,7 +379,7 @@ pub(crate) type ChangeOutputType<T, V> = <<T as Try>::Residual as Residual<V>>:: pub(crate) struct NeverShortCircuit<T>(pub T); impl<T> NeverShortCircuit<T> { - /// Wrap a binary `FnMut` to return its result wrapped in a `NeverShortCircuit`. + /// Implementation for building `ConstFnMutClosure` for wrapping the output of a ~const FnMut in a `NeverShortCircuit`. #[inline] pub const fn wrap_mut_2_imp<A, B, F: ~const FnMut(A, B) -> T>( f: &mut F, diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 4a93df4591b..4b57371096e 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -559,22 +559,25 @@ impl<T> Option<T> { /// # Examples /// /// ``` - /// #![feature(is_some_with)] + /// #![feature(is_some_and)] /// /// let x: Option<u32> = Some(2); - /// assert_eq!(x.is_some_and(|&x| x > 1), true); + /// assert_eq!(x.is_some_and(|x| x > 1), true); /// /// let x: Option<u32> = Some(0); - /// assert_eq!(x.is_some_and(|&x| x > 1), false); + /// assert_eq!(x.is_some_and(|x| x > 1), false); /// /// let x: Option<u32> = None; - /// assert_eq!(x.is_some_and(|&x| x > 1), false); + /// assert_eq!(x.is_some_and(|x| x > 1), false); /// ``` #[must_use] #[inline] - #[unstable(feature = "is_some_with", issue = "93050")] - pub fn is_some_and(&self, f: impl FnOnce(&T) -> bool) -> bool { - matches!(self, Some(x) if f(x)) + #[unstable(feature = "is_some_and", issue = "93050")] + pub fn is_some_and(self, f: impl FnOnce(T) -> bool) -> bool { + match self { + None => false, + Some(x) => f(x), + } } /// Returns `true` if the option is a [`None`] value. diff --git a/library/core/src/result.rs b/library/core/src/result.rs index dc90e90402c..3f33c5fd6ca 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -548,22 +548,25 @@ impl<T, E> Result<T, E> { /// # Examples /// /// ``` - /// #![feature(is_some_with)] + /// #![feature(is_some_and)] /// /// let x: Result<u32, &str> = Ok(2); - /// assert_eq!(x.is_ok_and(|&x| x > 1), true); + /// assert_eq!(x.is_ok_and(|x| x > 1), true); /// /// let x: Result<u32, &str> = Ok(0); - /// assert_eq!(x.is_ok_and(|&x| x > 1), false); + /// assert_eq!(x.is_ok_and(|x| x > 1), false); /// /// let x: Result<u32, &str> = Err("hey"); - /// assert_eq!(x.is_ok_and(|&x| x > 1), false); + /// assert_eq!(x.is_ok_and(|x| x > 1), false); /// ``` #[must_use] #[inline] - #[unstable(feature = "is_some_with", issue = "93050")] - pub fn is_ok_and(&self, f: impl FnOnce(&T) -> bool) -> bool { - matches!(self, Ok(x) if f(x)) + #[unstable(feature = "is_some_and", issue = "93050")] + pub fn is_ok_and(self, f: impl FnOnce(T) -> bool) -> bool { + match self { + Err(_) => false, + Ok(x) => f(x), + } } /// Returns `true` if the result is [`Err`]. @@ -592,7 +595,7 @@ impl<T, E> Result<T, E> { /// # Examples /// /// ``` - /// #![feature(is_some_with)] + /// #![feature(is_some_and)] /// use std::io::{Error, ErrorKind}; /// /// let x: Result<u32, Error> = Err(Error::new(ErrorKind::NotFound, "!")); @@ -606,9 +609,12 @@ impl<T, E> Result<T, E> { /// ``` #[must_use] #[inline] - #[unstable(feature = "is_some_with", issue = "93050")] - pub fn is_err_and(&self, f: impl FnOnce(&E) -> bool) -> bool { - matches!(self, Err(x) if f(x)) + #[unstable(feature = "is_some_and", issue = "93050")] + pub fn is_err_and(self, f: impl FnOnce(E) -> bool) -> bool { + match self { + Ok(_) => false, + Err(e) => f(e), + } } ///////////////////////////////////////////////////////////////////////// @@ -2066,9 +2072,6 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> { /// so the final value of `shared` is 6 (= `3 + 2 + 1`), not 16. #[inline] fn from_iter<I: IntoIterator<Item = Result<A, E>>>(iter: I) -> Result<V, E> { - // FIXME(#11084): This could be replaced with Iterator::scan when this - // performance bug is closed. - iter::try_process(iter.into_iter(), |i| i.collect()) } } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index aed8fbf092e..56133f346ae 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2426,15 +2426,20 @@ impl<T> [T] { where F: FnMut(&'a T) -> Ordering, { + // INVARIANTS: + // - 0 <= left <= left + size = right <= self.len() + // - f returns Less for everything in self[..left] + // - f returns Greater for everything in self[right..] let mut size = self.len(); let mut left = 0; let mut right = size; while left < right { let mid = left + size / 2; - // SAFETY: the call is made safe by the following invariants: - // - `mid >= 0` - // - `mid < size`: `mid` is limited by `[left; right)` bound. + // SAFETY: the while condition means `size` is strictly positive, so + // `size/2 < size`. Thus `left + size/2 < left + size`, which + // coupled with the `left + size <= self.len()` invariant means + // we have `left + size/2 < self.len()`, and this is in-bounds. let cmp = f(unsafe { self.get_unchecked(mid) }); // The reason why we use if/else control flow rather than match @@ -2452,6 +2457,10 @@ impl<T> [T] { size = right - left; } + + // SAFETY: directly true from the overall invariant. + // Note that this is `<=`, unlike the assume in the `Ok` path. + unsafe { crate::intrinsics::assume(left <= self.len()) }; Err(left) } diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index f1e8bc79bf4..3c5abd215a4 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -188,6 +188,10 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T] { /// /// Note that a range created from [`slice::as_ptr_range`] fulfills these requirements. /// +/// # Panics +/// +/// This function panics if `T` is a Zero-Sized Type (“ZST”). +/// /// # Caveat /// /// The lifetime for the returned slice is inferred from its usage. To @@ -219,9 +223,15 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] { unsafe { from_raw_parts(range.start, range.end.sub_ptr(range.start)) } } -/// Performs the same functionality as [`from_ptr_range`], except that a +/// Forms a mutable slice from a pointer range. +/// +/// This is the same functionality as [`from_ptr_range`], except that a /// mutable slice is returned. /// +/// This function is useful for interacting with foreign interfaces which +/// use two pointers to refer to a range of elements in memory, as is +/// common in C++. +/// /// # Safety /// /// Behavior is undefined if any of the following conditions are violated: @@ -247,6 +257,18 @@ pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] { /// /// Note that a range created from [`slice::as_mut_ptr_range`] fulfills these requirements. /// +/// # Panics +/// +/// This function panics if `T` is a Zero-Sized Type (“ZST”). +/// +/// # Caveat +/// +/// The lifetime for the returned slice is inferred from its usage. To +/// prevent accidental misuse, it's suggested to tie the lifetime to whichever +/// source lifetime is safe in the context, such as by providing a helper +/// function taking the lifetime of a host value for the slice, or by explicit +/// annotation. +/// /// # Examples /// /// ``` diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 18f2ce6edc7..d3ed811b157 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -507,7 +507,6 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> { /// /// ``` /// use std::str::FromStr; -/// use std::num::ParseIntError; /// /// #[derive(Debug, PartialEq)] /// struct Point { @@ -515,18 +514,21 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> { /// y: i32 /// } /// +/// #[derive(Debug, PartialEq, Eq)] +/// struct ParsePointError; +/// /// impl FromStr for Point { -/// type Err = ParseIntError; +/// type Err = ParsePointError; /// /// fn from_str(s: &str) -> Result<Self, Self::Err> { /// let (x, y) = s /// .strip_prefix('(') /// .and_then(|s| s.strip_suffix(')')) /// .and_then(|s| s.split_once(',')) -/// .unwrap(); +/// .ok_or(ParsePointError)?; /// -/// let x_fromstr = x.parse::<i32>()?; -/// let y_fromstr = y.parse::<i32>()?; +/// let x_fromstr = x.parse::<i32>().map_err(|_| ParsePointError)?; +/// let y_fromstr = y.parse::<i32>().map_err(|_| ParsePointError)?; /// /// Ok(Point { x: x_fromstr, y: y_fromstr }) /// } @@ -538,6 +540,8 @@ unsafe impl const SliceIndex<str> for ops::RangeToInclusive<usize> { /// // Implicit calls, through parse /// assert_eq!("(1,2)".parse(), expected); /// assert_eq!("(1,2)".parse::<Point>(), expected); +/// // Invalid input string +/// assert!(Point::from_str("(1 2)").is_err()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub trait FromStr: Sized { diff --git a/library/core/src/time.rs b/library/core/src/time.rs index 4f29ecc0fba..1d0c51c3c83 100644 --- a/library/core/src/time.rs +++ b/library/core/src/time.rs @@ -29,6 +29,20 @@ const NANOS_PER_MICRO: u32 = 1_000; const MILLIS_PER_SEC: u64 = 1_000; const MICROS_PER_SEC: u64 = 1_000_000; +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(transparent)] +#[rustc_layout_scalar_valid_range_start(0)] +#[rustc_layout_scalar_valid_range_end(999_999_999)] +struct Nanoseconds(u32); + +impl Default for Nanoseconds { + #[inline] + fn default() -> Self { + // SAFETY: 0 is within the valid range + unsafe { Nanoseconds(0) } + } +} + /// A `Duration` type to represent a span of time, typically used for system /// timeouts. /// @@ -71,7 +85,7 @@ const MICROS_PER_SEC: u64 = 1_000_000; #[cfg_attr(not(test), rustc_diagnostic_item = "Duration")] pub struct Duration { secs: u64, - nanos: u32, // Always 0 <= nanos < NANOS_PER_SEC + nanos: Nanoseconds, // Always 0 <= nanos < NANOS_PER_SEC } impl Duration { @@ -188,7 +202,8 @@ impl Duration { None => panic!("overflow in Duration::new"), }; let nanos = nanos % NANOS_PER_SEC; - Duration { secs, nanos } + // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range + Duration { secs, nanos: unsafe { Nanoseconds(nanos) } } } /// Creates a new `Duration` from the specified number of whole seconds. @@ -208,7 +223,7 @@ impl Duration { #[inline] #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] pub const fn from_secs(secs: u64) -> Duration { - Duration { secs, nanos: 0 } + Duration::new(secs, 0) } /// Creates a new `Duration` from the specified number of milliseconds. @@ -228,10 +243,7 @@ impl Duration { #[inline] #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] pub const fn from_millis(millis: u64) -> Duration { - Duration { - secs: millis / MILLIS_PER_SEC, - nanos: ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI, - } + Duration::new(millis / MILLIS_PER_SEC, ((millis % MILLIS_PER_SEC) as u32) * NANOS_PER_MILLI) } /// Creates a new `Duration` from the specified number of microseconds. @@ -251,10 +263,7 @@ impl Duration { #[inline] #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] pub const fn from_micros(micros: u64) -> Duration { - Duration { - secs: micros / MICROS_PER_SEC, - nanos: ((micros % MICROS_PER_SEC) as u32) * NANOS_PER_MICRO, - } + Duration::new(micros / MICROS_PER_SEC, ((micros % MICROS_PER_SEC) as u32) * NANOS_PER_MICRO) } /// Creates a new `Duration` from the specified number of nanoseconds. @@ -274,10 +283,7 @@ impl Duration { #[inline] #[rustc_const_stable(feature = "duration_consts", since = "1.32.0")] pub const fn from_nanos(nanos: u64) -> Duration { - Duration { - secs: nanos / (NANOS_PER_SEC as u64), - nanos: (nanos % (NANOS_PER_SEC as u64)) as u32, - } + Duration::new(nanos / (NANOS_PER_SEC as u64), (nanos % (NANOS_PER_SEC as u64)) as u32) } /// Returns true if this `Duration` spans no time. @@ -301,7 +307,7 @@ impl Duration { #[rustc_const_stable(feature = "duration_zero", since = "1.53.0")] #[inline] pub const fn is_zero(&self) -> bool { - self.secs == 0 && self.nanos == 0 + self.secs == 0 && self.nanos.0 == 0 } /// Returns the number of _whole_ seconds contained by this `Duration`. @@ -352,7 +358,7 @@ impl Duration { #[must_use] #[inline] pub const fn subsec_millis(&self) -> u32 { - self.nanos / NANOS_PER_MILLI + self.nanos.0 / NANOS_PER_MILLI } /// Returns the fractional part of this `Duration`, in whole microseconds. @@ -375,7 +381,7 @@ impl Duration { #[must_use] #[inline] pub const fn subsec_micros(&self) -> u32 { - self.nanos / NANOS_PER_MICRO + self.nanos.0 / NANOS_PER_MICRO } /// Returns the fractional part of this `Duration`, in nanoseconds. @@ -398,7 +404,7 @@ impl Duration { #[must_use] #[inline] pub const fn subsec_nanos(&self) -> u32 { - self.nanos + self.nanos.0 } /// Returns the total number of whole milliseconds contained by this `Duration`. @@ -416,7 +422,7 @@ impl Duration { #[must_use] #[inline] pub const fn as_millis(&self) -> u128 { - self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos / NANOS_PER_MILLI) as u128 + self.secs as u128 * MILLIS_PER_SEC as u128 + (self.nanos.0 / NANOS_PER_MILLI) as u128 } /// Returns the total number of whole microseconds contained by this `Duration`. @@ -434,7 +440,7 @@ impl Duration { #[must_use] #[inline] pub const fn as_micros(&self) -> u128 { - self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos / NANOS_PER_MICRO) as u128 + self.secs as u128 * MICROS_PER_SEC as u128 + (self.nanos.0 / NANOS_PER_MICRO) as u128 } /// Returns the total number of nanoseconds contained by this `Duration`. @@ -452,7 +458,7 @@ impl Duration { #[must_use] #[inline] pub const fn as_nanos(&self) -> u128 { - self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos as u128 + self.secs as u128 * NANOS_PER_SEC as u128 + self.nanos.0 as u128 } /// Checked `Duration` addition. Computes `self + other`, returning [`None`] @@ -475,7 +481,7 @@ impl Duration { #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] pub const fn checked_add(self, rhs: Duration) -> Option<Duration> { if let Some(mut secs) = self.secs.checked_add(rhs.secs) { - let mut nanos = self.nanos + rhs.nanos; + let mut nanos = self.nanos.0 + rhs.nanos.0; if nanos >= NANOS_PER_SEC { nanos -= NANOS_PER_SEC; if let Some(new_secs) = secs.checked_add(1) { @@ -485,7 +491,7 @@ impl Duration { } } debug_assert!(nanos < NANOS_PER_SEC); - Some(Duration { secs, nanos }) + Some(Duration::new(secs, nanos)) } else { None } @@ -535,16 +541,16 @@ impl Duration { #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] pub const fn checked_sub(self, rhs: Duration) -> Option<Duration> { if let Some(mut secs) = self.secs.checked_sub(rhs.secs) { - let nanos = if self.nanos >= rhs.nanos { - self.nanos - rhs.nanos + let nanos = if self.nanos.0 >= rhs.nanos.0 { + self.nanos.0 - rhs.nanos.0 } else if let Some(sub_secs) = secs.checked_sub(1) { secs = sub_secs; - self.nanos + NANOS_PER_SEC - rhs.nanos + self.nanos.0 + NANOS_PER_SEC - rhs.nanos.0 } else { return None; }; debug_assert!(nanos < NANOS_PER_SEC); - Some(Duration { secs, nanos }) + Some(Duration::new(secs, nanos)) } else { None } @@ -593,13 +599,13 @@ impl Duration { #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")] pub const fn checked_mul(self, rhs: u32) -> Option<Duration> { // Multiply nanoseconds as u64, because it cannot overflow that way. - let total_nanos = self.nanos as u64 * rhs as u64; + let total_nanos = self.nanos.0 as u64 * rhs as u64; let extra_secs = total_nanos / (NANOS_PER_SEC as u64); let nanos = (total_nanos % (NANOS_PER_SEC as u64)) as u32; if let Some(s) = self.secs.checked_mul(rhs as u64) { if let Some(secs) = s.checked_add(extra_secs) { debug_assert!(nanos < NANOS_PER_SEC); - return Some(Duration { secs, nanos }); + return Some(Duration::new(secs, nanos)); } } None @@ -653,9 +659,9 @@ impl Duration { let secs = self.secs / (rhs as u64); let carry = self.secs - secs * (rhs as u64); let extra_nanos = carry * (NANOS_PER_SEC as u64) / (rhs as u64); - let nanos = self.nanos / rhs + (extra_nanos as u32); + let nanos = self.nanos.0 / rhs + (extra_nanos as u32); debug_assert!(nanos < NANOS_PER_SEC); - Some(Duration { secs, nanos }) + Some(Duration::new(secs, nanos)) } else { None } @@ -677,7 +683,7 @@ impl Duration { #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn as_secs_f64(&self) -> f64 { - (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64) + (self.secs as f64) + (self.nanos.0 as f64) / (NANOS_PER_SEC as f64) } /// Returns the number of seconds contained by this `Duration` as `f32`. @@ -696,7 +702,7 @@ impl Duration { #[inline] #[rustc_const_unstable(feature = "duration_consts_float", issue = "72440")] pub const fn as_secs_f32(&self) -> f32 { - (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32) + (self.secs as f32) + (self.nanos.0 as f32) / (NANOS_PER_SEC as f32) } /// Creates a new `Duration` from the specified number of seconds represented @@ -987,13 +993,13 @@ macro_rules! sum_durations { for entry in $iter { total_secs = total_secs.checked_add(entry.secs).expect("overflow in iter::sum over durations"); - total_nanos = match total_nanos.checked_add(entry.nanos as u64) { + total_nanos = match total_nanos.checked_add(entry.nanos.0 as u64) { Some(n) => n, None => { total_secs = total_secs .checked_add(total_nanos / NANOS_PER_SEC as u64) .expect("overflow in iter::sum over durations"); - (total_nanos % NANOS_PER_SEC as u64) + entry.nanos as u64 + (total_nanos % NANOS_PER_SEC as u64) + entry.nanos.0 as u64 } }; } @@ -1001,7 +1007,7 @@ macro_rules! sum_durations { .checked_add(total_nanos / NANOS_PER_SEC as u64) .expect("overflow in iter::sum over durations"); total_nanos = total_nanos % NANOS_PER_SEC as u64; - Duration { secs: total_secs, nanos: total_nanos as u32 } + Duration::new(total_secs, total_nanos as u32) }}; } @@ -1037,7 +1043,7 @@ impl fmt::Debug for Duration { /// to the formatter's `width`, if specified. fn fmt_decimal( f: &mut fmt::Formatter<'_>, - mut integer_part: u64, + integer_part: u64, mut fractional_part: u32, mut divisor: u32, prefix: &str, @@ -1069,7 +1075,7 @@ impl fmt::Debug for Duration { // normal floating point numbers. However, we only need to do work // when rounding up. This happens if the first digit of the // remaining ones is >= 5. - if fractional_part > 0 && fractional_part >= divisor * 5 { + let integer_part = if fractional_part > 0 && fractional_part >= divisor * 5 { // Round up the number contained in the buffer. We go through // the buffer backwards and keep track of the carry. let mut rev_pos = pos; @@ -1093,9 +1099,18 @@ impl fmt::Debug for Duration { // the whole buffer to '0's and need to increment the integer // part. if carry { - integer_part += 1; + // If `integer_part == u64::MAX` and precision < 9, any + // carry of the overflow during rounding of the + // `fractional_part` into the `integer_part` will cause the + // `integer_part` itself to overflow. Avoid this by using an + // `Option<u64>`, with `None` representing `u64::MAX + 1`. + integer_part.checked_add(1) + } else { + Some(integer_part) } - } + } else { + Some(integer_part) + }; // Determine the end of the buffer: if precision is set, we just // use as many digits from the buffer (capped to 9). If it isn't @@ -1105,7 +1120,12 @@ impl fmt::Debug for Duration { // This closure emits the formatted duration without emitting any // padding (padding is calculated below). let emit_without_padding = |f: &mut fmt::Formatter<'_>| { - write!(f, "{}{}", prefix, integer_part)?; + if let Some(integer_part) = integer_part { + write!(f, "{}{}", prefix, integer_part)?; + } else { + // u64::MAX + 1 == 18446744073709551616 + write!(f, "{}18446744073709551616", prefix)?; + } // Write the decimal point and the fractional part (if any). if end > 0 { @@ -1135,12 +1155,17 @@ impl fmt::Debug for Duration { // 2. The postfix: can be "µs" so we have to count UTF8 characters. let mut actual_w = prefix.len() + postfix.chars().count(); // 3. The integer part: - if let Some(log) = integer_part.checked_ilog10() { - // integer_part is > 0, so has length log10(x)+1 - actual_w += 1 + log as usize; + if let Some(integer_part) = integer_part { + if let Some(log) = integer_part.checked_ilog10() { + // integer_part is > 0, so has length log10(x)+1 + actual_w += 1 + log as usize; + } else { + // integer_part is 0, so has length 1. + actual_w += 1; + } } else { - // integer_part is 0, so has length 1. - actual_w += 1; + // integer_part is u64::MAX + 1, so has length 20 + actual_w += 20; } // 4. The fractional part (if any): if end > 0 { @@ -1166,27 +1191,27 @@ impl fmt::Debug for Duration { let prefix = if f.sign_plus() { "+" } else { "" }; if self.secs > 0 { - fmt_decimal(f, self.secs, self.nanos, NANOS_PER_SEC / 10, prefix, "s") - } else if self.nanos >= NANOS_PER_MILLI { + fmt_decimal(f, self.secs, self.nanos.0, NANOS_PER_SEC / 10, prefix, "s") + } else if self.nanos.0 >= NANOS_PER_MILLI { fmt_decimal( f, - (self.nanos / NANOS_PER_MILLI) as u64, - self.nanos % NANOS_PER_MILLI, + (self.nanos.0 / NANOS_PER_MILLI) as u64, + self.nanos.0 % NANOS_PER_MILLI, NANOS_PER_MILLI / 10, prefix, "ms", ) - } else if self.nanos >= NANOS_PER_MICRO { + } else if self.nanos.0 >= NANOS_PER_MICRO { fmt_decimal( f, - (self.nanos / NANOS_PER_MICRO) as u64, - self.nanos % NANOS_PER_MICRO, + (self.nanos.0 / NANOS_PER_MICRO) as u64, + self.nanos.0 % NANOS_PER_MICRO, NANOS_PER_MICRO / 10, prefix, "µs", ) } else { - fmt_decimal(f, self.nanos as u64, 0, 1, prefix, "ns") + fmt_decimal(f, self.nanos.0 as u64, 0, 1, prefix, "ns") } } } @@ -1317,7 +1342,7 @@ macro_rules! try_from_secs { return Err(FromFloatSecsError { kind: FromFloatSecsErrorKind::OverflowOrNan }); }; - Ok(Duration { secs, nanos }) + Ok(Duration::new(secs, nanos)) }}; } diff --git a/library/core/tests/ascii.rs b/library/core/tests/ascii.rs index 6d2cf3e83bc..f5f2dd04778 100644 --- a/library/core/tests/ascii.rs +++ b/library/core/tests/ascii.rs @@ -252,6 +252,23 @@ fn test_is_ascii_digit() { } #[test] +fn test_is_ascii_octdigit() { + assert_all!(is_ascii_octdigit, "", "01234567"); + assert_none!( + is_ascii_octdigit, + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOQPRSTUVWXYZ", + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~", + " \t\n\x0c\r", + "\x00\x01\x02\x03\x04\x05\x06\x07", + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + "\x10\x11\x12\x13\x14\x15\x16\x17", + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + "\x7f", + ); +} + +#[test] fn test_is_ascii_hexdigit() { assert_all!(is_ascii_hexdigit, "", "0123456789", "abcdefABCDEF",); assert_none!( @@ -454,6 +471,7 @@ fn ascii_ctype_const() { is_ascii_lowercase => [true, false, false, false, false]; is_ascii_alphanumeric => [true, true, true, false, false]; is_ascii_digit => [false, false, true, false, false]; + is_ascii_octdigit => [false, false, false, false, false]; is_ascii_hexdigit => [true, true, true, false, false]; is_ascii_punctuation => [false, false, false, true, false]; is_ascii_graphic => [true, true, true, true, false]; diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 6d58ed9743d..ca0c7a54b3e 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -100,6 +100,7 @@ #![feature(slice_flatten)] #![feature(provide_any)] #![feature(utf8_chunks)] +#![feature(is_ascii_octdigit)] #![deny(unsafe_op_in_unsafe_fn)] extern crate test; diff --git a/library/core/tests/time.rs b/library/core/tests/time.rs index fe2d2f2412d..697bf33a8b0 100644 --- a/library/core/tests/time.rs +++ b/library/core/tests/time.rs @@ -197,9 +197,31 @@ fn correct_sum() { #[test] fn debug_formatting_extreme_values() { assert_eq!( - format!("{:?}", Duration::new(18_446_744_073_709_551_615, 123_456_789)), + format!("{:?}", Duration::new(u64::MAX, 123_456_789)), "18446744073709551615.123456789s" ); + assert_eq!(format!("{:.0?}", Duration::MAX), "18446744073709551616s"); + assert_eq!(format!("{:.0?}", Duration::new(u64::MAX, 500_000_000)), "18446744073709551616s"); + assert_eq!(format!("{:.0?}", Duration::new(u64::MAX, 499_999_999)), "18446744073709551615s"); + assert_eq!( + format!("{:.3?}", Duration::new(u64::MAX, 999_500_000)), + "18446744073709551616.000s" + ); + assert_eq!( + format!("{:.3?}", Duration::new(u64::MAX, 999_499_999)), + "18446744073709551615.999s" + ); + assert_eq!( + format!("{:.8?}", Duration::new(u64::MAX, 999_999_995)), + "18446744073709551616.00000000s" + ); + assert_eq!( + format!("{:.8?}", Duration::new(u64::MAX, 999_999_994)), + "18446744073709551615.99999999s" + ); + assert_eq!(format!("{:21.0?}", Duration::MAX), "18446744073709551616s"); + assert_eq!(format!("{:22.0?}", Duration::MAX), "18446744073709551616s "); + assert_eq!(format!("{:24.0?}", Duration::MAX), "18446744073709551616s "); } #[test] diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index d2db4bb7a46..34983b976e3 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -280,7 +280,8 @@ impl<K, V, S> HashMap<K, V, S> { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> { + #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + pub const fn with_hasher(hash_builder: S) -> HashMap<K, V, S> { HashMap { base: base::HashMap::with_hasher(hash_builder) } } diff --git a/library/std/src/collections/hash/map/tests.rs b/library/std/src/collections/hash/map/tests.rs index cb3032719fa..65634f2063f 100644 --- a/library/std/src/collections/hash/map/tests.rs +++ b/library/std/src/collections/hash/map/tests.rs @@ -1115,3 +1115,9 @@ fn from_array() { // that's a problem! let _must_not_require_type_annotation = HashMap::from([(1, 2)]); } + +#[test] +fn const_with_hasher() { + const X: HashMap<(), (), ()> = HashMap::with_hasher(()); + assert_eq!(X.len(), 0); +} diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 5b6a415fadc..c36eeae3388 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -376,7 +376,8 @@ impl<T, S> HashSet<T, S> { /// ``` #[inline] #[stable(feature = "hashmap_build_hasher", since = "1.7.0")] - pub fn with_hasher(hasher: S) -> HashSet<T, S> { + #[rustc_const_unstable(feature = "const_collections_with_hasher", issue = "102575")] + pub const fn with_hasher(hasher: S) -> HashSet<T, S> { HashSet { base: base::HashSet::with_hasher(hasher) } } diff --git a/library/std/src/collections/hash/set/tests.rs b/library/std/src/collections/hash/set/tests.rs index 233db276b9e..941a0450cc7 100644 --- a/library/std/src/collections/hash/set/tests.rs +++ b/library/std/src/collections/hash/set/tests.rs @@ -496,3 +496,9 @@ fn from_array() { // that's a problem! let _must_not_require_type_annotation = HashSet::from([1, 2]); } + +#[test] +fn const_with_hasher() { + const X: HashSet<(), ()> = HashSet::with_hasher(()); + assert_eq!(X.len(), 0); +} diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 463f714064c..6eb7cbea626 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -603,7 +603,7 @@ pub fn home_dir() -> Option<PathBuf> { /// # Platform-specific behavior /// /// On Unix, returns the value of the `TMPDIR` environment variable if it is -/// set, otherwise for non-Android it returns `/tmp`. If Android, since there +/// set, otherwise for non-Android it returns `/tmp`. On Android, since there /// is no global temporary folder (it is usually allocated per-app), it returns /// `/data/local/tmp`. /// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] / diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 64b62fd3bba..a497acda4f6 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -251,6 +251,7 @@ #![feature(doc_notable_trait)] #![feature(dropck_eyepatch)] #![feature(exhaustive_patterns)] +#![feature(if_let_guard)] #![feature(intra_doc_pointers)] #![feature(lang_items)] #![feature(let_chains)] @@ -291,7 +292,7 @@ #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] #![feature(int_error_internals)] -#![feature(is_some_with)] +#![feature(is_some_and)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_write_slice)] #![feature(nonnull_slice_from_raw_parts)] @@ -350,6 +351,7 @@ // Only used in tests/benchmarks: // // Only for const-ness: +#![feature(const_collections_with_hasher)] #![feature(const_io_structs)] #![feature(const_ip)] #![feature(const_ipv4)] diff --git a/library/std/src/os/fd/mod.rs b/library/std/src/os/fd/mod.rs index a456947534a..c6aa7c77dbc 100644 --- a/library/std/src/os/fd/mod.rs +++ b/library/std/src/os/fd/mod.rs @@ -1,16 +1,25 @@ //! Owned and borrowed Unix-like file descriptors. +//! +//! This module is supported on Unix platforms and WASI, which both use a +//! similar file descriptor system for referencing OS resources. #![stable(feature = "io_safety", since = "1.63.0")] #![deny(unsafe_op_in_unsafe_fn)] // `RawFd`, `AsRawFd`, etc. -pub mod raw; +mod raw; // `OwnedFd`, `AsFd`, etc. -pub mod owned; +mod owned; // Implementations for `AsRawFd` etc. for network types. mod net; #[cfg(test)] mod tests; + +// Export the types and traits for the public API. +#[unstable(feature = "os_fd", issue = "98699")] +pub use owned::*; +#[unstable(feature = "os_fd", issue = "98699")] +pub use raw::*; diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 71e33fb9ed8..9875c389d8a 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -206,10 +206,8 @@ pub trait AsFd { /// ```rust,no_run /// use std::fs::File; /// # use std::io; - /// # #[cfg(target_os = "wasi")] - /// # use std::os::wasi::io::{AsFd, BorrowedFd}; - /// # #[cfg(unix)] - /// # use std::os::unix::io::{AsFd, BorrowedFd}; + /// # #[cfg(any(unix, target_os = "wasi"))] + /// # use std::os::fd::{AsFd, BorrowedFd}; /// /// let mut f = File::open("foo.txt")?; /// # #[cfg(any(unix, target_os = "wasi"))] diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index 1b3d110426f..f92a0506670 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -42,10 +42,8 @@ pub trait AsRawFd { /// ```no_run /// use std::fs::File; /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{AsRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{AsRawFd, RawFd}; + /// #[cfg(any(unix, target_os = "wasi"))] + /// use std::os::fd::{AsRawFd, RawFd}; /// /// let mut f = File::open("foo.txt")?; /// // Note that `raw_fd` is only valid as long as `f` exists. @@ -83,10 +81,8 @@ pub trait FromRawFd { /// ```no_run /// use std::fs::File; /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{FromRawFd, IntoRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{FromRawFd, IntoRawFd, RawFd}; + /// #[cfg(any(unix, target_os = "wasi"))] + /// use std::os::fd::{FromRawFd, IntoRawFd, RawFd}; /// /// let f = File::open("foo.txt")?; /// # #[cfg(any(unix, target_os = "wasi"))] @@ -121,10 +117,8 @@ pub trait IntoRawFd { /// ```no_run /// use std::fs::File; /// # use std::io; - /// #[cfg(unix)] - /// use std::os::unix::io::{IntoRawFd, RawFd}; - /// #[cfg(target_os = "wasi")] - /// use std::os::wasi::io::{IntoRawFd, RawFd}; + /// #[cfg(any(unix, target_os = "wasi"))] + /// use std::os::fd::{IntoRawFd, RawFd}; /// /// let f = File::open("foo.txt")?; /// #[cfg(any(unix, target_os = "wasi"))] diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 18c64b51007..f62f5af774f 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -147,7 +147,7 @@ pub mod solid; pub mod vxworks; #[cfg(any(unix, target_os = "wasi", doc))] -mod fd; +pub mod fd; #[cfg(any(target_os = "linux", target_os = "android", doc))] mod net; diff --git a/library/std/src/os/unix/io/fd.rs b/library/std/src/os/unix/io/fd.rs deleted file mode 100644 index d4cb696459b..00000000000 --- a/library/std/src/os/unix/io/fd.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Owned and borrowed file descriptors. - -// Tests for this module -#[cfg(test)] -mod tests; - -#[stable(feature = "io_safety", since = "1.63.0")] -pub use crate::os::fd::owned::*; diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs index 3ab5606f889..25b5dbff14f 100644 --- a/library/std/src/os/unix/io/mod.rs +++ b/library/std/src/os/unix/io/mod.rs @@ -77,10 +77,9 @@ #![stable(feature = "rust1", since = "1.0.0")] -mod fd; -mod raw; - -#[stable(feature = "io_safety", since = "1.63.0")] -pub use fd::*; #[stable(feature = "rust1", since = "1.0.0")] -pub use raw::*; +pub use crate::os::fd::*; + +// Tests for this module +#[cfg(test)] +mod tests; diff --git a/library/std/src/os/unix/io/raw.rs b/library/std/src/os/unix/io/raw.rs deleted file mode 100644 index a4d2ba797d9..00000000000 --- a/library/std/src/os/unix/io/raw.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Unix-specific extensions to general I/O primitives. - -#![stable(feature = "rust1", since = "1.0.0")] - -#[stable(feature = "rust1", since = "1.0.0")] -pub use crate::os::fd::raw::*; diff --git a/library/std/src/os/unix/io/fd/tests.rs b/library/std/src/os/unix/io/tests.rs index 84d2a7a1a91..84d2a7a1a91 100644 --- a/library/std/src/os/unix/io/fd/tests.rs +++ b/library/std/src/os/unix/io/tests.rs diff --git a/library/std/src/os/wasi/io/mod.rs b/library/std/src/os/wasi/io/mod.rs index 6c884e2eaf4..d528590d75b 100644 --- a/library/std/src/os/wasi/io/mod.rs +++ b/library/std/src/os/wasi/io/mod.rs @@ -1,12 +1,6 @@ //! WASI-specific extensions to general I/O primitives. -#![deny(unsafe_op_in_unsafe_fn)] #![unstable(feature = "wasi_ext", issue = "71213")] -mod fd; -mod raw; - -#[unstable(feature = "wasi_ext", issue = "71213")] -pub use fd::*; #[unstable(feature = "wasi_ext", issue = "71213")] -pub use raw::*; +pub use crate::os::fd::*; diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index cc347e3586a..57c7bf6a28b 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -313,8 +313,11 @@ pub struct FilePermissions { mode: mode_t, } -#[derive(Copy, Clone)] -pub struct FileTimes([libc::timespec; 2]); +#[derive(Copy, Clone, Debug, Default)] +pub struct FileTimes { + accessed: Option<SystemTime>, + modified: Option<SystemTime>, +} #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct FileType { @@ -512,45 +515,11 @@ impl FilePermissions { impl FileTimes { pub fn set_accessed(&mut self, t: SystemTime) { - self.0[0] = t.t.to_timespec().expect("Invalid system time"); + self.accessed = Some(t); } pub fn set_modified(&mut self, t: SystemTime) { - self.0[1] = t.t.to_timespec().expect("Invalid system time"); - } -} - -struct TimespecDebugAdapter<'a>(&'a libc::timespec); - -impl fmt::Debug for TimespecDebugAdapter<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("timespec") - .field("tv_sec", &self.0.tv_sec) - .field("tv_nsec", &self.0.tv_nsec) - .finish() - } -} - -impl fmt::Debug for FileTimes { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("FileTimes") - .field("accessed", &TimespecDebugAdapter(&self.0[0])) - .field("modified", &TimespecDebugAdapter(&self.0[1])) - .finish() - } -} - -impl Default for FileTimes { - fn default() -> Self { - // Redox doesn't appear to support `UTIME_OMIT`, so we stub it out here, and always return - // an error in `set_times`. - // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore - // the same as for Redox. - #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] - let omit = libc::timespec { tv_sec: 0, tv_nsec: 0 }; - #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))] - let omit = libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }; - Self([omit; 2]) + self.modified = Some(t); } } @@ -1084,6 +1053,17 @@ impl File { } pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))] + let to_timespec = |time: Option<SystemTime>| { + match time { + Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts), + Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")), + Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too small to set as a file time")), + None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }), + } + }; + #[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))] + let times = [to_timespec(times.accessed)?, to_timespec(times.modified)?]; cfg_if::cfg_if! { if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] { // Redox doesn't appear to support `UTIME_OMIT`. @@ -1099,7 +1079,7 @@ impl File { cvt(unsafe { weak!(fn futimens(c_int, *const libc::timespec) -> c_int); match futimens.get() { - Some(futimens) => futimens(self.as_raw_fd(), times.0.as_ptr()), + Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()), #[cfg(target_os = "macos")] None => { fn ts_to_tv(ts: &libc::timespec) -> libc::timeval { @@ -1108,7 +1088,7 @@ impl File { tv_usec: (ts.tv_nsec / 1000) as _ } } - let timevals = [ts_to_tv(×.0[0]), ts_to_tv(×.0[1])]; + let timevals = [ts_to_tv(×[0]), ts_to_tv(×[1])]; libc::futimes(self.as_raw_fd(), timevals.as_ptr()) } // futimes requires even newer Android. @@ -1121,7 +1101,7 @@ impl File { })?; Ok(()) } else { - cvt(unsafe { libc::futimens(self.as_raw_fd(), times.0.as_ptr()) })?; + cvt(unsafe { libc::futimens(self.as_raw_fd(), times.as_ptr()) })?; Ok(()) } } diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index dff973f59d1..cca9c676701 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -7,6 +7,12 @@ const NSEC_PER_SEC: u64 = 1_000_000_000; pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() }; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(transparent)] +#[rustc_layout_scalar_valid_range_start(0)] +#[rustc_layout_scalar_valid_range_end(999_999_999)] +struct Nanoseconds(u32); + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct SystemTime { pub(in crate::sys::unix) t: Timespec, } @@ -14,7 +20,7 @@ pub struct SystemTime { #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(in crate::sys::unix) struct Timespec { tv_sec: i64, - tv_nsec: i64, + tv_nsec: Nanoseconds, } impl SystemTime { @@ -46,18 +52,20 @@ impl fmt::Debug for SystemTime { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SystemTime") .field("tv_sec", &self.t.tv_sec) - .field("tv_nsec", &self.t.tv_nsec) + .field("tv_nsec", &self.t.tv_nsec.0) .finish() } } impl Timespec { pub const fn zero() -> Timespec { - Timespec { tv_sec: 0, tv_nsec: 0 } + Timespec::new(0, 0) } - fn new(tv_sec: i64, tv_nsec: i64) -> Timespec { - Timespec { tv_sec, tv_nsec } + const fn new(tv_sec: i64, tv_nsec: i64) -> Timespec { + assert!(tv_nsec >= 0 && tv_nsec < NSEC_PER_SEC as i64); + // SAFETY: The assert above checks tv_nsec is within the valid range + Timespec { tv_sec, tv_nsec: unsafe { Nanoseconds(tv_nsec as u32) } } } pub fn sub_timespec(&self, other: &Timespec) -> Result<Duration, Duration> { @@ -75,12 +83,12 @@ impl Timespec { // // Ideally this code could be rearranged such that it more // directly expresses the lower-cost behavior we want from it. - let (secs, nsec) = if self.tv_nsec >= other.tv_nsec { - ((self.tv_sec - other.tv_sec) as u64, (self.tv_nsec - other.tv_nsec) as u32) + let (secs, nsec) = if self.tv_nsec.0 >= other.tv_nsec.0 { + ((self.tv_sec - other.tv_sec) as u64, self.tv_nsec.0 - other.tv_nsec.0) } else { ( (self.tv_sec - other.tv_sec - 1) as u64, - self.tv_nsec as u32 + (NSEC_PER_SEC as u32) - other.tv_nsec as u32, + self.tv_nsec.0 + (NSEC_PER_SEC as u32) - other.tv_nsec.0, ) }; @@ -102,7 +110,7 @@ impl Timespec { // Nano calculations can't overflow because nanos are <1B which fit // in a u32. - let mut nsec = other.subsec_nanos() + self.tv_nsec as u32; + let mut nsec = other.subsec_nanos() + self.tv_nsec.0; if nsec >= NSEC_PER_SEC as u32 { nsec -= NSEC_PER_SEC as u32; secs = secs.checked_add(1)?; @@ -118,7 +126,7 @@ impl Timespec { .and_then(|secs| self.tv_sec.checked_sub(secs))?; // Similar to above, nanos can't overflow. - let mut nsec = self.tv_nsec as i32 - other.subsec_nanos() as i32; + let mut nsec = self.tv_nsec.0 as i32 - other.subsec_nanos() as i32; if nsec < 0 { nsec += NSEC_PER_SEC as i32; secs = secs.checked_sub(1)?; @@ -130,7 +138,7 @@ impl Timespec { pub fn to_timespec(&self) -> Option<libc::timespec> { Some(libc::timespec { tv_sec: self.tv_sec.try_into().ok()?, - tv_nsec: self.tv_nsec.try_into().ok()?, + tv_nsec: self.tv_nsec.0.try_into().ok()?, }) } } @@ -293,7 +301,7 @@ mod inner { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Instant") .field("tv_sec", &self.t.tv_sec) - .field("tv_nsec", &self.t.tv_nsec) + .field("tv_nsec", &self.t.tv_nsec.0) .finish() } } @@ -334,7 +342,7 @@ mod inner { let mut t = MaybeUninit::uninit(); cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap(); let t = unsafe { t.assume_init() }; - return Timespec { tv_sec: t.tv_sec, tv_nsec: t.tv_nsec as i64 }; + return Timespec::new(t.tv_sec, t.tv_nsec as i64); } } diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs index 510cf36b1bf..953fbeb8395 100644 --- a/library/std/src/sys/wasi/fs.rs +++ b/library/std/src/sys/wasi/fs.rs @@ -65,8 +65,8 @@ pub struct FilePermissions { #[derive(Copy, Clone, Debug, Default)] pub struct FileTimes { - accessed: Option<wasi::Timestamp>, - modified: Option<wasi::Timestamp>, + accessed: Option<SystemTime>, + modified: Option<SystemTime>, } #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] @@ -120,11 +120,11 @@ impl FilePermissions { impl FileTimes { pub fn set_accessed(&mut self, t: SystemTime) { - self.accessed = Some(t.to_wasi_timestamp_or_panic()); + self.accessed = Some(t); } pub fn set_modified(&mut self, t: SystemTime) { - self.modified = Some(t.to_wasi_timestamp_or_panic()); + self.modified = Some(t); } } @@ -476,9 +476,16 @@ impl File { } pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + let to_timestamp = |time: Option<SystemTime>| { + match time { + Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts), + Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")), + None => Ok(0), + } + }; self.fd.filestat_set_times( - times.accessed.unwrap_or(0), - times.modified.unwrap_or(0), + to_timestamp(times.accessed)?, + to_timestamp(times.modified)?, times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM) | times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM), ) diff --git a/library/std/src/sys/wasi/stdio.rs b/library/std/src/sys/wasi/stdio.rs index d2081771b6e..bf045c7841f 100644 --- a/library/std/src/sys/wasi/stdio.rs +++ b/library/std/src/sys/wasi/stdio.rs @@ -30,6 +30,15 @@ impl AsFd for Stdin { } } +#[stable(feature = "io_safety", since = "1.63.0")] +impl<'a> AsFd for io::StdinLock<'a> { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + // SAFETY: user code should not close stdin out from under the standard library + unsafe { BorrowedFd::borrow_raw(0) } + } +} + impl io::Read for Stdin { fn read(&mut self, data: &mut [u8]) -> io::Result<usize> { self.read_vectored(&mut [IoSliceMut::new(data)]) @@ -65,6 +74,15 @@ impl AsFd for Stdout { } } +#[stable(feature = "io_safety", since = "1.63.0")] +impl<'a> AsFd for io::StdoutLock<'a> { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + // SAFETY: user code should not close stdout out from under the standard library + unsafe { BorrowedFd::borrow_raw(1) } + } +} + impl io::Write for Stdout { fn write(&mut self, data: &[u8]) -> io::Result<usize> { self.write_vectored(&[IoSlice::new(data)]) @@ -103,6 +121,15 @@ impl AsFd for Stderr { } } +#[stable(feature = "io_safety", since = "1.63.0")] +impl<'a> AsFd for io::StderrLock<'a> { + #[inline] + fn as_fd(&self) -> BorrowedFd<'_> { + // SAFETY: user code should not close stderr out from under the standard library + unsafe { BorrowedFd::borrow_raw(2) } + } +} + impl io::Write for Stderr { fn write(&mut self, data: &[u8]) -> io::Result<usize> { self.write_vectored(&[IoSlice::new(data)]) diff --git a/library/std/src/sys/wasi/time.rs b/library/std/src/sys/wasi/time.rs index 3d326e49106..016b06efbdc 100644 --- a/library/std/src/sys/wasi/time.rs +++ b/library/std/src/sys/wasi/time.rs @@ -47,8 +47,8 @@ impl SystemTime { SystemTime(Duration::from_nanos(ts)) } - pub fn to_wasi_timestamp_or_panic(&self) -> wasi::Timestamp { - self.0.as_nanos().try_into().expect("time does not fit in WASI timestamp") + pub fn to_wasi_timestamp(&self) -> Option<wasi::Timestamp> { + self.0.as_nanos().try_into().ok() } pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 155d0297e49..ade00750c95 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -572,6 +572,14 @@ impl File { "Cannot set file timestamp to 0", )); } + let is_max = + |t: c::FILETIME| t.dwLowDateTime == c::DWORD::MAX && t.dwHighDateTime == c::DWORD::MAX; + if times.accessed.map_or(false, is_max) || times.modified.map_or(false, is_max) { + return Err(io::const_io_error!( + io::ErrorKind::InvalidInput, + "Cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF", + )); + } cvt(unsafe { c::SetFileTime(self.as_handle(), None, times.accessed.as_ref(), times.modified.as_ref()) })?; diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index ceea6986e33..2de7da3793f 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -779,6 +779,8 @@ pub fn panicking() -> bool { panicking::panicking() } +/// Use [`sleep`]. +/// /// Puts the current thread to sleep for at least the specified amount of time. /// /// The thread may sleep longer than the duration specified due to scheduling diff --git a/library/test/src/bench.rs b/library/test/src/bench.rs index 7869ba2c041..23925e6ea72 100644 --- a/library/test/src/bench.rs +++ b/library/test/src/bench.rs @@ -49,12 +49,12 @@ impl Bencher { self.summary = Some(iter(&mut inner)); } - pub fn bench<F>(&mut self, mut f: F) -> Option<stats::Summary> + pub fn bench<F>(&mut self, mut f: F) -> Result<Option<stats::Summary>, String> where - F: FnMut(&mut Bencher), + F: FnMut(&mut Bencher) -> Result<(), String>, { - f(self); - self.summary + let result = f(self); + result.map(|_| self.summary) } } @@ -195,7 +195,7 @@ pub fn benchmark<F>( nocapture: bool, f: F, ) where - F: FnMut(&mut Bencher), + F: FnMut(&mut Bencher) -> Result<(), String>, { let mut bs = Bencher { mode: BenchMode::Auto, summary: None, bytes: 0 }; @@ -211,14 +211,14 @@ pub fn benchmark<F>( let test_result = match result { //bs.bench(f) { - Ok(Some(ns_iter_summ)) => { + Ok(Ok(Some(ns_iter_summ))) => { let ns_iter = cmp::max(ns_iter_summ.median as u64, 1); let mb_s = bs.bytes * 1000 / ns_iter; let bs = BenchSamples { ns_iter_summ, mb_s: mb_s as usize }; TestResult::TrBench(bs) } - Ok(None) => { + Ok(Ok(None)) => { // iter not called, so no data. // FIXME: error in this case? let samples: &mut [f64] = &mut [0.0_f64; 1]; @@ -226,6 +226,7 @@ pub fn benchmark<F>( TestResult::TrBench(bs) } Err(_) => TestResult::TrFailed, + Ok(Err(_)) => TestResult::TrFailed, }; let stdout = data.lock().unwrap().to_vec(); @@ -233,10 +234,10 @@ pub fn benchmark<F>( monitor_ch.send(message).unwrap(); } -pub fn run_once<F>(f: F) +pub fn run_once<F>(f: F) -> Result<(), String> where - F: FnMut(&mut Bencher), + F: FnMut(&mut Bencher) -> Result<(), String>, { let mut bs = Bencher { mode: BenchMode::Single, summary: None, bytes: 0 }; - bs.bench(f); + bs.bench(f).map(|_| ()) } diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 33c6ea58532..c30257fc792 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -6,7 +6,8 @@ //! benchmarks themselves) should be done via the `#[test]` and //! `#[bench]` attributes. //! -//! See the [Testing Chapter](../book/ch11-00-testing.html) of the book for more details. +//! See the [Testing Chapter](../book/ch11-00-testing.html) of the book for more +//! details. // Currently, not much of this is meant for users. It is intended to // support the simplest interface possible for representing and @@ -76,6 +77,7 @@ mod types; #[cfg(test)] mod tests; +use core::any::Any; use event::{CompletedTest, TestEvent}; use helpers::concurrency::get_concurrency; use helpers::exit_code::get_exit_code; @@ -175,17 +177,20 @@ fn make_owned_test(test: &&TestDescAndFn) -> TestDescAndFn { } } -/// Invoked when unit tests terminate. Should panic if the unit -/// Tests is considered a failure. By default, invokes `report()` -/// and checks for a `0` result. -pub fn assert_test_result<T: Termination>(result: T) { +/// Invoked when unit tests terminate. Returns `Result::Err` if the test is +/// considered a failure. By default, invokes `report() and checks for a `0` +/// result. +pub fn assert_test_result<T: Termination>(result: T) -> Result<(), String> { let code = result.report().to_i32(); - assert_eq!( - code, 0, - "the test returned a termination value with a non-zero status code ({}) \ - which indicates a failure", - code - ); + if code == 0 { + Ok(()) + } else { + Err(format!( + "the test returned a termination value with a non-zero status code \ + ({}) which indicates a failure", + code + )) + } } pub fn run_tests<F>( @@ -478,7 +483,7 @@ pub fn run_test( id: TestId, desc: TestDesc, monitor_ch: Sender<CompletedTest>, - testfn: Box<dyn FnOnce() + Send>, + testfn: Box<dyn FnOnce() -> Result<(), String> + Send>, opts: TestRunOpts, ) -> Option<thread::JoinHandle<()>> { let concurrency = opts.concurrency; @@ -567,11 +572,11 @@ pub fn run_test( /// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. #[inline(never)] -fn __rust_begin_short_backtrace<F: FnOnce()>(f: F) { - f(); +fn __rust_begin_short_backtrace<T, F: FnOnce() -> T>(f: F) -> T { + let result = f(); // prevent this frame from being tail-call optimised away - black_box(()); + black_box(result) } fn run_test_in_process( @@ -579,7 +584,7 @@ fn run_test_in_process( desc: TestDesc, nocapture: bool, report_time: bool, - testfn: Box<dyn FnOnce() + Send>, + testfn: Box<dyn FnOnce() -> Result<(), String> + Send>, monitor_ch: Sender<CompletedTest>, time_opts: Option<time::TestTimeOptions>, ) { @@ -591,7 +596,7 @@ fn run_test_in_process( } let start = report_time.then(Instant::now); - let result = catch_unwind(AssertUnwindSafe(testfn)); + let result = fold_err(catch_unwind(AssertUnwindSafe(testfn))); let exec_time = start.map(|start| { let duration = start.elapsed(); TestExecTime(duration) @@ -608,6 +613,19 @@ fn run_test_in_process( monitor_ch.send(message).unwrap(); } +fn fold_err<T, E>( + result: Result<Result<T, E>, Box<dyn Any + Send>>, +) -> Result<T, Box<dyn Any + Send>> +where + E: Send + 'static, +{ + match result { + Ok(Err(e)) => Err(Box::new(e)), + Ok(Ok(v)) => Ok(v), + Err(e) => Err(e), + } +} + fn spawn_test_subprocess( id: TestId, desc: TestDesc, @@ -663,7 +681,10 @@ fn spawn_test_subprocess( monitor_ch.send(message).unwrap(); } -fn run_test_in_spawned_subprocess(desc: TestDesc, testfn: Box<dyn FnOnce() + Send>) -> ! { +fn run_test_in_spawned_subprocess( + desc: TestDesc, + testfn: Box<dyn FnOnce() -> Result<(), String> + Send>, +) -> ! { let builtin_panic_hook = panic::take_hook(); let record_result = Arc::new(move |panic_info: Option<&'_ PanicInfo<'_>>| { let test_result = match panic_info { @@ -689,7 +710,9 @@ fn run_test_in_spawned_subprocess(desc: TestDesc, testfn: Box<dyn FnOnce() + Sen }); let record_result2 = record_result.clone(); panic::set_hook(Box::new(move |info| record_result2(Some(&info)))); - testfn(); + if let Err(message) = testfn() { + panic!("{}", message); + } record_result(None); unreachable!("panic=abort callback should have exited the process") } diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index 0b81aff5907..278cfb15bb1 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -67,7 +67,7 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> { no_run: false, test_type: TestType::Unknown, }, - testfn: DynTestFn(Box::new(move || {})), + testfn: DynTestFn(Box::new(move || Ok(()))), }, TestDescAndFn { desc: TestDesc { @@ -79,14 +79,14 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> { no_run: false, test_type: TestType::Unknown, }, - testfn: DynTestFn(Box::new(move || {})), + testfn: DynTestFn(Box::new(move || Ok(()))), }, ] } #[test] pub fn do_not_run_ignored_tests() { - fn f() { + fn f() -> Result<(), String> { panic!(); } let desc = TestDescAndFn { @@ -109,7 +109,9 @@ pub fn do_not_run_ignored_tests() { #[test] pub fn ignored_tests_result_in_ignored() { - fn f() {} + fn f() -> Result<(), String> { + Ok(()) + } let desc = TestDescAndFn { desc: TestDesc { name: StaticTestName("whatever"), @@ -132,7 +134,7 @@ pub fn ignored_tests_result_in_ignored() { #[test] #[cfg(not(target_os = "emscripten"))] fn test_should_panic() { - fn f() { + fn f() -> Result<(), String> { panic!(); } let desc = TestDescAndFn { @@ -157,7 +159,7 @@ fn test_should_panic() { #[test] #[cfg(not(target_os = "emscripten"))] fn test_should_panic_good_message() { - fn f() { + fn f() -> Result<(), String> { panic!("an error message"); } let desc = TestDescAndFn { @@ -183,7 +185,7 @@ fn test_should_panic_good_message() { #[cfg(not(target_os = "emscripten"))] fn test_should_panic_bad_message() { use crate::tests::TrFailedMsg; - fn f() { + fn f() -> Result<(), String> { panic!("an error message"); } let expected = "foobar"; @@ -214,7 +216,7 @@ fn test_should_panic_bad_message() { fn test_should_panic_non_string_message_type() { use crate::tests::TrFailedMsg; use std::any::TypeId; - fn f() { + fn f() -> Result<(), String> { std::panic::panic_any(1i32); } let expected = "foobar"; @@ -249,7 +251,9 @@ fn test_should_panic_but_succeeds() { let should_panic_variants = [ShouldPanic::Yes, ShouldPanic::YesWithMessage("error message")]; for &should_panic in should_panic_variants.iter() { - fn f() {} + fn f() -> Result<(), String> { + Ok(()) + } let desc = TestDescAndFn { desc: TestDesc { name: StaticTestName("whatever"), @@ -283,7 +287,9 @@ fn test_should_panic_but_succeeds() { } fn report_time_test_template(report_time: bool) -> Option<TestExecTime> { - fn f() {} + fn f() -> Result<(), String> { + Ok(()) + } let desc = TestDescAndFn { desc: TestDesc { name: StaticTestName("whatever"), @@ -318,7 +324,9 @@ fn test_should_report_time() { } fn time_test_failure_template(test_type: TestType) -> TestResult { - fn f() {} + fn f() -> Result<(), String> { + Ok(()) + } let desc = TestDescAndFn { desc: TestDesc { name: StaticTestName("whatever"), @@ -480,7 +488,7 @@ pub fn exclude_should_panic_option() { no_run: false, test_type: TestType::Unknown, }, - testfn: DynTestFn(Box::new(move || {})), + testfn: DynTestFn(Box::new(move || Ok(()))), }); let filtered = filter_tests(&opts, tests); @@ -504,7 +512,7 @@ pub fn exact_filter_match() { no_run: false, test_type: TestType::Unknown, }, - testfn: DynTestFn(Box::new(move || {})), + testfn: DynTestFn(Box::new(move || Ok(()))), }) .collect() } @@ -580,7 +588,9 @@ fn sample_tests() -> Vec<TestDescAndFn> { "test::run_include_ignored_option".to_string(), "test::sort_tests".to_string(), ]; - fn testfn() {} + fn testfn() -> Result<(), String> { + Ok(()) + } let mut tests = Vec::new(); for name in &names { let test = TestDescAndFn { @@ -717,21 +727,26 @@ pub fn test_metricmap_compare() { #[test] pub fn test_bench_once_no_iter() { - fn f(_: &mut Bencher) {} - bench::run_once(f); + fn f(_: &mut Bencher) -> Result<(), String> { + Ok(()) + } + bench::run_once(f).unwrap(); } #[test] pub fn test_bench_once_iter() { - fn f(b: &mut Bencher) { - b.iter(|| {}) + fn f(b: &mut Bencher) -> Result<(), String> { + b.iter(|| {}); + Ok(()) } - bench::run_once(f); + bench::run_once(f).unwrap(); } #[test] pub fn test_bench_no_iter() { - fn f(_: &mut Bencher) {} + fn f(_: &mut Bencher) -> Result<(), String> { + Ok(()) + } let (tx, rx) = channel(); @@ -751,8 +766,9 @@ pub fn test_bench_no_iter() { #[test] pub fn test_bench_iter() { - fn f(b: &mut Bencher) { - b.iter(|| {}) + fn f(b: &mut Bencher) -> Result<(), String> { + b.iter(|| {}); + Ok(()) } let (tx, rx) = channel(); @@ -821,3 +837,33 @@ fn should_sort_failures_before_printing_them() { let bpos = s.find("b").unwrap(); assert!(apos < bpos); } + +#[test] +#[cfg(not(target_os = "emscripten"))] +fn test_dyn_bench_returning_err_fails_when_run_as_test() { + fn f(_: &mut Bencher) -> Result<(), String> { + Result::Err("An error".into()) + } + let desc = TestDescAndFn { + desc: TestDesc { + name: StaticTestName("whatever"), + ignore: false, + ignore_message: None, + should_panic: ShouldPanic::No, + compile_fail: false, + no_run: false, + test_type: TestType::Unknown, + }, + testfn: DynBenchFn(Box::new(f)), + }; + let (tx, rx) = channel(); + let notify = move |event: TestEvent| { + if let TestEvent::TeResult(result) = event { + tx.send(result).unwrap(); + } + Ok(()) + }; + run_tests(&TestOpts { run_tests: true, ..TestOpts::new() }, vec![desc], notify).unwrap(); + let result = rx.recv().unwrap().result; + assert_eq!(result, TrFailed); +} diff --git a/library/test/src/types.rs b/library/test/src/types.rs index ffb1efe18cc..888afff7921 100644 --- a/library/test/src/types.rs +++ b/library/test/src/types.rs @@ -75,14 +75,15 @@ impl fmt::Display for TestName { } // A function that runs a test. If the function returns successfully, -// the test succeeds; if the function panics then the test fails. We -// may need to come up with a more clever definition of test in order -// to support isolation of tests into threads. +// the test succeeds; if the function panics or returns Result::Err +// then the test fails. We may need to come up with a more clever +// definition of test in order to support isolation of tests into +// threads. pub enum TestFn { - StaticTestFn(fn()), - StaticBenchFn(fn(&mut Bencher)), - DynTestFn(Box<dyn FnOnce() + Send>), - DynBenchFn(Box<dyn Fn(&mut Bencher) + Send>), + StaticTestFn(fn() -> Result<(), String>), + StaticBenchFn(fn(&mut Bencher) -> Result<(), String>), + DynTestFn(Box<dyn FnOnce() -> Result<(), String> + Send>), + DynBenchFn(Box<dyn Fn(&mut Bencher) -> Result<(), String> + Send>), } impl TestFn { diff --git a/src/bootstrap/CHANGELOG.md b/src/bootstrap/CHANGELOG.md index 85afc1f5f6c..64b74ecc9de 100644 --- a/src/bootstrap/CHANGELOG.md +++ b/src/bootstrap/CHANGELOG.md @@ -13,6 +13,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Change the names for `dist` commands to match the component they generate. [#90684](https://github.com/rust-lang/rust/pull/90684) - The `build.fast-submodules` option has been removed. Fast submodule checkouts are enabled unconditionally. Automatic submodule handling can still be disabled with `build.submodules = false`. - Several unsupported `./configure` options have been removed: `optimize`, `parallel-compiler`. These can still be enabled with `--set`, although it isn't recommended. +- `remote-test-server`'s `verbose` argument has been removed in favor of the `--verbose` flag +- `remote-test-server`'s `remote` argument has been removed in favor of the `--bind` flag. Use `--bind 0.0.0.0:12345` to replicate the behavior of the `remote` argument. ### Non-breaking changes diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index 1932a0017ee..258352a21a4 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -5,10 +5,12 @@ //! `package_vers`, and otherwise indicating to the compiler what it should //! print out as part of its version information. +use std::fs; use std::path::Path; use std::process::Command; use crate::util::output; +use crate::util::t; use crate::Build; pub enum GitInfo { @@ -18,19 +20,25 @@ pub enum GitInfo { /// If the info should be used (`ignore_git` is false), this will be /// `Some`, otherwise it will be `None`. Present(Option<Info>), + /// This is not a git repostory, but the info can be fetched from the + /// `git-commit-info` file. + RecordedForTarball(Info), } pub struct Info { - commit_date: String, - sha: String, - short_sha: String, + pub commit_date: String, + pub sha: String, + pub short_sha: String, } impl GitInfo { pub fn new(ignore_git: bool, dir: &Path) -> GitInfo { // See if this even begins to look like a git dir if !dir.join(".git").exists() { - return GitInfo::Absent; + match read_commit_info_file(dir) { + Some(info) => return GitInfo::RecordedForTarball(info), + None => return GitInfo::Absent, + } } // Make sure git commands work @@ -65,10 +73,11 @@ impl GitInfo { })) } - fn info(&self) -> Option<&Info> { + pub fn info(&self) -> Option<&Info> { match self { - GitInfo::Present(info) => info.as_ref(), GitInfo::Absent => None, + GitInfo::Present(info) => info.as_ref(), + GitInfo::RecordedForTarball(info) => Some(info), } } @@ -96,10 +105,53 @@ impl GitInfo { version } - pub fn is_git(&self) -> bool { + /// Returns whether this directory has a `.git` directory which should be managed by bootstrap. + pub fn is_managed_git_subrepository(&self) -> bool { match self { - GitInfo::Absent => false, + GitInfo::Absent | GitInfo::RecordedForTarball(_) => false, GitInfo::Present(_) => true, } } + + /// Returns whether this is being built from a tarball. + pub fn is_from_tarball(&self) -> bool { + match self { + GitInfo::Absent | GitInfo::Present(_) => false, + GitInfo::RecordedForTarball(_) => true, + } + } +} + +/// Read the commit information from the `git-commit-info` file given the +/// project root. +pub fn read_commit_info_file(root: &Path) -> Option<Info> { + if let Ok(contents) = fs::read_to_string(root.join("git-commit-info")) { + let mut lines = contents.lines(); + let sha = lines.next(); + let short_sha = lines.next(); + let commit_date = lines.next(); + let info = match (commit_date, sha, short_sha) { + (Some(commit_date), Some(sha), Some(short_sha)) => Info { + commit_date: commit_date.to_owned(), + sha: sha.to_owned(), + short_sha: short_sha.to_owned(), + }, + _ => panic!("the `git-comit-info` file is malformed"), + }; + Some(info) + } else { + None + } +} + +/// Write the commit information to the `git-commit-info` file given the project +/// root. +pub fn write_commit_info_file(root: &Path, info: &Info) { + let commit_info = format!("{}\n{}\n{}\n", info.sha, info.short_sha, info.commit_date); + t!(fs::write(root.join("git-commit-info"), &commit_info)); +} + +/// Write the commit hash to the `git-commit-hash` file given the project root. +pub fn write_commit_hash_file(root: &Path, sha: &str) { + t!(fs::write(root.join("git-commit-hash"), sha)); } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index c13e83f6c86..58cf3edc317 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -299,9 +299,7 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car // Determine if we're going to compile in optimized C intrinsics to // the `compiler-builtins` crate. These intrinsics live in LLVM's - // `compiler-rt` repository, but our `src/llvm-project` submodule isn't - // always checked out, so we need to conditionally look for this. (e.g. if - // an external LLVM is used we skip the LLVM submodule checkout). + // `compiler-rt` repository. // // Note that this shouldn't affect the correctness of `compiler-builtins`, // but only its speed. Some intrinsics in C haven't been translated to Rust @@ -312,8 +310,15 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car // If `compiler-rt` is available ensure that the `c` feature of the // `compiler-builtins` crate is enabled and it's configured to learn where // `compiler-rt` is located. - let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt"); - let compiler_builtins_c_feature = if compiler_builtins_root.exists() { + let compiler_builtins_c_feature = if builder.config.optimized_compiler_builtins { + if !builder.is_rust_llvm(target) { + panic!( + "need a managed LLVM submodule for optimized intrinsics support; unset `llvm-config` or `optimized-compiler-builtins`" + ); + } + + builder.update_submodule(&Path::new("src").join("llvm-project")); + let compiler_builtins_root = builder.src.join("src/llvm-project/compiler-rt"); // Note that `libprofiler_builtins/build.rs` also computes this so if // you're changing something here please also change that. cargo.env("RUST_COMPILER_RT_ROOT", &compiler_builtins_root); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 74530dec97b..8c501f637d9 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -73,6 +73,8 @@ pub struct Config { pub color: Color, pub patch_binaries_for_nix: bool, pub stage0_metadata: Stage0Metadata, + /// Whether to use the `c` feature of the `compiler_builtins` crate. + pub optimized_compiler_builtins: bool, pub on_fail: Option<String>, pub stage: u32, @@ -597,6 +599,7 @@ define_config! { bench_stage: Option<u32> = "bench-stage", patch_binaries_for_nix: Option<bool> = "patch-binaries-for-nix", metrics: Option<bool> = "metrics", + optimized_compiler_builtins: Option<bool> = "optimized-compiler-builtins", } } @@ -966,6 +969,7 @@ impl Config { set(&mut config.print_step_timings, build.print_step_timings); set(&mut config.print_step_rusage, build.print_step_rusage); set(&mut config.patch_binaries_for_nix, build.patch_binaries_for_nix); + set(&mut config.optimized_compiler_builtins, build.optimized_compiler_builtins); config.verbose = cmp::max(config.verbose, flags.verbose); @@ -1330,11 +1334,22 @@ impl Config { git } - pub(crate) fn artifact_channel(&self, commit: &str) -> String { - let mut channel = self.git(); - channel.arg("show").arg(format!("{}:src/ci/channel", commit)); - let channel = output(&mut channel); - channel.trim().to_owned() + pub(crate) fn artifact_channel(&self, builder: &Builder<'_>, commit: &str) -> String { + if builder.rust_info.is_managed_git_subrepository() { + let mut channel = self.git(); + channel.arg("show").arg(format!("{}:src/ci/channel", commit)); + let channel = output(&mut channel); + channel.trim().to_owned() + } else if let Ok(channel) = fs::read_to_string(builder.src.join("src/ci/channel")) { + channel.trim().to_owned() + } else { + let src = builder.src.display(); + eprintln!("error: failed to determine artifact channel"); + eprintln!( + "help: either use git or ensure that {src}/src/ci/channel contains the name of the channel to use" + ); + panic!(); + } } /// Try to find the relative path of `bindir`, otherwise return it in full. @@ -1471,7 +1486,7 @@ impl Config { } pub fn submodules(&self, rust_info: &GitInfo) -> bool { - self.submodules.unwrap_or(rust_info.is_git()) + self.submodules.unwrap_or(rust_info.is_managed_git_subrepository()) } } @@ -1576,7 +1591,7 @@ fn maybe_download_rustfmt(builder: &Builder<'_>) -> Option<PathBuf> { fn download_ci_rustc(builder: &Builder<'_>, commit: &str) { builder.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})")); - let channel = builder.config.artifact_channel(commit); + let channel = builder.config.artifact_channel(builder, commit); let host = builder.config.build.triple; let bin_root = builder.out.join(host).join("ci-rustc"); let rustc_stamp = bin_root.join(".rustc-stamp"); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index f387496883b..7eb8f8bbb30 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -16,6 +16,7 @@ use std::process::Command; use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; +use crate::channel; use crate::compile; use crate::config::TargetSelection; use crate::tarball::{GeneratedTarball, OverlayKind, Tarball}; @@ -918,12 +919,13 @@ impl Step for PlainSourceTarball { // Create the version file builder.create(&plain_dst_src.join("version"), &builder.rust_version()); - if let Some(sha) = builder.rust_sha() { - builder.create(&plain_dst_src.join("git-commit-hash"), &sha); + if let Some(info) = builder.rust_info.info() { + channel::write_commit_hash_file(&plain_dst_src, &info.sha); + channel::write_commit_info_file(&plain_dst_src, info); } // If we're building from git sources, we need to vendor a complete distribution. - if builder.rust_info.is_git() { + if builder.rust_info.is_managed_git_subrepository() { // Ensure we have the submodules checked out. builder.update_submodule(Path::new("src/tools/rust-analyzer")); @@ -1365,6 +1367,7 @@ impl Step for Extended { } add_component!("rust-docs" => Docs { host: target }); + add_component!("rust-json-docs" => JsonDocs { host: target }); add_component!("rust-demangler"=> RustDemangler { compiler, target }); add_component!("cargo" => Cargo { compiler, target }); add_component!("rustfmt" => Rustfmt { compiler, target }); @@ -1844,23 +1847,21 @@ fn add_env(builder: &Builder<'_>, cmd: &mut Command, target: TargetSelection) { /// /// Returns whether the files were actually copied. fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir: &Path) -> bool { - if let Some(config) = builder.config.target_config.get(&target) { - if config.llvm_config.is_some() && !builder.config.llvm_from_ci { - // If the LLVM was externally provided, then we don't currently copy - // artifacts into the sysroot. This is not necessarily the right - // choice (in particular, it will require the LLVM dylib to be in - // the linker's load path at runtime), but the common use case for - // external LLVMs is distribution provided LLVMs, and in that case - // they're usually in the standard search path (e.g., /usr/lib) and - // copying them here is going to cause problems as we may end up - // with the wrong files and isn't what distributions want. - // - // This behavior may be revisited in the future though. - // - // If the LLVM is coming from ourselves (just from CI) though, we - // still want to install it, as it otherwise won't be available. - return false; - } + if !builder.is_rust_llvm(target) { + // If the LLVM was externally provided, then we don't currently copy + // artifacts into the sysroot. This is not necessarily the right + // choice (in particular, it will require the LLVM dylib to be in + // the linker's load path at runtime), but the common use case for + // external LLVMs is distribution provided LLVMs, and in that case + // they're usually in the standard search path (e.g., /usr/lib) and + // copying them here is going to cause problems as we may end up + // with the wrong files and isn't what distributions want. + // + // This behavior may be revisited in the future though. + // + // If the LLVM is coming from ourselves (just from CI) though, we + // still want to install it, as it otherwise won't be available. + return false; } // On macOS, rustc (and LLVM tools) link to an unversioned libLLVM.dylib diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index c83490316b6..9ada3f315c1 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -229,6 +229,8 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)] // FIXME: Used by proc-macro2, but we should not be triggering on external dependencies. (Some(Mode::Rustc), "span_locations", None), (Some(Mode::ToolRustc), "span_locations", None), + // Can be passed in RUSTFLAGS to prevent direct syscalls in rustix. + (None, "rustix_use_libc", None), ]; /// A structure representing a Rust compiler. @@ -398,7 +400,7 @@ impl Build { /// line and the filesystem `config`. /// /// By default all build output will be placed in the current directory. - pub fn new(config: Config) -> Build { + pub fn new(mut config: Config) -> Build { let src = config.src.clone(); let out = config.out.clone(); @@ -472,6 +474,10 @@ impl Build { ) } + if rust_info.is_from_tarball() && config.description.is_none() { + config.description = Some("built from a source tarball".to_owned()); + } + let mut build = Build { initial_rustc: config.initial_rustc.clone(), initial_cargo: config.initial_cargo.clone(), @@ -571,7 +577,9 @@ impl Build { // NOTE: The check for the empty directory is here because when running x.py the first time, // the submodule won't be checked out. Check it out now so we can build it. - if !channel::GitInfo::new(false, &absolute_path).is_git() && !dir_is_empty(&absolute_path) { + if !channel::GitInfo::new(false, &absolute_path).is_managed_git_subrepository() + && !dir_is_empty(&absolute_path) + { return; } @@ -642,7 +650,7 @@ impl Build { // Sample output: `submodule.src/rust-installer.path src/tools/rust-installer` let submodule = Path::new(line.splitn(2, ' ').nth(1).unwrap()); // Don't update the submodule unless it's already been cloned. - if channel::GitInfo::new(false, submodule).is_git() { + if channel::GitInfo::new(false, submodule).is_managed_git_subrepository() { self.update_submodule(submodule); } } @@ -668,6 +676,9 @@ impl Build { return setup::setup(&self.config, *profile); } + // Download rustfmt early so that it can be used in rust-analyzer configs. + let _ = &builder::Builder::new(&self).initial_rustfmt(); + { let builder = builder::Builder::new(&self); if let Some(path) = builder.paths.get(0) { @@ -1255,7 +1266,7 @@ impl Build { match &self.config.channel[..] { "stable" => num.to_string(), "beta" => { - if self.rust_info.is_git() && !self.config.ignore_git { + if self.rust_info.is_managed_git_subrepository() && !self.config.ignore_git { format!("{}-beta.{}", num, self.beta_prerelease_version()) } else { format!("{}-beta", num) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index d6ee6d489cf..9045354d0b2 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -17,6 +17,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; +use crate::channel; use crate::config::TargetSelection; use crate::util::get_clang_cl_resource_dir; use crate::util::{self, exe, output, program_out_of_date, t, up_to_date}; @@ -115,24 +116,29 @@ pub fn prebuilt_llvm_config( } /// This retrieves the LLVM sha we *want* to use, according to git history. -pub(crate) fn detect_llvm_sha(config: &crate::config::Config) -> String { - let mut rev_list = config.git(); - rev_list.args(&[ - PathBuf::from("rev-list"), - format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(), - "-n1".into(), - "--first-parent".into(), - "HEAD".into(), - "--".into(), - config.src.join("src/llvm-project"), - config.src.join("src/bootstrap/download-ci-llvm-stamp"), - // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly` - config.src.join("src/version"), - ]); - let llvm_sha = output(&mut rev_list); - let llvm_sha = llvm_sha.trim(); - - if llvm_sha == "" { +pub(crate) fn detect_llvm_sha(config: &crate::config::Config, is_git: bool) -> String { + let llvm_sha = if is_git { + let mut rev_list = config.git(); + rev_list.args(&[ + PathBuf::from("rev-list"), + format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(), + "-n1".into(), + "--first-parent".into(), + "HEAD".into(), + "--".into(), + config.src.join("src/llvm-project"), + config.src.join("src/bootstrap/download-ci-llvm-stamp"), + // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly` + config.src.join("src/version"), + ]); + output(&mut rev_list).trim().to_owned() + } else if let Some(info) = channel::read_commit_info_file(&config.src) { + info.sha.trim().to_owned() + } else { + "".to_owned() + }; + + if &llvm_sha == "" { eprintln!("error: could not find commit hash for downloading LLVM"); eprintln!("help: maybe your repository history is too shallow?"); eprintln!("help: consider disabling `download-ci-llvm`"); @@ -140,7 +146,7 @@ pub(crate) fn detect_llvm_sha(config: &crate::config::Config) -> String { panic!(); } - llvm_sha.to_owned() + llvm_sha } /// Returns whether the CI-found LLVM is currently usable. @@ -194,7 +200,9 @@ pub(crate) fn is_ci_llvm_available(config: &crate::config::Config, asserts: bool } if crate::util::CiEnv::is_ci() { - let llvm_sha = detect_llvm_sha(config); + // We assume we have access to git, so it's okay to unconditionally pass + // `true` here. + let llvm_sha = detect_llvm_sha(config, true); let head_sha = output(config.git().arg("rev-parse").arg("HEAD")); let head_sha = head_sha.trim(); if llvm_sha == head_sha { @@ -215,7 +223,7 @@ pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) { } let llvm_root = config.ci_llvm_root(); let llvm_stamp = llvm_root.join(".llvm-stamp"); - let llvm_sha = detect_llvm_sha(&config); + let llvm_sha = detect_llvm_sha(&config, builder.rust_info.is_managed_git_subrepository()); let key = format!("{}{}", llvm_sha, config.llvm_assertions); if program_out_of_date(&llvm_stamp, &key) && !config.dry_run { download_ci_llvm(builder, &llvm_sha); @@ -260,7 +268,7 @@ fn download_ci_llvm(builder: &Builder<'_>, llvm_sha: &str) { } else { &builder.config.stage0_metadata.config.artifacts_server }; - let channel = builder.config.artifact_channel(llvm_sha); + let channel = builder.config.artifact_channel(builder, llvm_sha); let filename = format!("rust-dev-{}-{}.tar.xz", channel, builder.build.build.triple); let tarball = rustc_cache.join(&filename); if !tarball.exists() { diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index cae41286f08..e905517253c 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -74,7 +74,7 @@ pub fn check(build: &mut Build) { let mut cmd_finder = Finder::new(); // If we've got a git directory we're gonna need git to update // submodules and learn about various other aspects. - if build.rust_info.is_git() { + if build.rust_info.is_managed_git_subrepository() { cmd_finder.must_have("git"); } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index e30067a5cbe..d999b6c1503 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -4,6 +4,7 @@ use std::{ }; use crate::builder::Builder; +use crate::channel; use crate::util::t; #[derive(Copy, Clone)] @@ -297,8 +298,9 @@ impl<'a> Tarball<'a> { fn run(self, build_cli: impl FnOnce(&Tarball<'a>, &mut Command)) -> GeneratedTarball { t!(std::fs::create_dir_all(&self.overlay_dir)); self.builder.create(&self.overlay_dir.join("version"), &self.overlay.version(self.builder)); - if let Some(sha) = self.builder.rust_sha() { - self.builder.create(&self.overlay_dir.join("git-commit-hash"), &sha); + if let Some(info) = self.builder.rust_info.info() { + channel::write_commit_hash_file(&self.overlay_dir, &info.sha); + channel::write_commit_info_file(&self.overlay_dir, info); } for file in self.overlay.legal_and_readme() { self.builder.install(&self.builder.src.join(file), &self.overlay_dir, 0o644); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index ff6f7909a5a..d6e7f787270 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -870,10 +870,10 @@ tool_extended!((self, builder), Clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {}; Miri, "src/tools/miri", "miri", stable=false, in_tree=true, {}; CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, in_tree=true, {}; - Rls, "src/tools/rls", "rls", stable=true, {}; // FIXME: tool_std is not quite right, we shouldn't allow nightly features. // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0, // and this is close enough for now. + Rls, "src/tools/rls", "rls", stable=true, in_tree=true, tool_std=true, {}; RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {}; Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {}; ); diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index b71a348abd9..64faaf4f19b 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -230,6 +230,22 @@ For targets: `aarch64-unknown-linux-gnu` - C compiler > gcc version = 8.3.0 - C compiler > C++ = ENABLE -- to cross compile LLVM +### `i586-linux-gnu.config` + +For targets: `i586-unknown-linux-gnu` + +- Path and misc options > Prefix directory = /x-tools/${CT\_TARGET} +- Path and misc options > Patches origin = Bundled only +- Target options > Target Architecture = x86 +- Target options > Architecture level = i586 +- Target options > Target CFLAGS = -Wa,-mrelax-relocations=no +- Operating System > Target OS = linux +- Operating System > Linux kernel version = 3.2.101 +- Binary utilities > Version of binutils = 2.32 +- C-library > glibc version = 2.17.0 +- C compiler > gcc version = 8.3.0 +- C compiler > C++ = ENABLE + ### `powerpc-linux-gnu.config` For targets: `powerpc-unknown-linux-gnu` diff --git a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile index 5ddd3f18039..637b5fa22f9 100644 --- a/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile +++ b/src/ci/docker/host-x86_64/disabled/dist-x86_64-haiku/Dockerfile @@ -47,4 +47,6 @@ ENV RUST_CONFIGURE_ARGS --disable-jemalloc \ --set=$TARGET.cc=x86_64-unknown-haiku-gcc \ --set=$TARGET.cxx=x86_64-unknown-haiku-g++ \ --set=$TARGET.llvm-config=/bin/llvm-config-haiku +ENV EXTERNAL_LLVM 1 + ENV SCRIPT python3 ../x.py dist --host=$HOST --target=$HOST diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile index b0d65428ec6..26eb69f2eae 100644 --- a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/Dockerfile @@ -1,5 +1,6 @@ -FROM ubuntu:16.04 +FROM ubuntu:22.04 +ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ g++-multilib \ make \ @@ -17,6 +18,25 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libssl-dev \ pkg-config +COPY scripts/cross-apt-packages.sh /scripts/ +RUN sh /scripts/cross-apt-packages.sh + +COPY scripts/crosstool-ng-1.24.sh /scripts/ +RUN sh /scripts/crosstool-ng-1.24.sh + +COPY scripts/rustbuild-setup.sh /scripts/ +RUN sh /scripts/rustbuild-setup.sh +WORKDIR /tmp + +COPY host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config \ + host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh \ + /tmp/ +RUN su rustbuild -c ./build-i586-gnu-toolchain.sh +ENV PATH=$PATH:/x-tools/i586-unknown-linux-gnu/bin +ENV \ + CC_i586_unknown_linux_gnu=i586-unknown-linux-gnu-gcc \ + AR_i586_unknown_linux_gnu=i586-unknown-linux-gnu-ar + WORKDIR /build/ COPY scripts/musl.sh /build/ RUN CC=gcc CFLAGS="-m32 -Wa,-mrelax-relocations=no" \ @@ -27,17 +47,20 @@ RUN CC=gcc CFLAGS="-m32 -Wa,-mrelax-relocations=no" \ bash musl.sh i586 --target=i586 && \ rm -rf /build +# FIXME: musl really shouldn't be linking libgcc_s.so, as it's linked to glibc, +# but it's required by src/test/ui/proc-macro/crt-static.rs. Ubuntu:16.04 gcc-5 +# had libgcc_s.so as a symlink to the absolute libgcc_s.so.1, but now it's an +# ld-script that expects to find libgcc_s.so.1 in the library search path. +# See also https://github.com/rust-lang/rust/issues/82521 +RUN ln -s /usr/lib32/libgcc_s.so.1 /musl-i686/lib/ + COPY scripts/sccache.sh /scripts/ RUN sh /scripts/sccache.sh -COPY scripts/cmake.sh /scripts/ -RUN /scripts/cmake.sh - ENV RUST_CONFIGURE_ARGS \ --musl-root-i586=/musl-i586 \ --musl-root-i686=/musl-i686 \ - --disable-docs \ - --set llvm.allow-old-toolchain + --disable-docs # Newer binutils broke things on some vms/distros (i.e., linking against # unknown relocs disabled by the following flag), so we need to go out of our diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh new file mode 100755 index 00000000000..ceab60cfb45 --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/build-i586-gnu-toolchain.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -ex + +hide_output() { + set +x + on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + PING_LOOP_PID=$! + "$@" &> /tmp/build.log + rm /tmp/build.log + trap - ERR + kill $PING_LOOP_PID + set -x +} + +mkdir build +cd build +cp ../i586-linux-gnu.config .config +hide_output ct-ng build +cd .. +rm -rf build diff --git a/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config new file mode 100644 index 00000000000..ef2e9467f4a --- /dev/null +++ b/src/ci/docker/host-x86_64/dist-i586-gnu-i586-i686-musl/i586-linux-gnu.config @@ -0,0 +1,726 @@ +# +# Automatically generated file; DO NOT EDIT. +# crosstool-NG Configuration +# +CT_CONFIGURE_has_static_link=y +CT_CONFIGURE_has_cxx11=y +CT_CONFIGURE_has_wget=y +CT_CONFIGURE_has_curl=y +CT_CONFIGURE_has_make_3_81_or_newer=y +CT_CONFIGURE_has_make_4_0_or_newer=y +CT_CONFIGURE_has_libtool_2_4_or_newer=y +CT_CONFIGURE_has_libtoolize_2_4_or_newer=y +CT_CONFIGURE_has_autoconf_2_65_or_newer=y +CT_CONFIGURE_has_autoreconf_2_65_or_newer=y +CT_CONFIGURE_has_automake_1_15_or_newer=y +CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y +CT_CONFIGURE_has_python_3_4_or_newer=y +CT_CONFIGURE_has_bison_2_7_or_newer=y +CT_CONFIGURE_has_python=y +CT_CONFIGURE_has_git=y +CT_CONFIGURE_has_md5sum=y +CT_CONFIGURE_has_sha1sum=y +CT_CONFIGURE_has_sha256sum=y +CT_CONFIGURE_has_sha512sum=y +CT_CONFIGURE_has_install_with_strip_program=y +CT_CONFIG_VERSION_CURRENT="3" +CT_CONFIG_VERSION="3" +CT_MODULES=y + +# +# Paths and misc options +# + +# +# crosstool-NG behavior +# +# CT_OBSOLETE is not set +# CT_EXPERIMENTAL is not set +# CT_DEBUG_CT is not set + +# +# Paths +# +CT_LOCAL_TARBALLS_DIR="${HOME}/src" +CT_SAVE_TARBALLS=y +# CT_TARBALLS_BUILDROOT_LAYOUT is not set +CT_WORK_DIR="${CT_TOP_DIR}/.build" +CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_RM_RF_PREFIX_DIR=y +CT_REMOVE_DOCS=y +CT_INSTALL_LICENSES=y +CT_PREFIX_DIR_RO=y +CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y +# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set + +# +# Downloading +# +CT_DOWNLOAD_AGENT_WGET=y +# CT_DOWNLOAD_AGENT_CURL is not set +# CT_DOWNLOAD_AGENT_NONE is not set +# CT_FORBID_DOWNLOAD is not set +# CT_FORCE_DOWNLOAD is not set +CT_CONNECT_TIMEOUT=10 +CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" +# CT_ONLY_DOWNLOAD is not set +CT_USE_MIRROR=y +# CT_FORCE_MIRROR is not set +CT_MIRROR_BASE_URL="https://ci-mirrors.rust-lang.org/rustc" +CT_VERIFY_DOWNLOAD_DIGEST=y +CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y +# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set +# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set +# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set +CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" +# CT_VERIFY_DOWNLOAD_SIGNATURE is not set + +# +# Extracting +# +# CT_FORCE_EXTRACT is not set +CT_OVERRIDE_CONFIG_GUESS_SUB=y +# CT_ONLY_EXTRACT is not set +CT_PATCH_BUNDLED=y +# CT_PATCH_BUNDLED_LOCAL is not set +CT_PATCH_ORDER="bundled" + +# +# Build behavior +# +CT_PARALLEL_JOBS=0 +CT_LOAD="" +CT_USE_PIPES=y +CT_EXTRA_CFLAGS_FOR_BUILD="" +CT_EXTRA_LDFLAGS_FOR_BUILD="" +CT_EXTRA_CFLAGS_FOR_HOST="" +CT_EXTRA_LDFLAGS_FOR_HOST="" +# CT_CONFIG_SHELL_SH is not set +# CT_CONFIG_SHELL_ASH is not set +CT_CONFIG_SHELL_BASH=y +# CT_CONFIG_SHELL_CUSTOM is not set +CT_CONFIG_SHELL="${bash}" + +# +# Logging +# +# CT_LOG_ERROR is not set +# CT_LOG_WARN is not set +# CT_LOG_INFO is not set +CT_LOG_EXTRA=y +# CT_LOG_ALL is not set +# CT_LOG_DEBUG is not set +CT_LOG_LEVEL_MAX="EXTRA" +# CT_LOG_SEE_TOOLS_WARN is not set +CT_LOG_PROGRESS_BAR=y +CT_LOG_TO_FILE=y +CT_LOG_FILE_COMPRESS=y + +# +# Target options +# +# CT_ARCH_ALPHA is not set +# CT_ARCH_ARC is not set +# CT_ARCH_ARM is not set +# CT_ARCH_AVR is not set +# CT_ARCH_M68K is not set +# CT_ARCH_MIPS is not set +# CT_ARCH_NIOS2 is not set +# CT_ARCH_POWERPC is not set +# CT_ARCH_S390 is not set +# CT_ARCH_SH is not set +# CT_ARCH_SPARC is not set +CT_ARCH_X86=y +# CT_ARCH_XTENSA is not set +CT_ARCH="x86" +CT_ARCH_CHOICE_KSYM="X86" +CT_ARCH_CPU="" +CT_ARCH_TUNE="" +CT_ARCH_X86_SHOW=y + +# +# Options for x86 +# +CT_ARCH_X86_PKG_KSYM="" +CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" +CT_ARCH_SUFFIX="" +# CT_OMIT_TARGET_VENDOR is not set + +# +# Generic target options +# +# CT_MULTILIB is not set +CT_DEMULTILIB=y +CT_ARCH_USE_MMU=y +CT_ARCH_SUPPORTS_32=y +CT_ARCH_SUPPORTS_64=y +CT_ARCH_DEFAULT_32=y +CT_ARCH_BITNESS=32 +CT_ARCH_32=y +# CT_ARCH_64 is not set + +# +# Target optimisations +# +CT_ARCH_SUPPORTS_WITH_ARCH=y +CT_ARCH_SUPPORTS_WITH_CPU=y +CT_ARCH_SUPPORTS_WITH_TUNE=y +CT_ARCH_ARCH="i586" +CT_TARGET_CFLAGS="-Wa,-mrelax-relocations=no" +CT_TARGET_LDFLAGS="" + +# +# Toolchain options +# + +# +# General toolchain options +# +CT_FORCE_SYSROOT=y +CT_USE_SYSROOT=y +CT_SYSROOT_NAME="sysroot" +CT_SYSROOT_DIR_PREFIX="" +CT_WANTS_STATIC_LINK=y +CT_WANTS_STATIC_LINK_CXX=y +# CT_STATIC_TOOLCHAIN is not set +CT_SHOW_CT_VERSION=y +CT_TOOLCHAIN_PKGVERSION="" +CT_TOOLCHAIN_BUGURL="" + +# +# Tuple completion and aliasing +# +CT_TARGET_VENDOR="unknown" +CT_TARGET_ALIAS_SED_EXPR="" +CT_TARGET_ALIAS="" + +# +# Toolchain type +# +CT_CROSS=y +# CT_CANADIAN is not set +CT_TOOLCHAIN_TYPE="cross" + +# +# Build system +# +CT_BUILD="" +CT_BUILD_PREFIX="" +CT_BUILD_SUFFIX="" + +# +# Misc options +# +# CT_TOOLCHAIN_ENABLE_NLS is not set + +# +# Operating System +# +CT_KERNEL_SUPPORTS_SHARED_LIBS=y +# CT_KERNEL_BARE_METAL is not set +CT_KERNEL_LINUX=y +CT_KERNEL="linux" +CT_KERNEL_CHOICE_KSYM="LINUX" +CT_KERNEL_LINUX_SHOW=y + +# +# Options for linux +# +CT_KERNEL_LINUX_PKG_KSYM="LINUX" +CT_LINUX_DIR_NAME="linux" +CT_LINUX_PKG_NAME="linux" +CT_LINUX_SRC_RELEASE=y +CT_LINUX_PATCH_ORDER="global" +# CT_LINUX_V_4_20 is not set +# CT_LINUX_V_4_19 is not set +# CT_LINUX_V_4_18 is not set +# CT_LINUX_V_4_17 is not set +# CT_LINUX_V_4_16 is not set +# CT_LINUX_V_4_15 is not set +# CT_LINUX_V_4_14 is not set +# CT_LINUX_V_4_13 is not set +# CT_LINUX_V_4_12 is not set +# CT_LINUX_V_4_11 is not set +# CT_LINUX_V_4_10 is not set +# CT_LINUX_V_4_9 is not set +# CT_LINUX_V_4_4 is not set +# CT_LINUX_V_4_1 is not set +# CT_LINUX_V_3_16 is not set +# CT_LINUX_V_3_13 is not set +# CT_LINUX_V_3_12 is not set +# CT_LINUX_V_3_10 is not set +# CT_LINUX_V_3_4 is not set +CT_LINUX_V_3_2=y +# CT_LINUX_V_2_6_32 is not set +# CT_LINUX_NO_VERSIONS is not set +CT_LINUX_VERSION="3.2.101" +CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" +CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" +CT_LINUX_4_8_or_older=y +CT_LINUX_older_than_4_8=y +CT_LINUX_3_7_or_older=y +CT_LINUX_older_than_3_7=y +CT_LINUX_later_than_3_2=y +CT_LINUX_3_2_or_later=y +CT_KERNEL_LINUX_VERBOSITY_0=y +# CT_KERNEL_LINUX_VERBOSITY_1 is not set +# CT_KERNEL_LINUX_VERBOSITY_2 is not set +CT_KERNEL_LINUX_VERBOSE_LEVEL=0 +CT_KERNEL_LINUX_INSTALL_CHECK=y +CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" + +# +# Common kernel options +# +CT_SHARED_LIBS=y + +# +# Binary utilities +# +CT_ARCH_BINFMT_ELF=y +CT_BINUTILS_BINUTILS=y +CT_BINUTILS="binutils" +CT_BINUTILS_CHOICE_KSYM="BINUTILS" +CT_BINUTILS_BINUTILS_SHOW=y + +# +# Options for binutils +# +CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" +CT_BINUTILS_DIR_NAME="binutils" +CT_BINUTILS_USE_GNU=y +CT_BINUTILS_USE="BINUTILS" +CT_BINUTILS_PKG_NAME="binutils" +CT_BINUTILS_SRC_RELEASE=y +CT_BINUTILS_PATCH_ORDER="global" +CT_BINUTILS_V_2_32=y +# CT_BINUTILS_V_2_31 is not set +# CT_BINUTILS_V_2_30 is not set +# CT_BINUTILS_V_2_29 is not set +# CT_BINUTILS_V_2_28 is not set +# CT_BINUTILS_V_2_27 is not set +# CT_BINUTILS_V_2_26 is not set +# CT_BINUTILS_NO_VERSIONS is not set +CT_BINUTILS_VERSION="2.32" +CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" +CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" +CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" +CT_BINUTILS_later_than_2_30=y +CT_BINUTILS_2_30_or_later=y +CT_BINUTILS_later_than_2_27=y +CT_BINUTILS_2_27_or_later=y +CT_BINUTILS_later_than_2_25=y +CT_BINUTILS_2_25_or_later=y +CT_BINUTILS_later_than_2_23=y +CT_BINUTILS_2_23_or_later=y + +# +# GNU binutils +# +CT_BINUTILS_HAS_HASH_STYLE=y +CT_BINUTILS_HAS_GOLD=y +CT_BINUTILS_HAS_PLUGINS=y +CT_BINUTILS_HAS_PKGVERSION_BUGURL=y +CT_BINUTILS_GOLD_SUPPORTS_ARCH=y +CT_BINUTILS_GOLD_SUPPORT=y +CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y +CT_BINUTILS_LINKER_LD=y +# CT_BINUTILS_LINKER_LD_GOLD is not set +CT_BINUTILS_LINKERS_LIST="ld" +CT_BINUTILS_LINKER_DEFAULT="bfd" +# CT_BINUTILS_PLUGINS is not set +CT_BINUTILS_RELRO=m +CT_BINUTILS_EXTRA_CONFIG_ARRAY="" +# CT_BINUTILS_FOR_TARGET is not set +CT_ALL_BINUTILS_CHOICES="BINUTILS" + +# +# C-library +# +CT_LIBC_GLIBC=y +# CT_LIBC_UCLIBC is not set +CT_LIBC="glibc" +CT_LIBC_CHOICE_KSYM="GLIBC" +CT_THREADS="nptl" +CT_LIBC_GLIBC_SHOW=y + +# +# Options for glibc +# +CT_LIBC_GLIBC_PKG_KSYM="GLIBC" +CT_GLIBC_DIR_NAME="glibc" +CT_GLIBC_USE_GNU=y +CT_GLIBC_USE="GLIBC" +CT_GLIBC_PKG_NAME="glibc" +CT_GLIBC_SRC_RELEASE=y +CT_GLIBC_PATCH_ORDER="global" +# CT_GLIBC_V_2_29 is not set +# CT_GLIBC_V_2_28 is not set +# CT_GLIBC_V_2_27 is not set +# CT_GLIBC_V_2_26 is not set +# CT_GLIBC_V_2_25 is not set +# CT_GLIBC_V_2_24 is not set +# CT_GLIBC_V_2_23 is not set +# CT_GLIBC_V_2_19 is not set +CT_GLIBC_V_2_17=y +# CT_GLIBC_V_2_12_1 is not set +# CT_GLIBC_NO_VERSIONS is not set +CT_GLIBC_VERSION="2.17" +CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" +CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" +CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" +CT_GLIBC_2_29_or_older=y +CT_GLIBC_older_than_2_29=y +CT_GLIBC_2_27_or_older=y +CT_GLIBC_older_than_2_27=y +CT_GLIBC_2_26_or_older=y +CT_GLIBC_older_than_2_26=y +CT_GLIBC_2_25_or_older=y +CT_GLIBC_older_than_2_25=y +CT_GLIBC_2_24_or_older=y +CT_GLIBC_older_than_2_24=y +CT_GLIBC_2_23_or_older=y +CT_GLIBC_older_than_2_23=y +CT_GLIBC_2_20_or_older=y +CT_GLIBC_older_than_2_20=y +CT_GLIBC_2_17_or_later=y +CT_GLIBC_2_17_or_older=y +CT_GLIBC_later_than_2_14=y +CT_GLIBC_2_14_or_later=y +CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y +CT_GLIBC_DEP_BINUTILS=y +CT_GLIBC_DEP_GCC=y +CT_GLIBC_DEP_PYTHON=y +CT_GLIBC_HAS_NPTL_ADDON=y +CT_GLIBC_HAS_PORTS_ADDON=y +CT_GLIBC_HAS_LIBIDN_ADDON=y +CT_GLIBC_USE_NPTL_ADDON=y +# CT_GLIBC_USE_LIBIDN_ADDON is not set +CT_GLIBC_HAS_OBSOLETE_RPC=y +CT_GLIBC_EXTRA_CONFIG_ARRAY="" +CT_GLIBC_CONFIGPARMS="" +CT_GLIBC_EXTRA_CFLAGS="" +CT_GLIBC_ENABLE_OBSOLETE_RPC=y +# CT_GLIBC_DISABLE_VERSIONING is not set +CT_GLIBC_OLDEST_ABI="" +CT_GLIBC_FORCE_UNWIND=y +# CT_GLIBC_LOCALES is not set +# CT_GLIBC_KERNEL_VERSION_NONE is not set +CT_GLIBC_KERNEL_VERSION_AS_HEADERS=y +# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set +CT_GLIBC_MIN_KERNEL="3.2.101" +CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" +CT_LIBC_SUPPORT_THREADS_ANY=y +CT_LIBC_SUPPORT_THREADS_NATIVE=y + +# +# Common C library options +# +CT_THREADS_NATIVE=y +# CT_CREATE_LDSO_CONF is not set +CT_LIBC_XLDD=y + +# +# C compiler +# +CT_CC_CORE_PASSES_NEEDED=y +CT_CC_CORE_PASS_1_NEEDED=y +CT_CC_CORE_PASS_2_NEEDED=y +CT_CC_SUPPORT_CXX=y +CT_CC_SUPPORT_FORTRAN=y +CT_CC_SUPPORT_ADA=y +CT_CC_SUPPORT_OBJC=y +CT_CC_SUPPORT_OBJCXX=y +CT_CC_SUPPORT_GOLANG=y +CT_CC_GCC=y +CT_CC="gcc" +CT_CC_CHOICE_KSYM="GCC" +CT_CC_GCC_SHOW=y + +# +# Options for gcc +# +CT_CC_GCC_PKG_KSYM="GCC" +CT_GCC_DIR_NAME="gcc" +CT_GCC_USE_GNU=y +CT_GCC_USE="GCC" +CT_GCC_PKG_NAME="gcc" +CT_GCC_SRC_RELEASE=y +CT_GCC_PATCH_ORDER="global" +CT_GCC_V_8=y +# CT_GCC_V_7 is not set +# CT_GCC_V_6 is not set +# CT_GCC_V_5 is not set +# CT_GCC_V_4_9 is not set +# CT_GCC_NO_VERSIONS is not set +CT_GCC_VERSION="8.3.0" +CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" +CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_GCC_SIGNATURE_FORMAT="" +CT_GCC_later_than_7=y +CT_GCC_7_or_later=y +CT_GCC_later_than_6=y +CT_GCC_6_or_later=y +CT_GCC_later_than_5=y +CT_GCC_5_or_later=y +CT_GCC_later_than_4_9=y +CT_GCC_4_9_or_later=y +CT_GCC_later_than_4_8=y +CT_GCC_4_8_or_later=y +CT_CC_GCC_HAS_LIBMPX=y +CT_CC_GCC_ENABLE_CXX_FLAGS="" +CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" +CT_CC_GCC_EXTRA_CONFIG_ARRAY="" +CT_CC_GCC_STATIC_LIBSTDCXX=y +# CT_CC_GCC_SYSTEM_ZLIB is not set +CT_CC_GCC_CONFIG_TLS=m + +# +# Optimisation features +# +CT_CC_GCC_USE_GRAPHITE=y +CT_CC_GCC_USE_LTO=y + +# +# Settings for libraries running on target +# +CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y +# CT_CC_GCC_LIBMUDFLAP is not set +# CT_CC_GCC_LIBGOMP is not set +# CT_CC_GCC_LIBSSP is not set +# CT_CC_GCC_LIBQUADMATH is not set +# CT_CC_GCC_LIBSANITIZER is not set +CT_CC_GCC_LIBMPX=y + +# +# Misc. obscure options. +# +CT_CC_CXA_ATEXIT=y +# CT_CC_GCC_DISABLE_PCH is not set +CT_CC_GCC_SJLJ_EXCEPTIONS=m +CT_CC_GCC_LDBL_128=m +# CT_CC_GCC_BUILD_ID is not set +CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y +# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set +# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set +# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set +CT_CC_GCC_LNK_HASH_STYLE="" +CT_CC_GCC_DEC_FLOAT_AUTO=y +# CT_CC_GCC_DEC_FLOAT_BID is not set +# CT_CC_GCC_DEC_FLOAT_DPD is not set +# CT_CC_GCC_DEC_FLOATS_NO is not set +CT_ALL_CC_CHOICES="GCC" + +# +# Additional supported languages: +# +CT_CC_LANG_CXX=y +# CT_CC_LANG_FORTRAN is not set + +# +# Debug facilities +# +# CT_DEBUG_DUMA is not set +# CT_DEBUG_GDB is not set +# CT_DEBUG_LTRACE is not set +# CT_DEBUG_STRACE is not set +CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" + +# +# Companion libraries +# +# CT_COMPLIBS_CHECK is not set +# CT_COMP_LIBS_CLOOG is not set +# CT_COMP_LIBS_EXPAT is not set +CT_COMP_LIBS_GETTEXT=y +CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" +CT_GETTEXT_DIR_NAME="gettext" +CT_GETTEXT_PKG_NAME="gettext" +CT_GETTEXT_SRC_RELEASE=y +CT_GETTEXT_PATCH_ORDER="global" +CT_GETTEXT_V_0_19_8_1=y +# CT_GETTEXT_NO_VERSIONS is not set +CT_GETTEXT_VERSION="0.19.8.1" +CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" +CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" +CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" +CT_COMP_LIBS_GMP=y +CT_COMP_LIBS_GMP_PKG_KSYM="GMP" +CT_GMP_DIR_NAME="gmp" +CT_GMP_PKG_NAME="gmp" +CT_GMP_SRC_RELEASE=y +CT_GMP_PATCH_ORDER="global" +CT_GMP_V_6_1=y +# CT_GMP_NO_VERSIONS is not set +CT_GMP_VERSION="6.1.2" +CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" +CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" +CT_GMP_SIGNATURE_FORMAT="packed/.sig" +CT_GMP_later_than_5_1_0=y +CT_GMP_5_1_0_or_later=y +CT_GMP_later_than_5_0_0=y +CT_GMP_5_0_0_or_later=y +CT_GMP_REQUIRE_5_0_0_or_later=y +CT_COMP_LIBS_ISL=y +CT_COMP_LIBS_ISL_PKG_KSYM="ISL" +CT_ISL_DIR_NAME="isl" +CT_ISL_PKG_NAME="isl" +CT_ISL_SRC_RELEASE=y +CT_ISL_PATCH_ORDER="global" +CT_ISL_V_0_20=y +# CT_ISL_V_0_19 is not set +# CT_ISL_V_0_18 is not set +# CT_ISL_V_0_17 is not set +# CT_ISL_V_0_16 is not set +# CT_ISL_V_0_15 is not set +# CT_ISL_NO_VERSIONS is not set +CT_ISL_VERSION="0.20" +CT_ISL_MIRRORS="https://ci-mirrors.rust-lang.org/rustc" +CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" +CT_ISL_SIGNATURE_FORMAT="" +CT_ISL_later_than_0_18=y +CT_ISL_0_18_or_later=y +CT_ISL_later_than_0_15=y +CT_ISL_0_15_or_later=y +CT_ISL_REQUIRE_0_15_or_later=y +CT_ISL_later_than_0_14=y +CT_ISL_0_14_or_later=y +CT_ISL_REQUIRE_0_14_or_later=y +CT_ISL_later_than_0_13=y +CT_ISL_0_13_or_later=y +CT_ISL_later_than_0_12=y +CT_ISL_0_12_or_later=y +CT_ISL_REQUIRE_0_12_or_later=y +# CT_COMP_LIBS_LIBELF is not set +CT_COMP_LIBS_LIBICONV=y +CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" +CT_LIBICONV_DIR_NAME="libiconv" +CT_LIBICONV_PKG_NAME="libiconv" +CT_LIBICONV_SRC_RELEASE=y +CT_LIBICONV_PATCH_ORDER="global" +CT_LIBICONV_V_1_15=y +# CT_LIBICONV_NO_VERSIONS is not set +CT_LIBICONV_VERSION="1.15" +CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" +CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" +CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" +CT_COMP_LIBS_MPC=y +CT_COMP_LIBS_MPC_PKG_KSYM="MPC" +CT_MPC_DIR_NAME="mpc" +CT_MPC_PKG_NAME="mpc" +CT_MPC_SRC_RELEASE=y +CT_MPC_PATCH_ORDER="global" +CT_MPC_V_1_1=y +# CT_MPC_V_1_0 is not set +# CT_MPC_NO_VERSIONS is not set +CT_MPC_VERSION="1.1.0" +CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" +CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_MPC_ARCHIVE_FORMATS=".tar.gz" +CT_MPC_SIGNATURE_FORMAT="packed/.sig" +CT_MPC_1_1_0_or_later=y +CT_MPC_1_1_0_or_older=y +CT_COMP_LIBS_MPFR=y +CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" +CT_MPFR_DIR_NAME="mpfr" +CT_MPFR_PKG_NAME="mpfr" +CT_MPFR_SRC_RELEASE=y +CT_MPFR_PATCH_ORDER="global" +CT_MPFR_V_4_0=y +# CT_MPFR_V_3_1 is not set +# CT_MPFR_NO_VERSIONS is not set +CT_MPFR_VERSION="4.0.2" +CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" +CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" +CT_MPFR_SIGNATURE_FORMAT="packed/.asc" +CT_MPFR_later_than_4_0_0=y +CT_MPFR_4_0_0_or_later=y +CT_MPFR_later_than_3_0_0=y +CT_MPFR_3_0_0_or_later=y +CT_MPFR_REQUIRE_3_0_0_or_later=y +CT_COMP_LIBS_NCURSES=y +CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" +CT_NCURSES_DIR_NAME="ncurses" +CT_NCURSES_PKG_NAME="ncurses" +CT_NCURSES_SRC_RELEASE=y +CT_NCURSES_PATCH_ORDER="global" +CT_NCURSES_V_6_1=y +# CT_NCURSES_V_6_0 is not set +# CT_NCURSES_NO_VERSIONS is not set +CT_NCURSES_VERSION="6.1" +CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" +CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" +CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" +CT_NCURSES_HOST_CONFIG_ARGS="" +CT_NCURSES_HOST_DISABLE_DB=y +CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" +CT_NCURSES_TARGET_CONFIG_ARGS="" +# CT_NCURSES_TARGET_DISABLE_DB is not set +CT_NCURSES_TARGET_FALLBACKS="" +CT_COMP_LIBS_ZLIB=y +CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" +CT_ZLIB_DIR_NAME="zlib" +CT_ZLIB_PKG_NAME="zlib" +CT_ZLIB_SRC_RELEASE=y +CT_ZLIB_PATCH_ORDER="global" +CT_ZLIB_V_1_2_11=y +# CT_ZLIB_NO_VERSIONS is not set +CT_ZLIB_VERSION="1.2.11" +CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" +CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" +CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" +CT_LIBICONV_NEEDED=y +CT_GETTEXT_NEEDED=y +CT_GMP_NEEDED=y +CT_MPFR_NEEDED=y +CT_ISL_NEEDED=y +CT_MPC_NEEDED=y +CT_NCURSES_NEEDED=y +CT_ZLIB_NEEDED=y +CT_LIBICONV=y +CT_GETTEXT=y +CT_GMP=y +CT_MPFR=y +CT_ISL=y +CT_MPC=y +CT_NCURSES=y +CT_ZLIB=y + +# +# Companion tools +# +# CT_COMP_TOOLS_FOR_HOST is not set +# CT_COMP_TOOLS_AUTOCONF is not set +# CT_COMP_TOOLS_AUTOMAKE is not set +# CT_COMP_TOOLS_BISON is not set +# CT_COMP_TOOLS_DTC is not set +# CT_COMP_TOOLS_LIBTOOL is not set +# CT_COMP_TOOLS_M4 is not set +# CT_COMP_TOOLS_MAKE is not set +CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index 126c292b38e..8250ec0c311 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -129,4 +129,6 @@ ENV RUST_CONFIGURE_ARGS --enable-extended --enable-lld --disable-docs \ --set target.wasm32-wasi.wasi-root=/wasm32-wasi \ --musl-root-armv7=/musl-armv7 +ENV EXTERNAL_LLVM 1 + ENV SCRIPT python3 ../x.py dist --host='' --target $TARGETS diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile index 23f2215c2d9..1289f116fe9 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13-stage1/Dockerfile @@ -29,6 +29,7 @@ RUN sh /scripts/sccache.sh # We are disabling CI LLVM since this builder is intentionally using a host # LLVM, rather than the typical src/llvm-project LLVM. ENV NO_DOWNLOAD_CI_LLVM 1 +ENV EXTERNAL_LLVM 1 # Using llvm-link-shared due to libffi issues -- see #34486 ENV RUST_CONFIGURE_ARGS \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile index 8f6831bc54e..4b89a72baa1 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-13/Dockerfile @@ -40,6 +40,7 @@ RUN sh /scripts/sccache.sh # We are disabling CI LLVM since this builder is intentionally using a host # LLVM, rather than the typical src/llvm-project LLVM. ENV NO_DOWNLOAD_CI_LLVM 1 +ENV EXTERNAL_LLVM 1 # Using llvm-link-shared due to libffi issues -- see #34486 ENV RUST_CONFIGURE_ARGS \ diff --git a/src/ci/run.sh b/src/ci/run.sh index 9a247fb60a8..9d98ce22498 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -69,6 +69,11 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-units-std=1" # space required for CI artifacts. RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --dist-compression-formats=xz" +# Enable the `c` feature for compiler_builtins, but only when the `compiler-rt` source is available. +if [ "$EXTERNAL_LLVM" = "" ]; then + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set build.optimized-compiler-builtins" +fi + if [ "$DIST_SRC" = "" ]; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-dist-src" fi diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index ea2792c218b..a36518cc8ce 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -144,7 +144,7 @@ target | std | notes `armv7r-none-eabihf` | * | Bare ARMv7-R, hardfloat `asmjs-unknown-emscripten` | ✓ | asm.js via Emscripten `i586-pc-windows-msvc` | * | 32-bit Windows w/o SSE -`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 4.4, glibc 2.23) +`i586-unknown-linux-gnu` | ✓ | 32-bit Linux w/o SSE (kernel 3.2, glibc 2.17) `i586-unknown-linux-musl` | ✓ | 32-bit Linux w/o SSE, MUSL [`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD diff --git a/src/etc/natvis/libcore.natvis b/src/etc/natvis/libcore.natvis index a4e8a57e4b1..624d8cc5cc5 100644 --- a/src/etc/natvis/libcore.natvis +++ b/src/etc/natvis/libcore.natvis @@ -154,10 +154,10 @@ </Type> <Type Name="core::time::Duration"> - <DisplayString>{secs,d}s {nanos,d}ns</DisplayString> + <DisplayString>{secs,d}s {nanos.__0,d}ns</DisplayString> <Expand> <Item Name="seconds">secs,d</Item> - <Item Name="nanoseconds">nanos,d</Item> + <Item Name="nanoseconds">nanos.__0,d</Item> </Expand> </Type> </AutoVisualizer> diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c8aa51c3a49..7893429f26f 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -718,10 +718,6 @@ pub(crate) fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) { debug!("record_extern_trait: {:?}", did); let trait_ = build_external_trait(cx, did); - let trait_ = clean::TraitWithExtraInfo { - trait_, - is_notable: clean::utils::has_doc_flag(cx.tcx, did, sym::notable_trait), - }; cx.external_traits.borrow_mut().insert(did, trait_); cx.active_extern_traits.remove(&did); } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 704292c1048..c61175ecebf 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1176,6 +1176,15 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } if let ty::TraitContainer = assoc_item.container { + // FIXME(fmease): `tcx.explicit_item_bounds` does not contain the bounds of GATs, + // e.g. the bounds `Copy`, `Display` & (implicitly) `Sized` in + // `type Assoc<T: Copy> where T: Display`. This also means that we + // later incorrectly render `where T: ?Sized`. + // + // The result of `tcx.explicit_predicates_of` *does* contain them but + // it does not contain the other bounds / predicates we need. + // Either merge those two interned lists somehow or refactor + // `clean_ty_generics` to call `explicit_item_bounds` by itself. let bounds = tcx.explicit_item_bounds(assoc_item.def_id); let predicates = ty::GenericPredicates { parent: None, predicates: bounds }; let mut generics = diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index af7813a7740..f82ea8969ab 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -14,7 +14,6 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; use rustc_middle::ty; -use rustc_span::Symbol; use crate::clean; use crate::clean::GenericArgs as PP; @@ -26,21 +25,17 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> { // // We use `FxIndexMap` so that the insertion order is preserved to prevent messing up to // the order of the generated bounds. - let mut params: FxIndexMap<Symbol, (Vec<_>, Vec<_>)> = FxIndexMap::default(); + let mut tybounds = FxIndexMap::default(); let mut lifetimes = Vec::new(); let mut equalities = Vec::new(); - let mut tybounds = Vec::new(); for clause in clauses { match clause { - WP::BoundPredicate { ty, bounds, bound_params } => match ty { - clean::Generic(s) => { - let (b, p) = params.entry(s).or_default(); - b.extend(bounds); - p.extend(bound_params); - } - t => tybounds.push((t, (bounds, bound_params))), - }, + WP::BoundPredicate { ty, bounds, bound_params } => { + let (b, p): &mut (Vec<_>, Vec<_>) = tybounds.entry(ty).or_default(); + b.extend(bounds); + p.extend(bound_params); + } WP::RegionPredicate { lifetime, bounds } => { lifetimes.push((lifetime, bounds)); } @@ -49,14 +44,17 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> { } // Look for equality predicates on associated types that can be merged into - // general bound predicates + // general bound predicates. equalities.retain(|&(ref lhs, ref rhs)| { - let Some((self_, trait_did, name)) = lhs.projection() else { - return true; - }; - let clean::Generic(generic) = self_ else { return true }; - let Some((bounds, _)) = params.get_mut(generic) else { return true }; - + let Some((ty, trait_did, name)) = lhs.projection() else { return true; }; + // FIXME(fmease): We don't handle HRTBs correctly here. + // Pass `_bound_params` (higher-rank lifetimes) to a modified version of + // `merge_bounds`. That vector is currently always empty though since we + // don't keep track of late-bound lifetimes when cleaning projection + // predicates to cleaned equality predicates while we should first query + // them with `collect_referenced_late_bound_regions` and then store them + // (or something similar). For prior art, see `clean::auto_trait`. + let Some((bounds, _bound_params)) = tybounds.get_mut(ty) else { return true }; merge_bounds(cx, bounds, trait_did, name, rhs) }); @@ -65,11 +63,6 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec<WP>) -> Vec<WP> { clauses.extend( lifetimes.into_iter().map(|(lt, bounds)| WP::RegionPredicate { lifetime: lt, bounds }), ); - clauses.extend(params.into_iter().map(|(k, (bounds, params))| WP::BoundPredicate { - ty: clean::Generic(k), - bounds, - bound_params: params, - })); clauses.extend(tybounds.into_iter().map(|(ty, (bounds, bound_params))| WP::BoundPredicate { ty, bounds, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index e53e93c4def..5a4fa05e261 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -119,7 +119,7 @@ pub(crate) struct Crate { pub(crate) module: Item, pub(crate) primitives: ThinVec<(DefId, PrimitiveType)>, /// Only here so that they can be filtered through the rustdoc passes. - pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, TraitWithExtraInfo>>>, + pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, Trait>>>, } impl Crate { @@ -132,13 +132,6 @@ impl Crate { } } -/// This struct is used to wrap additional information added by rustdoc on a `trait` item. -#[derive(Clone, Debug)] -pub(crate) struct TraitWithExtraInfo { - pub(crate) trait_: Trait, - pub(crate) is_notable: bool, -} - #[derive(Copy, Clone, Debug)] pub(crate) struct ExternalCrate { pub(crate) crate_num: CrateNum, @@ -689,7 +682,7 @@ impl Item { let abi = tcx.fn_sig(self.item_id.as_def_id().unwrap()).abi(); hir::FnHeader { unsafety: if abi == Abi::RustIntrinsic { - intrinsic_operation_unsafety(self.name.unwrap()) + intrinsic_operation_unsafety(tcx, self.item_id.as_def_id().unwrap()) } else { hir::Unsafety::Unsafe }, @@ -1530,6 +1523,9 @@ impl Trait { pub(crate) fn is_auto(&self, tcx: TyCtxt<'_>) -> bool { tcx.trait_is_auto(self.def_id) } + pub(crate) fn is_notable_trait(&self, tcx: TyCtxt<'_>) -> bool { + tcx.is_doc_notable_trait(self.def_id) + } pub(crate) fn unsafety(&self, tcx: TyCtxt<'_>) -> hir::Unsafety { tcx.trait_def(self.def_id).unsafety } @@ -2201,8 +2197,11 @@ impl Path { /// Checks if this is a `T::Name` path for an associated type. pub(crate) fn is_assoc_ty(&self) -> bool { match self.res { - Res::SelfTy { .. } if self.segments.len() != 1 => true, - Res::Def(DefKind::TyParam, _) if self.segments.len() != 1 => true, + Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Def(DefKind::TyParam, _) + if self.segments.len() != 1 => + { + true + } Res::Def(DefKind::AssocTy, _) => true, _ => false, } @@ -2535,11 +2534,11 @@ mod size_asserts { // These are in alphabetical order, which is easy to maintain. static_assert_size!(Crate, 72); // frequently moved by-value static_assert_size!(DocFragment, 32); - static_assert_size!(GenericArg, 56); + static_assert_size!(GenericArg, 48); static_assert_size!(GenericArgs, 32); static_assert_size!(GenericParamDef, 56); static_assert_size!(Item, 56); - static_assert_size!(ItemKind, 96); + static_assert_size!(ItemKind, 88); static_assert_size!(PathSegment, 40); - static_assert_size!(Type, 56); + static_assert_size!(Type, 48); } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index edcd81061f8..6b844710514 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -454,7 +454,9 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type { match path.res { Res::PrimTy(p) => Primitive(PrimitiveType::from(p)), - Res::SelfTy { .. } if path.segments.len() == 1 => Generic(kw::SelfUpper), + Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } if path.segments.len() == 1 => { + Generic(kw::SelfUpper) + } Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => Generic(path.segments[0].name), _ => { let _ = register_res(cx, path.res); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 09a26cbac3e..b463b934e29 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -25,7 +25,7 @@ use std::rc::Rc; use std::sync::LazyLock; use crate::clean::inline::build_external_trait; -use crate::clean::{self, ItemId, TraitWithExtraInfo}; +use crate::clean::{self, ItemId}; use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions}; use crate::formats::cache::Cache; use crate::passes::collect_intra_doc_links::PreprocessedMarkdownLink; @@ -58,7 +58,7 @@ pub(crate) struct DocContext<'tcx> { /// Most of this logic is copied from rustc_lint::late. pub(crate) param_env: ParamEnv<'tcx>, /// Later on moved through `clean::Crate` into `cache` - pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, clean::TraitWithExtraInfo>>>, + pub(crate) external_traits: Rc<RefCell<FxHashMap<DefId, clean::Trait>>>, /// Used while populating `external_traits` to ensure we don't process the same trait twice at /// the same time. pub(crate) active_extern_traits: FxHashSet<DefId>, @@ -388,9 +388,7 @@ pub(crate) fn run_global_ctxt( // Note that in case of `#![no_core]`, the trait is not available. if let Some(sized_trait_did) = ctxt.tcx.lang_items().sized_trait() { let sized_trait = build_external_trait(&mut ctxt, sized_trait_did); - ctxt.external_traits - .borrow_mut() - .insert(sized_trait_did, TraitWithExtraInfo { trait_: sized_trait, is_notable: false }); + ctxt.external_traits.borrow_mut().insert(sized_trait_did, sized_trait); } debug!("crate: {:?}", tcx.hir().krate()); @@ -406,12 +404,8 @@ pub(crate) fn run_global_ctxt( tcx.struct_lint_node( crate::lint::MISSING_CRATE_LEVEL_DOCS, DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(), - |lint| { - let mut diag = - lint.build("no documentation found for this crate's top-level module"); - diag.help(&help); - diag.emit(); - }, + "no documentation found for this crate's top-level module", + |lint| lint.help(help), ); } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 20ae102bc27..f4ec60735a8 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1134,6 +1134,7 @@ impl Tester for Collector { panic::resume_unwind(Box::new(())); } + Ok(()) })), }); } diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index ed702f5c4a9..c6f1f9de51a 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -94,7 +94,7 @@ pub(crate) trait DocFolder: Sized { let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) }; for (k, mut v) in external_traits { - v.trait_.items = v.trait_.items.into_iter().filter_map(|i| self.fold_item(i)).collect(); + v.items = v.items.into_iter().filter_map(|i| self.fold_item(i)).collect(); c.external_traits.borrow_mut().insert(k, v); } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 86392610d2c..2e428cfddcf 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::{CrateNum, DefId}; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::{self, TyCtxt}; -use rustc_span::{sym, Symbol}; +use rustc_span::Symbol; use crate::clean::{self, types::ExternalLocation, ExternalCrate, ItemId, PrimitiveType}; use crate::core::DocContext; @@ -62,7 +62,7 @@ pub(crate) struct Cache { /// Implementations of a crate should inherit the documentation of the /// parent trait if no extra documentation is specified, and default methods /// should show up in documentation about trait implementations. - pub(crate) traits: FxHashMap<DefId, clean::TraitWithExtraInfo>, + pub(crate) traits: FxHashMap<DefId, clean::Trait>, /// When rendering traits, it's often useful to be able to list all /// implementors of the trait, and this mapping is exactly, that: a mapping @@ -225,12 +225,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // Propagate a trait method's documentation to all implementors of the // trait. if let clean::TraitItem(ref t) = *item.kind { - self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| { - clean::TraitWithExtraInfo { - trait_: *t.clone(), - is_notable: item.attrs.has_doc_flag(sym::notable_trait), - } - }); + self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| (**t).clone()); } // Collect all the implementors of traits. diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index b499e186cc0..6d46267931b 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1010,15 +1010,25 @@ fn fmt_type<'cx>( write!(f, "]") } }, - clean::Array(ref t, ref n) => { - primitive_link(f, PrimitiveType::Array, "[", cx)?; - fmt::Display::fmt(&t.print(cx), f)?; - if f.alternate() { - primitive_link(f, PrimitiveType::Array, &format!("; {}]", n), cx) - } else { - primitive_link(f, PrimitiveType::Array, &format!("; {}]", Escape(n)), cx) + clean::Array(ref t, ref n) => match **t { + clean::Generic(name) if !f.alternate() => primitive_link( + f, + PrimitiveType::Array, + &format!("[{name}; {n}]", n = Escape(n)), + cx, + ), + _ => { + write!(f, "[")?; + fmt::Display::fmt(&t.print(cx), f)?; + if f.alternate() { + write!(f, "; {n}")?; + } else { + write!(f, "; ")?; + primitive_link(f, PrimitiveType::Array, &format!("{n}", n = Escape(n)), cx)?; + } + write!(f, "]") } - } + }, clean::RawPointer(m, ref t) => { let m = match m { hir::Mutability::Mut => "mut", diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 8e53fbbcd19..68eb5008583 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -813,11 +813,8 @@ impl<'tcx> ExtraInfo<'tcx> { crate::lint::INVALID_CODEBLOCK_ATTRIBUTES, hir_id, self.sp, - |lint| { - let mut diag = lint.build(msg); - diag.help(help); - diag.emit(); - }, + msg, + |lint| lint.help(help), ); } } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 75ac11a3a88..aa9788fad2b 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1294,7 +1294,12 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String { if let Some(trait_) = &impl_.trait_ { let trait_did = trait_.def_id(); - if cx.cache().traits.get(&trait_did).map_or(false, |t| t.is_notable) { + if cx + .cache() + .traits + .get(&trait_did) + .map_or(false, |t| t.is_notable_trait(cx.tcx())) + { if out.is_empty() { write!( &mut out, @@ -1598,7 +1603,7 @@ fn render_impl( link, render_mode, false, - trait_.map(|t| &t.trait_), + trait_, rendering_params, ); } @@ -1658,7 +1663,7 @@ fn render_impl( &mut default_impl_items, &mut impl_items, cx, - &t.trait_, + t, i.inner_impl(), &i.impl_item, parent, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 3e324bbb069..7bd0dbf9325 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -716,9 +716,9 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: document(&mut content, cx, m, Some(t), HeadingOffset::H5); let toggled = !content.is_empty(); if toggled { - write!(w, "<details class=\"rustdoc-toggle\" open><summary>"); + write!(w, "<details class=\"rustdoc-toggle method-toggle\" open><summary>"); } - write!(w, "<div id=\"{}\" class=\"method has-srclink\">", id); + write!(w, "<section id=\"{}\" class=\"method has-srclink\">", id); render_rightside(w, cx, m, t, RenderMode::Normal); write!(w, "<h4 class=\"code-header\">"); render_assoc_item( @@ -730,7 +730,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: RenderMode::Normal, ); w.write_str("</h4>"); - w.write_str("</div>"); + w.write_str("</section>"); if toggled { write!(w, "</summary>"); w.push_buffer(content); diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 0ea6d9c38b6..140ce3ba9fc 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -138,6 +138,13 @@ h1, h2, h3, h4 { .docblock h3, .docblock h4, h5, h6 { margin: 15px 0 5px 0; } +.docblock > h2:first-child, +.docblock > h3:first-child, +.docblock > h4:first-child, +.docblock > h5:first-child, +.docblock > h6:first-child { + margin-top: 0; +} h1.fqn { margin: 0; padding: 0; @@ -177,36 +184,20 @@ h4.code-header { margin: 0; padding: 0; } -.impl, -.impl-items .method, -.methods .method, -.impl-items .type, -.methods .type, -.impl-items .associatedconstant, -.methods .associatedconstant, -.impl-items .associatedtype, -.methods .associatedtype { - flex-basis: 100%; - font-weight: 600; - position: relative; -} +#crate-search, h1, h2, h3, h4, h5, h6, .sidebar, .mobile-topbar, -a.source, .search-input, .search-results .result-name, .item-left > a, .out-of-band, span.since, -details.rustdoc-toggle > summary::before, a.srclink, #help-button > button, details.rustdoc-toggle.top-doc > summary, -details.rustdoc-toggle.top-doc > summary::before, details.rustdoc-toggle.non-exhaustive > summary, -details.rustdoc-toggle.non-exhaustive > summary::before, .scraped-example-title, .more-examples-toggle summary, .more-examples-toggle .hide-more, .example-links a, @@ -304,16 +295,6 @@ summary { /* Fix some style changes due to normalize.css 8 */ -button, -input, -optgroup, -select, -textarea { - color: inherit; - font: inherit; - margin: 0; -} - button { /* Buttons on Safari have different default padding than other platforms. Make them the same. */ padding: 1px 6px; @@ -451,7 +432,6 @@ img { } .source .sidebar > *:not(#sidebar-toggle) { - opacity: 0; visibility: hidden; } @@ -460,7 +440,6 @@ img { } .source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) { - opacity: 1; visibility: visible; } @@ -550,6 +529,14 @@ h2.location a { margin: 0; } +.sidebar a, .sidebar .current { + color: var(--sidebar-link-color); +} +.sidebar .current, +.sidebar a:hover { + background-color: var(--sidebar-current-link-background-color); +} + .sidebar-elems .block { margin-bottom: 2em; } @@ -667,10 +654,6 @@ pre.example-line-numbers { font-weight: normal; } -.method > .code-header, .trait-impl > .code-header { - display: block; -} - .in-band { flex-grow: 1; margin: 0px; @@ -887,6 +870,9 @@ table, /* Removes default arrow from firefox */ text-indent: 0.01px; background-color: var(--main-background-color); + color: inherit; + line-height: 1.5; + font-weight: 500; } /* cancel stylistic differences in padding in firefox for "appearance: none"-style (or equivalent) <select>s */ @@ -977,6 +963,11 @@ so that we can apply CSS-filters to change the arrow color in themes */ padding-right: 1em; } +.search-results a:hover, +.search-results a:focus { + background-color: var(--search-result-link-focus-background-color); +} + .popover { font-size: 1rem; position: absolute; @@ -1057,6 +1048,13 @@ so that we can apply CSS-filters to change the arrow color in themes */ margin-bottom: 5px; font-size: 0.875rem; font-weight: normal; + color: var(--main-color); + background-color: var(--stab-background-color); +} + +.stab.portability > code { + background: none; + color: var(--stab-code-color); } .stab .emoji { @@ -1247,13 +1245,11 @@ h3.variant { font-weight: 600; font-size: 1.125rem; margin-bottom: 10px; - border-bottom: none; } .sub-variant h4 { font-size: 1rem; font-weight: 400; - border-bottom: none; margin-top: 0; margin-bottom: 0; } @@ -1322,11 +1318,6 @@ h3.variant { font-size: 1.25rem; } -/* Example code has the "Run" button that needs to be positioned relative to the pre */ -pre.rust.rust-example-rendered { - position: relative; -} - pre.rust { tab-size: 4; -moz-tab-size: 4; @@ -1363,6 +1354,8 @@ pre.rust { border: 0; border-top: 2px solid; flex: 1; + line-height: 1.5; + color: inherit; } #titles > button > div.count { @@ -1380,7 +1373,6 @@ pre.rust { position: sticky; top: 0; left: 0; - font-weight: bold; font-size: 1.25rem; border-bottom: 1px solid; display: flex; @@ -1400,6 +1392,8 @@ pre.rust { margin-bottom: 6px; } #sidebar-toggle > button { + font-size: inherit; + font-weight: bold; background: none; color: inherit; cursor: pointer; @@ -1428,6 +1422,7 @@ pre.rust { border: 1px solid var(--border-color); border-radius: 2px; cursor: pointer; + line-height: 1.5; } #settings-menu > a, #help-button > button { @@ -1570,7 +1565,6 @@ details.rustdoc-toggle > summary::before { } details.rustdoc-toggle > summary.hideme > span, -details.rustdoc-toggle > summary::before, .more-examples-toggle summary, .more-examples-toggle .hide-more { color: var(--toggles-color); } @@ -1832,6 +1826,7 @@ in storage.js plus the media query with (min-width: 701px) as an icon, it's okay to specify its sizes in pixels. */ font-size: 32px; border: none; + color: var(--main-color); } .sidebar-elems { @@ -1887,7 +1882,6 @@ in storage.js plus the media query with (min-width: 701px) border-top-right-radius: 3px; border-bottom-right-radius: 3px; cursor: pointer; - font-weight: bold; border: 1px solid; border-left: 0; } @@ -2011,7 +2005,11 @@ in storage.js plus the media query with (min-width: 701px) .method-toggle summary, .implementors-toggle summary, -.impl { +.impl, +#implementors-list > .docblock, +.impl-items > section, +.methods > section +{ margin-bottom: 0.75em; } diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css index e82ec042637..821c4e978e8 100644 --- a/src/librustdoc/html/static/css/settings.css +++ b/src/librustdoc/html/static/css/settings.css @@ -12,7 +12,8 @@ margin-right: 0.3em; height: 1.2rem; width: 1.2rem; - border: 1px solid; + color: inherit; + border: 1px solid currentColor; outline: none; -webkit-appearance: none; cursor: pointer; diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 44238ca573d..7245dce6ed6 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -35,6 +35,11 @@ Original by Dempfi (https://github.com/dempfi/ayu) --keyword-link-color: #39afd7; --mod-link-color: #39afd7; --link-color: #39afd7; + --sidebar-link-color: #53b1db; + --sidebar-current-link-background-color: transparent; + --search-result-link-focus-background-color: #3c3c3c; + --stab-background-color: #314559; + --stab-code-color: #e6e1cf; } .slider { @@ -85,7 +90,6 @@ pre, .rustdoc.source .example-wrap { .sidebar .current, .sidebar a:hover { - background-color: transparent; color: #ffb44c; } @@ -119,9 +123,6 @@ pre, .rustdoc.source .example-wrap { .content .item-info::before { color: #ccc; } -.sidebar a { color: #53b1db; } -.sidebar a.current.type { color: #53b1db; } - pre.rust .comment { color: #788797; } pre.rust .doccomment { color: #a1ac88; } @@ -157,16 +158,6 @@ details.rustdoc-toggle > summary::before { color: #000; } -.stab { - color: #c5c5c5; - background: #314559 !important; -} - -.stab.portability > code { - color: #e6e1cf; - background: none; -} - .result-name .primitive > i, .result-name .keyword > i { color: #788797; } @@ -260,45 +251,6 @@ pre.rust .kw {} pre.rust .self, pre.rust .bool-val, pre.rust .prelude-val, pre.rust .attribute {} pre.rust .kw-2, pre.rust .prelude-ty {} -.search-results a:focus span {} -a.result-trait:focus {} -a.result-traitalias:focus {} -a.result-mod:focus, -a.result-externcrate:focus {} -a.result-mod:focus {} -a.result-externcrate:focus {} -a.result-enum:focus {} -a.result-struct:focus {} -a.result-union:focus {} -a.result-fn:focus, -a.result-method:focus, -a.result-tymethod:focus {} -a.result-type:focus {} -a.result-associatedtype:focus {} -a.result-foreigntype:focus {} -a.result-attr:focus, -a.result-derive:focus, -a.result-macro:focus {} -a.result-constant:focus, -a.result-static:focus {} -a.result-primitive:focus {} -a.result-keyword:focus {} - -.sidebar a.current.enum {} -.sidebar a.current.struct {} -.sidebar a.current.foreigntype {} -.sidebar a.current.attr, -.sidebar a.current.derive, -.sidebar a.current.macro {} -.sidebar a.current.union {} -.sidebar a.current.constant -.sidebar a.current.static {} -.sidebar a.current.primitive {} -.sidebar a.current.trait {} -.sidebar a.current.traitalias {} -.sidebar a.current.fn {} -.sidebar a.current.keyword {} - kbd { color: #c5c5c5; background-color: #314559; diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 858d836c03d..9d5406e65a8 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -30,6 +30,11 @@ --keyword-link-color: #d2991d; --mod-link-color: #d2991d; --link-color: #d2991d; + --sidebar-link-color: #fdbf35; + --sidebar-current-link-background-color: #444; + --search-result-link-focus-background-color: #616161; + --stab-background-color: #314559; + --stab-code-color: #e6e1cf; } .slider { @@ -49,65 +54,13 @@ input:focus + .slider { drop-shadow(0 -1px 0 #fff) } -.sidebar .current, -.sidebar a:hover { - background: #444; -} - .src-line-numbers span { color: #3B91E2; } .src-line-numbers .line-highlighted { background-color: #0a042f !important; } -.search-results a:hover { - background-color: #777; -} - -.search-results a:focus { - color: #eee !important; - background-color: #616161; -} -.search-results a:focus span { color: #eee !important; } -a.result-trait:focus { background-color: #013191; } -a.result-traitalias:focus { background-color: #013191; } -a.result-mod:focus, -a.result-externcrate:focus { background-color: #884719; } -a.result-enum:focus { background-color: #194e9f; } -a.result-struct:focus { background-color: #194e9f; } -a.result-union:focus { background-color: #194e9f; } -a.result-fn:focus, -a.result-method:focus, -a.result-tymethod:focus { background-color: #4950ed; } -a.result-type:focus { background-color: #194e9f; } -a.result-associatedtype:focus { background-color: #884719; } -a.result-foreigntype:focus { background-color: #194e9f; } -a.result-attr:focus, -a.result-derive:focus, -a.result-macro:focus { background-color: #217d1c; } -a.result-constant:focus, -a.result-static:focus { background-color: #884719; } -a.result-primitive:focus { background-color: #194e9f; } -a.result-keyword:focus { background-color: #884719; } - .content .item-info::before { color: #ccc; } -.sidebar a { color: #fdbf35; } -.sidebar a.current.enum { color: #12ece2; } -.sidebar a.current.struct { color: #12ece2; } -.sidebar a.current.type { color: #12ece2; } -.sidebar a.current.foreigntype { color: #12ece2; } -.sidebar a.current.attr, -.sidebar a.current.derive, -.sidebar a.current.macro { color: #0be900; } -.sidebar a.current.union { color: #12ece2; } -.sidebar a.current.constant -.sidebar a.current.static { color: #fdbf35; } -.sidebar a.current.primitive { color: #12ece2; } -.sidebar a.current.trait { color: #cca7ff; } -.sidebar a.current.traitalias { color: #cca7ff; } -.sidebar a.current.fn { color: #32d479; } -.sidebar a.current.keyword { color: #fdbf35; } - pre.rust .comment { color: #8d8d8b; } pre.rust .doccomment { color: #8ca375; } @@ -134,13 +87,6 @@ details.rustdoc-toggle > summary::before { filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%); } -.stab { background: #314559; } - -.stab.portability > code { - color: #e6e1cf; - background: none; -} - .src-line-numbers :target { background-color: transparent; } /* Code highlighting */ diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 6fbea6f6c7a..b63895e56c6 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -30,6 +30,11 @@ --keyword-link-color: #3873ad; --mod-link-color: #3873ad; --link-color: #3873ad; + --sidebar-link-color: #356da4; + --sidebar-current-link-background-color: #fff; + --search-result-link-focus-background-color: #ccc; + --stab-background-color: #fff5d6; + --stab-code-color: #000; } .slider { @@ -48,65 +53,13 @@ input:focus + .slider { */ } -.sidebar .current, -.sidebar a:hover { - background-color: #fff; -} - .src-line-numbers span { color: #c67e2d; } .src-line-numbers .line-highlighted { background-color: #FDFFD3 !important; } -.search-results a:hover { - background-color: #ddd; -} - -.search-results a:focus { - color: #000 !important; - background-color: #ccc; -} -.search-results a:focus span { color: #000 !important; } -a.result-trait:focus { background-color: #c7b6ff; } -a.result-traitalias:focus { background-color: #c7b6ff; } -a.result-mod:focus, -a.result-externcrate:focus { background-color: #afc6e4; } -a.result-enum:focus { background-color: #e7b1a0; } -a.result-struct:focus { background-color: #e7b1a0; } -a.result-union:focus { background-color: #e7b1a0; } -a.result-fn:focus, -a.result-method:focus, -a.result-tymethod:focus { background-color: #c6afb3; } -a.result-type:focus { background-color: #e7b1a0; } -a.result-associatedtype:focus { background-color: #afc6e4; } -a.result-foreigntype:focus { background-color: #e7b1a0; } -a.result-attr:focus, -a.result-derive:focus, -a.result-macro:focus { background-color: #8ce488; } -a.result-constant:focus, -a.result-static:focus { background-color: #afc6e4; } -a.result-primitive:focus { background-color: #e7b1a0; } -a.result-keyword:focus { background-color: #afc6e4; } - .content .item-info::before { color: #ccc; } -.sidebar a { color: #356da4; } -.sidebar a.current.enum { color: #a63283; } -.sidebar a.current.struct { color: #a63283; } -.sidebar a.current.type { color: #a63283; } -.sidebar a.current.foreigntype { color: #356da4; } -.sidebar a.current.attr, -.sidebar a.current.derive, -.sidebar a.current.macro { color: #067901; } -.sidebar a.current.union { color: #a63283; } -.sidebar a.current.constant -.sidebar a.current.static { color: #356da4; } -.sidebar a.current.primitive { color: #a63283; } -.sidebar a.current.trait { color: #6849c3; } -.sidebar a.current.traitalias { color: #4b349e; } -.sidebar a.current.fn { color: #a67736; } -.sidebar a.current.keyword { color: #356da4; } - body.source .example-wrap pre.rust a { background: #eee; } @@ -122,9 +75,6 @@ body.source .example-wrap pre.rust a { filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%); } -.stab { background: #FFF5D6; border-color: #FFC600; } -.stab.portability > code { background: none; } - .src-line-numbers :target { background-color: transparent; } /* Code highlighting */ diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 8d6450838c1..d13efe6c113 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -108,7 +108,6 @@ impl<'tcx> JsonRenderer<'tcx> { .filter_map(|(&id, trait_item)| { // only need to synthesize items for external traits if !id.is_local() { - let trait_item = &trait_item.trait_; for item in &trait_item.items { trace!("Adding subitem to {id:?}: {:?}", item.item_id); self.item(item.clone()).unwrap(); diff --git a/src/librustdoc/passes/bare_urls.rs b/src/librustdoc/passes/bare_urls.rs index 392e26ea6ac..7ff3ccef945 100644 --- a/src/librustdoc/passes/bare_urls.rs +++ b/src/librustdoc/passes/bare_urls.rs @@ -71,16 +71,14 @@ impl<'a, 'tcx> DocVisitor for BareUrlsLinter<'a, 'tcx> { let report_diag = |cx: &DocContext<'_>, msg: &str, url: &str, range: Range<usize>| { let sp = super::source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs) .unwrap_or_else(|| item.attr_span(cx.tcx)); - cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, |lint| { - lint.build(msg) - .note("bare URLs are not automatically turned into clickable links") + cx.tcx.struct_span_lint_hir(crate::lint::BARE_URLS, hir_id, sp, msg, |lint| { + lint.note("bare URLs are not automatically turned into clickable links") .span_suggestion( sp, "use an automatic link instead", format!("<{}>", url), Applicability::MachineApplicable, ) - .emit(); }); }; diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index 381ac7a5dee..14a38a760d2 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -2,7 +2,7 @@ use rustc_data_structures::sync::{Lock, Lrc}; use rustc_errors::{ emitter::Emitter, translation::Translate, Applicability, Diagnostic, Handler, - LazyFallbackBundle, LintDiagnosticBuilder, + LazyFallbackBundle, }; use rustc_parse::parse_stream_from_source_str; use rustc_session::parse::ParseSess; @@ -97,48 +97,10 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { None => (item.attr_span(self.cx.tcx), false), }; - // lambda that will use the lint to start a new diagnostic and add - // a suggestion to it when needed. - let diag_builder = |lint: LintDiagnosticBuilder<'_, ()>| { - let explanation = if is_ignore { - "`ignore` code blocks require valid Rust code for syntax highlighting; \ - mark blocks that do not contain Rust code as text" - } else { - "mark blocks that do not contain Rust code as text" - }; - let msg = if buffer.has_errors { - "could not parse code block as Rust code" - } else { - "Rust code block is empty" - }; - let mut diag = lint.build(msg); - - if precise_span { - if is_ignore { - // giving an accurate suggestion is hard because `ignore` might not have come first in the list. - // just give a `help` instead. - diag.span_help( - sp.from_inner(InnerSpan::new(0, 3)), - &format!("{}: ```text", explanation), - ); - } else if empty_block { - diag.span_suggestion( - sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(), - explanation, - "text", - Applicability::MachineApplicable, - ); - } - } else if empty_block || is_ignore { - diag.help(&format!("{}: ```text", explanation)); - } - - // FIXME(#67563): Provide more context for these errors by displaying the spans inline. - for message in buffer.messages.iter() { - diag.note(message); - } - - diag.emit(); + let msg = if buffer.has_errors { + "could not parse code block as Rust code" + } else { + "Rust code block is empty" }; // Finally build and emit the completed diagnostic. @@ -148,7 +110,42 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { crate::lint::INVALID_RUST_CODEBLOCKS, hir_id, sp, - diag_builder, + msg, + |lint| { + let explanation = if is_ignore { + "`ignore` code blocks require valid Rust code for syntax highlighting; \ + mark blocks that do not contain Rust code as text" + } else { + "mark blocks that do not contain Rust code as text" + }; + + if precise_span { + if is_ignore { + // giving an accurate suggestion is hard because `ignore` might not have come first in the list. + // just give a `help` instead. + lint.span_help( + sp.from_inner(InnerSpan::new(0, 3)), + &format!("{}: ```text", explanation), + ); + } else if empty_block { + lint.span_suggestion( + sp.from_inner(InnerSpan::new(0, 3)).shrink_to_hi(), + explanation, + "text", + Applicability::MachineApplicable, + ); + } + } else if empty_block || is_ignore { + lint.help(&format!("{}: ```text", explanation)); + } + + // FIXME(#67563): Provide more context for these errors by displaying the spans inline. + for message in buffer.messages.iter() { + lint.note(message); + } + + lint + }, ); } } @@ -195,8 +192,11 @@ impl Translate for BufferEmitter { impl Emitter for BufferEmitter { fn emit_diagnostic(&mut self, diag: &Diagnostic) { let mut buffer = self.buffer.borrow_mut(); - // FIXME(davidtwco): need to support translation here eventually - buffer.messages.push(format!("error from rustc: {}", diag.message[0].0.expect_str())); + + let fluent_args = self.to_fluent_args(diag.args()); + let translated_main_message = self.translate_message(&diag.message[0].0, &fluent_args); + + buffer.messages.push(format!("error from rustc: {}", translated_main_message)); if diag.is_error() { buffer.has_errors = true; } diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index 55d5f303d34..15982b40944 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -125,9 +125,8 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item crate::lint::MISSING_DOC_CODE_EXAMPLES, hir_id, sp, - |lint| { - lint.build("missing code example in this documentation").emit(); - }, + "missing code example in this documentation", + |lint| lint, ); } } else if tests.found_tests > 0 @@ -137,9 +136,8 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item crate::lint::PRIVATE_DOC_TESTS, hir_id, item.attr_span(cx.tcx), - |lint| { - lint.build("documentation test in private item").emit(); - }, + "documentation test in private item", + |lint| lint, ); } } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 677c980f63c..3beda708bf2 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1609,9 +1609,7 @@ fn report_diagnostic( let sp = item.attr_span(tcx); - tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| { - let mut diag = lint.build(msg); - + tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |lint| { let span = super::source_span_for_markdown_range(tcx, dox, link_range, &item.attrs).map(|sp| { if dox.as_bytes().get(link_range.start) == Some(&b'`') @@ -1624,7 +1622,7 @@ fn report_diagnostic( }); if let Some(sp) = span { - diag.set_span(sp); + lint.set_span(sp); } else { // blah blah blah\nblah\nblah [blah] blah blah\nblah blah // ^ ~~~~ @@ -1634,7 +1632,7 @@ fn report_diagnostic( let line = dox[last_new_line_offset..].lines().next().unwrap_or(""); // Print the line containing the `link_range` and manually mark it with '^'s. - diag.note(&format!( + lint.note(&format!( "the link appears in this line:\n\n{line}\n\ {indicator: <before$}{indicator:^<found$}", line = line, @@ -1644,9 +1642,9 @@ fn report_diagnostic( )); } - decorate(&mut diag, span); + decorate(lint, span); - diag.emit(); + lint }); } diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs index 885dadb32a8..694b03161d9 100644 --- a/src/librustdoc/passes/html_tags.rs +++ b/src/librustdoc/passes/html_tags.rs @@ -240,9 +240,8 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> { Some(sp) => sp, None => item.attr_span(tcx), }; - tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| { + tcx.struct_span_lint_hir(crate::lint::INVALID_HTML_TAGS, hir_id, sp, msg, |lint| { use rustc_lint_defs::Applicability; - let mut diag = lint.build(msg); // If a tag looks like `<this>`, it might actually be a generic. // We don't try to detect stuff `<like, this>` because that's not valid HTML, // and we don't try to detect stuff `<like this>` because that's not valid Rust. @@ -305,11 +304,10 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> { if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<') || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>') { - diag.emit(); - return; + return lint; } // multipart form is chosen here because ``Vec<i32>`` would be confusing. - diag.multipart_suggestion( + lint.multipart_suggestion( "try marking as source code", vec![ (generics_sp.shrink_to_lo(), String::from("`")), @@ -318,7 +316,8 @@ impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> { Applicability::MaybeIncorrect, ); } - diag.emit() + + lint }); }; diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index c40274394f3..d29ceead4f3 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -65,7 +65,7 @@ pub(crate) trait DocVisitor: Sized { // FIXME: make this a simple by-ref for loop once external_traits is cleaned up let external_traits = { std::mem::take(&mut *c.external_traits.borrow_mut()) }; for (k, v) in external_traits { - v.trait_.items.iter().for_each(|i| self.visit_item(i)); + v.items.iter().for_each(|i| self.visit_item(i)); c.external_traits.borrow_mut().insert(k, v); } } diff --git a/src/llvm-project b/src/llvm-project -Subproject 670e5f673acb736acbfce65e0ffe2c8cd115b93 +Subproject 9567f08afc94332d59025744f3a8198104949d3 diff --git a/src/test/assembly/x86-stack-probes.rs b/src/test/assembly/x86-stack-probes.rs new file mode 100644 index 00000000000..c7141fb208a --- /dev/null +++ b/src/test/assembly/x86-stack-probes.rs @@ -0,0 +1,42 @@ +// min-llvm-version: 16 +// revisions: x86_64 i686 +// assembly-output: emit-asm +//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//[x86_64] needs-llvm-components: x86 +//[i686] compile-flags: --target i686-unknown-linux-gnu +//[i686] needs-llvm-components: x86 +// compile-flags: -C llvm-args=-x86-asm-syntax=intel + +#![feature(no_core, lang_items)] +#![crate_type = "lib"] +#![no_core] + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +impl Copy for u8 {} + +// Check that inline-asm stack probes are generated correctly. +// To avoid making this test fragile to slight asm changes, +// we only check that the stack pointer is decremented by a page at a time, +// instead of matching the whole probe sequence. + +// CHECK-LABEL: small_stack_probe: +#[no_mangle] +pub fn small_stack_probe(x: u8, f: fn(&mut [u8; 8192])) { + // CHECK-NOT: __rust_probestack + // x86_64: sub rsp, 4096 + // i686: sub esp, 4096 + f(&mut [x; 8192]); +} + +// CHECK-LABEL: big_stack_probe: +#[no_mangle] +pub fn big_stack_probe(x: u8, f: fn(&[u8; 65536])) { + // CHECK-NOT: __rust_probestack + // x86_64: sub rsp, 4096 + // i686: sub esp, 4096 + f(&mut [x; 65536]); +} diff --git a/src/test/codegen/abi-main-signature-32bit-c-int.rs b/src/test/codegen/abi-main-signature-32bit-c-int.rs index 31b19a54276..7f22ddcfc12 100644 --- a/src/test/codegen/abi-main-signature-32bit-c-int.rs +++ b/src/test/codegen/abi-main-signature-32bit-c-int.rs @@ -7,4 +7,4 @@ fn main() { } -// CHECK: define i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}}) +// CHECK: define{{( hidden)?}} i32 @main(i32{{( %0)?}}, {{i8\*\*|ptr}}{{( %1)?}}) diff --git a/src/test/codegen/binary-search-index-no-bound-check.rs b/src/test/codegen/binary-search-index-no-bound-check.rs index 2deabcaa6c2..c1766a4a44a 100644 --- a/src/test/codegen/binary-search-index-no-bound-check.rs +++ b/src/test/codegen/binary-search-index-no-bound-check.rs @@ -16,3 +16,23 @@ pub fn binary_search_index_no_bounds_check(s: &[u8]) -> u8 { 42 } } + +// Similarly, check that `partition_point` is known to return a valid fencepost. + +// CHECK-LABEL: @unknown_split +#[no_mangle] +pub fn unknown_split(x: &[i32], i: usize) -> (&[i32], &[i32]) { + // This just makes sure that the subsequent function is looking for the + // absence of something that might actually be there. + + // CHECK: call core::panicking::panic + x.split_at(i) +} + +// CHECK-LABEL: @partition_point_split_no_bounds_check +#[no_mangle] +pub fn partition_point_split_no_bounds_check(x: &[i32], needle: i32) -> (&[i32], &[i32]) { + // CHECK-NOT: call core::panicking::panic + let i = x.partition_point(|p| p < &needle); + x.split_at(i) +} diff --git a/src/test/codegen/stack-probes-call.rs b/src/test/codegen/stack-probes-call.rs new file mode 100644 index 00000000000..a18fd41c28c --- /dev/null +++ b/src/test/codegen/stack-probes-call.rs @@ -0,0 +1,24 @@ +// Check the "probe-stack" attribute for targets with `StackProbeType::Call`, +// or `StackProbeType::InlineOrCall` when running on older LLVM. + +// compile-flags: -C no-prepopulate-passes +// revisions: i686 x86_64 +//[i686] compile-flags: --target i686-unknown-linux-gnu +//[i686] needs-llvm-components: x86 +//[i686] ignore-llvm-version: 16 - 99 +//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//[x86_64] needs-llvm-components: x86 +//[x86_64] ignore-llvm-version: 16 - 99 + +#![crate_type = "rlib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[no_mangle] +pub fn foo() { +// CHECK: @foo() unnamed_addr #0 +// CHECK: attributes #0 = { {{.*}}"probe-stack"="__rust_probestack"{{.*}} } +} diff --git a/src/test/codegen/stack-probes-inline.rs b/src/test/codegen/stack-probes-inline.rs new file mode 100644 index 00000000000..a6b781de531 --- /dev/null +++ b/src/test/codegen/stack-probes-inline.rs @@ -0,0 +1,32 @@ +// Check the "probe-stack" attribute for targets with `StackProbeType::Inline`, +// or `StackProbeType::InlineOrCall` when running on newer LLVM. + +// compile-flags: -C no-prepopulate-passes +// revisions: powerpc powerpc64 powerpc64le s390x i686 x86_64 +//[powerpc] compile-flags: --target powerpc-unknown-linux-gnu +//[powerpc] needs-llvm-components: powerpc +//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//[powerpc64] needs-llvm-components: powerpc +//[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu +//[powerpc64le] needs-llvm-components: powerpc +//[s390x] compile-flags: --target s390x-unknown-linux-gnu +//[s390x] needs-llvm-components: systemz +//[i686] compile-flags: --target i686-unknown-linux-gnu +//[i686] needs-llvm-components: x86 +//[i686] min-llvm-version: 16 +//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu +//[x86_64] needs-llvm-components: x86 +//[x86_64] min-llvm-version: 16 + +#![crate_type = "rlib"] +#![feature(no_core, lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[no_mangle] +pub fn foo() { +// CHECK: @foo() unnamed_addr #0 +// CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} } +} diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs deleted file mode 100644 index 9bd351df3ea..00000000000 --- a/src/test/codegen/stack-probes.rs +++ /dev/null @@ -1,22 +0,0 @@ -// ignore-arm -// ignore-aarch64 -// ignore-mips -// ignore-mips64 -// ignore-powerpc -// ignore-powerpc64 -// ignore-powerpc64le -// ignore-riscv64 -// ignore-s390x -// ignore-sparc -// ignore-sparc64 -// ignore-wasm -// ignore-emscripten -// ignore-windows -// compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] - -#[no_mangle] -pub fn foo() { -// CHECK: @foo() unnamed_addr #0 -} diff --git a/src/test/run-make/macos-fat-archive/Makefile b/src/test/run-make/macos-fat-archive/Makefile new file mode 100644 index 00000000000..cc99375db69 --- /dev/null +++ b/src/test/run-make/macos-fat-archive/Makefile @@ -0,0 +1,10 @@ +# only-macos + +-include ../../run-make-fulldeps/tools.mk + +"$(TMPDIR)"/libnative-library.a: native-library.c + $(CC) -arch arm64 -arch x86_64 native-library.c -c -o "$(TMPDIR)"/native-library.o + $(AR) crs "$(TMPDIR)"/libnative-library.a "$(TMPDIR)"/native-library.o + +all: "$(TMPDIR)"/libnative-library.a + $(RUSTC) lib.rs --crate-type=lib -L "native=$(TMPDIR)" -l static=native-library diff --git a/src/test/run-make/macos-fat-archive/lib.rs b/src/test/run-make/macos-fat-archive/lib.rs new file mode 100644 index 00000000000..9943a266c3e --- /dev/null +++ b/src/test/run-make/macos-fat-archive/lib.rs @@ -0,0 +1,3 @@ +extern "C" { + pub fn native_func(); +} diff --git a/src/test/run-make/macos-fat-archive/native-library.c b/src/test/run-make/macos-fat-archive/native-library.c new file mode 100644 index 00000000000..d300fdf1c17 --- /dev/null +++ b/src/test/run-make/macos-fat-archive/native-library.c @@ -0,0 +1 @@ +void native_func() {} diff --git a/src/test/rustdoc-gui/anchor-navigable.goml b/src/test/rustdoc-gui/anchor-navigable.goml index 424c312233b..14653f0bfc7 100644 --- a/src/test/rustdoc-gui/anchor-navigable.goml +++ b/src/test/rustdoc-gui/anchor-navigable.goml @@ -7,5 +7,5 @@ goto: file://|DOC_PATH|/test_docs/struct.Foo.html // We check that ".item-info" is bigger than its content. move-cursor-to: ".impl" -assert-property: (".impl > a.anchor", {"offsetWidth": "9"}) +assert-property: (".impl > a.anchor", {"offsetWidth": "8"}) assert-css: (".impl > a.anchor", {"left": "-8px"}) diff --git a/src/test/rustdoc-gui/font-weight.goml b/src/test/rustdoc-gui/font-weight.goml index 13e8ec9fb16..d5c934551a5 100644 --- a/src/test/rustdoc-gui/font-weight.goml +++ b/src/test/rustdoc-gui/font-weight.goml @@ -13,7 +13,7 @@ goto: file://|DOC_PATH|/test_docs/type.SomeType.html assert-css: (".top-doc .docblock p", {"font-weight": "400"}, ALL) goto: file://|DOC_PATH|/test_docs/struct.Foo.html -assert-css: (".impl-items .method", {"font-weight": "600"}, ALL) +assert-css: (".impl-items .method > .code-header", {"font-weight": "600"}, ALL) goto: file://|DOC_PATH|/lib2/trait.Trait.html @@ -41,4 +41,4 @@ assert-count: (".methods .associatedtype", 1) assert-css: (".methods .associatedtype", {"font-weight": "600"}) assert-count: (".methods .constant", 1) assert-css: (".methods .constant", {"font-weight": "600"}) -assert-css: (".methods .method", {"font-weight": "600"}) +assert-css: (".methods .method > .code-header", {"font-weight": "600"}) diff --git a/src/test/rustdoc-gui/no-docblock.goml b/src/test/rustdoc-gui/no-docblock.goml new file mode 100644 index 00000000000..2408be4534b --- /dev/null +++ b/src/test/rustdoc-gui/no-docblock.goml @@ -0,0 +1,8 @@ +// This test checks that there are margins applied to methods with no docblocks. +goto: file://|DOC_PATH|/test_docs/trait.TraitWithNoDocblocks.html +// Check that the two methods are more than 24px apart. +compare-elements-position-near-false: ("//*[@id='tymethod.first_fn']", "//*[@id='tymethod.second_fn']", {"y": 24}) + +goto: file://|DOC_PATH|/test_docs/struct.TypeWithNoDocblocks.html +// Check that the two methods are more than 24px apart. +compare-elements-position-near-false: ("//*[@id='method.first_fn']", "//*[@id='method.second_fn']", {"y": 24}) diff --git a/src/test/rustdoc-gui/search-result-color.goml b/src/test/rustdoc-gui/search-result-color.goml index c4b5fdf53dd..807646cce37 100644 --- a/src/test/rustdoc-gui/search-result-color.goml +++ b/src/test/rustdoc-gui/search-result-color.goml @@ -30,54 +30,243 @@ assert-css: ( // Checking the color of "keyword". assert-css: ( - ".result-name .keyword", + ".result-keyword .keyword", {"color": "rgb(57, 175, 215)"}, ALL, ) +assert-css: ( + ".result-keyword", + {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-keyword" +assert-css: ( + ".result-keyword:hover", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-keyword:hover .keyword", + {"color": "rgb(57, 175, 215)"}, +) +move-cursor-to: ".search-input" +focus: ".result-keyword" +assert-css: ( + ".result-keyword:focus", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-keyword:focus .keyword", + {"color": "rgb(57, 175, 215)"}, +) + // Check the color of "struct". assert-css: ( - ".result-name .struct", + ".result-struct .struct", {"color": "rgb(255, 160, 165)"}, ALL, ) +assert-css: ( + ".result-struct", + {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-struct" +assert-css: ( + ".result-struct:hover", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-struct:hover .struct", + {"color": "rgb(255, 160, 165)"}, +) +move-cursor-to: ".search-input" +focus: ".result-struct" +assert-css: ( + ".result-struct:focus", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-struct:focus .struct", + {"color": "rgb(255, 160, 165)"}, +) + // Check the color of "associated type". assert-css: ( - ".result-name .associatedtype", + ".result-associatedtype .associatedtype", {"color": "rgb(57, 175, 215)"}, ALL, ) +assert-css: ( + ".result-associatedtype", + {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-associatedtype" +assert-css: ( + ".result-associatedtype:hover", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-associatedtype:hover .associatedtype", + {"color": "rgb(57, 175, 215)"}, +) +move-cursor-to: ".search-input" +focus: ".result-associatedtype" +assert-css: ( + ".result-associatedtype:focus", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-associatedtype:focus .associatedtype", + {"color": "rgb(57, 175, 215)"}, +) + // Check the color of "type method". assert-css: ( - ".result-name .tymethod", + ".result-tymethod .tymethod", {"color": "rgb(253, 214, 135)"}, ALL, ) +assert-css: ( + ".result-tymethod", + {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, +) +assert-css: ( + ".result-tymethod .tymethod", + {"color": "rgb(253, 214, 135)"}, +) +move-cursor-to: ".result-tymethod" +assert-css: ( + ".result-tymethod:hover", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +move-cursor-to: ".search-input" +focus: ".result-tymethod" +assert-css: ( + ".result-tymethod:focus", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) + // Check the color of "method". assert-css: ( - ".result-name .method", + ".result-method .method", {"color": "rgb(253, 214, 135)"}, ALL, ) +assert-css: ( + ".result-method", + {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-method" +assert-css: ( + ".result-method:hover", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-method:hover .method", + {"color": "rgb(253, 214, 135)"}, +) +move-cursor-to: ".search-input" +focus: ".result-method" +assert-css: ( + ".result-method:focus", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-method:focus .method", + {"color": "rgb(253, 214, 135)"}, +) + // Check the color of "struct field". assert-css: ( - ".result-name .structfield", + ".result-structfield .structfield", {"color": "rgb(0, 150, 207)"}, ALL, ) +assert-css: ( + ".result-structfield", + {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-structfield" +assert-css: ( + ".result-structfield:hover", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-structfield:hover .structfield", + {"color": "rgb(255, 255, 255)"}, +) +move-cursor-to: ".search-input" +focus: ".result-structfield" +assert-css: ( + ".result-structfield:focus", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-structfield:focus .structfield", + {"color": "rgb(255, 255, 255)"}, +) + // Check the color of "macro". assert-css: ( - ".result-name .macro", + ".result-macro .macro", {"color": "rgb(163, 122, 204)"}, ALL, ) +assert-css: ( + ".result-macro", + {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-macro" +assert-css: ( + ".result-macro:hover", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-macro:hover .macro", + {"color": "rgb(163, 122, 204)"}, +) +move-cursor-to: ".search-input" +focus: ".result-macro" +assert-css: ( + ".result-macro:focus", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-macro:focus .macro", + {"color": "rgb(163, 122, 204)"}, +) + // Check the color of "fn". assert-css: ( - ".result-name .fn", + ".result-fn .fn", {"color": "rgb(253, 214, 135)"}, ALL, ) +assert-css: ( + ".result-fn", + {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-fn" +assert-css: ( + ".result-fn:hover", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-fn:hover .fn", + {"color": "rgb(253, 214, 135)"}, +) +move-cursor-to: ".search-input" +focus: ".result-fn" +assert-css: ( + ".result-fn:focus", + {"color": "rgb(255, 255, 255)", "background-color": "rgb(60, 60, 60)"}, +) +assert-css: ( + ".result-fn:focus .fn", + {"color": "rgb(253, 214, 135)"}, +) // Checking the `<a>` container. +move-cursor-to: ".search-input" +focus: ".search-input" // To ensure the `<a>` container isnt focus or hover. assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a", {"color": "rgb(0, 150, 207)", "background-color": "rgba(0, 0, 0, 0)"}, @@ -113,7 +302,7 @@ assert-css: ( {"color": "rgb(221, 221, 221)"}, ) -// Checking the color for "keyword". +// Checking the color for "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", {"color": "rgb(221, 221, 221)"}, @@ -121,68 +310,250 @@ assert-css: ( // Checking the color of "keyword". assert-css: ( - ".result-name .keyword", + ".result-keyword .keyword", {"color": "rgb(210, 153, 29)"}, ALL, ) +assert-css: ( + ".result-keyword", + {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-keyword" +assert-css: ( + ".result-keyword:hover", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-keyword:hover .keyword", + {"color": "rgb(210, 153, 29)"}, +) +move-cursor-to: ".search-input" +focus: ".result-keyword" +assert-css: ( + ".result-keyword:focus", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-keyword:focus .keyword", + {"color": "rgb(210, 153, 29)"}, +) + // Check the color of "struct". assert-css: ( - ".result-name .struct", + ".result-struct .struct", {"color": "rgb(45, 191, 184)"}, ALL, ) +assert-css: ( + ".result-struct", + {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-struct" +assert-css: ( + ".result-struct:hover", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-struct:hover .struct", + {"color": "rgb(45, 191, 184)"}, +) +move-cursor-to: ".search-input" +focus: ".result-struct" +assert-css: ( + ".result-struct:focus", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-struct:focus .struct", + {"color": "rgb(45, 191, 184)"}, +) + // Check the color of "associated type". assert-css: ( - ".result-name .associatedtype", + ".result-associatedtype .associatedtype", {"color": "rgb(210, 153, 29)"}, ALL, ) +assert-css: ( + ".result-associatedtype", + {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-associatedtype" +assert-css: ( + ".result-associatedtype:hover", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-associatedtype:hover .associatedtype", + {"color": "rgb(210, 153, 29)"}, +) +move-cursor-to: ".search-input" +focus: ".result-associatedtype" +assert-css: ( + ".result-associatedtype:focus", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-associatedtype:focus .associatedtype", + {"color": "rgb(210, 153, 29)"}, +) + // Check the color of "type method". assert-css: ( - ".result-name .tymethod", + ".result-tymethod .tymethod", {"color": "rgb(43, 171, 99)"}, ALL, ) +assert-css: ( + ".result-tymethod", + {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-tymethod" +assert-css: ( + ".result-tymethod:hover", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-tymethod:hover .tymethod", + {"color": "rgb(43, 171, 99)"}, +) +move-cursor-to: ".search-input" +focus: ".result-tymethod" +assert-css: ( + ".result-tymethod:focus", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-tymethod:focus .tymethod", + {"color": "rgb(43, 171, 99)"}, +) + // Check the color of "method". assert-css: ( - ".result-name .method", + ".result-method .method", {"color": "rgb(43, 171, 99)"}, ALL, ) +assert-css: ( + ".result-method", + {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-method" +assert-css: ( + ".result-method:hover", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-method:hover .method", + {"color": "rgb(43, 171, 99)"}, +) +move-cursor-to: ".search-input" +focus: ".result-method" +assert-css: ( + ".result-method:focus", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-method:focus .method", + {"color": "rgb(43, 171, 99)"}, +) + // Check the color of "struct field". assert-css: ( - ".result-name .structfield", + ".result-structfield .structfield", {"color": "rgb(221, 221, 221)"}, ALL, ) +assert-css: ( + ".result-structfield", + {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-structfield" +assert-css: ( + ".result-structfield:hover", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-structfield:hover .structfield", + {"color": "rgb(221, 221, 221)"}, +) +move-cursor-to: ".search-input" +focus: ".result-structfield" +assert-css: ( + ".result-structfield:focus", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-structfield:focus .structfield", + {"color": "rgb(221, 221, 221)"}, +) + // Check the color of "macro". assert-css: ( - ".result-name .macro", + ".result-macro .macro", {"color": "rgb(9, 189, 0)"}, ALL, ) +assert-css: ( + ".result-macro", + {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-macro" +assert-css: ( + ".result-macro:hover", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-macro:hover .macro", + {"color": "rgb(9, 189, 0)"}, +) +move-cursor-to: ".search-input" +focus: ".result-macro" +assert-css: ( + ".result-macro:focus", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-macro:focus .macro", + {"color": "rgb(9, 189, 0)"}, +) + // Check the color of "fn". assert-css: ( - ".result-name .fn", + ".result-fn .fn", {"color": "rgb(43, 171, 99)"}, ALL, ) - -// Checking the `<a>` container. assert-css: ( - "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a", + ".result-fn", {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, ) - -// Checking color and background on hover. -move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']" +move-cursor-to: ".result-fn" assert-css: ( - "//*[@class='result-name']/*[text()='test_docs::']", - {"color": "rgb(221, 221, 221)"}, + ".result-fn:hover", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, ) assert-css: ( + ".result-fn:hover .fn", + {"color": "rgb(43, 171, 99)"}, +) +move-cursor-to: ".search-input" +focus: ".result-fn" +assert-css: ( + ".result-fn:focus", + {"color": "rgb(221, 221, 221)", "background-color": "rgb(97, 97, 97)"}, +) +assert-css: ( + ".result-fn:focus .fn", + {"color": "rgb(43, 171, 99)"}, +) + +// Checking the `<a>` container. +move-cursor-to: ".search-input" +focus: ".search-input" // To ensure the `<a>` container isnt focus or hover. +assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a", - {"color": "rgb(221, 221, 221)", "background-color": "rgb(119, 119, 119)"}, + {"color": "rgb(221, 221, 221)", "background-color": "rgba(0, 0, 0, 0)"}, ) // Light theme @@ -200,7 +571,7 @@ assert-css: ( {"color": "rgb(0, 0, 0)"}, ) -// Checking the color for "keyword". +// Checking the color for "keyword" text. assert-css: ( "//*[@class='result-name']//*[text()='(keyword)']", {"color": "rgb(0, 0, 0)"}, @@ -208,68 +579,250 @@ assert-css: ( // Checking the color of "keyword". assert-css: ( - ".result-name .keyword", + ".result-keyword .keyword", {"color": "rgb(56, 115, 173)"}, ALL, ) +assert-css: ( + ".result-keyword", + {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-keyword" +assert-css: ( + ".result-keyword:hover", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-keyword:hover .keyword", + {"color": "rgb(56, 115, 173)"}, +) +move-cursor-to: ".search-input" +focus: ".result-keyword" +assert-css: ( + ".result-keyword:focus", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-keyword:focus .keyword", + {"color": "rgb(56, 115, 173)"}, +) + // Check the color of "struct". assert-css: ( - ".result-name .struct", + ".result-struct .struct", {"color": "rgb(173, 55, 138)"}, ALL, ) +assert-css: ( + ".result-struct", + {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-struct" +assert-css: ( + ".result-struct:hover", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-struct:hover .struct", + {"color": "rgb(173, 55, 138)"}, +) +move-cursor-to: ".search-input" +focus: ".result-struct" +assert-css: ( + ".result-struct:focus", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-struct:focus .struct", + {"color": "rgb(173, 55, 138)"}, +) + // Check the color of "associated type". assert-css: ( - ".result-name .associatedtype", + ".result-associatedtype .associatedtype", {"color": "rgb(56, 115, 173)"}, ALL, ) +assert-css: ( + ".result-associatedtype", + {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-associatedtype" +assert-css: ( + ".result-associatedtype:hover", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-associatedtype:hover .associatedtype", + {"color": "rgb(56, 115, 173)"}, +) +move-cursor-to: ".search-input" +focus: ".result-associatedtype" +assert-css: ( + ".result-associatedtype:focus", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-associatedtype:focus .associatedtype", + {"color": "rgb(56, 115, 173)"}, +) + // Check the color of "type method". assert-css: ( - ".result-name .tymethod", + ".result-tymethod .tymethod", {"color": "rgb(173, 124, 55)"}, ALL, ) +assert-css: ( + ".result-tymethod", + {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-tymethod" +assert-css: ( + ".result-tymethod:hover", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-tymethod:hover .tymethod", + {"color": "rgb(173, 124, 55)"}, +) +move-cursor-to: ".search-input" +focus: ".result-tymethod" +assert-css: ( + ".result-tymethod:focus", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-tymethod:focus .tymethod", + {"color": "rgb(173, 124, 55)"}, +) + // Check the color of "method". assert-css: ( - ".result-name .method", + ".result-method .method", {"color": "rgb(173, 124, 55)"}, ALL, ) +assert-css: ( + ".result-method", + {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-method" +assert-css: ( + ".result-method:hover", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-method:hover .method", + {"color": "rgb(173, 124, 55)"}, +) +move-cursor-to: ".search-input" +focus: ".result-method" +assert-css: ( + ".result-method:focus", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-method:focus .method", + {"color": "rgb(173, 124, 55)"}, +) + // Check the color of "struct field". assert-css: ( - ".result-name .structfield", + ".result-structfield .structfield", {"color": "rgb(0, 0, 0)"}, ALL, ) +assert-css: ( + ".result-structfield", + {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-structfield" +assert-css: ( + ".result-structfield:hover", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-structfield:hover .structfield", + {"color": "rgb(0, 0, 0)"}, +) +move-cursor-to: ".search-input" +focus: ".result-structfield" +assert-css: ( + ".result-structfield:focus", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-structfield:focus .structfield", + {"color": "rgb(0, 0, 0)"}, +) + // Check the color of "macro". assert-css: ( - ".result-name .macro", + ".result-macro .macro", {"color": "rgb(6, 128, 0)"}, ALL, ) +assert-css: ( + ".result-macro", + {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".result-macro" +assert-css: ( + ".result-macro:hover", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-macro:hover .macro", + {"color": "rgb(6, 128, 0)"}, +) +move-cursor-to: ".search-input" +focus: ".result-macro" +assert-css: ( + ".result-macro:focus", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-macro:focus .macro", + {"color": "rgb(6, 128, 0)"}, +) + // Check the color of "fn". assert-css: ( - ".result-name .fn", + ".result-fn .fn", {"color": "rgb(173, 124, 55)"}, ALL, ) - -// Checking the `<a>` container. assert-css: ( - "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a", + ".result-fn", {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, ) - -// Checking color and background on hover. -move-cursor-to: "//*[@class='desc']//*[text()='Just a normal struct.']" +move-cursor-to: ".result-fn" assert-css: ( - "//*[@class='result-name']/*[text()='test_docs::']", - {"color": "rgb(0, 0, 0)"}, + ".result-fn:hover", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, ) assert-css: ( + ".result-fn:hover .fn", + {"color": "rgb(173, 124, 55)"}, +) +move-cursor-to: ".search-input" +focus: ".result-fn" +assert-css: ( + ".result-fn:focus", + {"color": "rgb(0, 0, 0)", "background-color": "rgb(204, 204, 204)"}, +) +assert-css: ( + ".result-fn:focus .fn", + {"color": "rgb(173, 124, 55)"}, +) + +// Checking the `<a>` container. +move-cursor-to: ".search-input" +focus: ".search-input" // To ensure the `<a>` container isnt focus or hover. +assert-css: ( "//*[@class='result-name']/*[text()='test_docs::']/ancestor::a", - {"color": "rgb(0, 0, 0)", "background-color": "rgb(221, 221, 221)"}, + {"color": "rgb(0, 0, 0)", "background-color": "rgba(0, 0, 0, 0)"}, ) // Check the alias more specifically in the dark theme. diff --git a/src/test/rustdoc-gui/sidebar-links-color.goml b/src/test/rustdoc-gui/sidebar-links-color.goml new file mode 100644 index 00000000000..d2a1688080c --- /dev/null +++ b/src/test/rustdoc-gui/sidebar-links-color.goml @@ -0,0 +1,233 @@ +// This test checks links colors in sidebar before and after hover. +goto: file://|DOC_PATH|/test_docs/struct.Foo.html + +// This is needed so that the text color is computed. +show-text: true + +// Ayu theme +local-storage: { + "rustdoc-theme": "ayu", + "rustdoc-use-system-theme": "false", +} +reload: + +// Struct +assert-css: ( + ".sidebar a.struct:not(.current)", + {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.struct:not(.current)" +assert-css: ( + ".sidebar a.struct:hover", + {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, +) +// Enum +assert-css: ( + ".sidebar a.enum", + {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.enum" +assert-css: ( + ".sidebar a.enum:hover", + {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, +) +// Union +assert-css: ( + ".sidebar a.union", + {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.union" +assert-css: ( + ".sidebar a.union:hover", + {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, +) +// Trait +assert-css: ( + ".sidebar a.trait", + {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.trait" +assert-css: ( + ".sidebar a.trait:hover", + {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, +) +// Function +assert-css: ( + ".sidebar a.fn", + {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.fn" +assert-css: ( + ".sidebar a.fn:hover", + {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, +) +// Type definition +assert-css: ( + ".sidebar a.type", + {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.type" +assert-css: ( + ".sidebar a.type:hover", + {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, +) +// Keyword +assert-css: ( + ".sidebar a.keyword", + {"color": "rgb(83, 177, 219)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.keyword" +assert-css: ( + ".sidebar a.keyword:hover", + {"color": "rgb(255, 180, 76)", "background-color": "rgba(0, 0, 0, 0)"}, +) + +// Dark theme +local-storage: {"rustdoc-theme": "dark"} +reload: + +// Struct +assert-css: ( + ".sidebar a.struct:not(.current)", + {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.struct:not(.current)" +assert-css: ( + ".sidebar a.struct:hover", + {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, +) +// Enum +assert-css: ( + ".sidebar a.enum", + {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.enum" +assert-css: ( + ".sidebar a.enum:hover", + {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, +) +// Union +assert-css: ( + ".sidebar a.union", + {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.union" +assert-css: ( + ".sidebar a.union:hover", + {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, +) +// Trait +assert-css: ( + ".sidebar a.trait", + {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.trait" +assert-css: ( + ".sidebar a.trait:hover", + {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, +) +// Function +assert-css: ( + ".sidebar a.fn", + {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.fn" +assert-css: ( + ".sidebar a.fn:hover", + {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, +) +// Type definition +assert-css: ( + ".sidebar a.type", + {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.type" +assert-css: ( + ".sidebar a.type:hover", + {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, +) +// Keyword +assert-css: ( + ".sidebar a.keyword", + {"color": "rgb(253, 191, 53)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.keyword" +assert-css: ( + ".sidebar a.keyword:hover", + {"color": "rgb(253, 191, 53)", "background-color": "rgb(68, 68, 68)"}, +) + +// Light theme +local-storage: {"rustdoc-theme": "light"} +reload: + +// Struct +assert-css: ( + ".sidebar a.struct:not(.current)", + {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.struct:not(.current)" +assert-css: ( + ".sidebar a.struct:hover", + {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, +) +// Enum +assert-css: ( + ".sidebar a.enum", + {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.enum" +assert-css: ( + ".sidebar a.enum:hover", + {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, +) +// Union +assert-css: ( + ".sidebar a.union", + {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.union" +assert-css: ( + ".sidebar a.union:hover", + {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, +) +// Trait +assert-css: ( + ".sidebar a.trait", + {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.trait" +assert-css: ( + ".sidebar a.trait:hover", + {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, +) +// Function +assert-css: ( + ".sidebar a.fn", + {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.fn" +assert-css: ( + ".sidebar a.fn:hover", + {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, +) +// Type definition +assert-css: ( + ".sidebar a.type", + {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.type" +assert-css: ( + ".sidebar a.type:hover", + {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, +) +// Keyword +assert-css: ( + ".sidebar a.keyword", + {"color": "rgb(53, 109, 164)", "background-color": "rgba(0, 0, 0, 0)"}, +) +move-cursor-to: ".sidebar a.keyword" +assert-css: ( + ".sidebar a.keyword:hover", + {"color": "rgb(53, 109, 164)", "background-color": "rgb(255, 255, 255)"}, +) diff --git a/src/test/rustdoc-gui/sidebar-mobile-scroll.goml b/src/test/rustdoc-gui/sidebar-mobile-scroll.goml index 9af7c636a0c..6cb492cfc64 100644 --- a/src/test/rustdoc-gui/sidebar-mobile-scroll.goml +++ b/src/test/rustdoc-gui/sidebar-mobile-scroll.goml @@ -6,7 +6,7 @@ assert-css: (".sidebar", {"display": "block", "left": "-1000px"}) // Scroll down. scroll-to: "//h2[@id='blanket-implementations']" -assert-window-property: {"pageYOffset": "639"} +assert-window-property: {"pageYOffset": "651"} // Open the sidebar menu. click: ".sidebar-menu-toggle" @@ -21,11 +21,11 @@ assert-window-property: {"pageYOffset": "0"} // Close the sidebar menu. Make sure the scroll position gets restored. click: ".sidebar-menu-toggle" wait-for-css: (".sidebar", {"left": "-1000px"}) -assert-window-property: {"pageYOffset": "639"} +assert-window-property: {"pageYOffset": "651"} // Now test that scrollability returns when the browser window is just resized. click: ".sidebar-menu-toggle" wait-for-css: (".sidebar", {"left": "0px"}) assert-window-property: {"pageYOffset": "0"} size: (900, 600) -assert-window-property: {"pageYOffset": "639"} +assert-window-property: {"pageYOffset": "651"} diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml index 033c6578349..04dcb532504 100644 --- a/src/test/rustdoc-gui/sidebar-mobile.goml +++ b/src/test/rustdoc-gui/sidebar-mobile.goml @@ -42,23 +42,24 @@ scroll-to: ".block.keyword li:nth-child(1)" compare-elements-position-near: (".block.keyword li:nth-child(1)", ".mobile-topbar", {"y": 543}) // Now checking the background color of the sidebar. +show-text: true local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"} reload: // Open the sidebar menu. click: ".sidebar-menu-toggle" -assert-css: (".sidebar", {"background-color": "rgb(80, 80, 80)"}) +assert-css: (".sidebar", {"background-color": "rgb(80, 80, 80)", "color": "rgb(221, 221, 221)"}) local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "ayu"} reload: // Open the sidebar menu. click: ".sidebar-menu-toggle" -assert-css: (".sidebar", {"background-color": "rgb(20, 25, 31)"}) +assert-css: (".sidebar", {"background-color": "rgb(20, 25, 31)", "color": "rgb(197, 197, 197)"}) local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "light"} reload: // Open the sidebar menu. click: ".sidebar-menu-toggle" -assert-css: (".sidebar", {"background-color": "rgb(245, 245, 245)"}) +assert-css: (".sidebar", {"background-color": "rgb(245, 245, 245)", "color": "rgb(0, 0, 0)"}) diff --git a/src/test/rustdoc-gui/sidebar-source-code-display.goml b/src/test/rustdoc-gui/sidebar-source-code-display.goml index 4321efcdb17..24d1820ff27 100644 --- a/src/test/rustdoc-gui/sidebar-source-code-display.goml +++ b/src/test/rustdoc-gui/sidebar-source-code-display.goml @@ -3,20 +3,17 @@ javascript: false goto: file://|DOC_PATH|/src/test_docs/lib.rs.html // Since the javascript is disabled, there shouldn't be a toggle. assert-false: "#sidebar-toggle" -// For some reason, we need to wait a bit here because it seems like the transition on opacity -// is being applied whereas it can't be reproduced in a browser... -wait-for-css: (".sidebar > *", {"visibility": "hidden", "opacity": 0}) +wait-for-css: (".sidebar > *", {"visibility": "hidden"}) // Let's retry with javascript enabled. javascript: true reload: wait-for: "#sidebar-toggle" -assert-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1}) -assert-css: (".sidebar > *:not(#sidebar-toggle)", {"visibility": "hidden", "opacity": 0}) +assert-css: ("#sidebar-toggle", {"visibility": "visible"}) +assert-css: (".sidebar > *:not(#sidebar-toggle)", {"visibility": "hidden"}) // Let's expand the sidebar now. click: "#sidebar-toggle" -// Because of the transition CSS, we check by using `wait-for-css` instead of `assert-css`. -wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1}) +wait-for-css: ("#sidebar-toggle", {"visibility": "visible"}) // We now check that opening the sidebar and clicking a link will leave it open. // The behavior here on desktop is different than the behavior on mobile, @@ -36,7 +33,7 @@ show-text: true local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"} reload: // Waiting for the sidebar to be displayed... -wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1}) +wait-for-css: ("#sidebar-toggle", {"visibility": "visible"}) assert-css: ( "#source-sidebar details[open] > .files a.selected", {"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"}, @@ -91,7 +88,7 @@ assert-css: ( local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"} reload: // Waiting for the sidebar to be displayed... -wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1}) +wait-for-css: ("#sidebar-toggle", {"visibility": "visible"}) assert-css: ( "#source-sidebar details[open] > .files > a.selected", {"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"}, @@ -146,7 +143,7 @@ assert-css: ( local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"} reload: // Waiting for the sidebar to be displayed... -wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1}) +wait-for-css: ("#sidebar-toggle", {"visibility": "visible"}) assert-css: ( "#source-sidebar details[open] > .files a.selected", {"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"}, @@ -201,7 +198,7 @@ assert-css: ( size: (500, 700) reload: // Waiting for the sidebar to be displayed... -wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1}) +wait-for-css: ("#sidebar-toggle", {"visibility": "visible"}) // We now check it takes the full size of the display. assert-property: ("body", {"clientWidth": "500", "clientHeight": "700"}) diff --git a/src/test/rustdoc-gui/src-font-size.goml b/src/test/rustdoc-gui/src-font-size.goml index 9797f196c55..ebb413b8c41 100644 --- a/src/test/rustdoc-gui/src-font-size.goml +++ b/src/test/rustdoc-gui/src-font-size.goml @@ -4,8 +4,8 @@ goto: file://|DOC_PATH|/test_docs/struct.Foo.html show-text: true // Check the impl headers. -assert-css: (".impl.has-srclink .srclink", {"font-size": "16px"}, ALL) -assert-css: (".impl.has-srclink .code-header", {"font-size": "18px"}, ALL) +assert-css: (".impl.has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL) +assert-css: (".impl.has-srclink .code-header", {"font-size": "18px", "font-weight": 600}, ALL) // Check the impl items. -assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px"}, ALL) -assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px"}, ALL) +assert-css: (".impl-items .has-srclink .srclink", {"font-size": "16px", "font-weight": 400}, ALL) +assert-css: (".impl-items .has-srclink .code-header", {"font-size": "16px", "font-weight": 600}, ALL) diff --git a/src/test/rustdoc-gui/src/test_docs/lib.rs b/src/test/rustdoc-gui/src/test_docs/lib.rs index 1c066206c1f..0281973c1ba 100644 --- a/src/test/rustdoc-gui/src/test_docs/lib.rs +++ b/src/test/rustdoc-gui/src/test_docs/lib.rs @@ -355,3 +355,15 @@ impl<R: std::io::Read> std::iter::Iterator for NotableStructWithLongName<R> { fn next(&mut self) -> Option<Self::Item> { () } } + +pub trait TraitWithNoDocblocks { + fn first_fn(&self); + fn second_fn(&self); +} + +pub struct TypeWithNoDocblocks; + +impl TypeWithNoDocblocks { + pub fn first_fn(&self) {} + pub fn second_fn(&self) {} +} diff --git a/src/test/rustdoc-js-std/asrawfd.js b/src/test/rustdoc-js-std/asrawfd.js index fd228a59099..369a34f9c6e 100644 --- a/src/test/rustdoc-js-std/asrawfd.js +++ b/src/test/rustdoc-js-std/asrawfd.js @@ -6,9 +6,9 @@ const EXPECTED = { 'others': [ // Reproduction test for https://github.com/rust-lang/rust/issues/78724 // Validate that type alias methods get the correct path. - { 'path': 'std::os::unix::io::AsRawFd', 'name': 'as_raw_fd' }, - { 'path': 'std::os::wasi::io::AsRawFd', 'name': 'as_raw_fd' }, + { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' }, + { 'path': 'std::os::fd::AsRawFd', 'name': 'as_raw_fd' }, { 'path': 'std::os::linux::process::PidFd', 'name': 'as_raw_fd' }, - { 'path': 'std::os::unix::io::RawFd', 'name': 'as_raw_fd' }, + { 'path': 'std::os::fd::RawFd', 'name': 'as_raw_fd' }, ], }; diff --git a/src/test/rustdoc-ui/bare-urls.stderr b/src/test/rustdoc-ui/bare-urls.stderr index 7097a8ddf3a..ccf52cd0b93 100644 --- a/src/test/rustdoc-ui/bare-urls.stderr +++ b/src/test/rustdoc-ui/bare-urls.stderr @@ -4,12 +4,12 @@ error: this URL is not a hyperlink LL | /// https://somewhere.com | ^^^^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<https://somewhere.com>` | + = note: bare URLs are not automatically turned into clickable links note: the lint level is defined here --> $DIR/bare-urls.rs:3:9 | LL | #![deny(rustdoc::bare_urls)] | ^^^^^^^^^^^^^^^^^^ - = note: bare URLs are not automatically turned into clickable links error: this URL is not a hyperlink --> $DIR/bare-urls.rs:7:5 diff --git a/src/test/rustdoc-ui/check-attr-test.stderr b/src/test/rustdoc-ui/check-attr-test.stderr index b1fa9edf0e4..01beba1ffc4 100644 --- a/src/test/rustdoc-ui/check-attr-test.stderr +++ b/src/test/rustdoc-ui/check-attr-test.stderr @@ -8,12 +8,12 @@ error: unknown attribute `compile-fail`. Did you mean `compile_fail`? 9 | | /// ``` | |_______^ | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully note: the lint level is defined here --> $DIR/check-attr-test.rs:3:9 | 3 | #![deny(rustdoc::invalid_codeblock_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully error: unknown attribute `compilefail`. Did you mean `compile_fail`? --> $DIR/check-attr-test.rs:5:1 diff --git a/src/test/rustdoc-ui/check-attr.stderr b/src/test/rustdoc-ui/check-attr.stderr index 370b804c56c..f66e63ab727 100644 --- a/src/test/rustdoc-ui/check-attr.stderr +++ b/src/test/rustdoc-ui/check-attr.stderr @@ -10,12 +10,12 @@ LL | | /// boo LL | | /// ``` | |_______^ | + = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully note: the lint level is defined here --> $DIR/check-attr.rs:1:9 | LL | #![deny(rustdoc::invalid_codeblock_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: the code block will either not be tested if not marked as a rust one or won't fail if it compiles successfully error: unknown attribute `compilefail`. Did you mean `compile_fail`? --> $DIR/check-attr.rs:3:1 diff --git a/src/test/rustdoc-ui/check-cfg-test.stderr b/src/test/rustdoc-ui/check-cfg-test.stderr index dc25205da77..9770be2f191 100644 --- a/src/test/rustdoc-ui/check-cfg-test.stderr +++ b/src/test/rustdoc-ui/check-cfg-test.stderr @@ -4,8 +4,8 @@ warning: unexpected `cfg` condition value LL | #[cfg(feature = "invalid")] | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unexpected_cfgs)]` on by default = note: expected values for `feature` are: test + = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr index 217b89d935b..d8aeccbfc31 100644 --- a/src/test/rustdoc-ui/check-fail.stderr +++ b/src/test/rustdoc-ui/check-fail.stderr @@ -32,8 +32,8 @@ LL | | //! let x = 12; LL | | //! ``` | |_______^ | - = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]` = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + = note: `#[deny(rustdoc::invalid_codeblock_attributes)]` implied by `#[deny(rustdoc::all)]` error: unknown attribute `testharness`. Did you mean `test_harness`? --> $DIR/check-fail.rs:16:1 diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr index 78ae65d313a..d379f33f2bd 100644 --- a/src/test/rustdoc-ui/check.stderr +++ b/src/test/rustdoc-ui/check.stderr @@ -24,14 +24,14 @@ LL | pub fn foo() {} warning: no documentation found for this crate's top-level module | + = help: The following guide may be of use: + https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html note: the lint level is defined here --> $DIR/check.rs:10:9 | LL | #![warn(rustdoc::all)] | ^^^^^^^^^^^^ = note: `#[warn(rustdoc::missing_crate_level_docs)]` implied by `#[warn(rustdoc::all)]` - = help: The following guide may be of use: - https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html warning: missing code example in this documentation --> $DIR/check.rs:5:1 diff --git a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr index 67d9c3989f5..3e08354a61d 100644 --- a/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr +++ b/src/test/rustdoc-ui/deny-intra-link-resolution-failure.stderr @@ -4,12 +4,12 @@ error: unresolved link to `v2` LL | /// [v2] | ^^ no item named `v2` in scope | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here --> $DIR/deny-intra-link-resolution-failure.rs:1:9 | LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/diagnostic-width.stderr b/src/test/rustdoc-ui/diagnostic-width.stderr index fed049d2b37..1a00d10d3fc 100644 --- a/src/test/rustdoc-ui/diagnostic-width.stderr +++ b/src/test/rustdoc-ui/diagnostic-width.stderr @@ -4,12 +4,12 @@ error: this URL is not a hyperlink LL | ... a http://link.com | ^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://link.com>` | + = note: bare URLs are not automatically turned into clickable links note: the lint level is defined here --> $DIR/diagnostic-width.rs:2:9 | LL | ...ny(rustdoc::bare_url... | ^^^^^^^^^^^^^^^^^^ - = note: bare URLs are not automatically turned into clickable links error: aborting due to previous error diff --git a/src/test/rustdoc-ui/doc-attr.stderr b/src/test/rustdoc-ui/doc-attr.stderr index cc2494c92e6..68df2771fd7 100644 --- a/src/test/rustdoc-ui/doc-attr.stderr +++ b/src/test/rustdoc-ui/doc-attr.stderr @@ -4,14 +4,14 @@ error: unknown `doc` attribute `as_ptr` LL | #[doc(as_ptr)] | ^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> note: the lint level is defined here --> $DIR/doc-attr.rs:2:9 | LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> error: invalid `doc` attribute --> $DIR/doc-attr.rs:12:7 diff --git a/src/test/rustdoc-ui/doc-include-suggestion.stderr b/src/test/rustdoc-ui/doc-include-suggestion.stderr index 870b7efa2ac..fcc93d0532a 100644 --- a/src/test/rustdoc-ui/doc-include-suggestion.stderr +++ b/src/test/rustdoc-ui/doc-include-suggestion.stderr @@ -4,9 +4,9 @@ warning: unknown `doc` attribute `include` LL | #[doc(include = "external-cross-doc.md")] | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- help: use `doc = include_str!` instead: `#[doc = include_str!("external-cross-doc.md")]` | - = note: `#[warn(invalid_doc_attributes)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: `#[warn(invalid_doc_attributes)]` on by default warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/doc-spotlight.stderr b/src/test/rustdoc-ui/doc-spotlight.stderr index 8e7831139a8..58612327ff9 100644 --- a/src/test/rustdoc-ui/doc-spotlight.stderr +++ b/src/test/rustdoc-ui/doc-spotlight.stderr @@ -4,16 +4,16 @@ error: unknown `doc` attribute `spotlight` LL | #[doc(spotlight)] | ^^^^^^^^^ help: use `notable_trait` instead | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: `doc(spotlight)` was renamed to `doc(notable_trait)` + = note: `doc(spotlight)` is now a no-op note: the lint level is defined here --> $DIR/doc-spotlight.rs:2:9 | LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> - = note: `doc(spotlight)` was renamed to `doc(notable_trait)` - = note: `doc(spotlight)` is now a no-op error: aborting due to previous error diff --git a/src/test/rustdoc-ui/doc-test-attr.stderr b/src/test/rustdoc-ui/doc-test-attr.stderr index 7f5e2d6bc70..5e6014954a4 100644 --- a/src/test/rustdoc-ui/doc-test-attr.stderr +++ b/src/test/rustdoc-ui/doc-test-attr.stderr @@ -4,13 +4,13 @@ error: `#[doc(test(...)]` takes a list of attributes LL | #![doc(test)] | ^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> note: the lint level is defined here --> $DIR/doc-test-attr.rs:2:9 | LL | #![deny(invalid_doc_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> error: `#[doc(test(...)]` takes a list of attributes --> $DIR/doc-test-attr.rs:7:8 diff --git a/src/test/rustdoc-ui/doctest-edition.stderr b/src/test/rustdoc-ui/doctest-edition.stderr index 1643d605375..8a3329aa3ed 100644 --- a/src/test/rustdoc-ui/doctest-edition.stderr +++ b/src/test/rustdoc-ui/doctest-edition.stderr @@ -7,12 +7,12 @@ LL | | //! foo'b' LL | | //! ``` | |_______^ | + = note: error from rustc: prefix `foo` is unknown note: the lint level is defined here --> $DIR/doctest-edition.rs:3:9 | LL | #![deny(rustdoc::invalid_rust_codeblocks)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: error from rustc: prefix `foo` is unknown help: mark blocks that do not contain Rust code as text | LL | //! ```text diff --git a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr index 517e08aa7c9..cbe9a3d14af 100644 --- a/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr +++ b/src/test/rustdoc-ui/feature-gate-rustdoc_missing_doc_code_examples.stderr @@ -4,14 +4,14 @@ error: unknown lint: `rustdoc::missing_doc_code_examples` LL | #![allow(rustdoc::missing_doc_code_examples)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: the `rustdoc::missing_doc_code_examples` lint is unstable + = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information + = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable note: the lint level is defined here --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:1:9 | LL | #![deny(unknown_lints)] | ^^^^^^^^^^^^^ - = note: the `rustdoc::missing_doc_code_examples` lint is unstable - = note: see issue #101730 <https://github.com/rust-lang/rust/issues/101730> for more information - = help: add `#![feature(rustdoc_missing_doc_code_examples)]` to the crate attributes to enable error: unknown lint: `rustdoc::missing_doc_code_examples` --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1 diff --git a/src/test/rustdoc-ui/ignore-block-help.stderr b/src/test/rustdoc-ui/ignore-block-help.stderr index 9c02ff11d19..a30ea51dd8a 100644 --- a/src/test/rustdoc-ui/ignore-block-help.stderr +++ b/src/test/rustdoc-ui/ignore-block-help.stderr @@ -7,13 +7,13 @@ LL | | /// let heart = '❤️'; LL | | /// ``` | |_______^ | - = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default help: `ignore` code blocks require valid Rust code for syntax highlighting; mark blocks that do not contain Rust code as text: ```text --> $DIR/ignore-block-help.rs:3:5 | LL | /// ```ignore (to-prevent-tidy-error) | ^^^ = note: error from rustc: character literal may only contain one codepoint + = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr b/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr index 00fe229da40..7c81044dbf8 100644 --- a/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr +++ b/src/test/rustdoc-ui/intra-doc/html-as-generics-intra-doc.stderr @@ -4,12 +4,12 @@ error: unresolved link to `NonExistentStruct` LL | /// This [test][NonExistentStruct<i32>] thing! | ^^^^^^^^^^^^^^^^^^^^^^ no item named `NonExistentStruct` in scope | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here --> $DIR/html-as-generics-intra-doc.rs:2:9 | LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: unresolved link to `NonExistentStruct2` --> $DIR/html-as-generics-intra-doc.rs:17:11 diff --git a/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr b/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr index 8e17323fdde..6ad8084b09c 100644 --- a/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr +++ b/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr @@ -4,12 +4,12 @@ error: unresolved link to `before_but_limited_to_module` LL | /// [before_but_limited_to_module] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `before_but_limited_to_module` in scope | + = note: `macro_rules` named `before_but_limited_to_module` exists in this crate, but it is not in scope at this link's location note: the lint level is defined here --> $DIR/macro-rules-error.rs:5:9 | LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: `macro_rules` named `before_but_limited_to_module` exists in this crate, but it is not in scope at this link's location error: unresolved link to `after` --> $DIR/macro-rules-error.rs:15:6 diff --git a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr index 4828a304463..8ec894d101b 100644 --- a/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr +++ b/src/test/rustdoc-ui/intra-doc/non-path-primitives.stderr @@ -4,12 +4,12 @@ error: unresolved link to `T` LL | //! [[T]::rotate_left] | ^ no item named `T` in scope | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here --> $DIR/non-path-primitives.rs:1:9 | LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: unresolved link to `Z` --> $DIR/non-path-primitives.rs:14:5 diff --git a/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr b/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr index 6172cd2e316..4d5bd70bff6 100644 --- a/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr +++ b/src/test/rustdoc-ui/intra-doc/private-from-crate-level.stderr @@ -4,8 +4,8 @@ warning: public documentation for `private_from_crate_level` links to private it LL | //! [my_module] | ^^^^^^^^^ this item is private | - = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default = note: this link will resolve properly if you pass `--document-private-items` + = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/intra-doc/private.private.stderr b/src/test/rustdoc-ui/intra-doc/private.private.stderr index 392321f9c60..6661e9021f8 100644 --- a/src/test/rustdoc-ui/intra-doc/private.private.stderr +++ b/src/test/rustdoc-ui/intra-doc/private.private.stderr @@ -4,8 +4,8 @@ warning: public documentation for `DocMe` links to private item `DontDocMe` LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] | ^^^^^^^^^ this item is private | - = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default = note: this link resolves only because you passed `--document-private-items`, but will break without + = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default warning: public documentation for `DocMe` links to private item `DontDocMe::f` --> $DIR/private.rs:7:23 diff --git a/src/test/rustdoc-ui/intra-doc/private.public.stderr b/src/test/rustdoc-ui/intra-doc/private.public.stderr index 5d1c34b9168..45b51e12edc 100644 --- a/src/test/rustdoc-ui/intra-doc/private.public.stderr +++ b/src/test/rustdoc-ui/intra-doc/private.public.stderr @@ -4,8 +4,8 @@ warning: public documentation for `DocMe` links to private item `DontDocMe` LL | /// docs [DontDocMe] [DontDocMe::f] [DontDocMe::x] | ^^^^^^^^^ this item is private | - = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default = note: this link will resolve properly if you pass `--document-private-items` + = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default warning: public documentation for `DocMe` links to private item `DontDocMe::f` --> $DIR/private.rs:7:23 diff --git a/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr b/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr index bf4ab9fdd18..e8ee40ad4e8 100644 --- a/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr +++ b/src/test/rustdoc-ui/intra-doc/span-ice-55723.stderr @@ -4,12 +4,12 @@ error: unresolved link to `i` LL | /// (arr[i]) | ^ no item named `i` in scope | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here --> $DIR/span-ice-55723.rs:1:9 | LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr b/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr index f0a7ed1785b..508d0683d5d 100644 --- a/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr +++ b/src/test/rustdoc-ui/intra-doc/through-proc-macro.stderr @@ -4,12 +4,12 @@ warning: unresolved link to `Oooops` LL | /// [Oooops] | ^^^^^^ no item named `Oooops` in scope | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here --> $DIR/through-proc-macro.rs:7:9 | LL | #![warn(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr index d280e6497e0..e7b4c43e790 100644 --- a/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr +++ b/src/test/rustdoc-ui/intra-doc/unknown-disambiguator.stderr @@ -4,13 +4,13 @@ error: unknown disambiguator `foo` LL | //! Linking to [foo@banana] and [`bar@banana!()`]. | ^^^ | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators note: the lint level is defined here --> $DIR/unknown-disambiguator.rs:2:9 | LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators error: unknown disambiguator `bar` --> $DIR/unknown-disambiguator.rs:4:35 diff --git a/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr index 5c0df1d1b9e..815324563cb 100644 --- a/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr +++ b/src/test/rustdoc-ui/intra-doc/unused-extern-crate.stderr @@ -4,12 +4,12 @@ error: unresolved link to `zip` LL | /// See [zip] crate. | ^^^ no item named `zip` in scope | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here --> $DIR/unused-extern-crate.rs:2:9 | LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr b/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr index d46df92649d..c309a55f44d 100644 --- a/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr +++ b/src/test/rustdoc-ui/intra-doc/warning-crlf.stderr @@ -4,8 +4,8 @@ warning: unresolved link to `error` LL | /// [error] | ^^^^^ no item named `error` in scope | - = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default warning: unresolved link to `error1` --> $DIR/warning-crlf.rs:12:11 diff --git a/src/test/rustdoc-ui/invalid-doc-attr.stderr b/src/test/rustdoc-ui/invalid-doc-attr.stderr index a4fa3817905..3c66e587b47 100644 --- a/src/test/rustdoc-ui/invalid-doc-attr.stderr +++ b/src/test/rustdoc-ui/invalid-doc-attr.stderr @@ -4,15 +4,15 @@ error: this attribute can only be applied at the crate level LL | #[doc(test(no_crate_inject))] | ^^^^^^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information note: the lint level is defined here --> $DIR/invalid-doc-attr.rs:2:9 | LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> - = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information help: to apply to the crate, use an inner attribute | LL | #![doc(test(no_crate_inject))] diff --git a/src/test/rustdoc-ui/invalid-syntax.rs b/src/test/rustdoc-ui/invalid-syntax.rs index b503d1093fd..acb2a6f084f 100644 --- a/src/test/rustdoc-ui/invalid-syntax.rs +++ b/src/test/rustdoc-ui/invalid-syntax.rs @@ -99,3 +99,9 @@ pub fn indent_after_fenced() {} /// ``` pub fn invalid() {} //~^^^^ WARNING could not parse code block as Rust code + +/// ``` +/// fn wook_at_my_beautifuw_bwaces_plz() {); +/// ``` +pub fn uwu() {} +//~^^^^ WARNING could not parse code block as Rust code diff --git a/src/test/rustdoc-ui/invalid-syntax.stderr b/src/test/rustdoc-ui/invalid-syntax.stderr index 4c6249cc6d9..597d19e748c 100644 --- a/src/test/rustdoc-ui/invalid-syntax.stderr +++ b/src/test/rustdoc-ui/invalid-syntax.stderr @@ -7,10 +7,10 @@ LL | | /// \__________pkt->size___________/ \_result->size_/ \__pkt->si LL | | /// ``` | |_______^ | - = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default = note: error from rustc: unknown start of token: \ = note: error from rustc: unknown start of token: \ = note: error from rustc: unknown start of token: \ + = note: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default help: mark blocks that do not contain Rust code as text | LL | /// ```text @@ -150,5 +150,20 @@ help: mark blocks that do not contain Rust code as text LL | /// ```text | ++++ -warning: 12 warnings emitted +warning: could not parse code block as Rust code + --> $DIR/invalid-syntax.rs:103:5 + | +LL | /// ``` + | _____^ +LL | | /// fn wook_at_my_beautifuw_bwaces_plz() {); +LL | | /// ``` + | |_______^ + | + = note: error from rustc: mismatched closing delimiter: `)` +help: mark blocks that do not contain Rust code as text + | +LL | /// ```text + | ++++ + +warning: 13 warnings emitted diff --git a/src/test/rustdoc-ui/issue-74134.private.stderr b/src/test/rustdoc-ui/issue-74134.private.stderr index 31d2dbe9637..44c88b6183a 100644 --- a/src/test/rustdoc-ui/issue-74134.private.stderr +++ b/src/test/rustdoc-ui/issue-74134.private.stderr @@ -4,8 +4,8 @@ warning: public documentation for `public_item` links to private item `PrivateTy LL | /// [`PrivateType`] | ^^^^^^^^^^^ this item is private | - = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default = note: this link resolves only because you passed `--document-private-items`, but will break without + = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/issue-74134.public.stderr b/src/test/rustdoc-ui/issue-74134.public.stderr index 6a3173e3e0d..5b1887b8310 100644 --- a/src/test/rustdoc-ui/issue-74134.public.stderr +++ b/src/test/rustdoc-ui/issue-74134.public.stderr @@ -4,8 +4,8 @@ warning: public documentation for `public_item` links to private item `PrivateTy LL | /// [`PrivateType`] | ^^^^^^^^^^^ this item is private | - = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default = note: this link will resolve properly if you pass `--document-private-items` + = note: `#[warn(rustdoc::private_intra_doc_links)]` on by default warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/lint-group.stderr b/src/test/rustdoc-ui/lint-group.stderr index 5336c044574..4f2c9658891 100644 --- a/src/test/rustdoc-ui/lint-group.stderr +++ b/src/test/rustdoc-ui/lint-group.stderr @@ -35,8 +35,8 @@ error: unresolved link to `error` LL | /// what up, let's make an [error] | ^^^^^ no item named `error` in scope | - = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc::all)]` = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(rustdoc::all)]` error: unclosed HTML tag `unknown` --> $DIR/lint-group.rs:28:5 diff --git a/src/test/rustdoc-ui/macro-docs.stderr b/src/test/rustdoc-ui/macro-docs.stderr index e3cc1731146..2b136f5be16 100644 --- a/src/test/rustdoc-ui/macro-docs.stderr +++ b/src/test/rustdoc-ui/macro-docs.stderr @@ -7,13 +7,13 @@ LL | /// A LL | m!(); | ---- in this macro invocation | - = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default = note: the link appears in this line: [`long_cat`] is really long ^^^^^^^^^^ = note: no item named `long_cat` in scope = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr b/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr index 1a1f8085a1b..fb3a5e415df 100644 --- a/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr +++ b/src/test/rustdoc-ui/no-crate-level-doc-lint.stderr @@ -1,12 +1,12 @@ error: no documentation found for this crate's top-level module | + = help: The following guide may be of use: + https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html note: the lint level is defined here --> $DIR/no-crate-level-doc-lint.rs:3:9 | LL | #![deny(rustdoc::missing_crate_level_docs)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: The following guide may be of use: - https://doc.rust-lang.org/$CHANNEL/rustdoc/how-to-write-documentation.html error: aborting due to previous error diff --git a/src/test/rustdoc-ui/pub-export-lint.stderr b/src/test/rustdoc-ui/pub-export-lint.stderr index c6be9c6a9f5..81ef799617c 100644 --- a/src/test/rustdoc-ui/pub-export-lint.stderr +++ b/src/test/rustdoc-ui/pub-export-lint.stderr @@ -4,12 +4,12 @@ error: unresolved link to `aloha` LL | /// [aloha] | ^^^^^ no item named `aloha` in scope | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here --> $DIR/pub-export-lint.rs:1:9 | LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: aborting due to previous error diff --git a/src/test/rustdoc-ui/reference-link-reports-error-once.stderr b/src/test/rustdoc-ui/reference-link-reports-error-once.stderr index b46a51e93fb..2ab67090f66 100644 --- a/src/test/rustdoc-ui/reference-link-reports-error-once.stderr +++ b/src/test/rustdoc-ui/reference-link-reports-error-once.stderr @@ -4,12 +4,12 @@ error: unresolved link to `ref` LL | /// [a]: ref | ^^^ no item named `ref` in scope | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here --> $DIR/reference-link-reports-error-once.rs:1:9 | LL | #![deny(rustdoc::broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: unresolved link to `ref2` --> $DIR/reference-link-reports-error-once.rs:15:10 diff --git a/src/test/rustdoc-ui/renamed-lint-still-applies.stderr b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr index 8e2a2cdd759..ee9b67cb91b 100644 --- a/src/test/rustdoc-ui/renamed-lint-still-applies.stderr +++ b/src/test/rustdoc-ui/renamed-lint-still-applies.stderr @@ -18,12 +18,12 @@ error: unresolved link to `x` LL | //! [x] | ^ no item named `x` in scope | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` note: the lint level is defined here --> $DIR/renamed-lint-still-applies.rs:2:9 | LL | #![deny(broken_intra_doc_links)] | ^^^^^^^^^^^^^^^^^^^^^^ - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` error: this URL is not a hyperlink --> $DIR/renamed-lint-still-applies.rs:9:5 @@ -31,12 +31,12 @@ error: this URL is not a hyperlink LL | //! http://example.com | ^^^^^^^^^^^^^^^^^^ help: use an automatic link instead: `<http://example.com>` | + = note: bare URLs are not automatically turned into clickable links note: the lint level is defined here --> $DIR/renamed-lint-still-applies.rs:7:9 | LL | #![deny(rustdoc::non_autolinks)] | ^^^^^^^^^^^^^^^^^^^^^^ - = note: bare URLs are not automatically turned into clickable links error: aborting due to 2 previous errors; 2 warnings emitted diff --git a/src/test/rustdoc/anchors.no_const_anchor.html b/src/test/rustdoc/anchors.no_const_anchor.html index 4da1ffead2a..75e67330a3e 100644 --- a/src/test/rustdoc/anchors.no_const_anchor.html +++ b/src/test/rustdoc/anchors.no_const_anchor.html @@ -1 +1 @@ -<div id="associatedconstant.YOLO" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#16">source</a><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></div> \ No newline at end of file +<section id="associatedconstant.YOLO" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#16">source</a><h4 class="code-header">const <a href="#associatedconstant.YOLO" class="constant">YOLO</a>: <a class="primitive" href="{{channel}}/std/primitive.u32.html">u32</a></h4></section> \ No newline at end of file diff --git a/src/test/rustdoc/anchors.no_trait_method_anchor.html b/src/test/rustdoc/anchors.no_trait_method_anchor.html index 6b78c7c811a..d7bd525ff0f 100644 --- a/src/test/rustdoc/anchors.no_trait_method_anchor.html +++ b/src/test/rustdoc/anchors.no_trait_method_anchor.html @@ -1 +1 @@ -<div id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fnname">bar</a>()</h4></div> \ No newline at end of file +<section id="method.bar" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#23">source</a><h4 class="code-header">fn <a href="#method.bar" class="fnname">bar</a>()</h4></section> \ No newline at end of file diff --git a/src/test/rustdoc/anchors.no_tymethod_anchor.html b/src/test/rustdoc/anchors.no_tymethod_anchor.html index c08f4427cf6..e668e5e4db1 100644 --- a/src/test/rustdoc/anchors.no_tymethod_anchor.html +++ b/src/test/rustdoc/anchors.no_tymethod_anchor.html @@ -1 +1 @@ -<div id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fnname">foo</a>()</h4></div> \ No newline at end of file +<section id="tymethod.foo" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#20">source</a><h4 class="code-header">fn <a href="#tymethod.foo" class="fnname">foo</a>()</h4></section> \ No newline at end of file diff --git a/src/test/rustdoc/anchors.no_type_anchor.html b/src/test/rustdoc/anchors.no_type_anchor.html index ba8e65443ec..2c66d5aa315 100644 --- a/src/test/rustdoc/anchors.no_type_anchor.html +++ b/src/test/rustdoc/anchors.no_type_anchor.html @@ -1 +1 @@ -<div id="associatedtype.T" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#13">source</a><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></div> \ No newline at end of file +<section id="associatedtype.T" class="method has-srclink"><a class="srclink rightside" href="../src/foo/anchors.rs.html#13">source</a><h4 class="code-header">type <a href="#associatedtype.T" class="associatedtype">T</a></h4></section> \ No newline at end of file diff --git a/src/test/rustdoc/array-links.link_box_generic.html b/src/test/rustdoc/array-links.link_box_generic.html new file mode 100644 index 00000000000..3481bb6a025 --- /dev/null +++ b/src/test/rustdoc/array-links.link_box_generic.html @@ -0,0 +1 @@ +<code>pub fn delta<T>() -> <a class="struct" href="struct.MyBox.html" title="struct foo::MyBox">MyBox</a><<a class="primitive" href="{{channel}}/core/primitive.array.html">[T; 1]</a>></code> \ No newline at end of file diff --git a/src/test/rustdoc/array-links.link_box_u32.html b/src/test/rustdoc/array-links.link_box_u32.html new file mode 100644 index 00000000000..e864ae55c9f --- /dev/null +++ b/src/test/rustdoc/array-links.link_box_u32.html @@ -0,0 +1 @@ +<code>pub fn gamma() -> <a class="struct" href="struct.MyBox.html" title="struct foo::MyBox">MyBox</a><[<a class="primitive" href="{{channel}}/core/primitive.u32.html">u32</a>; <a class="primitive" href="{{channel}}/core/primitive.array.html">1</a>]></code> \ No newline at end of file diff --git a/src/test/rustdoc/array-links.link_slice_generic.html b/src/test/rustdoc/array-links.link_slice_generic.html new file mode 100644 index 00000000000..f1ca2f59bd7 --- /dev/null +++ b/src/test/rustdoc/array-links.link_slice_generic.html @@ -0,0 +1 @@ +<code>pub fn beta<T>() -> &'static <a class="primitive" href="{{channel}}/core/primitive.array.html">[T; 1]</a></code> \ No newline at end of file diff --git a/src/test/rustdoc/array-links.link_slice_u32.html b/src/test/rustdoc/array-links.link_slice_u32.html new file mode 100644 index 00000000000..c3943e8d321 --- /dev/null +++ b/src/test/rustdoc/array-links.link_slice_u32.html @@ -0,0 +1 @@ +<code>pub fn alpha() -> &'static [<a class="primitive" href="{{channel}}/core/primitive.u32.html">u32</a>; <a class="primitive" href="{{channel}}/core/primitive.array.html">1</a>]</code> \ No newline at end of file diff --git a/src/test/rustdoc/array-links.rs b/src/test/rustdoc/array-links.rs new file mode 100644 index 00000000000..07f92ac51b9 --- /dev/null +++ b/src/test/rustdoc/array-links.rs @@ -0,0 +1,28 @@ +#![crate_name = "foo"] +#![no_std] + +pub struct MyBox<T: ?Sized>(*const T); + +// @has 'foo/fn.alpha.html' +// @snapshot link_slice_u32 - '//pre[@class="rust fn"]/code' +pub fn alpha() -> &'static [u32; 1] { + loop {} +} + +// @has 'foo/fn.beta.html' +// @snapshot link_slice_generic - '//pre[@class="rust fn"]/code' +pub fn beta<T>() -> &'static [T; 1] { + loop {} +} + +// @has 'foo/fn.gamma.html' +// @snapshot link_box_u32 - '//pre[@class="rust fn"]/code' +pub fn gamma() -> MyBox<[u32; 1]> { + loop {} +} + +// @has 'foo/fn.delta.html' +// @snapshot link_box_generic - '//pre[@class="rust fn"]/code' +pub fn delta<T>() -> MyBox<[T; 1]> { + loop {} +} diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html new file mode 100644 index 00000000000..927a1a42a1f --- /dev/null +++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out0.html @@ -0,0 +1 @@ +<h4 class="code-header">type <a href="#associatedtype.Out0" class="associatedtype">Out0</a>: <a class="trait" href="../assoc_item_trait_bounds_with_bindings/trait.Support.html" title="trait assoc_item_trait_bounds_with_bindings::Support">Support</a><Item = <a class="primitive" href="{{channel}}/std/primitive.unit.html">()</a>></h4> \ No newline at end of file diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html new file mode 100644 index 00000000000..69d84e1b2c1 --- /dev/null +++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.out9.html @@ -0,0 +1 @@ +<h4 class="code-header">type <a href="#associatedtype.Out9" class="associatedtype">Out9</a>: <a class="trait" href="{{channel}}/core/ops/function/trait.FnMut.html" title="trait core::ops::function::FnMut">FnMut</a>(<a class="primitive" href="{{channel}}/std/primitive.i32.html">i32</a>) -> <a class="primitive" href="{{channel}}/std/primitive.bool.html">bool</a> + <a class="trait" href="{{channel}}/core/clone/trait.Clone.html" title="trait core::clone::Clone">Clone</a></h4> \ No newline at end of file diff --git a/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs new file mode 100644 index 00000000000..b026f399a56 --- /dev/null +++ b/src/test/rustdoc/inline_cross/assoc_item_trait_bounds_with_bindings.rs @@ -0,0 +1,40 @@ +// Regression test for issues #77763, #84579 and #102142. +#![crate_name = "main"] + +// aux-build:assoc_item_trait_bounds_with_bindings.rs +// build-aux-docs +// ignore-cross-compile +extern crate assoc_item_trait_bounds_with_bindings as aux; + +// FIXME(fmease): Don't render an incorrect `T: ?Sized` where-clause for parameters +// of GATs like `Main::Out{2,4}`. Add a snapshot test once it's fixed. +// FIXME(fmease): Print the `for<>` parameter list in the bounds of +// `Main::Out{6,11,12}`. + +// @has main/trait.Main.html +// @has - '//*[@id="associatedtype.Out0"]' 'type Out0: Support<Item = ()>' +// @has - '//*[@id="associatedtype.Out1"]' 'type Out1: Support<Item = Self::Item>' +// @has - '//*[@id="associatedtype.Out2"]' 'type Out2<T>: Support<Item = T>' +// @has - '//*[@id="associatedtype.Out3"]' 'type Out3: Support<Produce<()> = bool>' +// @has - '//*[@id="associatedtype.Out4"]' 'type Out4<T>: Support<Produce<T> = T>' +// @has - '//*[@id="associatedtype.Out5"]' "type Out5: Support<Output<'static> = &'static ()>" +// @has - '//*[@id="associatedtype.Out6"]' "type Out6: Support<Output<'a> = &'a ()>" +// @has - '//*[@id="associatedtype.Out7"]' "type Out7: Support<Item = String, Produce<i32> = u32> + Unrelated" +// @has - '//*[@id="associatedtype.Out8"]' "type Out8: Unrelated + Protocol<i16, Q1 = u128, Q0 = ()>" +// @has - '//*[@id="associatedtype.Out9"]' "type Out9: FnMut(i32) -> bool + Clone" +// @has - '//*[@id="associatedtype.Out10"]' "type Out10<'q>: Support<Output<'q> = ()>" +// @has - '//*[@id="associatedtype.Out11"]' "type Out11: Helper<A<'s> = &'s (), B<'r> = ()>" +// @has - '//*[@id="associatedtype.Out12"]' "type Out12: Helper<B<'w> = Cow<'w, str>, A<'w> = bool>" +// +// Snapshots: Check that we do not render any where-clauses for those associated types since all of +// the trait bounds contained within were moved to the bounds of the respective item. +// +// @snapshot out0 - '//*[@id="associatedtype.Out0"]/*[@class="code-header"]' +// @snapshot out9 - '//*[@id="associatedtype.Out9"]/*[@class="code-header"]' +// +// @has - '//*[@id="tymethod.make"]' \ +// "fn make<F>(F, impl FnMut(&str) -> bool)\ +// where \ +// F: FnOnce(u32) -> String, \ +// Self::Out2<()>: Protocol<u8, Q0 = Self::Item, Q1 = ()>" +pub use aux::Main; diff --git a/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs new file mode 100644 index 00000000000..7225f2dca10 --- /dev/null +++ b/src/test/rustdoc/inline_cross/auxiliary/assoc_item_trait_bounds_with_bindings.rs @@ -0,0 +1,40 @@ +pub trait Main { + type Item; + + type Out0: Support<Item = ()>; + type Out1: Support<Item = Self::Item>; + type Out2<T>: Support<Item = T>; + type Out3: Support<Produce<()> = bool>; + type Out4<T>: Support<Produce<T> = T>; + type Out5: Support<Output<'static> = &'static ()>; + type Out6: for<'a> Support<Output<'a> = &'a ()>; + type Out7: Support<Item = String, Produce<i32> = u32> + Unrelated; + type Out8: Unrelated + Protocol<i16, Q1 = u128, Q0 = ()>; + type Out9: FnMut(i32) -> bool + Clone; + type Out10<'q>: Support<Output<'q> = ()>; + type Out11: for<'r, 's> Helper<A<'s> = &'s (), B<'r> = ()>; + type Out12: for<'w> Helper<B<'w> = std::borrow::Cow<'w, str>, A<'w> = bool>; + + fn make<F>(_: F, _: impl FnMut(&str) -> bool) + where + F: FnOnce(u32) -> String, + Self::Out2<()>: Protocol<u8, Q0 = Self::Item, Q1 = ()>; +} + +pub trait Support { + type Item; + type Output<'a>; + type Produce<T>; +} + +pub trait Protocol<K> { + type Q0; + type Q1; +} + +pub trait Unrelated {} + +pub trait Helper { + type A<'q>; + type B<'q>; +} diff --git a/src/test/rustdoc/rfc-2632-const-trait-impl.rs b/src/test/rustdoc/rfc-2632-const-trait-impl.rs index 8bd402291aa..602ee1b1b1f 100644 --- a/src/test/rustdoc/rfc-2632-const-trait-impl.rs +++ b/src/test/rustdoc/rfc-2632-const-trait-impl.rs @@ -18,10 +18,10 @@ pub struct S<T>(T); // @has - '//pre[@class="rust trait"]/code/span[@class="where"]' ': Clone' #[const_trait] pub trait Tr<T> { - // @!has - '//div[@id="method.a"]/h4[@class="code-header"]' '~const' - // @has - '//div[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' - // @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const' - // @has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' + // @!has - '//section[@id="method.a"]/h4[@class="code-header"]' '~const' + // @has - '//section[@id="method.a"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone' + // @!has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const' + // @has - '//section[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone' fn a<A: ~const Clone + ~const Destruct>() where Option<A>: ~const Clone + ~const Destruct, diff --git a/src/test/rustdoc/safe-intrinsic.rs b/src/test/rustdoc/safe-intrinsic.rs index d3bb8514b7e..d08abdaeb14 100644 --- a/src/test/rustdoc/safe-intrinsic.rs +++ b/src/test/rustdoc/safe-intrinsic.rs @@ -1,5 +1,6 @@ #![feature(intrinsics)] #![feature(no_core)] +#![feature(rustc_attrs)] #![no_core] #![crate_name = "foo"] @@ -7,6 +8,7 @@ extern "rust-intrinsic" { // @has 'foo/fn.abort.html' // @has - '//pre[@class="rust fn"]' 'pub extern "rust-intrinsic" fn abort() -> !' + #[rustc_safe_intrinsic] pub fn abort() -> !; // @has 'foo/fn.unreachable.html' // @has - '//pre[@class="rust fn"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !' diff --git a/src/test/rustdoc/toggle-trait-fn.rs b/src/test/rustdoc/toggle-trait-fn.rs index 65e8daeb066..e41422ce7c5 100644 --- a/src/test/rustdoc/toggle-trait-fn.rs +++ b/src/test/rustdoc/toggle-trait-fn.rs @@ -4,12 +4,12 @@ // summary. Trait methods with no documentation should not be wrapped. // // @has foo/trait.Foo.html -// @has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'is_documented()' -// @!has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'not_documented()' -// @has - '//details[@class="rustdoc-toggle"]//*[@class="docblock"]' 'is_documented is documented' -// @has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'is_documented_optional()' -// @!has - '//details[@class="rustdoc-toggle"]//summary//h4[@class="code-header"]' 'not_documented_optional()' -// @has - '//details[@class="rustdoc-toggle"]//*[@class="docblock"]' 'is_documented_optional is documented' +// @has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'is_documented()' +// @!has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'not_documented()' +// @has - '//details[@class="rustdoc-toggle method-toggle"]//*[@class="docblock"]' 'is_documented is documented' +// @has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'is_documented_optional()' +// @!has - '//details[@class="rustdoc-toggle method-toggle"]//summary//h4[@class="code-header"]' 'not_documented_optional()' +// @has - '//details[@class="rustdoc-toggle method-toggle"]//*[@class="docblock"]' 'is_documented_optional is documented' pub trait Foo { fn not_documented(); diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs index 03da804bd1c..c05443488c3 100644 --- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -49,9 +49,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingAllowedAttrPass { let allowed = |attr| pprust::attribute_to_string(attr).contains("allowed_attr"); if !cx.tcx.hir().attrs(item.hir_id()).iter().any(allowed) { - cx.lint(MISSING_ALLOWED_ATTR, |lint| { - lint.build("Missing 'allowed_attr' attribute").set_span(span).emit(); - }); + cx.lint( + MISSING_ALLOWED_ATTR, + "Missing 'allowed_attr' attribute", + |lint| lint.set_span(span) + ); } } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index 0b1534939b7..073da688c7c 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -29,9 +29,11 @@ impl<'tcx> LateLintPass<'tcx> for Pass { let attrs = cx.tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); let span = cx.tcx.def_span(CRATE_DEF_ID); if !cx.sess().contains_name(attrs, Symbol::intern("crate_okay")) { - cx.lint(CRATE_NOT_OKAY, |lint| { - lint.build("crate is not marked with #![crate_okay]").set_span(span).emit(); - }); + cx.lint( + CRATE_NOT_OKAY, + "crate is not marked with #![crate_okay]", + |lint| lint.set_span(span) + ); } } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs index 2d41b5f30e9..4a41e7fbb72 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs @@ -22,12 +22,10 @@ declare_lint_pass!(Pass => [TEST_LINT, PLEASE_LINT]); impl<'tcx> LateLintPass<'tcx> for Pass { fn check_item(&mut self, cx: &LateContext, it: &rustc_hir::Item) { match it.ident.as_str() { - "lintme" => cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit(); - }), - "pleaselintme" => cx.lint(PLEASE_LINT, |lint| { - lint.build("item is named 'pleaselintme'").set_span(it.span).emit(); - }), + "lintme" => cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span)), + "pleaselintme" => { + cx.lint(PLEASE_LINT, "item is named 'pleaselintme'", |lint| lint.set_span(it.span)) + } _ => {} } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs index 285754928c2..30956deb799 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs @@ -21,9 +21,7 @@ declare_lint_pass!(Pass => [TEST_LINT]); impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { if it.ident.name.as_str() == "lintme" { - cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit(); - }); + cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span)); } } } diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs index 3d5dba42b5f..c2c024865e8 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs @@ -31,14 +31,10 @@ declare_lint_pass!(Pass => [TEST_LINT, TEST_GROUP, TEST_RUSTC_TOOL_LINT]); impl EarlyLintPass for Pass { fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) { if it.ident.name.as_str() == "lintme" { - cx.lint(TEST_LINT, |lint| { - lint.build("item is named 'lintme'").set_span(it.span).emit(); - }); + cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span)); } if it.ident.name.as_str() == "lintmetoo" { - cx.lint(TEST_GROUP, |lint| { - lint.build("item is named 'lintmetoo'").set_span(it.span).emit(); - }); + cx.lint(TEST_GROUP, "item is named 'lintmetoo'", |lint| lint.set_span(it.span)); } } } diff --git a/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr b/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr index 9d13ee89bca..3cb13082f25 100644 --- a/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr +++ b/src/test/ui-fulldeps/internal-lints/default_hash_types.stderr @@ -4,12 +4,12 @@ error: prefer `FxHashMap` over `HashMap`, it has better performance LL | let _map: HashMap<String, String> = HashMap::default(); | ^^^^^^^ | + = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary note: the lint level is defined here --> $DIR/default_hash_types.rs:4:9 | LL | #![deny(rustc::default_hash_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary error: prefer `FxHashMap` over `HashMap`, it has better performance --> $DIR/default_hash_types.rs:16:15 diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs index 18e39108eca..9a5100ce17f 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs @@ -19,14 +19,14 @@ use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; #[derive(Diagnostic)] -#[diag(parser::expect_path)] +#[diag(compiletest::example)] struct DeriveDiagnostic { #[primary_span] span: Span, } #[derive(Subdiagnostic)] -#[note(parser::add_paren)] +#[note(compiletest::example)] struct Note { #[primary_span] span: Span, @@ -45,7 +45,7 @@ pub struct TranslatableInIntoDiagnostic; impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for TranslatableInIntoDiagnostic { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - handler.struct_err(fluent::parser::expect_path) + handler.struct_err(fluent::compiletest::example) } } @@ -62,12 +62,12 @@ pub struct TranslatableInAddToDiagnostic; impl AddToDiagnostic for TranslatableInAddToDiagnostic { fn add_to_diagnostic(self, diag: &mut Diagnostic) { - diag.note(fluent::typeck::note); + diag.note(fluent::compiletest::note); } } pub fn make_diagnostics<'a>(handler: &'a Handler) { - let _diag = handler.struct_err(fluent::parser::expect_path); + let _diag = handler.struct_err(fluent::compiletest::example); //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls let _diag = handler.struct_err("untranslatable diagnostic"); diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr index 9219d09e9b4..f5f92ac1e7f 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.stderr @@ -19,7 +19,7 @@ LL | diag.note("untranslatable diagnostic"); error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls --> $DIR/diagnostics.rs:70:25 | -LL | let _diag = handler.struct_err(fluent::parser::expect_path); +LL | let _diag = handler.struct_err(fluent::compiletest::example); | ^^^^^^^^^^ | note: the lint level is defined here diff --git a/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr b/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr index bc9fcdd7bc7..4e296fff6d0 100644 --- a/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr +++ b/src/test/ui-fulldeps/internal-lints/existing_doc_keyword.stderr @@ -4,12 +4,12 @@ error: found non-existing keyword `tadam` used in `#[doc(keyword = \"...\")]` LL | #[doc(keyword = "tadam")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: only existing keywords are allowed in core/std note: the lint level is defined here --> $DIR/existing_doc_keyword.rs:8:9 | LL | #![deny(rustc::existing_doc_keyword)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: only existing keywords are allowed in core/std error: aborting due to previous error diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index 9df6be65eb3..ad6e93334cd 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -4,12 +4,12 @@ error: implementing `LintPass` by hand LL | impl LintPass for Foo { | ^^^^^^^^ | + = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead note: the lint level is defined here --> $DIR/lint_pass_impl_without_macro.rs:4:9 | LL | #![deny(rustc::lint_pass_impl_without_macro)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: implementing `LintPass` by hand --> $DIR/lint_pass_impl_without_macro.rs:30:14 diff --git a/src/test/ui-fulldeps/internal-lints/query_stability.stderr b/src/test/ui-fulldeps/internal-lints/query_stability.stderr index 7e8b448f41a..ee4ef998237 100644 --- a/src/test/ui-fulldeps/internal-lints/query_stability.stderr +++ b/src/test/ui-fulldeps/internal-lints/query_stability.stderr @@ -4,12 +4,12 @@ error: using `drain` can result in unstable query results LL | for _ in x.drain() {} | ^^^^^ | + = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale note: the lint level is defined here --> $DIR/query_stability.rs:4:9 | LL | #![deny(rustc::potential_query_instability)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale error: using `iter` can result in unstable query results --> $DIR/query_stability.rs:16:16 diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 3d363cae473..1dc71abc104 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -28,15 +28,15 @@ use rustc_errors::{Applicability, MultiSpan}; extern crate rustc_session; #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct Hello {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct HelloWarn {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] //~^ ERROR unsupported type attribute for diagnostic derive enum enum DiagnosticOnEnum { Foo, @@ -46,13 +46,13 @@ enum DiagnosticOnEnum { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[diag = "E0123"] //~^ ERROR `#[diag = ...]` is not a valid attribute struct WrongStructAttrStyle {} #[derive(Diagnostic)] -#[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[nonsense(compiletest::example, code = "E0123")] //~^ ERROR `#[nonsense(...)]` is not a valid attribute //~^^ ERROR diagnostic slug not specified //~^^^ ERROR cannot find attribute `nonsense` in this scope @@ -90,12 +90,12 @@ struct InvalidNestedStructAttr2 {} struct InvalidNestedStructAttr3 {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] +#[diag(compiletest::example, code = "E0123", slug = "foo")] //~^ ERROR `#[diag(slug = ...)]` is not a valid attribute struct InvalidNestedStructAttr4 {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct WrongPlaceField { #[suggestion = "bar"] //~^ ERROR `#[suggestion = ...]` is not a valid attribute @@ -103,20 +103,20 @@ struct WrongPlaceField { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] +#[diag(compiletest::example, code = "E0123")] +#[diag(compiletest::example, code = "E0456")] //~^ ERROR specified multiple times //~^^ ERROR specified multiple times struct DiagSpecifiedTwice {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] +#[diag(compiletest::example, code = "E0456", code = "E0457")] //~^ ERROR specified multiple times struct CodeSpecifiedTwice {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] -//~^ ERROR `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute +#[diag(compiletest::example, compiletest::example, code = "E0456")] +//~^ ERROR `#[diag(compiletest::example)]` is not a valid attribute struct SlugSpecifiedTwice {} #[derive(Diagnostic)] @@ -128,11 +128,11 @@ struct KindNotProvided {} //~ ERROR diagnostic slug not specified struct SlugNotProvided {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound)] +#[diag(compiletest::example)] struct CodeNotProvided {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct MessageWrongType { #[primary_span] //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` @@ -140,7 +140,7 @@ struct MessageWrongType { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct InvalidPathFieldAttr { #[nonsense] //~^ ERROR `#[nonsense]` is not a valid attribute @@ -149,34 +149,34 @@ struct InvalidPathFieldAttr { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithField { name: String, - #[label(typeck::label)] + #[label(compiletest::label)] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithMessageAppliedToField { - #[label(typeck::label)] + #[label(compiletest::label)] //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` name: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithNonexistentField { - #[suggestion(typeck::suggestion, code = "{name}")] + #[suggestion(compiletest::suggestion, code = "{name}")] //~^ ERROR `name` doesn't refer to a field on this type suggestion: (Span, Applicability), } #[derive(Diagnostic)] //~^ ERROR invalid format string: expected `'}'` -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorMissingClosingBrace { - #[suggestion(typeck::suggestion, code = "{name")] + #[suggestion(compiletest::suggestion, code = "{name")] suggestion: (Span, Applicability), name: String, val: usize, @@ -184,49 +184,49 @@ struct ErrorMissingClosingBrace { #[derive(Diagnostic)] //~^ ERROR invalid format string: unmatched `}` -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorMissingOpeningBrace { - #[suggestion(typeck::suggestion, code = "name}")] + #[suggestion(compiletest::suggestion, code = "name}")] suggestion: (Span, Applicability), name: String, val: usize, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelOnSpan { - #[label(typeck::label)] + #[label(compiletest::label)] sp: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelOnNonSpan { - #[label(typeck::label)] + #[label(compiletest::label)] //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` id: u32, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct Suggest { - #[suggestion(typeck::suggestion, code = "This is the suggested code")] - #[suggestion_short(typeck::suggestion, code = "This is the suggested code")] - #[suggestion_hidden(typeck::suggestion, code = "This is the suggested code")] - #[suggestion_verbose(typeck::suggestion, code = "This is the suggested code")] + #[suggestion(compiletest::suggestion, code = "This is the suggested code")] + #[suggestion_short(compiletest::suggestion, code = "This is the suggested code")] + #[suggestion_hidden(compiletest::suggestion, code = "This is the suggested code")] + #[suggestion_verbose(compiletest::suggestion, code = "This is the suggested code")] suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithoutCode { - #[suggestion(typeck::suggestion)] + #[suggestion(compiletest::suggestion)] //~^ ERROR suggestion without `code = "..."` suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithBadKey { #[suggestion(nonsense = "bar")] //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute @@ -235,7 +235,7 @@ struct SuggestWithBadKey { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithShorthandMsg { #[suggestion(msg = "bar")] //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute @@ -244,52 +244,52 @@ struct SuggestWithShorthandMsg { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithoutMsg { #[suggestion(code = "bar")] suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithTypesSwapped { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] suggestion: (Applicability, Span), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithWrongTypeApplicabilityOnly { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] //~^ ERROR wrong field type for suggestion suggestion: Applicability, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithSpanOnly { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithDuplicateSpanAndApplicability { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] suggestion: (Span, Span, Applicability), //~^ ERROR specified multiple times } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct SuggestWithDuplicateApplicabilityAndSpan { - #[suggestion(typeck::suggestion, code = "This is suggested code")] + #[suggestion(compiletest::suggestion, code = "This is suggested code")] suggestion: (Applicability, Applicability, Span), //~^ ERROR specified multiple times } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct WrongKindOfAnnotation { #[label = "bar"] //~^ ERROR `#[label = ...]` is not a valid attribute @@ -297,38 +297,38 @@ struct WrongKindOfAnnotation { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct OptionsInErrors { - #[label(typeck::label)] + #[label(compiletest::label)] label: Option<Span>, - #[suggestion(typeck::suggestion, code = "...")] + #[suggestion(compiletest::suggestion, code = "...")] opt_sugg: Option<(Span, Applicability)>, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] +#[diag(compiletest::example, code = "E0456")] struct MoveOutOfBorrowError<'tcx> { name: Ident, ty: Ty<'tcx>, #[primary_span] - #[label(typeck::label)] + #[label(compiletest::label)] span: Span, - #[label(typeck::label)] + #[label(compiletest::label)] other_span: Span, - #[suggestion(typeck::suggestion, code = "{name}.clone()")] + #[suggestion(compiletest::suggestion, code = "{name}.clone()")] opt_sugg: Option<(Span, Applicability)>, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithLifetime<'a> { - #[label(typeck::label)] + #[label(compiletest::label)] span: Span, name: &'a str, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithDefaultLabelAttr<'a> { #[label] span: Span, @@ -337,7 +337,7 @@ struct ErrorWithDefaultLabelAttr<'a> { #[derive(Diagnostic)] //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ArgFieldWithoutSkip { #[primary_span] span: Span, @@ -345,7 +345,7 @@ struct ArgFieldWithoutSkip { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ArgFieldWithSkip { #[primary_span] span: Span, @@ -356,116 +356,116 @@ struct ArgFieldWithSkip { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithSpannedNote { #[note] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithSpannedNoteCustom { - #[note(typeck::note)] + #[note(compiletest::note)] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[note] struct ErrorWithNote { val: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[note(typeck::note)] +#[diag(compiletest::example, code = "E0123")] +#[note(compiletest::note)] struct ErrorWithNoteCustom { val: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithSpannedHelp { #[help] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithSpannedHelpCustom { - #[help(typeck::help)] + #[help(compiletest::help)] span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[help] struct ErrorWithHelp { val: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[help(typeck::help)] +#[diag(compiletest::example, code = "E0123")] +#[help(compiletest::help)] struct ErrorWithHelpCustom { val: String, } #[derive(Diagnostic)] #[help] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithHelpWrongOrder { val: String, } #[derive(Diagnostic)] -#[help(typeck::help)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[help(compiletest::help)] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithHelpCustomWrongOrder { val: String, } #[derive(Diagnostic)] #[note] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithNoteWrongOrder { val: String, } #[derive(Diagnostic)] -#[note(typeck::note)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[note(compiletest::note)] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithNoteCustomWrongOrder { val: String, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ApplicabilityInBoth { - #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] + #[suggestion(compiletest::suggestion, code = "...", applicability = "maybe-incorrect")] //~^ ERROR specified multiple times suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct InvalidApplicability { - #[suggestion(typeck::suggestion, code = "...", applicability = "batman")] + #[suggestion(compiletest::suggestion, code = "...", applicability = "batman")] //~^ ERROR invalid applicability suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ValidApplicability { - #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] + #[suggestion(compiletest::suggestion, code = "...", applicability = "maybe-incorrect")] suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct NoApplicability { - #[suggestion(typeck::suggestion, code = "...")] + #[suggestion(compiletest::suggestion, code = "...")] suggestion: Span, } @@ -474,14 +474,14 @@ struct NoApplicability { struct Note; #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound)] +#[diag(compiletest::example)] struct Subdiagnostic { #[subdiagnostic] note: Note, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct VecField { #[primary_span] #[label] @@ -489,58 +489,58 @@ struct VecField { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct UnitField { #[primary_span] spans: Span, #[help] foo: (), - #[help(typeck::help)] + #[help(compiletest::help)] bar: (), } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct OptUnitField { #[primary_span] spans: Span, #[help] foo: Option<()>, - #[help(typeck::help)] + #[help(compiletest::help)] bar: Option<()>, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelWithTrailingPath { - #[label(typeck::label, foo)] + #[label(compiletest::label, foo)] //~^ ERROR `#[label(foo)]` is not a valid attribute span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelWithTrailingNameValue { - #[label(typeck::label, foo = "...")] + #[label(compiletest::label, foo = "...")] //~^ ERROR `#[label(foo = ...)]` is not a valid attribute span: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct LabelWithTrailingList { - #[label(typeck::label, foo("..."))] + #[label(compiletest::label, foo("..."))] //~^ ERROR `#[label(foo(...))]` is not a valid attribute span: Span, } #[derive(LintDiagnostic)] -#[diag(typeck::ambiguous_lifetime_bound)] +#[diag(compiletest::example)] struct LintsGood { } #[derive(LintDiagnostic)] -#[diag(typeck::ambiguous_lifetime_bound)] +#[diag(compiletest::example)] struct PrimarySpanOnLint { #[primary_span] //~^ ERROR `#[primary_span]` is not a valid attribute @@ -548,97 +548,98 @@ struct PrimarySpanOnLint { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct ErrorWithMultiSpan { #[primary_span] span: MultiSpan, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[warning] struct ErrorWithWarn { val: String, } #[derive(Diagnostic)] -#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[error(compiletest::example, code = "E0123")] //~^ ERROR `#[error(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `error` in this scope struct ErrorAttribute {} #[derive(Diagnostic)] -#[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[warn_(compiletest::example, code = "E0123")] //~^ ERROR `#[warn_(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `warn_` in this scope struct WarnAttribute {} #[derive(Diagnostic)] -#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[lint(compiletest::example, code = "E0123")] //~^ ERROR `#[lint(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `lint` in this scope struct LintAttributeOnSessionDiag {} #[derive(LintDiagnostic)] -#[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[lint(compiletest::example, code = "E0123")] //~^ ERROR `#[lint(...)]` is not a valid attribute +//~| ERROR `#[lint(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `lint` in this scope struct LintAttributeOnLintDiag {} #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct DuplicatedSuggestionCode { - #[suggestion(typeck::suggestion, code = "...", code = ",,,")] + #[suggestion(compiletest::suggestion, code = "...", code = ",,,")] //~^ ERROR specified multiple times suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct InvalidTypeInSuggestionTuple { - #[suggestion(typeck::suggestion, code = "...")] + #[suggestion(compiletest::suggestion, code = "...")] suggestion: (Span, usize), //~^ ERROR wrong types for suggestion } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct MissingApplicabilityInSuggestionTuple { - #[suggestion(typeck::suggestion, code = "...")] + #[suggestion(compiletest::suggestion, code = "...")] suggestion: (Span,), //~^ ERROR wrong types for suggestion } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct MissingCodeInSuggestion { - #[suggestion(typeck::suggestion)] + #[suggestion(compiletest::suggestion)] //~^ ERROR suggestion without `code = "..."` suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[multipart_suggestion(typeck::suggestion)] +#[diag(compiletest::example, code = "E0123")] +#[multipart_suggestion(compiletest::suggestion)] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute //~| ERROR cannot find attribute `multipart_suggestion` in this scope #[multipart_suggestion()] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute //~| ERROR cannot find attribute `multipart_suggestion` in this scope struct MultipartSuggestion { - #[multipart_suggestion(typeck::suggestion)] + #[multipart_suggestion(compiletest::suggestion)] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute //~| ERROR cannot find attribute `multipart_suggestion` in this scope suggestion: Span, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] -#[suggestion(typeck::suggestion, code = "...")] +#[diag(compiletest::example, code = "E0123")] +#[suggestion(compiletest::suggestion, code = "...")] //~^ ERROR `#[suggestion(...)]` is not a valid attribute struct SuggestionOnStruct { #[primary_span] @@ -646,7 +647,7 @@ struct SuggestionOnStruct { } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] #[label] //~^ ERROR `#[label]` is not a valid attribute struct LabelOnStruct { @@ -656,24 +657,24 @@ struct LabelOnStruct { #[derive(Diagnostic)] enum ExampleEnum { - #[diag(typeck::ambiguous_lifetime_bound)] + #[diag(compiletest::example)] Foo { #[primary_span] sp: Span, #[note] note_sp: Span, }, - #[diag(typeck::ambiguous_lifetime_bound)] + #[diag(compiletest::example)] Bar { #[primary_span] sp: Span, }, - #[diag(typeck::ambiguous_lifetime_bound)] + #[diag(compiletest::example)] Baz, } #[derive(Diagnostic)] -#[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[diag(compiletest::example, code = "E0123")] struct RawIdentDiagnosticArg { pub r#type: String, } diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 21a402c7b9d..167198b47f2 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -1,8 +1,8 @@ error: unsupported type attribute for diagnostic derive enum --> $DIR/diagnostic-derive.rs:39:1 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:42:5 @@ -10,7 +10,7 @@ error: diagnostic slug not specified LL | Foo, | ^^^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:44:5 @@ -18,7 +18,7 @@ error: diagnostic slug not specified LL | Bar, | ^^^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag = ...]` is not a valid attribute --> $DIR/diagnostic-derive.rs:50:1 @@ -29,20 +29,20 @@ LL | #[diag = "E0123"] error: `#[nonsense(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:55:1 | -LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[nonsense(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:55:1 | -LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[nonsense(compiletest::example, code = "E0123")] LL | | LL | | LL | | LL | | struct InvalidStructAttr {} | |___________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag("...")]` is not a valid attribute --> $DIR/diagnostic-derive.rs:62:8 @@ -61,7 +61,7 @@ LL | | LL | | struct InvalidLitNestedAttr {} | |______________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag(nonsense(...))]` is not a valid attribute --> $DIR/diagnostic-derive.rs:73:8 @@ -80,7 +80,7 @@ LL | | LL | | struct InvalidNestedStructAttr1 {} | |__________________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:79:8 @@ -108,7 +108,7 @@ LL | | LL | | struct InvalidNestedStructAttr2 {} | |__________________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:86:8 @@ -134,13 +134,13 @@ LL | | LL | | struct InvalidNestedStructAttr3 {} | |__________________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[diag(slug = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:93:58 + --> $DIR/diagnostic-derive.rs:93:46 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^ +LL | #[diag(compiletest::example, code = "E0123", slug = "foo")] + | ^^^^^^^^^^^^ | = help: only `code` is a valid nested attributes following the slug @@ -153,44 +153,44 @@ LL | #[suggestion = "bar"] error: specified multiple times --> $DIR/diagnostic-derive.rs:107:8 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(compiletest::example, code = "E0456")] + | ^^^^^^^^^^^^^^^^^^^^ | note: previously specified here --> $DIR/diagnostic-derive.rs:106:8 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:107:49 + --> $DIR/diagnostic-derive.rs:107:37 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^ +LL | #[diag(compiletest::example, code = "E0456")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:106:49 + --> $DIR/diagnostic-derive.rs:106:37 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^ +LL | #[diag(compiletest::example, code = "E0123")] + | ^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:113:65 + --> $DIR/diagnostic-derive.rs:113:53 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] - | ^^^^^^^ +LL | #[diag(compiletest::example, code = "E0456", code = "E0457")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:113:49 + --> $DIR/diagnostic-derive.rs:113:37 | -LL | #[diag(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] - | ^^^^^^^ +LL | #[diag(compiletest::example, code = "E0456", code = "E0457")] + | ^^^^^^^ -error: `#[diag(typeck::ambiguous_lifetime_bound)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:118:42 +error: `#[diag(compiletest::example)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:118:30 | -LL | #[diag(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(compiletest::example, compiletest::example, code = "E0456")] + | ^^^^^^^^^^^^^^^^^^^^ | = help: diagnostic slug must be the first argument @@ -200,7 +200,7 @@ error: diagnostic slug not specified LL | struct KindNotProvided {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:126:1 @@ -210,7 +210,7 @@ LL | | LL | | struct SlugNotProvided {} | |_________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/diagnostic-derive.rs:137:5 @@ -227,14 +227,14 @@ LL | #[nonsense] error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/diagnostic-derive.rs:162:5 | -LL | #[label(typeck::label)] - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[label(compiletest::label)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:170:45 + --> $DIR/diagnostic-derive.rs:170:50 | -LL | #[suggestion(typeck::suggestion, code = "{name}")] - | ^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "{name}")] + | ^^^^^^^^ error: invalid format string: expected `'}'` but string was terminated --> $DIR/diagnostic-derive.rs:175:10 @@ -257,14 +257,14 @@ LL | #[derive(Diagnostic)] error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` --> $DIR/diagnostic-derive.rs:205:5 | -LL | #[label(typeck::label)] - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[label(compiletest::label)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: suggestion without `code = "..."` --> $DIR/diagnostic-derive.rs:223:5 | -LL | #[suggestion(typeck::suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion(nonsense = ...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:231:18 @@ -297,7 +297,7 @@ LL | #[suggestion(msg = "bar")] error: wrong field type for suggestion --> $DIR/diagnostic-derive.rs:263:5 | -LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] +LL | / #[suggestion(compiletest::suggestion, code = "This is suggested code")] LL | | LL | | suggestion: Applicability, | |_____________________________^ @@ -335,10 +335,10 @@ LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:445:52 + --> $DIR/diagnostic-derive.rs:445:57 | -LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...", applicability = "maybe-incorrect")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here --> $DIR/diagnostic-derive.rs:447:24 @@ -347,30 +347,30 @@ LL | suggestion: (Span, Applicability), | ^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/diagnostic-derive.rs:453:52 + --> $DIR/diagnostic-derive.rs:453:57 | -LL | #[suggestion(typeck::suggestion, code = "...", applicability = "batman")] - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...", applicability = "batman")] + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(foo)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:516:28 + --> $DIR/diagnostic-derive.rs:516:33 | -LL | #[label(typeck::label, foo)] - | ^^^ +LL | #[label(compiletest::label, foo)] + | ^^^ | = help: a diagnostic slug must be the first argument to the attribute error: `#[label(foo = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:524:28 + --> $DIR/diagnostic-derive.rs:524:33 | -LL | #[label(typeck::label, foo = "...")] - | ^^^^^^^^^^^ +LL | #[label(compiletest::label, foo = "...")] + | ^^^^^^^^^^^ error: `#[label(foo(...))]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:532:28 + --> $DIR/diagnostic-derive.rs:532:33 | -LL | #[label(typeck::label, foo("..."))] - | ^^^^^^^^^^ +LL | #[label(compiletest::label, foo("..."))] + | ^^^^^^^^^^ error: `#[primary_span]` is not a valid attribute --> $DIR/diagnostic-derive.rs:545:5 @@ -383,89 +383,96 @@ LL | #[primary_span] error: `#[error(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:565:1 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[error(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:565:1 | -LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[error(compiletest::example, code = "E0123")] LL | | LL | | LL | | LL | | struct ErrorAttribute {} | |________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[warn_(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:572:1 | -LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[warn_(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:572:1 | -LL | / #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[warn_(compiletest::example, code = "E0123")] LL | | LL | | LL | | LL | | struct WarnAttribute {} | |_______________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[lint(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:579:1 | -LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[lint(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:579:1 | -LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[lint(compiletest::example, code = "E0123")] LL | | LL | | LL | | LL | | struct LintAttributeOnSessionDiag {} | |____________________________________^ | - = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis::example_error)]` error: `#[lint(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:586:1 | -LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[lint(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[lint(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:586:1 + | +LL | #[lint(compiletest::example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:586:1 | -LL | / #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | / #[lint(compiletest::example, code = "E0123")] +LL | | LL | | LL | | LL | | LL | | struct LintAttributeOnLintDiag {} | |_________________________________^ | - = help: specify the slug as the first argument to the attribute, such as `#[diag(typeck::example_error)]` + = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest::example)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:595:52 + --> $DIR/diagnostic-derive.rs:596:57 | -LL | #[suggestion(typeck::suggestion, code = "...", code = ",,,")] - | ^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...", code = ",,,")] + | ^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:595:38 + --> $DIR/diagnostic-derive.rs:596:43 | -LL | #[suggestion(typeck::suggestion, code = "...", code = ",,,")] - | ^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...", code = ",,,")] + | ^^^^^^^^^^^^ error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:604:24 + --> $DIR/diagnostic-derive.rs:605:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -473,7 +480,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:612:17 + --> $DIR/diagnostic-derive.rs:613:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -481,21 +488,21 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:619:5 + --> $DIR/diagnostic-derive.rs:620:5 | -LL | #[suggestion(typeck::suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:626:1 + --> $DIR/diagnostic-derive.rs:627:1 | -LL | #[multipart_suggestion(typeck::suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[multipart_suggestion(compiletest::suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:629:1 + --> $DIR/diagnostic-derive.rs:630:1 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -503,23 +510,23 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:633:5 + --> $DIR/diagnostic-derive.rs:634:5 | -LL | #[multipart_suggestion(typeck::suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[multipart_suggestion(compiletest::suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider creating a `Subdiagnostic` instead error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:641:1 + --> $DIR/diagnostic-derive.rs:642:1 | -LL | #[suggestion(typeck::suggestion, code = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(compiletest::suggestion, code = "...")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:650:1 + --> $DIR/diagnostic-derive.rs:651:1 | LL | #[label] | ^^^^^^^^ @@ -529,7 +536,7 @@ LL | #[label] error: cannot find attribute `nonsense` in this scope --> $DIR/diagnostic-derive.rs:55:3 | -LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[nonsense(compiletest::example, code = "E0123")] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope @@ -541,43 +548,43 @@ LL | #[nonsense] error: cannot find attribute `error` in this scope --> $DIR/diagnostic-derive.rs:565:3 | -LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[error(compiletest::example, code = "E0123")] | ^^^^^ error: cannot find attribute `warn_` in this scope --> $DIR/diagnostic-derive.rs:572:3 | -LL | #[warn_(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[warn_(compiletest::example, code = "E0123")] | ^^^^^ help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope --> $DIR/diagnostic-derive.rs:579:3 | -LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[lint(compiletest::example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `lint` in this scope --> $DIR/diagnostic-derive.rs:586:3 | -LL | #[lint(typeck::ambiguous_lifetime_bound, code = "E0123")] +LL | #[lint(compiletest::example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:626:3 + --> $DIR/diagnostic-derive.rs:627:3 | -LL | #[multipart_suggestion(typeck::suggestion)] +LL | #[multipart_suggestion(compiletest::suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:629:3 + --> $DIR/diagnostic-derive.rs:630:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:633:7 + --> $DIR/diagnostic-derive.rs:634:7 | -LL | #[multipart_suggestion(typeck::suggestion)] +LL | #[multipart_suggestion(compiletest::suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent` @@ -600,7 +607,7 @@ LL | arg: impl IntoDiagnosticArg, | ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg` = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 74 previous errors +error: aborting due to 75 previous errors Some errors have detailed explanations: E0277, E0425. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/abi/stack-probes-lto.rs b/src/test/ui/abi/stack-probes-lto.rs index 74b5e843f77..6d934538f4c 100644 --- a/src/test/ui/abi/stack-probes-lto.rs +++ b/src/test/ui/abi/stack-probes-lto.rs @@ -3,8 +3,6 @@ // ignore-aarch64 // ignore-mips // ignore-mips64 -// ignore-powerpc -// ignore-s390x // ignore-sparc // ignore-sparc64 // ignore-wasm diff --git a/src/test/ui/abi/stack-probes.rs b/src/test/ui/abi/stack-probes.rs index b497af7abad..e7b91644b3b 100644 --- a/src/test/ui/abi/stack-probes.rs +++ b/src/test/ui/abi/stack-probes.rs @@ -3,8 +3,6 @@ // ignore-aarch64 // ignore-mips // ignore-mips64 -// ignore-powerpc -// ignore-s390x // ignore-sparc // ignore-sparc64 // ignore-wasm @@ -27,8 +25,9 @@ fn main() { let args = env::args().skip(1).collect::<Vec<_>>(); if args.len() > 0 { match &args[0][..] { - "main-thread" => recurse(&MaybeUninit::uninit()), - "child-thread" => thread::spawn(|| recurse(&MaybeUninit::uninit())).join().unwrap(), + "main-recurse" => overflow_recurse(), + "child-recurse" => thread::spawn(overflow_recurse).join().unwrap(), + "child-frame" => overflow_frame(), _ => panic!(), } return; @@ -41,9 +40,10 @@ fn main() { // that we report stack overflow on the main thread, see #43052 for some // details if cfg!(not(target_os = "linux")) { - assert_overflow(Command::new(&me).arg("main-thread")); + assert_overflow(Command::new(&me).arg("main-recurse")); } - assert_overflow(Command::new(&me).arg("child-thread")); + assert_overflow(Command::new(&me).arg("child-recurse")); + assert_overflow(Command::new(&me).arg("child-frame")); } #[allow(unconditional_recursion)] @@ -55,6 +55,23 @@ fn recurse(array: &MaybeUninit<[u64; 1024]>) { recurse(&local); } +#[inline(never)] +fn overflow_recurse() { + recurse(&MaybeUninit::uninit()); +} + +fn overflow_frame() { + // By using a 1MiB stack frame with only 512KiB stack, we'll jump over any + // guard page, even with 64K pages -- but stack probes should catch it. + const STACK_SIZE: usize = 512 * 1024; + thread::Builder::new().stack_size(STACK_SIZE).spawn(|| { + let local: MaybeUninit<[u8; 2 * STACK_SIZE]> = MaybeUninit::uninit(); + unsafe { + black_box(local.as_ptr() as u64); + } + }).unwrap().join().unwrap(); +} + fn assert_overflow(cmd: &mut Command) { let output = cmd.output().unwrap(); assert!(!output.status.success()); diff --git a/src/test/ui/abi/unsupported.aarch64.stderr b/src/test/ui/abi/unsupported.aarch64.stderr index a948947dbdb..e86a73ea60f 100644 --- a/src/test/ui/abi/unsupported.aarch64.stderr +++ b/src/test/ui/abi/unsupported.aarch64.stderr @@ -52,9 +52,9 @@ warning: use of calling convention not supported on this target LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unsupported_calling_conventions)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678> + = note: `#[warn(unsupported_calling_conventions)]` on by default error: aborting due to 8 previous errors; 1 warning emitted diff --git a/src/test/ui/abi/unsupported.arm.stderr b/src/test/ui/abi/unsupported.arm.stderr index 297354c2828..f7569c8cdd7 100644 --- a/src/test/ui/abi/unsupported.arm.stderr +++ b/src/test/ui/abi/unsupported.arm.stderr @@ -46,9 +46,9 @@ warning: use of calling convention not supported on this target LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unsupported_calling_conventions)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678> + = note: `#[warn(unsupported_calling_conventions)]` on by default error: aborting due to 7 previous errors; 1 warning emitted diff --git a/src/test/ui/abi/unsupported.x64.stderr b/src/test/ui/abi/unsupported.x64.stderr index 49b88cd3fac..26023a4584e 100644 --- a/src/test/ui/abi/unsupported.x64.stderr +++ b/src/test/ui/abi/unsupported.x64.stderr @@ -46,9 +46,9 @@ warning: use of calling convention not supported on this target LL | extern "stdcall" fn stdcall() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unsupported_calling_conventions)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678> + = note: `#[warn(unsupported_calling_conventions)]` on by default error: aborting due to 7 previous errors; 1 warning emitted diff --git a/src/test/ui/abi/x86stdcall.rs b/src/test/ui/abi/x86stdcall.rs index 868923e5932..d1cf1319fb0 100644 --- a/src/test/ui/abi/x86stdcall.rs +++ b/src/test/ui/abi/x86stdcall.rs @@ -1,17 +1,15 @@ // run-pass -// ignore-wasm32-bare no libc to test ffi with -// ignore-sgx no libc +// only-windows // GetLastError doesn't seem to work with stack switching #[cfg(windows)] mod kernel32 { - extern "system" { - pub fn SetLastError(err: usize); - pub fn GetLastError() -> usize; - } + extern "system" { + pub fn SetLastError(err: usize); + pub fn GetLastError() -> usize; + } } - #[cfg(windows)] pub fn main() { unsafe { @@ -22,17 +20,3 @@ pub fn main() { assert_eq!(expected, actual); } } - -#[cfg(any(target_os = "android", - target_os = "dragonfly", - target_os = "emscripten", - target_os = "freebsd", - target_os = "fuchsia", - target_os = "illumos", - target_os = "linux", - target_os = "macos", - target_os = "netbsd", - target_os = "openbsd", - target_os = "solaris", - target_os = "vxworks"))] -pub fn main() { } diff --git a/src/test/ui/abi/x86stdcall2.rs b/src/test/ui/abi/x86stdcall2.rs index 563e3aba632..4d508ecb242 100644 --- a/src/test/ui/abi/x86stdcall2.rs +++ b/src/test/ui/abi/x86stdcall2.rs @@ -1,4 +1,5 @@ // run-pass +// only-windows #![allow(non_camel_case_types)] pub type HANDLE = usize; @@ -7,20 +8,16 @@ pub type SIZE_T = u32; pub type LPVOID = usize; pub type BOOL = u8; -#[cfg(windows)] mod kernel32 { - use super::{HANDLE, DWORD, SIZE_T, LPVOID, BOOL}; + use super::{BOOL, DWORD, HANDLE, LPVOID, SIZE_T}; extern "system" { pub fn GetProcessHeap() -> HANDLE; - pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) - -> LPVOID; + pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; pub fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; } } - -#[cfg(windows)] pub fn main() { let heap = unsafe { kernel32::GetProcessHeap() }; let mem = unsafe { kernel32::HeapAlloc(heap, 0, 100) }; @@ -28,6 +25,3 @@ pub fn main() { let res = unsafe { kernel32::HeapFree(heap, 0, mem) }; assert!(res != 0); } - -#[cfg(not(windows))] -pub fn main() { } diff --git a/src/test/ui/anon-params/anon-params-deprecated.stderr b/src/test/ui/anon-params/anon-params-deprecated.stderr index 474b14f59e3..691e2c79512 100644 --- a/src/test/ui/anon-params/anon-params-deprecated.stderr +++ b/src/test/ui/anon-params/anon-params-deprecated.stderr @@ -4,13 +4,13 @@ warning: anonymous parameters are deprecated and will be removed in the next edi LL | fn foo(i32); | ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686> note: the lint level is defined here --> $DIR/anon-params-deprecated.rs:1:9 | LL | #![warn(anonymous_parameters)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686> warning: anonymous parameters are deprecated and will be removed in the next edition --> $DIR/anon-params-deprecated.rs:12:30 diff --git a/src/test/ui/array-slice-vec/array_const_index-0.stderr b/src/test/ui/array-slice-vec/array_const_index-0.stderr index 4832398713d..154872915d6 100644 --- a/src/test/ui/array-slice-vec/array_const_index-0.stderr +++ b/src/test/ui/array-slice-vec/array_const_index-0.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const B: i32 = (&A)[1]; | ------------ ^^^^^^^ index out of bounds: the length is 0 but the index is 1 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to previous error @@ -17,7 +17,7 @@ error: any use of this value will cause an error LL | const B: i32 = (&A)[1]; | ------------ ^^^^^^^ index out of bounds: the length is 0 but the index is 1 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/array-slice-vec/array_const_index-1.stderr b/src/test/ui/array-slice-vec/array_const_index-1.stderr index 361f518c052..a13b5b4ccc1 100644 --- a/src/test/ui/array-slice-vec/array_const_index-1.stderr +++ b/src/test/ui/array-slice-vec/array_const_index-1.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const B: i32 = A[1]; | ------------ ^^^^ index out of bounds: the length is 0 but the index is 1 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to previous error @@ -17,7 +17,7 @@ error: any use of this value will cause an error LL | const B: i32 = A[1]; | ------------ ^^^^ index out of bounds: the length is 0 but the index is 1 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/asm/aarch64/type-check-3.stderr b/src/test/ui/asm/aarch64/type-check-3.stderr index 49292982eec..f710df2dcde 100644 --- a/src/test/ui/asm/aarch64/type-check-3.stderr +++ b/src/test/ui/asm/aarch64/type-check-3.stderr @@ -4,9 +4,9 @@ warning: formatting may not be suitable for sub-register argument LL | asm!("{}", in(reg) 0u8); | ^^ --- for this argument | - = note: `#[warn(asm_sub_register)]` on by default = help: use `{0:w}` to have the register formatted as `w0` = help: or use `{0:x}` to keep the default formatting of `x0` + = note: `#[warn(asm_sub_register)]` on by default warning: formatting may not be suitable for sub-register argument --> $DIR/type-check-3.rs:50:15 diff --git a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr index 5dac693cc27..bb6a222b22e 100644 --- a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr +++ b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr @@ -189,9 +189,9 @@ warning: formatting may not be suitable for sub-register argument LL | asm!("{:foo}", in(reg) foo); | ^^^^^^ --- for this argument | - = note: `#[warn(asm_sub_register)]` on by default = help: use `{0:w}` to have the register formatted as `w0` = help: or use `{0:x}` to keep the default formatting of `x0` + = note: `#[warn(asm_sub_register)]` on by default error: aborting due to 21 previous errors; 1 warning emitted diff --git a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr index 5dac693cc27..bb6a222b22e 100644 --- a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr +++ b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr @@ -189,9 +189,9 @@ warning: formatting may not be suitable for sub-register argument LL | asm!("{:foo}", in(reg) foo); | ^^^^^^ --- for this argument | - = note: `#[warn(asm_sub_register)]` on by default = help: use `{0:w}` to have the register formatted as `w0` = help: or use `{0:x}` to keep the default formatting of `x0` + = note: `#[warn(asm_sub_register)]` on by default error: aborting due to 21 previous errors; 1 warning emitted diff --git a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr index b29b74bac80..903b5e959f3 100644 --- a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr +++ b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr @@ -189,9 +189,9 @@ warning: formatting may not be suitable for sub-register argument LL | asm!("{:foo}", in(reg) foo); | ^^^^^^ --- for this argument | - = note: `#[warn(asm_sub_register)]` on by default = help: use `{0:e}` to have the register formatted as `eax` = help: or use `{0:r}` to keep the default formatting of `rax` + = note: `#[warn(asm_sub_register)]` on by default error: aborting due to 21 previous errors; 1 warning emitted diff --git a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr index b29b74bac80..903b5e959f3 100644 --- a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr +++ b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr @@ -189,9 +189,9 @@ warning: formatting may not be suitable for sub-register argument LL | asm!("{:foo}", in(reg) foo); | ^^^^^^ --- for this argument | - = note: `#[warn(asm_sub_register)]` on by default = help: use `{0:e}` to have the register formatted as `eax` = help: or use `{0:r}` to keep the default formatting of `rax` + = note: `#[warn(asm_sub_register)]` on by default error: aborting due to 21 previous errors; 1 warning emitted diff --git a/src/test/ui/asm/naked-functions-ffi.stderr b/src/test/ui/asm/naked-functions-ffi.stderr index ac743551311..908881b1949 100644 --- a/src/test/ui/asm/naked-functions-ffi.stderr +++ b/src/test/ui/asm/naked-functions-ffi.stderr @@ -4,9 +4,9 @@ warning: `extern` fn uses type `char`, which is not FFI-safe LL | pub extern "C" fn naked(p: char) -> u128 { | ^^^^ not FFI-safe | - = note: `#[warn(improper_ctypes_definitions)]` on by default = help: consider using `u32` or `libc::wchar_t` instead = note: the `char` type has no C equivalent + = note: `#[warn(improper_ctypes_definitions)]` on by default warning: `extern` fn uses type `u128`, which is not FFI-safe --> $DIR/naked-functions-ffi.rs:9:37 diff --git a/src/test/ui/asm/named-asm-labels.stderr b/src/test/ui/asm/named-asm-labels.stderr index 001601497a2..c8380629e12 100644 --- a/src/test/ui/asm/named-asm-labels.stderr +++ b/src/test/ui/asm/named-asm-labels.stderr @@ -4,9 +4,9 @@ error: avoid using named labels in inline assembly LL | asm!("bar: nop"); | ^^^ | - = note: `#[deny(named_asm_labels)]` on by default = help: only local labels of the form `<number>:` should be used in inline asm = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information + = note: `#[deny(named_asm_labels)]` on by default error: avoid using named labels in inline assembly --> $DIR/named-asm-labels.rs:27:15 @@ -259,13 +259,13 @@ warning: avoid using named labels in inline assembly LL | asm!("warned: nop"); | ^^^^^^ | + = help: only local labels of the form `<number>:` should be used in inline asm + = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information note: the lint level is defined here --> $DIR/named-asm-labels.rs:132:16 | LL | #[warn(named_asm_labels)] | ^^^^^^^^^^^^^^^^ - = help: only local labels of the form `<number>:` should be used in inline asm - = note: see the asm section of Rust By Example <https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html#labels> for more information error: avoid using named labels in inline assembly --> $DIR/named-asm-labels.rs:143:20 diff --git a/src/test/ui/asm/x86_64/type-check-3.stderr b/src/test/ui/asm/x86_64/type-check-3.stderr index 366038fea23..1baf50ff6e0 100644 --- a/src/test/ui/asm/x86_64/type-check-3.stderr +++ b/src/test/ui/asm/x86_64/type-check-3.stderr @@ -44,9 +44,9 @@ warning: formatting may not be suitable for sub-register argument LL | asm!("{0} {0}", in(reg) 0i16); | ^^^ ^^^ ---- for this argument | - = note: `#[warn(asm_sub_register)]` on by default = help: use `{0:x}` to have the register formatted as `ax` = help: or use `{0:r}` to keep the default formatting of `rax` + = note: `#[warn(asm_sub_register)]` on by default warning: formatting may not be suitable for sub-register argument --> $DIR/type-check-3.rs:36:15 diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr index 66ee6031c71..8a7c16e6117 100644 --- a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr +++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const B: u8 = Self::A + 1; | ----------- ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error[E0080]: evaluation of constant value failed --> $DIR/defaults-not-assumed-fail.rs:34:16 @@ -34,9 +34,9 @@ error: any use of this value will cause an error LL | const B: u8 = Self::A + 1; | ----------- ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: erroneous constant used @@ -45,8 +45,8 @@ error: erroneous constant used LL | assert_eq!(<() as Tr>::B, 0); // causes the error above | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/associated-types/defaults-specialization.stderr b/src/test/ui/associated-types/defaults-specialization.stderr index 2d61b2a647b..8df326351fa 100644 --- a/src/test/ui/associated-types/defaults-specialization.stderr +++ b/src/test/ui/associated-types/defaults-specialization.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(associated_type_defaults, specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0053]: method `make` has an incompatible type for trait --> $DIR/defaults-specialization.rs:19:18 diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr index 50a82c08c3f..d99967eb23c 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr +++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr @@ -4,13 +4,13 @@ error: `await` is a keyword in the 2018 edition LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> note: the lint level is defined here --> $DIR/2015-edition-error-various-positions.rs:2:9 | LL | #![deny(keyword_idents)] | ^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-error-various-positions.rs:7:20 diff --git a/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr b/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr index 1c4c19ea45f..bf5c4d8d6aa 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr +++ b/src/test/ui/async-await/await-keyword/2015-edition-warning.stderr @@ -4,13 +4,13 @@ error: `await` is a keyword in the 2018 edition LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> note: the lint level is defined here --> $DIR/2015-edition-warning.rs:4:9 | LL | #![deny(keyword_idents)] | ^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition --> $DIR/2015-edition-warning.rs:10:20 diff --git a/src/test/ui/async-await/large_moves.attribute.stderr b/src/test/ui/async-await/large_moves.attribute.stderr index 8d3f0b77f43..da34f44b2d6 100644 --- a/src/test/ui/async-await/large_moves.attribute.stderr +++ b/src/test/ui/async-await/large_moves.attribute.stderr @@ -10,12 +10,12 @@ LL | | dbg!(y); LL | | }; | |_____^ value moved from here | + = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/large_moves.rs:1:9 | LL | #![deny(large_assignments)] | ^^^^^^^^^^^^^^^^^ - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: moving 10024 bytes --> $DIR/large_moves.rs:18:14 diff --git a/src/test/ui/async-await/large_moves.option.stderr b/src/test/ui/async-await/large_moves.option.stderr index 8d3f0b77f43..da34f44b2d6 100644 --- a/src/test/ui/async-await/large_moves.option.stderr +++ b/src/test/ui/async-await/large_moves.option.stderr @@ -10,12 +10,12 @@ LL | | dbg!(y); LL | | }; | |_____^ value moved from here | + = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` note: the lint level is defined here --> $DIR/large_moves.rs:1:9 | LL | #![deny(large_assignments)] | ^^^^^^^^^^^^^^^^^ - = note: The current maximum size is 1000, but it can be customized with the move_size_limit attribute: `#![move_size_limit = "..."]` error: moving 10024 bytes --> $DIR/large_moves.rs:18:14 diff --git a/src/test/ui/attributes/doc-attr.stderr b/src/test/ui/attributes/doc-attr.stderr index cc2494c92e6..68df2771fd7 100644 --- a/src/test/ui/attributes/doc-attr.stderr +++ b/src/test/ui/attributes/doc-attr.stderr @@ -4,14 +4,14 @@ error: unknown `doc` attribute `as_ptr` LL | #[doc(as_ptr)] | ^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> note: the lint level is defined here --> $DIR/doc-attr.rs:2:9 | LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> error: invalid `doc` attribute --> $DIR/doc-attr.rs:12:7 diff --git a/src/test/ui/attributes/invalid-doc-attr.stderr b/src/test/ui/attributes/invalid-doc-attr.stderr index a4fa3817905..3c66e587b47 100644 --- a/src/test/ui/attributes/invalid-doc-attr.stderr +++ b/src/test/ui/attributes/invalid-doc-attr.stderr @@ -4,15 +4,15 @@ error: this attribute can only be applied at the crate level LL | #[doc(test(no_crate_inject))] | ^^^^^^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information note: the lint level is defined here --> $DIR/invalid-doc-attr.rs:2:9 | LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]` - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> - = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information help: to apply to the crate, use an inner attribute | LL | #![doc(test(no_crate_inject))] diff --git a/src/test/ui/auto-traits/suspicious-impls-lint.stderr b/src/test/ui/auto-traits/suspicious-impls-lint.stderr index 97b2d7221fd..9cd4e79f851 100644 --- a/src/test/ui/auto-traits/suspicious-impls-lint.stderr +++ b/src/test/ui/auto-traits/suspicious-impls-lint.stderr @@ -4,11 +4,6 @@ error: cross-crate traits with a default impl, like `Send`, should not be specia LL | unsafe impl<T: Send> Send for MayImplementSendErr<&T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/suspicious-impls-lint.rs:1:9 - | -LL | #![deny(suspicious_auto_trait_impls)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this will change its meaning in a future release! = note: for more information, see issue #93367 <https://github.com/rust-lang/rust/issues/93367> = note: `&T` is not a generic parameter @@ -17,6 +12,11 @@ note: try using the same sequence of generic parameters as the struct definition | LL | struct MayImplementSendErr<T>(T); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/suspicious-impls-lint.rs:1:9 + | +LL | #![deny(suspicious_auto_trait_impls)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cross-crate traits with a default impl, like `Send`, should not be specialized --> $DIR/suspicious-impls-lint.rs:21:1 diff --git a/src/test/ui/binding/issue-53114-safety-checks.stderr b/src/test/ui/binding/issue-53114-safety-checks.stderr index f3840273cfa..57a065d6d4d 100644 --- a/src/test/ui/binding/issue-53114-safety-checks.stderr +++ b/src/test/ui/binding/issue-53114-safety-checks.stderr @@ -4,11 +4,11 @@ error: reference to packed field is unaligned LL | let _ = &p.b; | ^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default error: reference to packed field is unaligned --> $DIR/issue-53114-safety-checks.rs:29:17 @@ -109,11 +109,11 @@ error: reference to packed field is unaligned LL | let _ = &p.b; | ^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default Future breakage diagnostic: error: reference to packed field is unaligned @@ -122,11 +122,11 @@ error: reference to packed field is unaligned LL | let (_,) = (&p.b,); | ^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default Future breakage diagnostic: error: reference to packed field is unaligned @@ -135,11 +135,11 @@ error: reference to packed field is unaligned LL | match &p.b { _ => { } } | ^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default Future breakage diagnostic: error: reference to packed field is unaligned @@ -148,9 +148,9 @@ error: reference to packed field is unaligned LL | match (&p.b,) { (_,) => { } } | ^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default diff --git a/src/test/ui/block-result/consider-removing-last-semi.stderr b/src/test/ui/block-result/consider-removing-last-semi.stderr index 2412dcd32f7..9be0367ae38 100644 --- a/src/test/ui/block-result/consider-removing-last-semi.stderr +++ b/src/test/ui/block-result/consider-removing-last-semi.stderr @@ -7,7 +7,7 @@ LL | pub fn f() -> String { | implicitly returns `()` as its body has no tail or `return` expression LL | 0u8; LL | "bla".to_string(); - | - help: remove this semicolon + | - help: remove this semicolon to return this value error[E0308]: mismatched types --> $DIR/consider-removing-last-semi.rs:8:15 @@ -18,7 +18,7 @@ LL | pub fn g() -> String { | implicitly returns `()` as its body has no tail or `return` expression LL | "this won't work".to_string(); LL | "removeme".to_string(); - | - help: remove this semicolon + | - help: remove this semicolon to return this value error[E0308]: mismatched types --> $DIR/consider-removing-last-semi.rs:13:25 @@ -29,7 +29,7 @@ LL | pub fn macro_tests() -> u32 { | implicitly returns `()` as its body has no tail or `return` expression ... LL | mac!(); - | - help: remove this semicolon + | - help: remove this semicolon to return this value error: aborting due to 3 previous errors diff --git a/src/test/ui/block-result/issue-11714.stderr b/src/test/ui/block-result/issue-11714.stderr index 5b8d96fd4eb..42fb3d3d43d 100644 --- a/src/test/ui/block-result/issue-11714.stderr +++ b/src/test/ui/block-result/issue-11714.stderr @@ -7,7 +7,7 @@ LL | fn blah() -> i32 { | implicitly returns `()` as its body has no tail or `return` expression ... LL | ; - | - help: remove this semicolon + | - help: remove this semicolon to return this value error: aborting due to previous error diff --git a/src/test/ui/block-result/issue-13428.stderr b/src/test/ui/block-result/issue-13428.stderr index a33448edff2..2b386d10c53 100644 --- a/src/test/ui/block-result/issue-13428.stderr +++ b/src/test/ui/block-result/issue-13428.stderr @@ -15,7 +15,7 @@ LL | fn bar() -> String { | implicitly returns `()` as its body has no tail or `return` expression LL | "foobar".to_string() LL | ; - | - help: remove this semicolon + | - help: remove this semicolon to return this value error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/issue-102209.rs b/src/test/ui/borrowck/issue-102209.rs new file mode 100644 index 00000000000..37628bff7df --- /dev/null +++ b/src/test/ui/borrowck/issue-102209.rs @@ -0,0 +1,28 @@ +use std::marker::PhantomData; + +pub struct NfaBuilder<'brand> { + brand: PhantomData<&'brand mut &'brand mut ()>, +} + +impl NfaBuilder<'_> { + pub fn with<R, F: FnOnce(NfaBuilder<'_>) -> R>(f: F) -> R { + Brand::with(|brand| { + f(Self { brand: brand.lt }) + //~^ ERROR lifetime may not live long enough + //~| ERROR lifetime may not live long enough + }) + } +} + +#[derive(Clone, Copy)] +pub struct Brand<'brand> { + lt: PhantomData<&'brand mut &'brand mut ()>, +} + +impl Brand<'_> { + pub fn with<R, F: FnOnce(Brand<'_>) -> R>(f: F) -> R { + f(Self { lt: PhantomData }) + } +} + +fn main() {} diff --git a/src/test/ui/borrowck/issue-102209.stderr b/src/test/ui/borrowck/issue-102209.stderr new file mode 100644 index 00000000000..351de8217b2 --- /dev/null +++ b/src/test/ui/borrowck/issue-102209.stderr @@ -0,0 +1,22 @@ +error: lifetime may not live long enough + --> $DIR/issue-102209.rs:10:29 + | +LL | impl NfaBuilder<'_> { + | -- lifetime `'2` appears in the `impl`'s self type +LL | pub fn with<R, F: FnOnce(NfaBuilder<'_>) -> R>(f: F) -> R { +LL | Brand::with(|brand| { + | ----- has type `Brand<'1>` +LL | f(Self { brand: brand.lt }) + | ^^^^^^^^ this usage requires that `'1` must outlive `'2` + +error: lifetime may not live long enough + --> $DIR/issue-102209.rs:10:29 + | +LL | impl NfaBuilder<'_> { + | -- lifetime `'1` appears in the `impl`'s self type +... +LL | f(Self { brand: brand.lt }) + | ^^^^^^^^ this usage requires that `'1` must outlive `'static` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/borrowck/issue-81899.stderr b/src/test/ui/borrowck/issue-81899.stderr index fd591c7b563..19cd323ce57 100644 --- a/src/test/ui/borrowck/issue-81899.stderr +++ b/src/test/ui/borrowck/issue-81899.stderr @@ -18,9 +18,9 @@ error: any use of this value will cause an error LL | const _CONST: &[u8] = &f(&[], |_| {}); | ------------------- ^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to 2 previous errors @@ -32,7 +32,7 @@ error: any use of this value will cause an error LL | const _CONST: &[u8] = &f(&[], |_| {}); | ------------------- ^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.stderr b/src/test/ui/borrowck/issue-88434-minimal-example.stderr index a3582e78041..4492af7ec6b 100644 --- a/src/test/ui/borrowck/issue-88434-minimal-example.stderr +++ b/src/test/ui/borrowck/issue-88434-minimal-example.stderr @@ -18,9 +18,9 @@ error: any use of this value will cause an error LL | const _CONST: &() = &f(&|_| {}); | ----------------- ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to 2 previous errors @@ -32,7 +32,7 @@ error: any use of this value will cause an error LL | const _CONST: &() = &f(&|_| {}); | ----------------- ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr index a6c65b302db..a889e67f4ea 100644 --- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr +++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr @@ -18,9 +18,9 @@ error: any use of this value will cause an error LL | const _CONST: &[u8] = &f(&[], |_| {}); | ------------------- ^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to 2 previous errors @@ -32,7 +32,7 @@ error: any use of this value will cause an error LL | const _CONST: &[u8] = &f(&[], |_| {}); | ------------------- ^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/cenum_impl_drop_cast.stderr b/src/test/ui/cenum_impl_drop_cast.stderr index 98c33105733..b3f921c14ed 100644 --- a/src/test/ui/cenum_impl_drop_cast.stderr +++ b/src/test/ui/cenum_impl_drop_cast.stderr @@ -4,13 +4,13 @@ error: cannot cast enum `E` into integer `u32` because it implements `Drop` LL | let i = e as u32; | ^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333> note: the lint level is defined here --> $DIR/cenum_impl_drop_cast.rs:1:9 | LL | #![deny(cenum_impl_drop_cast)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333> error: aborting due to previous error @@ -21,11 +21,11 @@ error: cannot cast enum `E` into integer `u32` because it implements `Drop` LL | let i = e as u32; | ^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333> note: the lint level is defined here --> $DIR/cenum_impl_drop_cast.rs:1:9 | LL | #![deny(cenum_impl_drop_cast)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #73333 <https://github.com/rust-lang/rust/issues/73333> diff --git a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr index b52535ffdba..9ce4710d69b 100644 --- a/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr +++ b/src/test/ui/cfg/future-compat-crate-attributes-using-cfg_attr.stderr @@ -4,9 +4,9 @@ error: `crate_type` within an `#![cfg_attr] attribute is deprecated` LL | #![cfg_attr(foo, crate_type="bin")] | ^^^^^^^^^^^^^^^^ | - = note: `#[deny(deprecated_cfg_attr_crate_type_name)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #91632 <https://github.com/rust-lang/rust/issues/91632> + = note: `#[deny(deprecated_cfg_attr_crate_type_name)]` on by default error: `crate_name` within an `#![cfg_attr] attribute is deprecated` --> $DIR/future-compat-crate-attributes-using-cfg_attr.rs:9:18 diff --git a/src/test/ui/check-cfg/compact-values.stderr b/src/test/ui/check-cfg/compact-values.stderr index a196e1537df..9864aa385f9 100644 --- a/src/test/ui/check-cfg/compact-values.stderr +++ b/src/test/ui/check-cfg/compact-values.stderr @@ -4,8 +4,8 @@ warning: unexpected `cfg` condition value LL | #[cfg(target(os = "linux", arch = "X"))] | ^^^^^^^^^^ | - = note: `#[warn(unexpected_cfgs)]` on by default = note: expected values for `target_arch` are: aarch64, arm, avr, bpf, hexagon, m68k, mips, mips64, msp430, nvptx64, powerpc, powerpc64, riscv32, riscv64, s390x, sparc, sparc64, wasm32, wasm64, x86, x86_64 + = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/check-cfg/empty-values.stderr b/src/test/ui/check-cfg/empty-values.stderr index 10dab503489..a0168b2caa8 100644 --- a/src/test/ui/check-cfg/empty-values.stderr +++ b/src/test/ui/check-cfg/empty-values.stderr @@ -6,8 +6,8 @@ LL | #[cfg(test = "value")] | | | help: remove the value | - = note: `#[warn(unexpected_cfgs)]` on by default = note: no expected value for `test` + = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/check-cfg/invalid-cfg-value.stderr b/src/test/ui/check-cfg/invalid-cfg-value.stderr index 7db2aadec17..60abcb18824 100644 --- a/src/test/ui/check-cfg/invalid-cfg-value.stderr +++ b/src/test/ui/check-cfg/invalid-cfg-value.stderr @@ -4,8 +4,8 @@ warning: unexpected `cfg` condition value LL | #[cfg(feature = "sedre")] | ^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unexpected_cfgs)]` on by default = note: expected values for `feature` are: full, serde + = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value --> $DIR/invalid-cfg-value.rs:14:7 diff --git a/src/test/ui/check-cfg/no-values.stderr b/src/test/ui/check-cfg/no-values.stderr index 7025b4cd7ba..8c926d187fe 100644 --- a/src/test/ui/check-cfg/no-values.stderr +++ b/src/test/ui/check-cfg/no-values.stderr @@ -4,8 +4,8 @@ warning: unexpected `cfg` condition value LL | #[cfg(feature = "foo")] | ^^^^^^^^^^^^^^^ | - = note: `#[warn(unexpected_cfgs)]` on by default = note: no expected value for `feature` + = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value --> $DIR/no-values.rs:10:7 diff --git a/src/test/ui/check-cfg/well-known-values.stderr b/src/test/ui/check-cfg/well-known-values.stderr index 24ce2280c8a..4ec74494fe0 100644 --- a/src/test/ui/check-cfg/well-known-values.stderr +++ b/src/test/ui/check-cfg/well-known-values.stderr @@ -6,8 +6,8 @@ LL | #[cfg(target_os = "linuz")] | | | help: did you mean: `"linux"` | - = note: `#[warn(unexpected_cfgs)]` on by default = note: expected values for `target_os` are: android, cuda, dragonfly, emscripten, espidf, freebsd, fuchsia, haiku, hermit, horizon, illumos, ios, l4re, linux, macos, netbsd, none, openbsd, psp, redox, solaris, solid_asp3, tvos, uefi, unknown, vxworks, wasi, watchos, windows, xous + = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value --> $DIR/well-known-values.rs:14:7 diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr index 7e767cba3cc..cf414adc0b9 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness.stderr @@ -4,13 +4,13 @@ warning: value captured by `a` is never read LL | a = 1; | ^ | + = help: did you mean to capture by reference instead? note: the lint level is defined here --> $DIR/liveness.rs:5:9 | LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` - = help: did you mean to capture by reference instead? warning: unused variable: `a` --> $DIR/liveness.rs:33:9 @@ -18,8 +18,8 @@ warning: unused variable: `a` LL | a += 1; | ^ | - = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` = help: did you mean to capture by reference instead? + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: value assigned to `a` is never read --> $DIR/liveness.rs:53:9 diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr index 2ac801b49f1..0410de4c798 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/liveness_unintentional_copy.stderr @@ -4,13 +4,13 @@ warning: value assigned to `a` is never read LL | a = s; | ^ | + = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/liveness_unintentional_copy.rs:4:9 | LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` - = help: maybe it is overwritten before being read? warning: unused variable: `a` --> $DIR/liveness_unintentional_copy.rs:20:9 @@ -18,8 +18,8 @@ warning: unused variable: `a` LL | a = s; | ^ | - = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` = help: did you mean to capture by reference instead? + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: unused variable: `a` --> $DIR/liveness_unintentional_copy.rs:36:9 diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr index 93abbecf4e4..508c4b911b7 100644 --- a/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr +++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/repr_packed.stderr @@ -4,11 +4,11 @@ error: reference to packed field is unaligned LL | println!("{}", foo.x); | ^^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error @@ -20,10 +20,10 @@ error: reference to packed field is unaligned LL | println!("{}", foo.x); | ^^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr b/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr index 15689023d81..b3cb558f976 100644 --- a/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr +++ b/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr @@ -4,9 +4,9 @@ warning: irrefutable `if let` guard pattern LL | Registry if let _ = registry.try_find_description() => { } | ^ | - = note: `#[warn(irrefutable_let_patterns)]` on by default = note: this pattern will always match, so the guard is useless = help: consider removing the guard and adding a `let` inside the match arm + = note: `#[warn(irrefutable_let_patterns)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr b/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr index 3e921dc0f8a..c1679c6b637 100644 --- a/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr +++ b/src/test/ui/closures/2229_closure_analysis/issue-90465.stderr @@ -10,12 +10,12 @@ LL | let _ = f0; LL | } | - in Rust 2018, `f0` is dropped here along with the closure, but in Rust 2021 `f0` is not part of the closure | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/issue-90465.rs:3:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `f0` to be fully captured | LL ~ let c0 = move || { diff --git a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr index 2a49ed4b5ff..38401085971 100644 --- a/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr +++ b/src/test/ui/closures/2229_closure_analysis/match/issue-87097.stderr @@ -18,8 +18,8 @@ LL | | Variant::B => (), LL | | }; | |______^ | - = note: `#[warn(unused_must_use)]` on by default = note: closures are lazy and do nothing unless called + = note: `#[warn(unused_must_use)]` on by default warning: unused closure that must be used --> $DIR/issue-87097.rs:26:5 diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr index d7104bafeb1..3a42cc8b843 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/auto_traits.stderr @@ -7,12 +7,12 @@ LL | thread::spawn(move || unsafe { LL | *fptr.0 = 20; | ------- in Rust 2018, this closure captures all of `fptr`, but in Rust 2021, it will only capture `fptr.0` | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/auto_traits.rs:2:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `fptr` to be fully captured | LL ~ thread::spawn(move || { let _ = &fptr; unsafe { diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr index c611daf13fd..bb17e3a34af 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/closure-body-macro-fragment.stderr @@ -15,13 +15,13 @@ LL | | println!("{:?}", x); LL | | }); | |______- in this macro invocation | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/closure-body-macro-fragment.rs:4:9 | LL | #![warn(rust_2021_compatibility)] | ^^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(rust_2021_incompatible_closure_captures)]` implied by `#[warn(rust_2021_compatibility)]` - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) help: add a dummy let to cause `a` to be fully captured | diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr index 832a81711b1..a0795c12928 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/insignificant_drop_attr_migrations.stderr @@ -10,12 +10,12 @@ LL | let _t = t.0; LL | } | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/insignificant_drop_attr_migrations.rs:3:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `t` to be fully captured | LL ~ let c = || { diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr index 41b675f7960..36a80e694e8 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr @@ -4,9 +4,9 @@ warning: irrefutable `if let` pattern LL | if let a = "" { | ^^^^^^^^^^ | - = note: `#[warn(irrefutable_let_patterns)]` on by default = note: this pattern will always match, so the `if let` is useless = help: consider replacing the `if let` with a `let` + = note: `#[warn(irrefutable_let_patterns)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr index 2d0c56aad8d..c17edce72f9 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/macro.stderr @@ -7,12 +7,12 @@ LL | let _ = || dbg!(a.0); LL | } | - in Rust 2018, `a` is dropped here, but in Rust 2021, only `a.0` will be dropped here as part of the closure | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/macro.rs:5:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `a` to be fully captured | LL | let _ = || { let _ = &a; dbg!(a.0) }; diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr index 12760cc7256..94526487e67 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/migrations_rustfix.stderr @@ -10,12 +10,12 @@ LL | let _t = t.0; LL | } | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/migrations_rustfix.rs:2:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `t` to be fully captured | LL ~ let c = || { diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr index 62cfcbe95bc..e10898f9844 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/mir_calls_to_shims.stderr @@ -10,12 +10,12 @@ LL | let result = panic::catch_unwind(move || { LL | f.0() | --- in Rust 2018, this closure captures all of `f`, but in Rust 2021, it will only capture `f.0` | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/mir_calls_to_shims.rs:4:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `f` to be fully captured | LL ~ let result = panic::catch_unwind(move || { diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr index 96d5c936fa5..efb264447f6 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/multi_diagnostics.stderr @@ -13,12 +13,12 @@ LL | let _f_2 = f2.1; LL | } | - in Rust 2018, `f2` is dropped here, but in Rust 2021, only `f2.1` will be dropped here as part of the closure | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/multi_diagnostics.rs:2:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `f1`, `f2` to be fully captured | LL ~ let c = || { diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr index aa9b8672a0f..eff26a4d6f5 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/precise.stderr @@ -10,12 +10,12 @@ LL | let _t = t.0; LL | } | - in Rust 2018, `t` is dropped here, but in Rust 2021, only `t.0` will be dropped here as part of the closure | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/precise.rs:3:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `t` to be fully captured | LL ~ let c = || { diff --git a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr index 0d9f09ee354..54ad20f8983 100644 --- a/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr +++ b/src/test/ui/closures/2229_closure_analysis/migrations/significant_drop.stderr @@ -20,12 +20,12 @@ LL | } | in Rust 2018, `t1` is dropped here, but in Rust 2021, only `t1.0` will be dropped here as part of the closure | in Rust 2018, `t2` is dropped here, but in Rust 2021, only `t2.0` will be dropped here as part of the closure | + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> note: the lint level is defined here --> $DIR/significant_drop.rs:2:9 | LL | #![deny(rust_2021_incompatible_closure_captures)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> help: add a dummy let to cause `t`, `t1`, `t2` to be fully captured | LL ~ let c = || { diff --git a/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed b/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed index 623e917da07..8aa9e952b99 100644 --- a/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed +++ b/src/test/ui/closures/old-closure-expression-remove-semicolon.fixed @@ -7,6 +7,6 @@ fn foo() -> i32 { fn main() { let _x: i32 = { //~^ ERROR mismatched types - foo() //~ HELP remove this semicolon + foo() //~ HELP remove this semicolon to return this value }; } diff --git a/src/test/ui/closures/old-closure-expression-remove-semicolon.rs b/src/test/ui/closures/old-closure-expression-remove-semicolon.rs index 4974b086649..912c7a3314a 100644 --- a/src/test/ui/closures/old-closure-expression-remove-semicolon.rs +++ b/src/test/ui/closures/old-closure-expression-remove-semicolon.rs @@ -7,6 +7,6 @@ fn foo() -> i32 { fn main() { let _x: i32 = { //~^ ERROR mismatched types - foo(); //~ HELP remove this semicolon + foo(); //~ HELP remove this semicolon to return this value }; } diff --git a/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr b/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr index 9b73ce4fee3..bc54ab4d511 100644 --- a/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr +++ b/src/test/ui/closures/old-closure-expression-remove-semicolon.stderr @@ -5,7 +5,7 @@ LL | let _x: i32 = { | ___________________^ LL | | LL | | foo(); - | | - help: remove this semicolon + | | - help: remove this semicolon to return this value LL | | }; | |_____^ expected `i32`, found `()` diff --git a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr index a4843bca58c..4c04bb11351 100644 --- a/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr +++ b/src/test/ui/coercion/coercion-missing-tail-expected-type.stderr @@ -6,7 +6,7 @@ LL | fn plus_one(x: i32) -> i32 { | | | implicitly returns `()` as its body has no tail or `return` expression LL | x + 1; - | - help: remove this semicolon + | - help: remove this semicolon to return this value error[E0308]: mismatched types --> $DIR/coercion-missing-tail-expected-type.rs:8:13 @@ -16,7 +16,7 @@ LL | fn foo() -> Result<u8, u64> { | | | implicitly returns `()` as its body has no tail or `return` expression LL | Ok(1); - | - help: remove this semicolon + | - help: remove this semicolon to return this value | = note: expected enum `Result<u8, u64>` found unit type `()` diff --git a/src/test/ui/coherence/coherence-fn-implied-bounds.stderr b/src/test/ui/coherence/coherence-fn-implied-bounds.stderr index 8612ce60d18..2018712043e 100644 --- a/src/test/ui/coherence/coherence-fn-implied-bounds.stderr +++ b/src/test/ui/coherence/coherence-fn-implied-bounds.stderr @@ -7,14 +7,14 @@ LL | LL | impl Trait for for<'c> fn(&'c &'c u32, &'c &'c u32) -> &'c u32 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a &'b u32, &'b &'a u32) -> &'b u32` | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details note: the lint level is defined here --> $DIR/coherence-fn-implied-bounds.rs:15:9 | LL | #![deny(coherence_leak_check)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-free-vs-bound-region.stderr b/src/test/ui/coherence/coherence-free-vs-bound-region.stderr index af18655b06f..e2d84b83320 100644 --- a/src/test/ui/coherence/coherence-free-vs-bound-region.stderr +++ b/src/test/ui/coherence/coherence-free-vs-bound-region.stderr @@ -7,14 +7,14 @@ LL | LL | impl TheTrait for fn(&u8) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(&u8)` | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details note: the lint level is defined here --> $DIR/coherence-free-vs-bound-region.rs:10:9 | LL | #![deny(coherence_leak_check)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details error: aborting due to previous error diff --git a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr index 97f3c759355..7bd50649d6d 100644 --- a/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr +++ b/src/test/ui/coherence/coherence-inherited-assoc-ty-cycle-err.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0391]: cycle detected when building specialization graph of trait `Trait` --> $DIR/coherence-inherited-assoc-ty-cycle-err.rs:9:1 diff --git a/src/test/ui/coherence/coherence-subtyping.stderr b/src/test/ui/coherence/coherence-subtyping.stderr index 25d8c875653..9d90019a50f 100644 --- a/src/test/ui/coherence/coherence-subtyping.stderr +++ b/src/test/ui/coherence/coherence-subtyping.stderr @@ -7,10 +7,10 @@ LL | LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` | - = note: `#[warn(coherence_leak_check)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + = note: `#[warn(coherence_leak_check)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/coherence/coherence-wasm-bindgen.stderr b/src/test/ui/coherence/coherence-wasm-bindgen.stderr index aa74e231539..cfcc21240e4 100644 --- a/src/test/ui/coherence/coherence-wasm-bindgen.stderr +++ b/src/test/ui/coherence/coherence-wasm-bindgen.stderr @@ -7,15 +7,15 @@ LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn Fn(A) -> R + 'b) LL | impl<'a, 'b, A, R> IntoWasmAbi for &'a (dyn for<'x> Fn(&'x A) -> R + 'b) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&dyn std::ops::Fn(&_) -> _` | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> + = note: downstream crates may implement trait `FromWasmAbi` for type `&_` + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details note: the lint level is defined here --> $DIR/coherence-wasm-bindgen.rs:10:9 | LL | #![deny(coherence_leak_check)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> - = note: downstream crates may implement trait `FromWasmAbi` for type `&_` - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details error: aborting due to previous error diff --git a/src/test/ui/conflicting-repr-hints.stderr b/src/test/ui/conflicting-repr-hints.stderr index 0c7c50d6730..4dcd8f4fc28 100644 --- a/src/test/ui/conflicting-repr-hints.stderr +++ b/src/test/ui/conflicting-repr-hints.stderr @@ -4,9 +4,9 @@ error[E0566]: conflicting representation hints LL | #[repr(C, u64)] | ^ ^^^ | - = note: `#[deny(conflicting_repr_hints)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585> + = note: `#[deny(conflicting_repr_hints)]` on by default error[E0566]: conflicting representation hints --> $DIR/conflicting-repr-hints.rs:19:8 diff --git a/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr index 4cd86fecd7e..828f0988a03 100644 --- a/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr @@ -22,9 +22,9 @@ warning: cannot use constants which depend on generic parameters in types LL | [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs` | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(const_evaluatable_unchecked)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200> + = note: `#[warn(const_evaluatable_unchecked)]` on by default warning: cannot use constants which depend on generic parameters in types --> $DIR/dependence_lint.rs:16:9 diff --git a/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr index b5719b3fe1d..8eb1fccc5f8 100644 --- a/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/eval-try-unify.stderr @@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to LL | #![feature(generic_const_exprs)] | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/const-generics/generic_const_exprs/function-call.stderr b/src/test/ui/const-generics/generic_const_exprs/function-call.stderr index 0d8463714e8..796dc01043c 100644 --- a/src/test/ui/const-generics/generic_const_exprs/function-call.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/function-call.stderr @@ -4,9 +4,9 @@ warning: cannot use constants which depend on generic parameters in types LL | let _ = [0; foo::<T>()]; | ^^^^^^^^^^ | - = note: `#[warn(const_evaluatable_unchecked)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200> + = note: `#[warn(const_evaluatable_unchecked)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-102074.rs b/src/test/ui/const-generics/generic_const_exprs/issue-102074.rs new file mode 100644 index 00000000000..66d15cf1215 --- /dev/null +++ b/src/test/ui/const-generics/generic_const_exprs/issue-102074.rs @@ -0,0 +1,23 @@ +// check-pass +// Checks that the NoopMethodCall lint doesn't call Instance::resolve on unresolved consts + +#![feature(generic_const_exprs)] +#![allow(incomplete_features)] + +#[derive(Debug, Clone)] +pub struct Aes128CipherKey([u8; Aes128Cipher::KEY_LEN]); + +impl Aes128CipherKey { + pub fn new(key: &[u8; Aes128Cipher::KEY_LEN]) -> Self { + Self(key.clone()) + } +} + +#[derive(Debug, Clone)] +pub struct Aes128Cipher; + +impl Aes128Cipher { + const KEY_LEN: usize = 16; +} + +fn main() {} diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr index b5b2b0e405a..1cceaece715 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-1.stderr @@ -4,8 +4,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use LL | #![feature(adt_const_params, generic_const_exprs)] | ^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information + = note: `#[warn(incomplete_features)]` on by default warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/issue-97047-ice-1.rs:3:30 diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr index 5dfbd87ccd4..774e842bcbe 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-97047-ice-2.stderr @@ -4,8 +4,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use LL | #![feature(adt_const_params, generic_const_exprs)] | ^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information + = note: `#[warn(incomplete_features)]` on by default warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/issue-97047-ice-2.rs:3:30 diff --git a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr index 45c7d835f33..440cf457e19 100644 --- a/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/object-safety-err-where-bounds.stderr @@ -4,11 +4,6 @@ error: the trait `Foo` cannot be made into an object LL | fn test(&self) where [u8; bar::<Self>()]: Sized; | ^^^^ | -note: the lint level is defined here - --> $DIR/object-safety-err-where-bounds.rs:3:9 - | -LL | #![deny(where_clauses_object_safety)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443> note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> @@ -19,6 +14,11 @@ LL | trait Foo { LL | fn test(&self) where [u8; bar::<Self>()]: Sized; | ^^^^ ...because method `test` references the `Self` type in its `where` clause = help: consider moving `test` to another trait +note: the lint level is defined here + --> $DIR/object-safety-err-where-bounds.rs:3:9 + | +LL | #![deny(where_clauses_object_safety)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/const-generics/invariant.stderr b/src/test/ui/const-generics/invariant.stderr index ce0fad10471..aabe4c93b36 100644 --- a/src/test/ui/const-generics/invariant.stderr +++ b/src/test/ui/const-generics/invariant.stderr @@ -7,10 +7,10 @@ LL | impl SadBee for for<'a> fn(&'a ()) { LL | impl SadBee for fn(&'static ()) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a ())` | - = note: `#[warn(coherence_leak_check)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105> = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details + = note: `#[warn(coherence_leak_check)]` on by default error[E0308]: mismatched types --> $DIR/invariant.rs:27:5 diff --git a/src/test/ui/const-generics/issue-80471.stderr b/src/test/ui/const-generics/issue-80471.stderr index dbcc0b7b600..b89706710bc 100644 --- a/src/test/ui/const-generics/issue-80471.stderr +++ b/src/test/ui/const-generics/issue-80471.stderr @@ -4,8 +4,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use LL | #![feature(adt_const_params)] | ^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information + = note: `#[warn(incomplete_features)]` on by default error[E0741]: `Box<Nat>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter --> $DIR/issue-80471.rs:10:17 diff --git a/src/test/ui/const-generics/issues/issue-83466.stderr b/src/test/ui/const-generics/issues/issue-83466.stderr index a60f71ea614..bcfd7063989 100644 --- a/src/test/ui/const-generics/issues/issue-83466.stderr +++ b/src/test/ui/const-generics/issues/issue-83466.stderr @@ -7,9 +7,9 @@ LL | fn func<'a, U>(self) -> U { LL | S.func::<'a, 10_u32>() | ^^ | - = note: `#[warn(late_bound_lifetime_arguments)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> + = note: `#[warn(late_bound_lifetime_arguments)]` on by default error[E0747]: constant provided when a type was expected --> $DIR/issue-83466.rs:11:18 diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr index bf0d0f352eb..0b051c6131b 100644 --- a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr +++ b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr @@ -67,9 +67,9 @@ warning: cannot use constants which depend on generic parameters in types LL | let _ = [0; size_of::<*mut T>() + 1]; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(const_evaluatable_unchecked)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200> + = note: `#[warn(const_evaluatable_unchecked)]` on by default error: aborting due to 7 previous errors; 1 warning emitted diff --git a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr index f9f6660f6b8..f0ba7a39d1e 100644 --- a/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr +++ b/src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr @@ -4,9 +4,9 @@ warning: cannot use constants which depend on generic parameters in types LL | [0; std::mem::size_of::<*mut T>()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(const_evaluatable_unchecked)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200> + = note: `#[warn(const_evaluatable_unchecked)]` on by default warning: cannot use constants which depend on generic parameters in types --> $DIR/const-evaluatable-unchecked.rs:16:21 diff --git a/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr b/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr index f9b56bd387a..fe3f24a67a2 100644 --- a/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr +++ b/src/test/ui/const-generics/occurs-check/unify-fixpoint.stderr @@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to LL | #![feature(generic_const_exprs)] | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/const_prop/issue-102553.rs b/src/test/ui/const_prop/issue-102553.rs new file mode 100644 index 00000000000..523a9d7ac72 --- /dev/null +++ b/src/test/ui/const_prop/issue-102553.rs @@ -0,0 +1,24 @@ +// compile-flags: --crate-type=lib +// check-pass + +pub trait Widget<E> { + fn boxed<'w>(self) -> Box<dyn WidgetDyn<E> + 'w> + where + Self: Sized + 'w; +} + +pub trait WidgetDyn<E> {} + +impl<T, E> WidgetDyn<E> for T where T: Widget<E> {} + +impl<E> Widget<E> for dyn WidgetDyn<E> + '_ { + fn boxed<'w>(self) -> Box<dyn WidgetDyn<E> + 'w> + where + Self: Sized + 'w, + { + // Even though this is illegal to const evaluate, this should never + // trigger an ICE because it can never be called from actual code + // (due to the trivially false where-clause predicate). + Box::new(self) + } +} diff --git a/src/test/ui/consts/assert-type-intrinsics.rs b/src/test/ui/consts/assert-type-intrinsics.rs index 3ce3e1bdbac..6b5612dda90 100644 --- a/src/test/ui/consts/assert-type-intrinsics.rs +++ b/src/test/ui/consts/assert-type-intrinsics.rs @@ -11,12 +11,15 @@ fn main() { use std::mem::MaybeUninit; const _BAD1: () = unsafe { - MaybeUninit::<!>::uninit().assume_init(); + intrinsics::assert_inhabited::<!>(); //~ERROR: any use of this value will cause an error + //~^WARN: previously accepted }; const _BAD2: () = { - intrinsics::assert_uninit_valid::<bool>(); + intrinsics::assert_uninit_valid::<!>(); //~ERROR: any use of this value will cause an error + //~^WARN: previously accepted }; const _BAD3: () = { - intrinsics::assert_zero_valid::<&'static i32>(); + intrinsics::assert_zero_valid::<&'static i32>(); //~ERROR: any use of this value will cause an error + //~^WARN: previously accepted }; } diff --git a/src/test/ui/consts/assert-type-intrinsics.stderr b/src/test/ui/consts/assert-type-intrinsics.stderr index 6eab10197b8..9f97d836705 100644 --- a/src/test/ui/consts/assert-type-intrinsics.stderr +++ b/src/test/ui/consts/assert-type-intrinsics.stderr @@ -3,26 +3,26 @@ error: any use of this value will cause an error | LL | const _BAD1: () = unsafe { | --------------- -LL | MaybeUninit::<!>::uninit().assume_init(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!` +LL | intrinsics::assert_inhabited::<!>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!` | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error - --> $DIR/assert-type-intrinsics.rs:17:9 + --> $DIR/assert-type-intrinsics.rs:18:9 | LL | const _BAD2: () = { | --------------- -LL | intrinsics::assert_uninit_valid::<bool>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid +LL | intrinsics::assert_uninit_valid::<!>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: any use of this value will cause an error - --> $DIR/assert-type-intrinsics.rs:20:9 + --> $DIR/assert-type-intrinsics.rs:22:9 | LL | const _BAD3: () = { | --------------- @@ -40,36 +40,36 @@ error: any use of this value will cause an error | LL | const _BAD1: () = unsafe { | --------------- -LL | MaybeUninit::<!>::uninit().assume_init(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!` +LL | intrinsics::assert_inhabited::<!>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!` | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/assert-type-intrinsics.rs:17:9 + --> $DIR/assert-type-intrinsics.rs:18:9 | LL | const _BAD2: () = { | --------------- -LL | intrinsics::assert_uninit_valid::<bool>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid +LL | intrinsics::assert_uninit_valid::<!>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!` | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/assert-type-intrinsics.rs:20:9 + --> $DIR/assert-type-intrinsics.rs:22:9 | LL | const _BAD3: () = { | --------------- LL | intrinsics::assert_zero_valid::<&'static i32>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/assoc_const_generic_impl.stderr b/src/test/ui/consts/assoc_const_generic_impl.stderr index 17cbaef1f06..ca6db350c75 100644 --- a/src/test/ui/consts/assoc_const_generic_impl.stderr +++ b/src/test/ui/consts/assoc_const_generic_impl.stderr @@ -4,13 +4,13 @@ warning: any use of this value will cause an error LL | const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::<Self>()]; | ------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 4 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/assoc_const_generic_impl.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: erroneous constant encountered --> $DIR/assoc_const_generic_impl.rs:14:18 @@ -27,11 +27,11 @@ warning: any use of this value will cause an error LL | const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::<Self>()]; | ------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 4 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/assoc_const_generic_impl.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-err-early.stderr b/src/test/ui/consts/const-err-early.stderr index 1b94aa080dd..fce8f051061 100644 --- a/src/test/ui/consts/const-err-early.stderr +++ b/src/test/ui/consts/const-err-early.stderr @@ -4,13 +4,13 @@ error: any use of this value will cause an error LL | pub const A: i8 = -i8::MIN; | --------------- ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-early.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: any use of this value will cause an error --> $DIR/const-err-early.rs:5:19 @@ -57,13 +57,13 @@ error: any use of this value will cause an error LL | pub const A: i8 = -i8::MIN; | --------------- ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-early.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -72,13 +72,13 @@ error: any use of this value will cause an error LL | pub const B: u8 = 200u8 + 200u8; | --------------- ^^^^^^^^^^^^^ attempt to compute `200_u8 + 200_u8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-early.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -87,13 +87,13 @@ error: any use of this value will cause an error LL | pub const C: u8 = 200u8 * 4; | --------------- ^^^^^^^^^ attempt to compute `200_u8 * 4_u8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-early.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -102,13 +102,13 @@ error: any use of this value will cause an error LL | pub const D: u8 = 42u8 - (42u8 + 1); | --------------- ^^^^^^^^^^^^^^^^^ attempt to compute `42_u8 - 43_u8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-early.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -117,11 +117,11 @@ error: any use of this value will cause an error LL | pub const E: u8 = [5u8][1]; | --------------- ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-early.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-err-multi.stderr b/src/test/ui/consts/const-err-multi.stderr index f179843654e..16b912695a6 100644 --- a/src/test/ui/consts/const-err-multi.stderr +++ b/src/test/ui/consts/const-err-multi.stderr @@ -4,13 +4,13 @@ error: any use of this value will cause an error LL | pub const A: i8 = -i8::MIN; | --------------- ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-multi.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: any use of this value will cause an error --> $DIR/const-err-multi.rs:6:19 @@ -48,13 +48,13 @@ error: any use of this value will cause an error LL | pub const A: i8 = -i8::MIN; | --------------- ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-multi.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -63,13 +63,13 @@ error: any use of this value will cause an error LL | pub const B: i8 = A; | --------------- ^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-multi.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -78,13 +78,13 @@ error: any use of this value will cause an error LL | pub const C: u8 = A as u8; | --------------- ^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-multi.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -93,11 +93,11 @@ error: any use of this value will cause an error LL | pub const D: i8 = 50 - A; | --------------- ^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err-multi.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-err.stderr b/src/test/ui/consts/const-err.stderr index e3b0d29c853..f83a2cbb190 100644 --- a/src/test/ui/consts/const-err.stderr +++ b/src/test/ui/consts/const-err.stderr @@ -4,13 +4,13 @@ warning: any use of this value will cause an error LL | const FOO: u8 = [5u8][1]; | ------------- ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err.rs:5:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error[E0080]: erroneous constant used --> $DIR/const-err.rs:16:16 @@ -34,11 +34,11 @@ warning: any use of this value will cause an error LL | const FOO: u8 = [5u8][1]; | ------------- ^^^^^^^^ index out of bounds: the length is 1 but the index is 1 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-err.rs:5:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr index 2953406ee40..84061e52d31 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr @@ -4,13 +4,13 @@ warning: any use of this value will cause an error LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; | -------------- ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/conditional_array_execution.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error[E0080]: evaluation of constant value failed --> $DIR/conditional_array_execution.rs:12:20 @@ -38,13 +38,13 @@ warning: any use of this value will cause an error LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; | -------------- ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/conditional_array_execution.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: erroneous constant used @@ -53,12 +53,12 @@ warning: erroneous constant used LL | println!("{}", FOO); | ^^^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/conditional_array_execution.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: this warning originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr index cf50c19caa7..b6d0898bb92 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr @@ -19,11 +19,11 @@ warning: any use of this value will cause an error LL | const NEG_NEG_128: i8 = -NEG_128; | --------------------- ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow-2.rs:4:36 | LL | #![allow(unused_imports, warnings, const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr index dab9a76c7d4..8e3028c50f3 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr @@ -7,13 +7,13 @@ LL | ( LL | i8::MIN - 1, | ^^^^^^^^^^^ attempt to compute `i8::MIN - 1_i8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: any use of this value will cause an error --> $DIR/const-eval-overflow2.rs:21:6 @@ -109,13 +109,13 @@ LL | ( LL | i8::MIN - 1, | ^^^^^^^^^^^ attempt to compute `i8::MIN - 1_i8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -127,13 +127,13 @@ LL | ( LL | i16::MIN - 1, | ^^^^^^^^^^^^ attempt to compute `i16::MIN - 1_i16`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -145,13 +145,13 @@ LL | ( LL | i32::MIN - 1, | ^^^^^^^^^^^^ attempt to compute `i32::MIN - 1_i32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -163,13 +163,13 @@ LL | ( LL | i64::MIN - 1, | ^^^^^^^^^^^^ attempt to compute `i64::MIN - 1_i64`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -181,13 +181,13 @@ LL | ( LL | u8::MIN - 1, | ^^^^^^^^^^^ attempt to compute `0_u8 - 1_u8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -198,13 +198,13 @@ LL | const VALS_U16: (u16,) = ( LL | u16::MIN - 1, | ^^^^^^^^^^^^ attempt to compute `0_u16 - 1_u16`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -215,13 +215,13 @@ LL | const VALS_U32: (u32,) = ( LL | u32::MIN - 1, | ^^^^^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -233,11 +233,11 @@ LL | ( LL | u64::MIN - 1, | ^^^^^^^^^^^^ attempt to compute `0_u64 - 1_u64`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr index 5fe9917437e..b6dc85f416b 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr @@ -7,13 +7,13 @@ LL | ( LL | i8::MAX + 1, | ^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: any use of this value will cause an error --> $DIR/const-eval-overflow2b.rs:21:6 @@ -109,13 +109,13 @@ LL | ( LL | i8::MAX + 1, | ^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -127,13 +127,13 @@ LL | ( LL | i16::MAX + 1, | ^^^^^^^^^^^^ attempt to compute `i16::MAX + 1_i16`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -145,13 +145,13 @@ LL | ( LL | i32::MAX + 1, | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -163,13 +163,13 @@ LL | ( LL | i64::MAX + 1, | ^^^^^^^^^^^^ attempt to compute `i64::MAX + 1_i64`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -181,13 +181,13 @@ LL | ( LL | u8::MAX + 1, | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -198,13 +198,13 @@ LL | const VALS_U16: (u16,) = ( LL | u16::MAX + 1, | ^^^^^^^^^^^^ attempt to compute `u16::MAX + 1_u16`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -215,13 +215,13 @@ LL | const VALS_U32: (u32,) = ( LL | u32::MAX + 1, | ^^^^^^^^^^^^ attempt to compute `u32::MAX + 1_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -233,11 +233,11 @@ LL | ( LL | u64::MAX + 1, | ^^^^^^^^^^^^ attempt to compute `u64::MAX + 1_u64`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2b.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr index d5f3a0fb1c3..df66fe1e5de 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr @@ -7,13 +7,13 @@ LL | ( LL | i8::MIN * 2, | ^^^^^^^^^^^ attempt to compute `i8::MIN * 2_i8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: any use of this value will cause an error --> $DIR/const-eval-overflow2c.rs:21:6 @@ -109,13 +109,13 @@ LL | ( LL | i8::MIN * 2, | ^^^^^^^^^^^ attempt to compute `i8::MIN * 2_i8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -127,13 +127,13 @@ LL | ( LL | i16::MIN * 2, | ^^^^^^^^^^^^ attempt to compute `i16::MIN * 2_i16`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -145,13 +145,13 @@ LL | ( LL | i32::MIN * 2, | ^^^^^^^^^^^^ attempt to compute `i32::MIN * 2_i32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -163,13 +163,13 @@ LL | ( LL | i64::MIN * 2, | ^^^^^^^^^^^^ attempt to compute `i64::MIN * 2_i64`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -181,13 +181,13 @@ LL | ( LL | u8::MAX * 2, | ^^^^^^^^^^^ attempt to compute `u8::MAX * 2_u8`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -198,13 +198,13 @@ LL | const VALS_U16: (u16,) = ( LL | u16::MAX * 2, | ^^^^^^^^^^^^ attempt to compute `u16::MAX * 2_u16`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -215,13 +215,13 @@ LL | const VALS_U32: (u32,) = ( LL | u32::MAX * 2, | ^^^^^^^^^^^^ attempt to compute `u32::MAX * 2_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: any use of this value will cause an error @@ -233,11 +233,11 @@ LL | ( LL | u64::MAX * 2, | ^^^^^^^^^^^^ attempt to compute `u64::MAX * 2_u64`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-overflow2c.rs:8:9 | LL | #![deny(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index 0ae7bfa86bc..67d290bbcaa 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -4,13 +4,13 @@ warning: any use of this value will cause an error LL | const X: i32 = 1 / 0; | ------------ ^^^^^ attempt to divide `1_i32` by zero | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-query-stack.rs:18:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error[E0080]: evaluation of constant value failed --> $DIR/const-eval-query-stack.rs:23:28 @@ -24,9 +24,9 @@ error: erroneous constant used LL | let x: &'static i32 = &X; | ^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default query stack during panic: #0 [mir_drops_elaborated_and_const_checked] elaborating drops for `main` @@ -40,13 +40,13 @@ warning: any use of this value will cause an error LL | const X: i32 = 1 / 0; | ------------ ^^^^^ attempt to divide `1_i32` by zero | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const-eval-query-stack.rs:18:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: error: erroneous constant used @@ -55,7 +55,7 @@ error: erroneous constant used LL | let x: &'static i32 = &X; | ^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr index 12d5b7bd6bb..de717899dd8 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr @@ -4,11 +4,11 @@ error: any use of this value will cause an error LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u }; | -------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/const-pointer-values-in-various-types.rs:30:43 @@ -318,11 +318,11 @@ error: any use of this value will cause an error LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u }; | -------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -331,11 +331,11 @@ error: any use of this value will cause an error LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 }; | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -344,11 +344,11 @@ error: any use of this value will cause an error LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 }; | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -357,11 +357,11 @@ error: any use of this value will cause an error LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 }; | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -370,11 +370,11 @@ error: any use of this value will cause an error LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 }; | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -383,11 +383,11 @@ error: any use of this value will cause an error LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -396,11 +396,11 @@ error: any use of this value will cause an error LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 }; | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -409,11 +409,11 @@ error: any use of this value will cause an error LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 }; | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -422,11 +422,11 @@ error: any use of this value will cause an error LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -435,11 +435,11 @@ error: any use of this value will cause an error LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -448,11 +448,11 @@ error: any use of this value will cause an error LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; | ---------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -461,11 +461,11 @@ error: any use of this value will cause an error LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey }; | ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -474,11 +474,11 @@ error: any use of this value will cause an error LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character }; | ------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -487,11 +487,11 @@ error: any use of this value will cause an error LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; | ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -500,11 +500,11 @@ error: any use of this value will cause an error LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }; | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -513,11 +513,11 @@ error: any use of this value will cause an error LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }; | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -526,11 +526,11 @@ error: any use of this value will cause an error LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -539,11 +539,11 @@ error: any use of this value will cause an error LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 }; | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -552,11 +552,11 @@ error: any use of this value will cause an error LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; | ---------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -565,11 +565,11 @@ error: any use of this value will cause an error LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -578,11 +578,11 @@ error: any use of this value will cause an error LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -591,11 +591,11 @@ error: any use of this value will cause an error LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -604,11 +604,11 @@ error: any use of this value will cause an error LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 }; | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -617,11 +617,11 @@ error: any use of this value will cause an error LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 }; | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -630,11 +630,11 @@ error: any use of this value will cause an error LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; | ------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -643,11 +643,11 @@ error: any use of this value will cause an error LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey }; | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -656,9 +656,9 @@ error: any use of this value will cause an error LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character }; | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index f6ffa1ef296..6aacc6cffc9 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -35,13 +35,13 @@ LL | x(y) LL | const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday | -------------- | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_fn_ptr_fail2.rs:4:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: any use of this value will cause an error @@ -57,13 +57,13 @@ LL | x(y) LL | const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday | -------------- | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_fn_ptr_fail2.rs:4:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: erroneous constant used @@ -72,13 +72,13 @@ warning: erroneous constant used LL | assert_eq!(Y, 4); | ^^^^^^^^^^^^^^^^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_fn_ptr_fail2.rs:4:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -88,12 +88,12 @@ warning: erroneous constant used LL | assert_eq!(Z, 4); | ^^^^^^^^^^^^^^^^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_fn_ptr_fail2.rs:4:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr b/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr index f06dedc2298..3553a18d388 100644 --- a/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr +++ b/src/test/ui/consts/const-eval/const_panic_stability.e2018.stderr @@ -4,9 +4,9 @@ warning: panic message is not a string literal LL | panic!({ "foo" }); | ^^^^^^^^^ | - = note: `#[warn(non_fmt_panics)]` on by default = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021 = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html> + = note: `#[warn(non_fmt_panics)]` on by default help: add a "{}" format string to `Display` the message | LL | panic!("{}", { "foo" }); diff --git a/src/test/ui/consts/const-eval/erroneous-const.stderr b/src/test/ui/consts/const-eval/erroneous-const.stderr index adfb4cc61cc..24428732a42 100644 --- a/src/test/ui/consts/const-eval/erroneous-const.stderr +++ b/src/test/ui/consts/const-eval/erroneous-const.stderr @@ -16,13 +16,13 @@ warning: any use of this value will cause an error LL | const VOID: () = [()][2]; | -------------- ^^^^^^^ index out of bounds: the length is 1 but the index is 2 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/erroneous-const.rs:2:9 | LL | #![warn(const_err, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error[E0080]: could not evaluate static initializer --> $DIR/erroneous-const.rs:15:17 @@ -46,11 +46,11 @@ warning: any use of this value will cause an error LL | const VOID: () = [()][2]; | -------------- ^^^^^^^ index out of bounds: the length is 1 but the index is 2 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/erroneous-const.rs:2:9 | LL | #![warn(const_err, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/erroneous-const2.stderr b/src/test/ui/consts/const-eval/erroneous-const2.stderr index e947d93e405..0eea5648a64 100644 --- a/src/test/ui/consts/const-eval/erroneous-const2.stderr +++ b/src/test/ui/consts/const-eval/erroneous-const2.stderr @@ -16,13 +16,13 @@ warning: any use of this value will cause an error LL | const VOID: () = [()][2]; | -------------- ^^^^^^^ index out of bounds: the length is 1 but the index is 2 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/erroneous-const2.rs:2:9 | LL | #![warn(const_err, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error[E0080]: could not evaluate static initializer --> $DIR/erroneous-const2.rs:15:17 @@ -40,11 +40,11 @@ warning: any use of this value will cause an error LL | const VOID: () = [()][2]; | -------------- ^^^^^^^ index out of bounds: the length is 1 but the index is 2 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/erroneous-const2.rs:2:9 | LL | #![warn(const_err, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/format.stderr b/src/test/ui/consts/const-eval/format.stderr index a476b0f587f..f3f6f2bb028 100644 --- a/src/test/ui/consts/const-eval/format.stderr +++ b/src/test/ui/consts/const-eval/format.stderr @@ -40,9 +40,9 @@ error: erroneous constant used LL | panic!("{:?}", 0); | ^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: erroneous constant used --> $DIR/format.rs:2:20 @@ -83,9 +83,9 @@ error: erroneous constant used LL | panic!("{:?}", 0); | ^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: erroneous constant used @@ -94,9 +94,9 @@ error: erroneous constant used LL | panic!("{:?}", 0); | ^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -106,9 +106,9 @@ error: erroneous constant used LL | println!("{:?}", 0); | ^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: erroneous constant used @@ -117,8 +117,8 @@ error: erroneous constant used LL | println!("{:?}", 0); | ^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr index da4a21e08ab..3f4739c56f0 100644 --- a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr +++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr @@ -4,13 +4,13 @@ warning: any use of this value will cause an error LL | const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] }; | ------------- ^^^^^ index out of bounds: the length is 0 but the index is 0 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/index-out-of-bounds-never-type.rs:4:9 | LL | #![warn(const_err, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: erroneous constant encountered --> $DIR/index-out-of-bounds-never-type.rs:17:13 @@ -27,11 +27,11 @@ warning: any use of this value will cause an error LL | const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] }; | ------------- ^^^^^ index out of bounds: the length is 0 but the index is 0 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/index-out-of-bounds-never-type.rs:4:9 | LL | #![warn(const_err, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr index 3f67c38f82e..ceeaa1baece 100644 --- a/src/test/ui/consts/const-eval/issue-43197.stderr +++ b/src/test/ui/consts/const-eval/issue-43197.stderr @@ -4,13 +4,13 @@ warning: any use of this value will cause an error LL | const X: u32 = 0 - 1; | ------------ ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/issue-43197.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> warning: any use of this value will cause an error --> $DIR/issue-43197.rs:13:24 @@ -63,13 +63,13 @@ warning: any use of this value will cause an error LL | const X: u32 = 0 - 1; | ------------ ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/issue-43197.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: any use of this value will cause an error @@ -78,13 +78,13 @@ warning: any use of this value will cause an error LL | const Y: u32 = foo(0 - 1); | ------------ ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/issue-43197.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: erroneous constant used @@ -93,13 +93,13 @@ warning: erroneous constant used LL | println!("{} {}", X, Y); | ^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/issue-43197.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: this warning originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -109,12 +109,12 @@ warning: erroneous constant used LL | println!("{} {}", X, Y); | ^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/issue-43197.rs:3:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: this warning originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr index 4c27ceea19b..c3a794d2fe3 100644 --- a/src/test/ui/consts/const-eval/issue-44578.stderr +++ b/src/test/ui/consts/const-eval/issue-44578.stderr @@ -14,13 +14,13 @@ warning: any use of this value will cause an error LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize]; | ---------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1 | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/issue-44578.rs:3:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: erroneous constant used @@ -29,12 +29,12 @@ warning: erroneous constant used LL | println!("{}", <Bar<u16, u8> as Foo>::AMT); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/issue-44578.rs:3:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = note: this warning originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr index cc19caca724..bd860197720 100644 --- a/src/test/ui/consts/const-eval/issue-50814-2.stderr +++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const BAR: usize = [5, 6, 7][T::BOO]; | ---------------- ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error[E0080]: evaluation of `foo::<()>` failed --> $DIR/issue-50814-2.rs:19:6 @@ -30,7 +30,7 @@ error: any use of this value will cause an error LL | const BAR: usize = [5, 6, 7][T::BOO]; | ---------------- ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr index 6ceef91a042..c8e5a169ff9 100644 --- a/src/test/ui/consts/const-eval/issue-50814.stderr +++ b/src/test/ui/consts/const-eval/issue-50814.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const MAX: u8 = A::MAX + B::MAX; | ------------- ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error[E0080]: evaluation of `foo::<i32>` failed --> $DIR/issue-50814.rs:21:6 @@ -30,7 +30,7 @@ error: any use of this value will cause an error LL | const MAX: u8 = A::MAX + B::MAX; | ------------- ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr b/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr index 75e50a27b3a..f41fa1c1ee0 100644 --- a/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr +++ b/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr @@ -7,11 +7,11 @@ LL | const PARTIAL_OVERWRITE: () = { LL | *(ptr as *mut u8) = 123; | ^^^^^^^^^^^^^^^^^^^^^^^ unable to overwrite parts of a pointer in memory at alloc4 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: aborting due to previous error @@ -25,9 +25,9 @@ LL | const PARTIAL_OVERWRITE: () = { LL | *(ptr as *mut u8) = 123; | ^^^^^^^^^^^^^^^^^^^^^^^ unable to overwrite parts of a pointer in memory at alloc4 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr index cfca8ef0746..d5f73dcd11f 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr @@ -53,13 +53,13 @@ LL | 0 - 1 LL | const X: () = { | ----------- | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/promoted_errors.rs:11:9 | LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> warning: any use of this value will cause an error --> $DIR/promoted_errors.rs:43:28 @@ -88,13 +88,13 @@ LL | 0 - 1 LL | const X: () = { | ----------- | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/promoted_errors.rs:11:9 | LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: any use of this value will cause an error @@ -105,11 +105,11 @@ LL | const X: () = { LL | let _x: &'static u32 = &overflow(); | ^^^^^^^^^^^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/promoted_errors.rs:11:9 | LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr index 984484a850f..42310327692 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.opt.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr @@ -53,13 +53,13 @@ LL | 1 / 0 LL | const X: () = { | ----------- | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/promoted_errors.rs:11:9 | LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> warning: any use of this value will cause an error --> $DIR/promoted_errors.rs:46:28 @@ -89,13 +89,13 @@ LL | 1 / 0 LL | const X: () = { | ----------- | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/promoted_errors.rs:11:9 | LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: any use of this value will cause an error @@ -107,11 +107,11 @@ LL | const X: () = { LL | let _x: &'static i32 = &div_by_zero1(); | ^^^^^^^^^^^^^^^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/promoted_errors.rs:11:9 | LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr index cfca8ef0746..d5f73dcd11f 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr @@ -53,13 +53,13 @@ LL | 0 - 1 LL | const X: () = { | ----------- | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/promoted_errors.rs:11:9 | LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> warning: any use of this value will cause an error --> $DIR/promoted_errors.rs:43:28 @@ -88,13 +88,13 @@ LL | 0 - 1 LL | const X: () = { | ----------- | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/promoted_errors.rs:11:9 | LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: any use of this value will cause an error @@ -105,11 +105,11 @@ LL | const X: () = { LL | let _x: &'static u32 = &overflow(); | ^^^^^^^^^^^ referenced constant has errors | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/promoted_errors.rs:11:9 | LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/pub_const_err.stderr b/src/test/ui/consts/const-eval/pub_const_err.stderr index 36197a7ab59..d1081f9c2ca 100644 --- a/src/test/ui/consts/const-eval/pub_const_err.stderr +++ b/src/test/ui/consts/const-eval/pub_const_err.stderr @@ -4,13 +4,13 @@ warning: any use of this value will cause an error LL | pub const Z: u32 = 0 - 1; | ---------------- ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/pub_const_err.rs:2:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> warning: 1 warning emitted @@ -21,11 +21,11 @@ warning: any use of this value will cause an error LL | pub const Z: u32 = 0 - 1; | ---------------- ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/pub_const_err.rs:2:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr index 2eef3b8f5c4..93362a9375c 100644 --- a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr +++ b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr @@ -4,13 +4,13 @@ warning: any use of this value will cause an error LL | pub const Z: u32 = 0 - 1; | ---------------- ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/pub_const_err_bin.rs:2:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> warning: 1 warning emitted @@ -21,11 +21,11 @@ warning: any use of this value will cause an error LL | pub const Z: u32 = 0 - 1; | ---------------- ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/pub_const_err_bin.rs:2:9 | LL | #![warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr index 30935e41549..02feb6a7832 100644 --- a/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr +++ b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr @@ -4,11 +4,11 @@ error: any use of this value will cause an error LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; | -------------- ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: could not evaluate constant pattern --> $DIR/ref_to_int_match.rs:7:14 @@ -31,9 +31,9 @@ error: any use of this value will cause an error LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; | -------------- ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr index 30935e41549..02feb6a7832 100644 --- a/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr +++ b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr @@ -4,11 +4,11 @@ error: any use of this value will cause an error LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; | -------------- ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: could not evaluate constant pattern --> $DIR/ref_to_int_match.rs:7:14 @@ -31,9 +31,9 @@ error: any use of this value will cause an error LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; | -------------- ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr index 80395e32db0..ddfe1d5909f 100644 --- a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr @@ -15,11 +15,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/ub-enum.rs:31:1 @@ -137,11 +137,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -150,11 +150,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -163,11 +163,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -176,11 +176,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -189,9 +189,9 @@ error: any use of this value will cause an error LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr index d20f63a7289..930f8130bc3 100644 --- a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr @@ -15,11 +15,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/ub-enum.rs:31:1 @@ -137,11 +137,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -150,11 +150,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -163,11 +163,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -176,11 +176,11 @@ error: any use of this value will cause an error LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -189,9 +189,9 @@ error: any use of this value will cause an error LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr index 3e93219c86d..66b993764e9 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr @@ -48,11 +48,11 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/ub-ref-ptr.rs:35:39 @@ -171,11 +171,11 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -184,11 +184,11 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ---------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -197,9 +197,9 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ---------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -208,11 +208,11 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ------------------------------------------ ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -221,7 +221,7 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ------------------------------------------ ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr index bc2aa12a2f3..cbf120a397e 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr @@ -48,11 +48,11 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/ub-ref-ptr.rs:35:39 @@ -171,11 +171,11 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -184,11 +184,11 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ---------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -197,9 +197,9 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; | ---------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -208,11 +208,11 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ------------------------------------------ ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -221,7 +221,7 @@ error: any use of this value will cause an error LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; | ------------------------------------------ ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr index 4cd974e7bf9..2d4218a94f5 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr @@ -26,11 +26,11 @@ error: any use of this value will cause an error LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/ub-wide-ptr.rs:46:1 @@ -320,11 +320,11 @@ error: any use of this value will cause an error LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -333,11 +333,11 @@ error: any use of this value will cause an error LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -346,11 +346,11 @@ error: any use of this value will cause an error LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -359,11 +359,11 @@ error: any use of this value will cause an error LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -372,9 +372,9 @@ error: any use of this value will cause an error LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -383,9 +383,9 @@ error: any use of this value will cause an error LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -394,7 +394,7 @@ error: any use of this value will cause an error LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr index 1d84b7bce14..9997b8fe5f2 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr @@ -26,11 +26,11 @@ error: any use of this value will cause an error LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/ub-wide-ptr.rs:46:1 @@ -320,11 +320,11 @@ error: any use of this value will cause an error LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -333,11 +333,11 @@ error: any use of this value will cause an error LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -346,11 +346,11 @@ error: any use of this value will cause an error LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -359,11 +359,11 @@ error: any use of this value will cause an error LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -372,9 +372,9 @@ error: any use of this value will cause an error LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; | ------------------------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -383,9 +383,9 @@ error: any use of this value will cause an error LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -394,7 +394,7 @@ error: any use of this value will cause an error LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); | -------------------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/unused-broken-const.stderr b/src/test/ui/consts/const-eval/unused-broken-const.stderr index df5bd524f27..cdc1e9d97f4 100644 --- a/src/test/ui/consts/const-eval/unused-broken-const.stderr +++ b/src/test/ui/consts/const-eval/unused-broken-const.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const FOO: i32 = [][0]; | -------------- ^^^^^ index out of bounds: the length is 0 but the index is 0 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to previous error @@ -17,7 +17,7 @@ error: any use of this value will cause an error LL | const FOO: i32 = [][0]; | -------------- ^^^^^ index out of bounds: the length is 0 but the index is 0 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr index b568518b449..dd948f9adb3 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr @@ -7,8 +7,8 @@ LL | unsafe { std::mem::transmute(()) } | this code causes undefined behavior when executed | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | - = note: `#[warn(invalid_value)]` on by default = note: the `!` type has no valid value + = note: `#[warn(invalid_value)]` on by default error[E0080]: evaluation of constant value failed --> $DIR/validate_uninhabited_zsts.rs:4:14 diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr index b568518b449..dd948f9adb3 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr @@ -7,8 +7,8 @@ LL | unsafe { std::mem::transmute(()) } | this code causes undefined behavior when executed | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | - = note: `#[warn(invalid_value)]` on by default = note: the `!` type has no valid value + = note: `#[warn(invalid_value)]` on by default error[E0080]: evaluation of constant value failed --> $DIR/validate_uninhabited_zsts.rs:4:14 diff --git a/src/test/ui/consts/const-external-macro-const-err.stderr b/src/test/ui/consts/const-external-macro-const-err.stderr index 205ee92dfd7..b57615e9a7c 100644 --- a/src/test/ui/consts/const-external-macro-const-err.stderr +++ b/src/test/ui/consts/const-external-macro-const-err.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | static_assert!(2 + 2 == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default = note: this error originates in the macro `static_assert` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error @@ -18,8 +18,8 @@ error: any use of this value will cause an error LL | static_assert!(2 + 2 == 5); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default = note: this error originates in the macro `static_assert` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr index 01f2f489564..908fef7265d 100644 --- a/src/test/ui/consts/const-float-bits-reject-conv.stderr +++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr @@ -45,9 +45,9 @@ LL | const _: () = assert!($a); LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); | ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/const-float-bits-reject-conv.rs:33:34 @@ -184,9 +184,9 @@ LL | const _: () = assert!($a); LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); | ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -198,9 +198,9 @@ LL | const _: () = assert!($a); LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); | ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -212,9 +212,9 @@ LL | const _: () = assert!($a == $b); LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); | ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -226,9 +226,9 @@ LL | const _: () = assert!($a == $b); LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); | ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -240,9 +240,9 @@ LL | const _: () = assert!($a); LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); | ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -254,9 +254,9 @@ LL | const _: () = assert!($a); LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); | ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -268,9 +268,9 @@ LL | const _: () = assert!($a == $b); LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); | ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -282,7 +282,7 @@ LL | const _: () = assert!($a == $b); LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); | ^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-fn-error.stderr b/src/test/ui/consts/const-fn-error.stderr index e36324f0b3e..02960b363e7 100644 --- a/src/test/ui/consts/const-fn-error.stderr +++ b/src/test/ui/consts/const-fn-error.stderr @@ -22,8 +22,8 @@ LL | for i in 0..x { note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | -LL | impl<I: ~const Iterator> const IntoIterator for I { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<I: Iterator> const IntoIterator for I { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0658]: mutable references are not allowed in constant functions diff --git a/src/test/ui/consts/const-for.stderr b/src/test/ui/consts/const-for.stderr index f2e1c8a4991..11e4ae309c0 100644 --- a/src/test/ui/consts/const-for.stderr +++ b/src/test/ui/consts/const-for.stderr @@ -7,8 +7,8 @@ LL | for _ in 0..5 {} note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | -LL | impl<I: ~const Iterator> const IntoIterator for I { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<I: Iterator> const IntoIterator for I { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants diff --git a/src/test/ui/consts/const-len-underflow-separate-spans.stderr b/src/test/ui/consts/const-len-underflow-separate-spans.stderr index d1bf4b92e6a..56645980b05 100644 --- a/src/test/ui/consts/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/consts/const-len-underflow-separate-spans.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const LEN: usize = ONE - TWO; | ---------------- ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error[E0080]: evaluation of constant value failed --> $DIR/const-len-underflow-separate-spans.rs:12:17 @@ -24,7 +24,7 @@ error: any use of this value will cause an error LL | const LEN: usize = ONE - TWO; | ---------------- ^^^^^^^^^ attempt to compute `1_usize - 2_usize`, which would overflow | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-prop-read-static-in-const.stderr b/src/test/ui/consts/const-prop-read-static-in-const.stderr index ea5ad24b0b1..38941331003 100644 --- a/src/test/ui/consts/const-prop-read-static-in-const.stderr +++ b/src/test/ui/consts/const-prop-read-static-in-const.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const TEST: u8 = MY_STATIC; | -------------- ^^^^^^^^^ constant accesses static | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default warning: skipping const checks | @@ -25,7 +25,7 @@ error: any use of this value will cause an error LL | const TEST: u8 = MY_STATIC; | -------------- ^^^^^^^^^ constant accesses static | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr index d19a89378ec..0ed09ff8341 100644 --- a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr +++ b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; | ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/const-size_of_val-align_of_val-extern-type.rs:13:32 @@ -26,9 +26,9 @@ error: any use of this value will cause an error LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; | ------------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -37,7 +37,7 @@ error: any use of this value will cause an error LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; | ------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `extern type` does not have known layout | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const-slice-oob.stderr b/src/test/ui/consts/const-slice-oob.stderr index 27c21e7af14..16756454974 100644 --- a/src/test/ui/consts/const-slice-oob.stderr +++ b/src/test/ui/consts/const-slice-oob.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const BAR: u32 = FOO[5]; | -------------- ^^^^^^ index out of bounds: the length is 3 but the index is 5 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to previous error @@ -17,7 +17,7 @@ error: any use of this value will cause an error LL | const BAR: u32 = FOO[5]; | -------------- ^^^^^^ index out of bounds: the length is 3 but the index is 5 | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr b/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr index e51d6f91649..22348272275 100644 --- a/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr +++ b/src/test/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr @@ -4,9 +4,9 @@ warning: to use a constant of type `CustomEq` in a pattern, the constant's initi LL | BAR_BAZ => panic!(), | ^^^^^^^ | - = note: `#[warn(nontrivial_structural_match)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448> + = note: `#[warn(nontrivial_structural_match)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr b/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr index 0ff70837138..ddc576ced8f 100644 --- a/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr +++ b/src/test/ui/consts/const_in_pattern/incomplete-slice.stderr @@ -4,9 +4,9 @@ warning: to use a constant of type `E` in a pattern, `E` must be annotated with LL | E_SL => {} | ^^^^ | - = note: `#[warn(indirect_structural_match)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> + = note: `#[warn(indirect_structural_match)]` on by default error[E0004]: non-exhaustive patterns: `&_` not covered --> $DIR/incomplete-slice.rs:9:11 diff --git a/src/test/ui/consts/const_in_pattern/issue-44333.stderr b/src/test/ui/consts/const_in_pattern/issue-44333.stderr index 8302b09e533..731ef509cca 100644 --- a/src/test/ui/consts/const_in_pattern/issue-44333.stderr +++ b/src/test/ui/consts/const_in_pattern/issue-44333.stderr @@ -4,13 +4,13 @@ warning: function pointers and unsized pointers in patterns behave unpredictably LL | FOO => println!("foo"), | ^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861> note: the lint level is defined here --> $DIR/issue-44333.rs:3:9 | LL | #![warn(pointer_structural_match)] | ^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861> warning: function pointers and unsized pointers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details. --> $DIR/issue-44333.rs:21:9 diff --git a/src/test/ui/consts/const_in_pattern/reject_non_structural.stderr b/src/test/ui/consts/const_in_pattern/reject_non_structural.stderr index 56405a55d69..66019834997 100644 --- a/src/test/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/src/test/ui/consts/const_in_pattern/reject_non_structural.stderr @@ -64,13 +64,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; | ^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> note: the lint level is defined here --> $DIR/reject_non_structural.rs:12:9 | LL | #![warn(indirect_structural_match)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> error: aborting due to 10 previous errors; 1 warning emitted diff --git a/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr b/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr index a24c8d18184..e957a43a13d 100644 --- a/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr +++ b/src/test/ui/consts/const_in_pattern/warn_corner_cases.stderr @@ -4,9 +4,9 @@ warning: to use a constant of type `NoDerive` in a pattern, the constant's initi LL | match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), }; | ^^^^^ | - = note: `#[warn(nontrivial_structural_match)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448> + = note: `#[warn(nontrivial_structural_match)]` on by default warning: to use a constant of type `NoDerive` in a pattern, the constant's initializer must be trivial or `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/warn_corner_cases.rs:32:47 diff --git a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr index e450f4aa3bd..0f7d93a3be3 100644 --- a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr +++ b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr @@ -7,9 +7,9 @@ LL | let mut x = 0; LL | while x != 1000 { | ^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to previous error @@ -23,7 +23,7 @@ LL | let mut x = 0; LL | while x != 1000 { | ^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/constifconst-call-in-const-position.rs b/src/test/ui/consts/constifconst-call-in-const-position.rs new file mode 100644 index 00000000000..fcf01d5bc71 --- /dev/null +++ b/src/test/ui/consts/constifconst-call-in-const-position.rs @@ -0,0 +1,22 @@ +// known-bug: #102498 + +#![feature(const_trait_impl, generic_const_exprs)] + +#[const_trait] +pub trait Tr { + fn a() -> usize; +} + +impl Tr for () { + fn a() -> usize { + 1 + } +} + +const fn foo<T: ~const Tr>() -> [u8; T::a()] { + [0; T::a()] +} + +fn main() { + foo::<()>(); +} diff --git a/src/test/ui/consts/constifconst-call-in-const-position.stderr b/src/test/ui/consts/constifconst-call-in-const-position.stderr new file mode 100644 index 00000000000..d4a445120a2 --- /dev/null +++ b/src/test/ui/consts/constifconst-call-in-const-position.stderr @@ -0,0 +1,18 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/constifconst-call-in-const-position.rs:3:30 + | +LL | #![feature(const_trait_impl, generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0080]: evaluation of `foo::<()>::{constant#0}` failed + --> $DIR/constifconst-call-in-const-position.rs:16:38 + | +LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] { + | ^^^^^^ calling non-const function `<() as Tr>::a` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr index 793725d3b80..a2d881f396e 100644 --- a/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr +++ b/src/test/ui/consts/extra-const-ub/detect-extra-ub.with_flag.stderr @@ -12,11 +12,11 @@ LL | const INVALID_PTR_IN_INT: () = unsafe { LL | let _x: usize = transmute(&3u8); | ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/detect-extra-ub.rs:22:30 @@ -80,11 +80,11 @@ LL | const INVALID_PTR_IN_INT: () = unsafe { LL | let _x: usize = transmute(&3u8); | ^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -96,11 +96,11 @@ LL | let x: &[u8] = &[0; 32]; LL | let _x: (usize, usize) = transmute(x); | ^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -111,7 +111,7 @@ LL | const UNALIGNED_READ: () = { LL | INNER; | ^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/invalid-union.32bit.stderr b/src/test/ui/consts/invalid-union.32bit.stderr index ae5f6b2baee..f4d69c801ab 100644 --- a/src/test/ui/consts/invalid-union.32bit.stderr +++ b/src/test/ui/consts/invalid-union.32bit.stderr @@ -15,9 +15,9 @@ error: erroneous constant used LL | let _: &'static _ = &C; | ^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to 2 previous errors @@ -29,7 +29,7 @@ error: erroneous constant used LL | let _: &'static _ = &C; | ^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr index d50e74a16ec..69b63d3ff92 100644 --- a/src/test/ui/consts/invalid-union.64bit.stderr +++ b/src/test/ui/consts/invalid-union.64bit.stderr @@ -15,9 +15,9 @@ error: erroneous constant used LL | let _: &'static _ = &C; | ^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to 2 previous errors @@ -29,7 +29,7 @@ error: erroneous constant used LL | let _: &'static _ = &C; | ^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/issue-56164.stderr b/src/test/ui/consts/issue-56164.stderr index 73a0f8ec0d0..b672f5690da 100644 --- a/src/test/ui/consts/issue-56164.stderr +++ b/src/test/ui/consts/issue-56164.stderr @@ -19,9 +19,9 @@ error: erroneous constant used LL | const fn foo() { (||{})() } | ^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to 3 previous errors @@ -33,7 +33,7 @@ error: erroneous constant used LL | const fn foo() { (||{})() } | ^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/issue-66693.stderr b/src/test/ui/consts/issue-66693.stderr index 5460cc1ee82..5320da00562 100644 --- a/src/test/ui/consts/issue-66693.stderr +++ b/src/test/ui/consts/issue-66693.stderr @@ -28,9 +28,9 @@ error: erroneous constant used LL | panic!(&1); | ^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to 4 previous errors @@ -41,7 +41,7 @@ error: erroneous constant used LL | panic!(&1); | ^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/issue-miri-1910.stderr b/src/test/ui/consts/issue-miri-1910.stderr index 0f0539e0979..bfd5421a93c 100644 --- a/src/test/ui/consts/issue-miri-1910.stderr +++ b/src/test/ui/consts/issue-miri-1910.stderr @@ -14,11 +14,11 @@ LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); LL | const C: () = unsafe { | ----------- | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: aborting due to previous error @@ -39,9 +39,9 @@ LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); LL | const C: () = unsafe { | ----------- | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.stderr b/src/test/ui/consts/miri_unleashed/assoc_const.stderr index 1f82ac827ad..c64107ee26e 100644 --- a/src/test/ui/consts/miri_unleashed/assoc_const.stderr +++ b/src/test/ui/consts/miri_unleashed/assoc_const.stderr @@ -32,11 +32,11 @@ LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { LL | const F: u32 = (U::X, 42).1; | ------------ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/assoc_const.rs:4:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr index cbf02199f5b..950c3db1b7e 100644 --- a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr +++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr @@ -14,11 +14,11 @@ warning: any use of this value will cause an error LL | const F: u32 = 100 / U::X; | ------------ ^^^^^^^^^^ attempt to divide `100_u32` by zero | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/assoc_const_2.rs:3:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr index fa2088124b0..03359e62264 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -57,13 +57,13 @@ LL | static FOO: AtomicUsize = AtomicUsize::new(0); LL | FOO.fetch_add(1, Ordering::Relaxed) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `AtomicUsize::fetch_add` | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static.rs:3:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: any use of this value will cause an error @@ -75,13 +75,13 @@ LL | static FOO: AtomicUsize = AtomicUsize::new(0); LL | unsafe { *(&FOO as *const _ as *const usize) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static.rs:3:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: any use of this value will cause an error @@ -90,11 +90,11 @@ warning: any use of this value will cause an error LL | const READ_MUT: u32 = unsafe { MUTABLE }; | ------------------- ^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static.rs:3:10 | LL | #![allow(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr index 3a22b068916..f66a96ae3f1 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr @@ -40,13 +40,13 @@ LL | const U8_MUT2: &u8 = { LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static_cross_crate.rs:23:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: could not evaluate constant pattern --> $DIR/const_refers_to_static_cross_crate.rs:60:9 @@ -62,13 +62,13 @@ LL | const U8_MUT3: &u8 = { LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static_cross_crate.rs:30:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: could not evaluate constant pattern --> $DIR/const_refers_to_static_cross_crate.rs:68:9 @@ -165,13 +165,13 @@ LL | const U8_MUT2: &u8 = { LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static_cross_crate.rs:23:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: any use of this value will cause an error @@ -182,11 +182,11 @@ LL | const U8_MUT3: &u8 = { LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static_cross_crate.rs:30:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr index 39c874d6498..f919c364310 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr @@ -40,13 +40,13 @@ LL | const U8_MUT2: &u8 = { LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static_cross_crate.rs:23:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: could not evaluate constant pattern --> $DIR/const_refers_to_static_cross_crate.rs:60:9 @@ -62,13 +62,13 @@ LL | const U8_MUT3: &u8 = { LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static_cross_crate.rs:30:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> error: could not evaluate constant pattern --> $DIR/const_refers_to_static_cross_crate.rs:68:9 @@ -165,13 +165,13 @@ LL | const U8_MUT2: &u8 = { LL | unsafe { &(*static_cross_crate::ZERO_REF)[0] } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static_cross_crate.rs:23:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> Future breakage diagnostic: warning: any use of this value will cause an error @@ -182,11 +182,11 @@ LL | const U8_MUT3: &u8 = { LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> note: the lint level is defined here --> $DIR/const_refers_to_static_cross_crate.rs:30:8 | LL | #[warn(const_err)] | ^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr index 3de2aba5b05..df9a8bf51b0 100644 --- a/src/test/ui/consts/ptr_comparisons.stderr +++ b/src/test/ui/consts/ptr_comparisons.stderr @@ -24,11 +24,11 @@ error: any use of this value will cause an error LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 }; | -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default error: any use of this value will cause an error --> $DIR/ptr_comparisons.rs:62:27 @@ -51,11 +51,11 @@ error: any use of this value will cause an error LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 }; | -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default Future breakage diagnostic: error: any use of this value will cause an error @@ -64,9 +64,9 @@ error: any use of this value will cause an error LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 }; | -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> = help: this code performed an operation that depends on the underlying bytes representing a pointer = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/recursive.stderr b/src/test/ui/consts/recursive.stderr index 647ed1db20b..65fb2a69d8f 100644 --- a/src/test/ui/consts/recursive.stderr +++ b/src/test/ui/consts/recursive.stderr @@ -6,8 +6,8 @@ LL | const fn f<T>(x: T) { LL | f(x); | ---- recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default error: any use of this value will cause an error --> $DIR/recursive.rs:4:5 @@ -23,9 +23,9 @@ LL | f(x); LL | const X: () = f(1); | ----------- | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error: aborting due to previous error; 1 warning emitted @@ -44,7 +44,7 @@ LL | f(x); LL | const X: () = f(1); | ----------- | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr b/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr index 4f2f5e244b6..3855b5f2a68 100644 --- a/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr +++ b/src/test/ui/consts/refs_check_const_eq-issue-88384.stderr @@ -4,8 +4,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use LL | #![feature(adt_const_params)] | ^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information + = note: `#[warn(incomplete_features)]` on by default error[E0741]: using function pointers as const generic parameters is forbidden --> $DIR/refs_check_const_eq-issue-88384.rs:10:21 diff --git a/src/test/ui/consts/trait_specialization.stderr b/src/test/ui/consts/trait_specialization.stderr index e80821cf46a..10bebe8ebc5 100644 --- a/src/test/ui/consts/trait_specialization.stderr +++ b/src/test/ui/consts/trait_specialization.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr index d3177784789..0848fbf1968 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr +++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr @@ -137,9 +137,9 @@ LL | hint_unreachable() LL | const CONSTANT: i32 = unsafe { fake_type() }; | ------------------- | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error[E0080]: erroneous constant used --> $DIR/uninhabited-const-issue-61744.rs:19:10 @@ -290,7 +290,7 @@ LL | hint_unreachable() LL | const CONSTANT: i32 = unsafe { fake_type() }; | ------------------- | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default diff --git a/src/test/ui/derive-uninhabited-enum-38885.stderr b/src/test/ui/derive-uninhabited-enum-38885.stderr index bd36a25686a..dcdf8f8430f 100644 --- a/src/test/ui/derive-uninhabited-enum-38885.stderr +++ b/src/test/ui/derive-uninhabited-enum-38885.stderr @@ -7,8 +7,8 @@ LL | Bar(u8), LL | Void(Void), | ^^^^ | - = note: `-W dead-code` implied by `-W unused` = note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis + = note: `-W dead-code` implied by `-W unused` warning: 1 warning emitted diff --git a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr index baf34b46d8b..512b870fa4b 100644 --- a/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr +++ b/src/test/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr @@ -13,12 +13,12 @@ LL | field3: (), LL | field4: (), | ^^^^^^ | + = note: `Whatever` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis note: the lint level is defined here --> $DIR/clone-debug-dead-code-in-the-same-struct.rs:1:11 | LL | #![forbid(dead_code)] | ^^^^^^^^^ - = note: `Whatever` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis error: aborting due to previous error diff --git a/src/test/ui/derives/deriving-with-repr-packed.stderr b/src/test/ui/derives/deriving-with-repr-packed.stderr index d3fe550c3e4..0ad800c3981 100644 --- a/src/test/ui/derives/deriving-with-repr-packed.stderr +++ b/src/test/ui/derives/deriving-with-repr-packed.stderr @@ -4,13 +4,13 @@ error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or co LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] | ^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type or const parameters @@ -52,13 +52,13 @@ error: `Clone` can't be derived on this `#[repr(packed)]` struct with type or co LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] | ^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -68,13 +68,13 @@ error: `PartialEq` can't be derived on this `#[repr(packed)]` struct with type o LL | #[derive(Copy, Clone, Default, PartialEq, Eq)] | ^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -84,13 +84,13 @@ error: `Hash` can't be derived on this `#[repr(packed)]` struct that does not de LL | #[derive(Default, Hash)] | ^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -100,12 +100,12 @@ error: `Debug` can't be derived on this `#[repr(packed)]` struct that does not d LL | #[derive(Debug, Default)] | ^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> note: the lint level is defined here --> $DIR/deriving-with-repr-packed.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/deriving/deriving-default-enum.rs b/src/test/ui/deriving/deriving-default-enum.rs index d1a81c72c2f..1c7a501edc7 100644 --- a/src/test/ui/deriving/deriving-default-enum.rs +++ b/src/test/ui/deriving/deriving-default-enum.rs @@ -12,6 +12,16 @@ enum Foo { Beta(NotDefault), } +// #[default] on a generic enum does not add `Default` bounds to the type params. +#[derive(Default)] +enum MyOption<T> { + #[default] + None, + #[allow(dead_code)] + Some(T), +} + fn main() { assert_eq!(Foo::default(), Foo::Alpha); + assert!(matches!(MyOption::<NotDefault>::default(), MyOption::None)); } diff --git a/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr b/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr index 1df7a5f224f..e16625136ac 100644 --- a/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr +++ b/src/test/ui/destructuring-assignment/warn-unused-duplication.stderr @@ -4,12 +4,12 @@ warning: value assigned to `a` is never read LL | (a, a) = (0, 1); | ^ | + = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/warn-unused-duplication.rs:3:9 | LL | #![warn(unused_assignments)] | ^^^^^^^^^^^^^^^^^^ - = help: maybe it is overwritten before being read? warning: 1 warning emitted diff --git a/src/test/ui/did_you_mean/bad-assoc-ty.stderr b/src/test/ui/did_you_mean/bad-assoc-ty.stderr index 2326af934d0..21f957ab549 100644 --- a/src/test/ui/did_you_mean/bad-assoc-ty.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-ty.stderr @@ -105,9 +105,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | type H = Fn(u8) -> (u8)::Output; | ^^^^^^^^^^^^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | type H = <dyn Fn(u8) -> (u8)>::Output; diff --git a/src/test/ui/did_you_mean/issue-31424.stderr b/src/test/ui/did_you_mean/issue-31424.stderr index 88617381236..8fe38bf6972 100644 --- a/src/test/ui/did_you_mean/issue-31424.stderr +++ b/src/test/ui/did_you_mean/issue-31424.stderr @@ -24,8 +24,8 @@ LL | fn bar(self: &mut Self) { LL | (&mut self).bar(); | ----------------- recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable --> $DIR/issue-31424.rs:16:9 diff --git a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr index 3eb5bb7b26d..89aded9134f 100644 --- a/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr +++ b/src/test/ui/dyn-keyword/dyn-2015-edition-keyword-ident-lint.stderr @@ -4,13 +4,13 @@ error: `dyn` is a keyword in the 2018 edition LL | pub mod dyn { | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> note: the lint level is defined here --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:11:9 | LL | #![deny(keyword_idents)] | ^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `dyn` is a keyword in the 2018 edition --> $DIR/dyn-2015-edition-keyword-ident-lint.rs:17:20 diff --git a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr index e7db68693c0..6bafff9192a 100644 --- a/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr +++ b/src/test/ui/dyn-keyword/dyn-2018-edition-lint.stderr @@ -4,13 +4,13 @@ error: trait objects without an explicit `dyn` are deprecated LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) { | ^^^^^^^^^ | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> note: the lint level is defined here --> $DIR/dyn-2018-edition-lint.rs:2:8 | LL | #[deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> help: use `dyn` | LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) { diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr index 261c2d5742f..0bb764d712e 100644 --- a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr @@ -4,13 +4,13 @@ error: trait objects without an explicit `dyn` are deprecated LL | <fmt::Debug>::fmt(self, f) | ^^^^^^^^^^ | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> note: the lint level is defined here --> $DIR/dyn-angle-brackets.rs:4:9 | LL | #![deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> help: use `dyn` | LL | <dyn fmt::Debug>::fmt(self, f) diff --git a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr index 417daf36fca..612dd17e71e 100644 --- a/src/test/ui/editions/edition-raw-pointer-method-2015.stderr +++ b/src/test/ui/editions/edition-raw-pointer-method-2015.stderr @@ -4,14 +4,14 @@ error: type annotations needed LL | let _ = y.is_null(); | ^^^^^^^ | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906> note: the lint level is defined here --> $DIR/edition-raw-pointer-method-2015.rs:5:8 | LL | #[deny(warnings)] | ^^^^^^^^ = note: `#[deny(tyvar_behind_raw_pointer)]` implied by `#[deny(warnings)]` - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906> error: aborting due to previous error diff --git a/src/test/ui/empty/empty-attributes.stderr b/src/test/ui/empty/empty-attributes.stderr index 8653eaf5ccd..01d0d5a6b48 100644 --- a/src/test/ui/empty/empty-attributes.stderr +++ b/src/test/ui/empty/empty-attributes.stderr @@ -4,12 +4,12 @@ error: unused attribute LL | #[repr()] | ^^^^^^^^^ help: remove this attribute | + = note: attribute `repr` with an empty list has no effect note: the lint level is defined here --> $DIR/empty-attributes.rs:3:9 | LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ - = note: attribute `repr` with an empty list has no effect error: unused attribute --> $DIR/empty-attributes.rs:14:1 diff --git a/src/test/ui/enum-discriminant/discriminant_size.stderr b/src/test/ui/enum-discriminant/discriminant_size.stderr index efc7d998466..9b1505b5c46 100644 --- a/src/test/ui/enum-discriminant/discriminant_size.stderr +++ b/src/test/ui/enum-discriminant/discriminant_size.stderr @@ -4,8 +4,8 @@ warning: the feature `repr128` is incomplete and may not be safe to use and/or c LL | #![feature(core_intrinsics, repr128)] | ^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/enum-discriminant/issue-43398.stderr b/src/test/ui/enum-discriminant/issue-43398.stderr index 9a394153bf6..fc7bbd06284 100644 --- a/src/test/ui/enum-discriminant/issue-43398.stderr +++ b/src/test/ui/enum-discriminant/issue-43398.stderr @@ -4,8 +4,8 @@ warning: the feature `repr128` is incomplete and may not be safe to use and/or c LL | #![feature(repr128)] | ^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr b/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr index 5bf6ea56ebc..ac93badf215 100644 --- a/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr +++ b/src/test/ui/enum-discriminant/issue-70509-partial_eq.stderr @@ -4,8 +4,8 @@ warning: the feature `repr128` is incomplete and may not be safe to use and/or c LL | #![feature(repr128, arbitrary_enum_discriminant)] | ^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/enum-discriminant/repr128.stderr b/src/test/ui/enum-discriminant/repr128.stderr index 88adfb1742d..da8d75c11af 100644 --- a/src/test/ui/enum-discriminant/repr128.stderr +++ b/src/test/ui/enum-discriminant/repr128.stderr @@ -4,8 +4,8 @@ warning: the feature `repr128` is incomplete and may not be safe to use and/or c LL | #![feature(repr128, core_intrinsics, discriminant_kind)] | ^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #56071 <https://github.com/rust-lang/rust/issues/56071> for more information + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/enum/enum-discrim-too-small2.stderr b/src/test/ui/enum/enum-discrim-too-small2.stderr index 43830679535..f79f7a043d6 100644 --- a/src/test/ui/enum/enum-discrim-too-small2.stderr +++ b/src/test/ui/enum/enum-discrim-too-small2.stderr @@ -4,13 +4,13 @@ error: literal out of range for `i8` LL | Ci8 = 223, | ^^^ | + = note: the literal `223` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using the type `u8` instead note: the lint level is defined here --> $DIR/enum-discrim-too-small2.rs:1:9 | LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ - = note: the literal `223` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using the type `u8` instead error: literal out of range for `i16` --> $DIR/enum-discrim-too-small2.rs:15:12 diff --git a/src/test/ui/error-codes/E0017.stderr b/src/test/ui/error-codes/E0017.stderr index 830e4db345a..6e48f9582f1 100644 --- a/src/test/ui/error-codes/E0017.stderr +++ b/src/test/ui/error-codes/E0017.stderr @@ -4,7 +4,6 @@ warning: taking a mutable reference to a `const` item LL | const CR: &'static mut i32 = &mut C; | ^^^^^^ | - = note: `#[warn(const_item_mutation)]` on by default = note: each usage of a `const` item creates a new temporary = note: the mutable reference will refer to this temporary, not the original `const` item note: `const` item defined here @@ -12,6 +11,7 @@ note: `const` item defined here | LL | const C: i32 = 2; | ^^^^^^^^^^^^ + = note: `#[warn(const_item_mutation)]` on by default error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/E0017.rs:5:30 diff --git a/src/test/ui/error-codes/E0094.rs b/src/test/ui/error-codes/E0094.rs index 0d58e5a2862..a2ec932c124 100644 --- a/src/test/ui/error-codes/E0094.rs +++ b/src/test/ui/error-codes/E0094.rs @@ -1,5 +1,7 @@ #![feature(intrinsics)] + extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of<T, U>() -> usize; //~ ERROR E0094 } diff --git a/src/test/ui/error-codes/E0094.stderr b/src/test/ui/error-codes/E0094.stderr index da97f3a014b..531cd4c784d 100644 --- a/src/test/ui/error-codes/E0094.stderr +++ b/src/test/ui/error-codes/E0094.stderr @@ -1,5 +1,5 @@ error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1 - --> $DIR/E0094.rs:3:15 + --> $DIR/E0094.rs:5:15 | LL | fn size_of<T, U>() -> usize; | ^^^^^^ expected 1 type parameter diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr index 90a28874ead..90316c6e981 100644 --- a/src/test/ui/error-codes/E0283.stderr +++ b/src/test/ui/error-codes/E0283.stderr @@ -9,8 +9,8 @@ LL | let cont: u32 = Generator::create(); | help: use a fully-qualified path to a specific available implementation (2 found) | -LL | let cont: u32 = <::Impl as Generator>::create(); - | ++++++++++ + +LL | let cont: u32 = <Impl as Generator>::create(); + | ++++++++ + error[E0283]: type annotations needed --> $DIR/E0283.rs:35:24 diff --git a/src/test/ui/error-codes/E0308.rs b/src/test/ui/error-codes/E0308.rs index fa79bee570e..dd9e0b284ea 100644 --- a/src/test/ui/error-codes/E0308.rs +++ b/src/test/ui/error-codes/E0308.rs @@ -1,6 +1,8 @@ #![feature(intrinsics)] +#![feature(rustc_attrs)] extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of<T>(); //~ ERROR E0308 } diff --git a/src/test/ui/error-codes/E0308.stderr b/src/test/ui/error-codes/E0308.stderr index b71fb95e706..187b775f92d 100644 --- a/src/test/ui/error-codes/E0308.stderr +++ b/src/test/ui/error-codes/E0308.stderr @@ -1,5 +1,5 @@ error[E0308]: intrinsic has wrong type - --> $DIR/E0308.rs:4:5 + --> $DIR/E0308.rs:6:5 | LL | fn size_of<T>(); | ^^^^^^^^^^^^^^^^ expected `()`, found `usize` diff --git a/src/test/ui/error-codes/E0388.stderr b/src/test/ui/error-codes/E0388.stderr index 106efc19ac9..b51aa263d5e 100644 --- a/src/test/ui/error-codes/E0388.stderr +++ b/src/test/ui/error-codes/E0388.stderr @@ -4,7 +4,6 @@ warning: taking a mutable reference to a `const` item LL | const CR: &'static mut i32 = &mut C; | ^^^^^^ | - = note: `#[warn(const_item_mutation)]` on by default = note: each usage of a `const` item creates a new temporary = note: the mutable reference will refer to this temporary, not the original `const` item note: `const` item defined here @@ -12,6 +11,7 @@ note: `const` item defined here | LL | const C: i32 = 2; | ^^^^^^^^^^^^ + = note: `#[warn(const_item_mutation)]` on by default error[E0764]: mutable references are not allowed in the final value of constants --> $DIR/E0388.rs:4:30 diff --git a/src/test/ui/error-codes/E0520.stderr b/src/test/ui/error-codes/E0520.stderr index 65ebfcdbe32..12ecead13de 100644 --- a/src/test/ui/error-codes/E0520.stderr +++ b/src/test/ui/error-codes/E0520.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0520]: `fly` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/E0520.rs:17:5 diff --git a/src/test/ui/error-codes/E0585.stderr b/src/test/ui/error-codes/E0585.stderr index 7a31c4896ee..53c82fb416b 100644 --- a/src/test/ui/error-codes/E0585.stderr +++ b/src/test/ui/error-codes/E0585.stderr @@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything LL | /// Hello! I'm useless... | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0771.stderr b/src/test/ui/error-codes/E0771.stderr index 3ab727f5f69..b759399a940 100644 --- a/src/test/ui/error-codes/E0771.stderr +++ b/src/test/ui/error-codes/E0771.stderr @@ -12,8 +12,8 @@ warning: the feature `adt_const_params` is incomplete and may not be safe to use LL | #![feature(adt_const_params)] | ^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information + = note: `#[warn(incomplete_features)]` on by default error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/error-codes/E0790.stderr b/src/test/ui/error-codes/E0790.stderr index 6e173a9682a..f68c0e7d220 100644 --- a/src/test/ui/error-codes/E0790.stderr +++ b/src/test/ui/error-codes/E0790.stderr @@ -9,8 +9,8 @@ LL | MyTrait::my_fn(); | help: use the fully-qualified path to the only available implementation | -LL | <::inner::MyStruct as MyTrait>::my_fn(); - | +++++++++++++++++++++ + +LL | <MyStruct as MyTrait>::my_fn(); + | ++++++++++++ + error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type --> $DIR/E0790.rs:21:17 @@ -23,8 +23,8 @@ LL | let _ = MyTrait::MY_ASSOC_CONST; | help: use the fully-qualified path to the only available implementation | -LL | let _ = <::inner::MyStruct as MyTrait>::MY_ASSOC_CONST; - | +++++++++++++++++++++ + +LL | let _ = <MyStruct as MyTrait>::MY_ASSOC_CONST; + | ++++++++++++ + error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> $DIR/E0790.rs:26:5 @@ -37,8 +37,8 @@ LL | inner::MyTrait::my_fn(); | help: use the fully-qualified path to the only available implementation | -LL | inner::<::inner::MyStruct as MyTrait>::my_fn(); - | +++++++++++++++++++++ + +LL | inner::<MyStruct as MyTrait>::my_fn(); + | ++++++++++++ + error[E0790]: cannot refer to the associated constant on trait without specifying the corresponding `impl` type --> $DIR/E0790.rs:30:13 @@ -51,8 +51,8 @@ LL | let _ = inner::MyTrait::MY_ASSOC_CONST; | help: use the fully-qualified path to the only available implementation | -LL | let _ = inner::<::inner::MyStruct as MyTrait>::MY_ASSOC_CONST; - | +++++++++++++++++++++ + +LL | let _ = inner::<MyStruct as MyTrait>::MY_ASSOC_CONST; + | ++++++++++++ + error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type --> $DIR/E0790.rs:50:5 @@ -65,8 +65,8 @@ LL | MyTrait2::my_fn(); | help: use a fully-qualified path to a specific available implementation (2 found) | -LL | <::Impl1 as MyTrait2>::my_fn(); - | +++++++++++ + +LL | <Impl1 as MyTrait2>::my_fn(); + | +++++++++ + error: aborting due to 5 previous errors diff --git a/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr b/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr index 4ec78a298fe..08eb8cfac49 100644 --- a/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr +++ b/src/test/ui/errors/issue-89280-emitter-overflow-splice-lines.stderr @@ -8,9 +8,9 @@ LL | | LL | | )) {} | |_____^ | - = note: `#[warn(anonymous_parameters)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686> + = note: `#[warn(anonymous_parameters)]` on by default help: try naming the parameter or explicitly ignoring it | LL ~ fn test(x: u32, _: ( diff --git a/src/test/ui/expr/if/if-let.stderr b/src/test/ui/expr/if/if-let.stderr index 8238b3f0e49..c4bba3cb1a8 100644 --- a/src/test/ui/expr/if/if-let.stderr +++ b/src/test/ui/expr/if/if-let.stderr @@ -9,9 +9,9 @@ LL | | println!("irrefutable pattern"); LL | | }); | |______- in this macro invocation | - = note: `#[warn(irrefutable_let_patterns)]` on by default = note: this pattern will always match, so the `if let` is useless = help: consider replacing the `if let` with a `let` + = note: `#[warn(irrefutable_let_patterns)]` on by default = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) warning: irrefutable `if let` pattern diff --git a/src/test/ui/extern/extern-no-mangle.stderr b/src/test/ui/extern/extern-no-mangle.stderr index b5642814114..f20ee158ac4 100644 --- a/src/test/ui/extern/extern-no-mangle.stderr +++ b/src/test/ui/extern/extern-no-mangle.stderr @@ -7,12 +7,12 @@ LL | #[no_mangle] LL | let x = 0_u8; | ------------- not a free function, impl method or static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! note: the lint level is defined here --> $DIR/extern-no-mangle.rs:1:9 | LL | #![warn(unused_attributes)] | ^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: `#[no_mangle]` has no effect on a foreign static --> $DIR/extern-no-mangle.rs:11:5 diff --git a/src/test/ui/extern/extern-with-type-bounds.rs b/src/test/ui/extern/extern-with-type-bounds.rs index 8f9683e4a74..a72aa4171a1 100644 --- a/src/test/ui/extern/extern-with-type-bounds.rs +++ b/src/test/ui/extern/extern-with-type-bounds.rs @@ -2,6 +2,7 @@ extern "rust-intrinsic" { // Real example from libcore + #[rustc_safe_intrinsic] fn type_id<T: ?Sized + 'static>() -> u64; // Silent bounds made explicit to make sure they are actually @@ -10,6 +11,7 @@ extern "rust-intrinsic" { // Bounds aren't checked right now, so this should work // even though it's incorrect. + #[rustc_safe_intrinsic] fn size_of<T: Clone>() -> usize; // Unresolved bounds should still error. diff --git a/src/test/ui/extern/extern-with-type-bounds.stderr b/src/test/ui/extern/extern-with-type-bounds.stderr index acd0596422f..88be1e5dd3d 100644 --- a/src/test/ui/extern/extern-with-type-bounds.stderr +++ b/src/test/ui/extern/extern-with-type-bounds.stderr @@ -1,5 +1,5 @@ error[E0405]: cannot find trait `NoSuchTrait` in this scope - --> $DIR/extern-with-type-bounds.rs:16:20 + --> $DIR/extern-with-type-bounds.rs:18:20 | LL | fn align_of<T: NoSuchTrait>() -> usize; | ^^^^^^^^^^^ not found in this scope diff --git a/src/test/ui/feature-gates/bench.stderr b/src/test/ui/feature-gates/bench.stderr index 168ac925724..5f0aaf9251f 100644 --- a/src/test/ui/feature-gates/bench.stderr +++ b/src/test/ui/feature-gates/bench.stderr @@ -4,9 +4,9 @@ error: use of unstable library feature 'test': `bench` is a part of custom test LL | #[bench] | ^^^^^ | - = note: `#[deny(soft_unstable)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266> + = note: `#[deny(soft_unstable)]` on by default error: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable --> $DIR/bench.rs:7:5 diff --git a/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr b/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr index a7d5c7ac39b..308de269293 100644 --- a/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr +++ b/src/test/ui/feature-gates/feature-gate-default_type_parameter_fallback.stderr @@ -4,9 +4,9 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type` LL | fn avg<T=i32>(_: T) {} | ^^^^^ | - = note: `#[deny(invalid_type_param_default)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887> + = note: `#[deny(invalid_type_param_default)]` on by default error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions --> $DIR/feature-gate-default_type_parameter_fallback.rs:8:6 diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr index 3de08e215da..4d79ce3c659 100644 --- a/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr +++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr @@ -4,10 +4,10 @@ warning: unknown lint: `non_exhaustive_omitted_patterns` LL | #![deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_lints)]` on by default = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 <https://github.com/rust-lang/rust/issues/89554> for more information = help: add `#![feature(non_exhaustive_omitted_patterns_lint)]` to the crate attributes to enable + = note: `#[warn(unknown_lints)]` on by default warning: unknown lint: `non_exhaustive_omitted_patterns` --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:6:1 diff --git a/src/test/ui/feature-gates/feature-gate-repr-simd.stderr b/src/test/ui/feature-gates/feature-gate-repr-simd.stderr index ae44b802069..5b1270a1984 100644 --- a/src/test/ui/feature-gates/feature-gate-repr-simd.stderr +++ b/src/test/ui/feature-gates/feature-gate-repr-simd.stderr @@ -25,9 +25,9 @@ LL | LL | #[repr(simd)] | ^^^^ | - = note: `#[deny(conflicting_repr_hints)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585> + = note: `#[deny(conflicting_repr_hints)]` on by default error: aborting due to 3 previous errors diff --git a/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr b/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr index 34bd240c304..751da87cc0d 100644 --- a/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr +++ b/src/test/ui/feature-gates/feature-gate-strict_provenance.stderr @@ -4,10 +4,10 @@ warning: unknown lint: `fuzzy_provenance_casts` LL | #![deny(fuzzy_provenance_casts)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_lints)]` on by default = note: the `fuzzy_provenance_casts` lint is unstable = note: see issue #95228 <https://github.com/rust-lang/rust/issues/95228> for more information = help: add `#![feature(strict_provenance)]` to the crate attributes to enable + = note: `#[warn(unknown_lints)]` on by default warning: unknown lint: `lossy_provenance_casts` --> $DIR/feature-gate-strict_provenance.rs:7:1 diff --git a/src/test/ui/feature-gates/feature-gate-test_unstable_lint.stderr b/src/test/ui/feature-gates/feature-gate-test_unstable_lint.stderr index a29322443ea..b4d6aa658e1 100644 --- a/src/test/ui/feature-gates/feature-gate-test_unstable_lint.stderr +++ b/src/test/ui/feature-gates/feature-gate-test_unstable_lint.stderr @@ -4,9 +4,9 @@ warning: unknown lint: `test_unstable_lint` LL | #![allow(test_unstable_lint)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_lints)]` on by default = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable + = note: `#[warn(unknown_lints)]` on by default warning: unknown lint: `test_unstable_lint` --> $DIR/feature-gate-test_unstable_lint.rs:4:1 diff --git a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index f94ec7d4704..5a645cf4ef9 100644 --- a/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/src/test/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -12,9 +12,9 @@ error: attribute must be of the form `#[inline]` or `#[inline(always|never)]` LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(ill_formed_attribute_input)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default error: `start` attribute can only be used on functions --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:1 diff --git a/src/test/ui/fmt/auxiliary/format-string-proc-macro.rs b/src/test/ui/fmt/auxiliary/format-string-proc-macro.rs new file mode 100644 index 00000000000..e44a84776bc --- /dev/null +++ b/src/test/ui/fmt/auxiliary/format-string-proc-macro.rs @@ -0,0 +1,28 @@ +// force-host +// no-prefer-dynamic + +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::{Literal, Span, TokenStream, TokenTree}; + +#[proc_macro] +pub fn foo_with_input_span(input: TokenStream) -> TokenStream { + let span = input.into_iter().next().unwrap().span(); + + let mut lit = Literal::string("{foo}"); + lit.set_span(span); + + TokenStream::from(TokenTree::Literal(lit)) +} + +#[proc_macro] +pub fn err_with_input_span(input: TokenStream) -> TokenStream { + let span = input.into_iter().next().unwrap().span(); + + let mut lit = Literal::string(" }"); + lit.set_span(span); + + TokenStream::from(TokenTree::Literal(lit)) +} diff --git a/src/test/ui/fmt/format-args-capture-issue-102057.rs b/src/test/ui/fmt/format-args-capture-issue-102057.rs new file mode 100644 index 00000000000..b8089d49bcb --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-issue-102057.rs @@ -0,0 +1,19 @@ +fn main() { + format!("\x7Ba}"); + //~^ ERROR cannot find value `a` in this scope + format!("\x7Ba\x7D"); + //~^ ERROR cannot find value `a` in this scope + + let a = 0; + + format!("\x7Ba} {b}"); + //~^ ERROR cannot find value `b` in this scope + format!("\x7Ba\x7D {b}"); + //~^ ERROR cannot find value `b` in this scope + format!("\x7Ba} \x7Bb}"); + //~^ ERROR cannot find value `b` in this scope + format!("\x7Ba\x7D \x7Bb}"); + //~^ ERROR cannot find value `b` in this scope + format!("\x7Ba\x7D \x7Bb\x7D"); + //~^ ERROR cannot find value `b` in this scope +} diff --git a/src/test/ui/fmt/format-args-capture-issue-102057.stderr b/src/test/ui/fmt/format-args-capture-issue-102057.stderr new file mode 100644 index 00000000000..f2d625e7f8d --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-issue-102057.stderr @@ -0,0 +1,45 @@ +error[E0425]: cannot find value `a` in this scope + --> $DIR/format-args-capture-issue-102057.rs:2:18 + | +LL | format!("\x7Ba}"); + | ^ not found in this scope + +error[E0425]: cannot find value `a` in this scope + --> $DIR/format-args-capture-issue-102057.rs:4:18 + | +LL | format!("\x7Ba\x7D"); + | ^ not found in this scope + +error[E0425]: cannot find value `b` in this scope + --> $DIR/format-args-capture-issue-102057.rs:9:22 + | +LL | format!("\x7Ba} {b}"); + | ^ help: a local variable with a similar name exists: `a` + +error[E0425]: cannot find value `b` in this scope + --> $DIR/format-args-capture-issue-102057.rs:11:25 + | +LL | format!("\x7Ba\x7D {b}"); + | ^ help: a local variable with a similar name exists: `a` + +error[E0425]: cannot find value `b` in this scope + --> $DIR/format-args-capture-issue-102057.rs:13:25 + | +LL | format!("\x7Ba} \x7Bb}"); + | ^ help: a local variable with a similar name exists: `a` + +error[E0425]: cannot find value `b` in this scope + --> $DIR/format-args-capture-issue-102057.rs:15:28 + | +LL | format!("\x7Ba\x7D \x7Bb}"); + | ^ help: a local variable with a similar name exists: `a` + +error[E0425]: cannot find value `b` in this scope + --> $DIR/format-args-capture-issue-102057.rs:17:28 + | +LL | format!("\x7Ba\x7D \x7Bb\x7D"); + | ^ help: a local variable with a similar name exists: `a` + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.rs b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs index fdbd93836ef..b04f80ba406 100644 --- a/src/test/ui/fmt/format-args-capture-macro-hygiene.rs +++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.rs @@ -1,4 +1,22 @@ +// aux-build:format-string-proc-macro.rs + +#[macro_use] +extern crate format_string_proc_macro; + +macro_rules! def_site { + () => { "{foo}" } //~ ERROR: there is no argument named `foo` +} + +macro_rules! call_site { + ($fmt:literal) => { $fmt } +} + fn main() { format!(concat!("{foo}")); //~ ERROR: there is no argument named `foo` format!(concat!("{ba", "r} {}"), 1); //~ ERROR: there is no argument named `bar` + + format!(def_site!()); + format!(call_site!("{foo}")); //~ ERROR: there is no argument named `foo` + + format!(foo_with_input_span!("")); //~ ERROR: there is no argument named `foo` } diff --git a/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr index 9423e8c819d..1b5fbd2af34 100644 --- a/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr +++ b/src/test/ui/fmt/format-args-capture-macro-hygiene.stderr @@ -1,5 +1,5 @@ error: there is no argument named `foo` - --> $DIR/format-args-capture-macro-hygiene.rs:2:13 + --> $DIR/format-args-capture-macro-hygiene.rs:15:13 | LL | format!(concat!("{foo}")); | ^^^^^^^^^^^^^^^^ @@ -9,7 +9,7 @@ LL | format!(concat!("{foo}")); = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) error: there is no argument named `bar` - --> $DIR/format-args-capture-macro-hygiene.rs:3:13 + --> $DIR/format-args-capture-macro-hygiene.rs:16:13 | LL | format!(concat!("{ba", "r} {}"), 1); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -18,5 +18,36 @@ LL | format!(concat!("{ba", "r} {}"), 1); = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 2 previous errors +error: there is no argument named `foo` + --> $DIR/format-args-capture-macro-hygiene.rs:7:13 + | +LL | () => { "{foo}" } + | ^^^^^^^ +... +LL | format!(def_site!()); + | ----------- in this macro invocation + | + = note: did you intend to capture a variable `foo` from the surrounding scope? + = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro + = note: this error originates in the macro `def_site` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: there is no argument named `foo` + --> $DIR/format-args-capture-macro-hygiene.rs:19:24 + | +LL | format!(call_site!("{foo}")); + | ^^^^^^^ + | + = note: did you intend to capture a variable `foo` from the surrounding scope? + = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro + +error: there is no argument named `foo` + --> $DIR/format-args-capture-macro-hygiene.rs:21:34 + | +LL | format!(foo_with_input_span!("")); + | ^^ + | + = note: did you intend to capture a variable `foo` from the surrounding scope? + = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro + +error: aborting due to 5 previous errors diff --git a/src/test/ui/fmt/format-concat-span.stderr b/src/test/ui/fmt/format-concat-span.stderr deleted file mode 100644 index da46f40abcb..00000000000 --- a/src/test/ui/fmt/format-concat-span.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error: invalid format string: unmatched `}` found - --> $DIR/format-concat-span.rs:13:13 - | -LL | format!(concat!("abc}")); - | ^^^^^^^^^^^^^^^ unmatched `}` in format string - | - = note: if you intended to print `}`, you can escape it using `}}` - = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to previous error - diff --git a/src/test/ui/fmt/format-concat-span.rs b/src/test/ui/fmt/format-expanded-string.rs index ce92df0ad92..4c716f08c71 100644 --- a/src/test/ui/fmt/format-concat-span.rs +++ b/src/test/ui/fmt/format-expanded-string.rs @@ -1,3 +1,9 @@ +// aux-build:format-string-proc-macro.rs + +#[macro_use] +extern crate format_string_proc_macro; + + // If the format string is another macro invocation, rustc would previously // compute nonsensical spans, such as: // @@ -12,4 +18,7 @@ fn main() { format!(concat!("abc}")); //~^ ERROR: invalid format string: unmatched `}` found + + format!(err_with_input_span!("")); + //~^ ERROR: invalid format string: unmatched `}` found } diff --git a/src/test/ui/fmt/format-expanded-string.stderr b/src/test/ui/fmt/format-expanded-string.stderr new file mode 100644 index 00000000000..26ce7f26958 --- /dev/null +++ b/src/test/ui/fmt/format-expanded-string.stderr @@ -0,0 +1,19 @@ +error: invalid format string: unmatched `}` found + --> $DIR/format-expanded-string.rs:19:13 + | +LL | format!(concat!("abc}")); + | ^^^^^^^^^^^^^^^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: invalid format string: unmatched `}` found + --> $DIR/format-expanded-string.rs:22:34 + | +LL | format!(err_with_input_span!("")); + | ^^ unmatched `}` in format string + | + = note: if you intended to print `}`, you can escape it using `}}` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/for-loop-while/while-let-2.stderr b/src/test/ui/for-loop-while/while-let-2.stderr index 2d23a637361..1b1cf679243 100644 --- a/src/test/ui/for-loop-while/while-let-2.stderr +++ b/src/test/ui/for-loop-while/while-let-2.stderr @@ -9,9 +9,9 @@ LL | | println!("irrefutable pattern"); LL | | }); | |______- in this macro invocation | - = note: `#[warn(irrefutable_let_patterns)]` on by default = note: this pattern will always match, so the loop will never exit = help: consider instead using a `loop { ... }` with a `let` inside it + = note: `#[warn(irrefutable_let_patterns)]` on by default = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) warning: irrefutable `while let` pattern diff --git a/src/test/ui/future-incompatible-lint-group.stderr b/src/test/ui/future-incompatible-lint-group.stderr index 8f6dde665e6..a8fb100a749 100644 --- a/src/test/ui/future-incompatible-lint-group.stderr +++ b/src/test/ui/future-incompatible-lint-group.stderr @@ -4,9 +4,9 @@ warning: anonymous parameters are deprecated and will be removed in the next edi LL | fn f(u8) {} | ^^ help: try naming the parameter or explicitly ignoring it: `_: u8` | - = note: `#[warn(anonymous_parameters)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686> + = note: `#[warn(anonymous_parameters)]` on by default error: this attribute can only be applied at the crate level --> $DIR/future-incompatible-lint-group.rs:13:12 @@ -14,15 +14,15 @@ error: this attribute can only be applied at the crate level LL | #![doc(test(some_test))] | ^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information note: the lint level is defined here --> $DIR/future-incompatible-lint-group.rs:3:9 | LL | #![deny(future_incompatible)] | ^^^^^^^^^^^^^^^^^^^ = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(future_incompatible)]` - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> - = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/generator/issue-52398.stderr b/src/test/ui/generator/issue-52398.stderr index 3f8ebb5a738..30a6732f759 100644 --- a/src/test/ui/generator/issue-52398.stderr +++ b/src/test/ui/generator/issue-52398.stderr @@ -6,8 +6,8 @@ LL | | A.test(yield); LL | | }; | |______^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: unused generator that must be used --> $DIR/issue-52398.rs:24:5 diff --git a/src/test/ui/generator/issue-57084.stderr b/src/test/ui/generator/issue-57084.stderr index 32a04f94dcb..29aca94408a 100644 --- a/src/test/ui/generator/issue-57084.stderr +++ b/src/test/ui/generator/issue-57084.stderr @@ -9,8 +9,8 @@ LL | | } LL | | }; | |______^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/generator/match-bindings.stderr b/src/test/ui/generator/match-bindings.stderr index 4fd1e26f0c8..b911b666190 100644 --- a/src/test/ui/generator/match-bindings.stderr +++ b/src/test/ui/generator/match-bindings.stderr @@ -10,8 +10,8 @@ LL | | } LL | | }; | |______^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/generator/print/generator-print-verbose-1.stderr b/src/test/ui/generator/print/generator-print-verbose-1.stderr index 3a83021dd99..2e020780480 100644 --- a/src/test/ui/generator/print/generator-print-verbose-1.stderr +++ b/src/test/ui/generator/print/generator-print-verbose-1.stderr @@ -9,7 +9,7 @@ note: generator is not `Send` as this value is used across a yield --> $DIR/generator-print-verbose-1.rs:35:9 | LL | let _non_send_gen = make_non_send_generator(); - | ------------- has type `Opaque(DefId(0:34 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send` + | ------------- has type `Opaque(DefId(0:44 ~ generator_print_verbose_1[749a]::make_non_send_generator::{opaque#0}), [])` which is not `Send` LL | yield; | ^^^^^ yield occurs here, with `_non_send_gen` maybe used later LL | }; @@ -35,17 +35,17 @@ note: required because it's used within this generator | LL | || { | ^^ -note: required because it appears within the type `Opaque(DefId(0:39 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])` +note: required because it appears within the type `Opaque(DefId(0:45 ~ generator_print_verbose_1[749a]::make_gen2::{opaque#0}), [std::sync::Arc<std::cell::RefCell<i32>>])` --> $DIR/generator-print-verbose-1.rs:41:30 | LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required because it appears within the type `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])` +note: required because it appears within the type `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])` --> $DIR/generator-print-verbose-1.rs:47:34 | LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: required because it captures the following types: `Opaque(DefId(0:42 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()` + = note: required because it captures the following types: `Opaque(DefId(0:46 ~ generator_print_verbose_1[749a]::make_non_send_generator2::{opaque#0}), [])`, `()` note: required because it's used within this generator --> $DIR/generator-print-verbose-1.rs:52:20 | diff --git a/src/test/ui/generator/reborrow-mut-upvar.stderr b/src/test/ui/generator/reborrow-mut-upvar.stderr index ff511b76672..e83dbf833bf 100644 --- a/src/test/ui/generator/reborrow-mut-upvar.stderr +++ b/src/test/ui/generator/reborrow-mut-upvar.stderr @@ -10,8 +10,8 @@ LL | | *bar = 2; LL | | }; | |______^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr index 72a2bd4ebc5..5cb43067fee 100644 --- a/src/test/ui/generator/too-live-local-in-immovable-gen.stderr +++ b/src/test/ui/generator/too-live-local-in-immovable-gen.stderr @@ -10,8 +10,8 @@ LL | | let _ = &a; LL | | }; | |__________^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/generator/yield-in-args-rev.stderr b/src/test/ui/generator/yield-in-args-rev.stderr index a575bf88678..c9e1ab722d4 100644 --- a/src/test/ui/generator/yield-in-args-rev.stderr +++ b/src/test/ui/generator/yield-in-args-rev.stderr @@ -7,8 +7,8 @@ LL | | foo(yield, &b); LL | | }; | |______^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/generator/yield-in-box.stderr b/src/test/ui/generator/yield-in-box.stderr index 7602e803945..8587e1dc663 100644 --- a/src/test/ui/generator/yield-in-box.stderr +++ b/src/test/ui/generator/yield-in-box.stderr @@ -10,8 +10,8 @@ LL | | } LL | | }; | |______^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/generator/yield-in-initializer.stderr b/src/test/ui/generator/yield-in-initializer.stderr index e79047ae701..07de24662cf 100644 --- a/src/test/ui/generator/yield-in-initializer.stderr +++ b/src/test/ui/generator/yield-in-initializer.stderr @@ -10,8 +10,8 @@ LL | | } LL | | }; | |______^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/generator/yield-subtype.stderr b/src/test/ui/generator/yield-subtype.stderr index bded36a4cda..fe10477bf73 100644 --- a/src/test/ui/generator/yield-subtype.stderr +++ b/src/test/ui/generator/yield-subtype.stderr @@ -7,8 +7,8 @@ LL | | yield b; LL | | }; | |______^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/generic-associated-types/issue-102114.rs b/src/test/ui/generic-associated-types/issue-102114.rs new file mode 100644 index 00000000000..de31737efef --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-102114.rs @@ -0,0 +1,16 @@ +trait A { + type B<'b>; + fn a() -> Self::B<'static>; +} + +struct C; + +struct Wrapper<T>(T); + +impl A for C { + type B<T> = Wrapper<T>; + //~^ ERROR type `B` has 1 type parameter but its trait declaration has 0 type parameters + fn a() -> Self::B<'static> {} +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-102114.stderr b/src/test/ui/generic-associated-types/issue-102114.stderr new file mode 100644 index 00000000000..8e41dee54d7 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-102114.stderr @@ -0,0 +1,12 @@ +error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters + --> $DIR/issue-102114.rs:11:12 + | +LL | type B<'b>; + | -- expected 0 type parameters +... +LL | type B<T> = Wrapper<T>; + | ^ found 1 type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0049`. diff --git a/src/test/ui/generic-associated-types/issue-102333.rs b/src/test/ui/generic-associated-types/issue-102333.rs new file mode 100644 index 00000000000..6c72563322f --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-102333.rs @@ -0,0 +1,15 @@ +// check-pass + +trait A { + type T: B<U<1i32> = ()>; +} + +trait B { + type U<const C: i32>; +} + +fn f<T: A>() { + let _: <<T as A>::T as B>::U<1i32> = (); +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-87429-specialization.stderr b/src/test/ui/generic-associated-types/issue-87429-specialization.stderr index d8e889aecef..11c4ebf604e 100644 --- a/src/test/ui/generic-associated-types/issue-87429-specialization.stderr +++ b/src/test/ui/generic-associated-types/issue-87429-specialization.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0277]: can't compare `Foo` with `Foo` --> $DIR/issue-87429-specialization.rs:20:31 diff --git a/src/test/ui/generics/issue-94923.rs b/src/test/ui/generics/issue-94923.rs new file mode 100644 index 00000000000..d337a5dffc9 --- /dev/null +++ b/src/test/ui/generics/issue-94923.rs @@ -0,0 +1,49 @@ +// run-pass +// regression test for issue #94923 +// min-llvm-version: 15.0.0 +// compile-flags: -C opt-level=3 + +fn f0<T>(mut x: usize) -> usize { + for _ in 0..1000 { + x *= 123; + x %= 99 + } + x + 321 // function composition is not just longer iteration +} + +fn f1<T>(x: usize) -> usize { + f0::<(i8, T)>(f0::<(u8, T)>(x)) +} + +fn f2<T>(x: usize) -> usize { + f1::<(i8, T)>(f1::<(u8, T)>(x)) +} + +fn f3<T>(x: usize) -> usize { + f2::<(i8, T)>(f2::<(u8, T)>(x)) +} + +fn f4<T>(x: usize) -> usize { + f3::<(i8, T)>(f3::<(u8, T)>(x)) +} + +fn f5<T>(x: usize) -> usize { + f4::<(i8, T)>(f4::<(u8, T)>(x)) +} + +fn f6<T>(x: usize) -> usize { + f5::<(i8, T)>(f5::<(u8, T)>(x)) +} + +fn f7<T>(x: usize) -> usize { + f6::<(i8, T)>(f6::<(u8, T)>(x)) +} + +fn f8<T>(x: usize) -> usize { + f7::<(i8, T)>(f7::<(u8, T)>(x)) +} + +fn main() { + let y = f8::<()>(1); + assert_eq!(y, 348); +} diff --git a/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr index 5e75a4cc8af..727b9e6bec8 100644 --- a/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr +++ b/src/test/ui/higher-rank-trait-bounds/hrtb-perfect-forwarding.stderr @@ -9,8 +9,8 @@ LL | | T: Bar<&'b isize>, LL | no_hrtb(&mut t); | --------------- recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default warning: function cannot return without recursing --> $DIR/hrtb-perfect-forwarding.rs:25:1 diff --git a/src/test/ui/impl-trait/equality-rpass.stderr b/src/test/ui/impl-trait/equality-rpass.stderr index 11eeceba0ee..bde8362fdf8 100644 --- a/src/test/ui/impl-trait/equality-rpass.stderr +++ b/src/test/ui/impl-trait/equality-rpass.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index d4a3495515c..1841b8e5dcd 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0308]: mismatched types --> $DIR/equality.rs:15:5 diff --git a/src/test/ui/impl-trait/equality2.stderr b/src/test/ui/impl-trait/equality2.stderr index 46053c6e7c1..e399a61023d 100644 --- a/src/test/ui/impl-trait/equality2.stderr +++ b/src/test/ui/impl-trait/equality2.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0308]: mismatched types --> $DIR/equality2.rs:25:18 diff --git a/src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs new file mode 100644 index 00000000000..74df300f85a --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/auxiliary/rpitit.rs @@ -0,0 +1,11 @@ +#![feature(return_position_impl_trait_in_trait)] + +pub trait Foo { + fn bar() -> impl Sized; +} + +pub struct Foreign; + +impl Foo for Foreign { + fn bar() {} +} diff --git a/src/test/ui/impl-trait/in-trait/foreign.rs b/src/test/ui/impl-trait/in-trait/foreign.rs new file mode 100644 index 00000000000..6341f5b4284 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/foreign.rs @@ -0,0 +1,9 @@ +// check-pass +// aux-build: rpitit.rs + +extern crate rpitit; + +fn main() { + // Witness an RPITIT from another crate + let () = <rpitit::Foreign as rpitit::Foo>::bar(); +} diff --git a/src/test/ui/impl-trait/in-trait/issue-102571.rs b/src/test/ui/impl-trait/in-trait/issue-102571.rs new file mode 100644 index 00000000000..61c91e64417 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/issue-102571.rs @@ -0,0 +1,24 @@ +#![feature(return_position_impl_trait_in_trait)] +#![allow(incomplete_features)] + +use std::fmt::Display; +use std::ops::Deref; + +trait Foo { + fn bar(self) -> impl Deref<Target = impl Display + ?Sized>; +} + +struct A; + +impl Foo for A { + fn bar(self) -> &'static str { + "Hello, world" + } +} + +fn foo<T: Foo>(t: T) { + let () = t.bar(); + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/impl-trait/in-trait/issue-102571.stderr b/src/test/ui/impl-trait/in-trait/issue-102571.stderr new file mode 100644 index 00000000000..87219941d91 --- /dev/null +++ b/src/test/ui/impl-trait/in-trait/issue-102571.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-102571.rs:20:9 + | +LL | let () = t.bar(); + | ^^ ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>` + | | + | expected associated type, found `()` + | + = note: expected associated type `impl Deref<Target = impl std::fmt::Display + ?Sized>` + found unit type `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/issue-100075-2.stderr b/src/test/ui/impl-trait/issue-100075-2.stderr index 5a1f1a97d04..d2dbd8c6205 100644 --- a/src/test/ui/impl-trait/issue-100075-2.stderr +++ b/src/test/ui/impl-trait/issue-100075-2.stderr @@ -7,8 +7,8 @@ LL | fn opaque<T>(t: T) -> impl Sized { LL | opaque(Some(t)) | --------------- recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default error[E0720]: cannot resolve opaque type --> $DIR/issue-100075-2.rs:1:23 diff --git a/src/test/ui/impl-trait/issue-102605.rs b/src/test/ui/impl-trait/issue-102605.rs new file mode 100644 index 00000000000..3bbdf35af8f --- /dev/null +++ b/src/test/ui/impl-trait/issue-102605.rs @@ -0,0 +1,15 @@ +// edition:2021 + +async fn foo() -> Result<(), String> { + Ok(()) +} + +fn convert_result<T, E>(r: Result<T, E>) -> Option<T> { + None +} + +fn main() -> Option<()> { + //~^ ERROR `main` has invalid return type `Option<()>` + convert_result(foo()) + //~^ ERROR mismatched types +} diff --git a/src/test/ui/impl-trait/issue-102605.stderr b/src/test/ui/impl-trait/issue-102605.stderr new file mode 100644 index 00000000000..d4aba914908 --- /dev/null +++ b/src/test/ui/impl-trait/issue-102605.stderr @@ -0,0 +1,41 @@ +error[E0308]: mismatched types + --> $DIR/issue-102605.rs:13:20 + | +LL | convert_result(foo()) + | -------------- ^^^^^ expected enum `Result`, found opaque type + | | + | arguments to this function are incorrect + | +note: while checking the return type of the `async fn` + --> $DIR/issue-102605.rs:3:19 + | +LL | async fn foo() -> Result<(), String> { + | ^^^^^^^^^^^^^^^^^^ checked the `Output` of this `async fn`, found opaque type + = note: expected enum `Result<(), _>` + found opaque type `impl Future<Output = Result<(), String>>` +note: function defined here + --> $DIR/issue-102605.rs:7:4 + | +LL | fn convert_result<T, E>(r: Result<T, E>) -> Option<T> { + | ^^^^^^^^^^^^^^ --------------- +help: consider `await`ing on the `Future` + | +LL | convert_result(foo().await) + | ++++++ +help: try wrapping the expression in `Err` + | +LL | convert_result(Err(foo())) + | ++++ + + +error[E0277]: `main` has invalid return type `Option<()>` + --> $DIR/issue-102605.rs:11:14 + | +LL | fn main() -> Option<()> { + | ^^^^^^^^^^ `main` can only return types that implement `Termination` + | + = help: consider using `()`, or a `Result` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/issue-87450.stderr b/src/test/ui/impl-trait/issue-87450.stderr index 5019e544bd5..173fca63fa0 100644 --- a/src/test/ui/impl-trait/issue-87450.stderr +++ b/src/test/ui/impl-trait/issue-87450.stderr @@ -7,8 +7,8 @@ LL | fn foo() -> impl Fn() { LL | wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo()))))))) | ----- recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default error[E0720]: cannot resolve opaque type --> $DIR/issue-87450.rs:5:13 diff --git a/src/test/ui/impl-trait/nested-return-type2-tait.rs b/src/test/ui/impl-trait/nested-return-type2-tait.rs index 42613d5ccd9..089018a1cdf 100644 --- a/src/test/ui/impl-trait/nested-return-type2-tait.rs +++ b/src/test/ui/impl-trait/nested-return-type2-tait.rs @@ -26,6 +26,7 @@ type Sendable = impl Send; // var to make it uphold the `: Duh` bound on `Trait::Assoc`. The opaque // type does not implement `Duh`, but if its hidden type does. fn foo() -> impl Trait<Assoc = Sendable> { + //~^ WARN opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds || 42 } diff --git a/src/test/ui/impl-trait/nested-return-type2-tait.stderr b/src/test/ui/impl-trait/nested-return-type2-tait.stderr new file mode 100644 index 00000000000..a8eb69cfcb7 --- /dev/null +++ b/src/test/ui/impl-trait/nested-return-type2-tait.stderr @@ -0,0 +1,17 @@ +warning: opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds + --> $DIR/nested-return-type2-tait.rs:28:24 + | +LL | type Assoc: Duh; + | --- this associated type bound is unsatisfied for `Sendable` +... +LL | fn foo() -> impl Trait<Assoc = Sendable> { + | ^^^^^^^^^^^^^^^^ + | + = note: `#[warn(opaque_hidden_inferred_bound)]` on by default +help: add this bound + | +LL | type Sendable = impl Send + Duh; + | +++++ + +warning: 1 warning emitted + diff --git a/src/test/ui/impl-trait/nested-return-type2.rs b/src/test/ui/impl-trait/nested-return-type2.rs index 39928d543e1..cc1f1f4ec44 100644 --- a/src/test/ui/impl-trait/nested-return-type2.rs +++ b/src/test/ui/impl-trait/nested-return-type2.rs @@ -23,6 +23,7 @@ impl<R: Duh, F: FnMut() -> R> Trait for F { // Lazy TAIT would error out, but we inserted a hack to make it work again, // keeping backwards compatibility. fn foo() -> impl Trait<Assoc = impl Send> { + //~^ WARN opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds || 42 } diff --git a/src/test/ui/impl-trait/nested-return-type2.stderr b/src/test/ui/impl-trait/nested-return-type2.stderr new file mode 100644 index 00000000000..3aed05ca132 --- /dev/null +++ b/src/test/ui/impl-trait/nested-return-type2.stderr @@ -0,0 +1,17 @@ +warning: opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds + --> $DIR/nested-return-type2.rs:25:24 + | +LL | type Assoc: Duh; + | --- this associated type bound is unsatisfied for `impl Send` +... +LL | fn foo() -> impl Trait<Assoc = impl Send> { + | ^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(opaque_hidden_inferred_bound)]` on by default +help: add this bound + | +LL | fn foo() -> impl Trait<Assoc = impl Send + Duh> { + | +++++ + +warning: 1 warning emitted + diff --git a/src/test/ui/impl-trait/nested-return-type3-tait.rs b/src/test/ui/impl-trait/nested-return-type3-tait.rs index 3936f4dbbb4..3a97e35b4c4 100644 --- a/src/test/ui/impl-trait/nested-return-type3-tait.rs +++ b/src/test/ui/impl-trait/nested-return-type3-tait.rs @@ -17,6 +17,7 @@ impl<F: Duh> Trait for F { type Sendable = impl Send; fn foo() -> impl Trait<Assoc = Sendable> { + //~^ WARN opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds 42 } diff --git a/src/test/ui/impl-trait/nested-return-type3-tait.stderr b/src/test/ui/impl-trait/nested-return-type3-tait.stderr new file mode 100644 index 00000000000..5f58c8dca4a --- /dev/null +++ b/src/test/ui/impl-trait/nested-return-type3-tait.stderr @@ -0,0 +1,17 @@ +warning: opaque type `impl Trait<Assoc = Sendable>` does not satisfy its associated type bounds + --> $DIR/nested-return-type3-tait.rs:19:24 + | +LL | type Assoc: Duh; + | --- this associated type bound is unsatisfied for `Sendable` +... +LL | fn foo() -> impl Trait<Assoc = Sendable> { + | ^^^^^^^^^^^^^^^^ + | + = note: `#[warn(opaque_hidden_inferred_bound)]` on by default +help: add this bound + | +LL | type Sendable = impl Send + Duh; + | +++++ + +warning: 1 warning emitted + diff --git a/src/test/ui/impl-trait/nested-return-type3-tait2.rs b/src/test/ui/impl-trait/nested-return-type3-tait2.rs index 56778ed90dc..5b6f78a9896 100644 --- a/src/test/ui/impl-trait/nested-return-type3-tait2.rs +++ b/src/test/ui/impl-trait/nested-return-type3-tait2.rs @@ -16,6 +16,7 @@ impl<F: Duh> Trait for F { type Sendable = impl Send; type Traitable = impl Trait<Assoc = Sendable>; +//~^ WARN opaque type `Traitable` does not satisfy its associated type bounds fn foo() -> Traitable { 42 diff --git a/src/test/ui/impl-trait/nested-return-type3-tait2.stderr b/src/test/ui/impl-trait/nested-return-type3-tait2.stderr new file mode 100644 index 00000000000..c07f6ead750 --- /dev/null +++ b/src/test/ui/impl-trait/nested-return-type3-tait2.stderr @@ -0,0 +1,17 @@ +warning: opaque type `Traitable` does not satisfy its associated type bounds + --> $DIR/nested-return-type3-tait2.rs:18:29 + | +LL | type Assoc: Duh; + | --- this associated type bound is unsatisfied for `Sendable` +... +LL | type Traitable = impl Trait<Assoc = Sendable>; + | ^^^^^^^^^^^^^^^^ + | + = note: `#[warn(opaque_hidden_inferred_bound)]` on by default +help: add this bound + | +LL | type Sendable = impl Send + Duh; + | +++++ + +warning: 1 warning emitted + diff --git a/src/test/ui/impl-trait/nested-return-type3-tait3.rs b/src/test/ui/impl-trait/nested-return-type3-tait3.rs index 04c6c92b1a3..394d8f58110 100644 --- a/src/test/ui/impl-trait/nested-return-type3-tait3.rs +++ b/src/test/ui/impl-trait/nested-return-type3-tait3.rs @@ -15,6 +15,7 @@ impl<F: Duh> Trait for F { } type Traitable = impl Trait<Assoc = impl Send>; +//~^ WARN opaque type `Traitable` does not satisfy its associated type bounds fn foo() -> Traitable { 42 diff --git a/src/test/ui/impl-trait/nested-return-type3-tait3.stderr b/src/test/ui/impl-trait/nested-return-type3-tait3.stderr new file mode 100644 index 00000000000..d98ad89222f --- /dev/null +++ b/src/test/ui/impl-trait/nested-return-type3-tait3.stderr @@ -0,0 +1,17 @@ +warning: opaque type `Traitable` does not satisfy its associated type bounds + --> $DIR/nested-return-type3-tait3.rs:17:29 + | +LL | type Assoc: Duh; + | --- this associated type bound is unsatisfied for `impl Send` +... +LL | type Traitable = impl Trait<Assoc = impl Send>; + | ^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(opaque_hidden_inferred_bound)]` on by default +help: add this bound + | +LL | type Traitable = impl Trait<Assoc = impl Send + Duh>; + | +++++ + +warning: 1 warning emitted + diff --git a/src/test/ui/impl-trait/nested-return-type3.rs b/src/test/ui/impl-trait/nested-return-type3.rs index 74b4dae22eb..5a764fc4c28 100644 --- a/src/test/ui/impl-trait/nested-return-type3.rs +++ b/src/test/ui/impl-trait/nested-return-type3.rs @@ -13,6 +13,7 @@ impl<F: Duh> Trait for F { } fn foo() -> impl Trait<Assoc = impl Send> { + //~^ WARN opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds 42 } diff --git a/src/test/ui/impl-trait/nested-return-type3.stderr b/src/test/ui/impl-trait/nested-return-type3.stderr new file mode 100644 index 00000000000..632de71aa4c --- /dev/null +++ b/src/test/ui/impl-trait/nested-return-type3.stderr @@ -0,0 +1,17 @@ +warning: opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds + --> $DIR/nested-return-type3.rs:15:24 + | +LL | type Assoc: Duh; + | --- this associated type bound is unsatisfied for `impl Send` +... +LL | fn foo() -> impl Trait<Assoc = impl Send> { + | ^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(opaque_hidden_inferred_bound)]` on by default +help: add this bound + | +LL | fn foo() -> impl Trait<Assoc = impl Send + Duh> { + | +++++ + +warning: 1 warning emitted + diff --git a/src/test/ui/impl-trait/where-allowed.stderr b/src/test/ui/impl-trait/where-allowed.stderr index 9b346387d61..2e7c7ca40dd 100644 --- a/src/test/ui/impl-trait/where-allowed.stderr +++ b/src/test/ui/impl-trait/where-allowed.stderr @@ -301,9 +301,9 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type` LL | impl <T = impl Debug> T {} | ^^^^^^^^^^^^^^ | - = note: `#[deny(invalid_type_param_default)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887> + = note: `#[deny(invalid_type_param_default)]` on by default error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions --> $DIR/where-allowed.rs:241:36 diff --git a/src/test/ui/imports/local-modularized-tricky-fail-2.stderr b/src/test/ui/imports/local-modularized-tricky-fail-2.stderr index 3c20f552fdf..2c1965ac0a4 100644 --- a/src/test/ui/imports/local-modularized-tricky-fail-2.stderr +++ b/src/test/ui/imports/local-modularized-tricky-fail-2.stderr @@ -4,7 +4,6 @@ error: macro-expanded `macro_export` macros from the current crate cannot be ref LL | use exported; | ^^^^^^^^ | - = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #52234 <https://github.com/rust-lang/rust/issues/52234> note: the macro is defined here @@ -17,6 +16,7 @@ LL | | } ... LL | define_exported!(); | ------------------ in this macro invocation + = note: `#[deny(macro_expanded_macro_exports_accessed_by_absolute_paths)]` on by default = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info) error: macro-expanded `macro_export` macros from the current crate cannot be referred to by absolute paths diff --git a/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr b/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr index c38f57912ad..3dea09e7f52 100644 --- a/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr +++ b/src/test/ui/inference/inference-variable-behind-raw-pointer.stderr @@ -4,9 +4,9 @@ warning: type annotations needed LL | if data.is_null() {} | ^^^^^^^ | - = note: `#[warn(tyvar_behind_raw_pointer)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #46906 <https://github.com/rust-lang/rust/issues/46906> + = note: `#[warn(tyvar_behind_raw_pointer)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/inference/inference_unstable.stderr b/src/test/ui/inference/inference_unstable.stderr index df7a09686bf..ecbf2641bec 100644 --- a/src/test/ui/inference/inference_unstable.stderr +++ b/src/test/ui/inference/inference_unstable.stderr @@ -4,11 +4,11 @@ warning: an associated function with this name may be added to the standard libr LL | assert_eq!('x'.ipu_flatten(), 1); | ^^^^^^^^^^^ | - = note: `#[warn(unstable_name_collisions)]` on by default = warning: once this associated item is added to the standard library, the ambiguity may cause an error or change in behavior! = note: for more information, see issue #48919 <https://github.com/rust-lang/rust/issues/48919> = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_flatten(...)` to keep using the current method = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten` + = note: `#[warn(unstable_name_collisions)]` on by default warning: an associated function with this name may be added to the standard library in the future --> $DIR/inference_unstable.rs:19:20 diff --git a/src/test/ui/inference/need_type_info/concrete-impl.stderr b/src/test/ui/inference/need_type_info/concrete-impl.stderr index b79d34affa2..aa32969950d 100644 --- a/src/test/ui/inference/need_type_info/concrete-impl.stderr +++ b/src/test/ui/inference/need_type_info/concrete-impl.stderr @@ -3,11 +3,6 @@ error[E0282]: type annotations needed | LL | <Struct as Ambiguous<_>>::method(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `Self` declared on the trait `Ambiguous` - | -help: consider specifying the generic argument - | -LL | <Struct as Ambiguous::<_>>::method(); - | ~~~~~ error[E0283]: type annotations needed --> $DIR/concrete-impl.rs:13:5 @@ -22,10 +17,6 @@ LL | impl Ambiguous<One> for Struct {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ LL | impl Ambiguous<Two> for Struct {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: consider specifying the generic argument - | -LL | <Struct as Ambiguous::<_>>::method(); - | ~~~~~ error: aborting due to 2 previous errors diff --git a/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs new file mode 100644 index 00000000000..3084f6eac67 --- /dev/null +++ b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.rs @@ -0,0 +1,11 @@ +enum OhNo<T, U> { + A(T), + B(U), + C, +} + +fn uwu() { + OhNo::C::<u32, _>; //~ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr new file mode 100644 index 00000000000..2ad35ab039f --- /dev/null +++ b/src/test/ui/inference/need_type_info/do-not-suggest-generic-arguments-for-turbofish.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/do-not-suggest-generic-arguments-for-turbofish.rs:8:5 + | +LL | OhNo::C::<u32, _>; + | ^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the enum `OhNo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/intrinsics/intrinsic-alignment.rs b/src/test/ui/intrinsics/intrinsic-alignment.rs index 6007eba8c09..c8b1ff1dbce 100644 --- a/src/test/ui/intrinsics/intrinsic-alignment.rs +++ b/src/test/ui/intrinsics/intrinsic-alignment.rs @@ -6,6 +6,7 @@ mod rusti { extern "rust-intrinsic" { pub fn pref_align_of<T>() -> usize; + #[rustc_safe_intrinsic] pub fn min_align_of<T>() -> usize; } } diff --git a/src/test/ui/intrinsics/intrinsics-integer.rs b/src/test/ui/intrinsics/intrinsics-integer.rs index bac6c8d872b..88bf42b685f 100644 --- a/src/test/ui/intrinsics/intrinsics-integer.rs +++ b/src/test/ui/intrinsics/intrinsics-integer.rs @@ -1,15 +1,21 @@ // run-pass #![feature(intrinsics)] +#![feature(rustc_attrs)] mod rusti { extern "rust-intrinsic" { + #[rustc_safe_intrinsic] pub fn ctpop<T>(x: T) -> T; + #[rustc_safe_intrinsic] pub fn ctlz<T>(x: T) -> T; pub fn ctlz_nonzero<T>(x: T) -> T; + #[rustc_safe_intrinsic] pub fn cttz<T>(x: T) -> T; pub fn cttz_nonzero<T>(x: T) -> T; + #[rustc_safe_intrinsic] pub fn bswap<T>(x: T) -> T; + #[rustc_safe_intrinsic] pub fn bitreverse<T>(x: T) -> T; } } diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs index 4aa869cca35..ae44ffd29bd 100644 --- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs +++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -34,6 +34,12 @@ enum OneVariant_NonZero { DeadVariant(Bar), } +#[allow(dead_code, non_camel_case_types)] +enum OneVariant_Ref { + Variant(&'static i32), + DeadVariant(Bar), +} + // An `Aggregate` abi enum where 0 is not a valid discriminant. #[allow(dead_code)] #[repr(i32)] @@ -63,6 +69,7 @@ enum ZeroIsValid { One(NonNull<()>) = 1, } +#[track_caller] fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) { let err = panic::catch_unwind(op).err(); assert_eq!( @@ -71,6 +78,15 @@ fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) { ); } +#[track_caller] +fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) { + let err = panic::catch_unwind(op).err(); + assert_eq!( + err.as_ref().and_then(|a| a.downcast_ref::<&str>()), + if cfg!(strict) { Some(&msg) } else { None }, + ); +} + fn main() { unsafe { // Uninhabited types @@ -139,92 +155,216 @@ fn main() { "attempted to instantiate uninhabited type `[Bar; 2]`" ); - // Types that do not like zero-initialziation + // Types that don't allow either. test_panic_msg( - || mem::uninitialized::<fn()>(), - "attempted to leave type `fn()` uninitialized, which is invalid" + || mem::zeroed::<&i32>(), + "attempted to zero-initialize type `&i32`, which is invalid" ); test_panic_msg( - || mem::zeroed::<fn()>(), - "attempted to zero-initialize type `fn()`, which is invalid" + || mem::uninitialized::<&i32>(), + "attempted to leave type `&i32` uninitialized, which is invalid" ); test_panic_msg( - || mem::uninitialized::<*const dyn Send>(), - "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid" + || mem::zeroed::<Box<[i32; 0]>>(), + "attempted to zero-initialize type `alloc::boxed::Box<[i32; 0]>`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<Box<[i32; 0]>>(), + "attempted to leave type `alloc::boxed::Box<[i32; 0]>` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<Box<u8>>(), + "attempted to zero-initialize type `alloc::boxed::Box<u8>`, which is invalid" ); test_panic_msg( + || mem::uninitialized::<Box<u8>>(), + "attempted to leave type `alloc::boxed::Box<u8>` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&[i32]>(), + "attempted to zero-initialize type `&[i32]`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<&[i32]>(), + "attempted to leave type `&[i32]` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&(u8, [u8])>(), + "attempted to zero-initialize type `&(u8, [u8])`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<&(u8, [u8])>(), + "attempted to leave type `&(u8, [u8])` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&dyn Send>(), + "attempted to zero-initialize type `&dyn core::marker::Send`, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<&dyn Send>(), + "attempted to leave type `&dyn core::marker::Send` uninitialized, which is invalid" + ); + + test_panic_msg( || mem::zeroed::<*const dyn Send>(), "attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid" ); + test_panic_msg( + || mem::uninitialized::<*const dyn Send>(), + "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid" + ); test_panic_msg( - || mem::uninitialized::<(NonNull<u32>, u32, u32)>(), - "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, \ + || mem::uninitialized::<NoNullVariant>(), + "attempted to leave type `NoNullVariant` uninitialized, \ + which is invalid" + ); + test_panic_msg( + || mem::zeroed::<NoNullVariant>(), + "attempted to zero-initialize type `NoNullVariant`, \ which is invalid" ); test_panic_msg( - || mem::zeroed::<(NonNull<u32>, u32, u32)>(), - "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \ + || mem::zeroed::<OneVariant_Ref>(), + "attempted to zero-initialize type `OneVariant_Ref`, \ which is invalid" ); + test_panic_msg( + || mem::uninitialized::<OneVariant_Ref>(), + "attempted to leave type `OneVariant_Ref` uninitialized, which is invalid" + ); + // Types where both are invalid, but we allow uninit since the 0x01-filling is not LLVM UB. test_panic_msg( - || mem::uninitialized::<OneVariant_NonZero>(), - "attempted to leave type `OneVariant_NonZero` uninitialized, \ + || mem::zeroed::<fn()>(), + "attempted to zero-initialize type `fn()`, which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<fn()>(), + "attempted to leave type `fn()` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&()>(), + "attempted to zero-initialize type `&()`, which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<&()>(), + "attempted to leave type `&()` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&[u8]>(), + "attempted to zero-initialize type `&[u8]`, which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<&[u8]>(), + "attempted to leave type `&[u8]` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<&str>(), + "attempted to zero-initialize type `&str`, which is invalid" + ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<&str>(), + "attempted to leave type `&str` uninitialized, which is invalid" + ); + + test_panic_msg( + || mem::zeroed::<(NonNull<u32>, u32, u32)>(), + "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \ which is invalid" ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<(NonNull<u32>, u32, u32)>(), + "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, which is invalid" + ); + test_panic_msg( || mem::zeroed::<OneVariant_NonZero>(), "attempted to zero-initialize type `OneVariant_NonZero`, \ which is invalid" ); + test_panic_msg_only_if_strict( + || mem::uninitialized::<OneVariant_NonZero>(), + "attempted to leave type `OneVariant_NonZero` uninitialized, which is invalid" + ); + // Types where both are invalid but we allow the zeroed form since it is not LLVM UB. + test_panic_msg_only_if_strict( + || mem::zeroed::<LR_NonZero>(), + "attempted to zero-initialize type `LR_NonZero`, which is invalid" + ); test_panic_msg( || mem::uninitialized::<LR_NonZero>(), "attempted to leave type `LR_NonZero` uninitialized, which is invalid" ); + test_panic_msg_only_if_strict( + || mem::zeroed::<ManuallyDrop<LR_NonZero>>(), + "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \ + which is invalid" + ); test_panic_msg( || mem::uninitialized::<ManuallyDrop<LR_NonZero>>(), "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>` uninitialized, \ which is invalid" ); - test_panic_msg( - || mem::uninitialized::<NoNullVariant>(), - "attempted to leave type `NoNullVariant` uninitialized, \ - which is invalid" + // Some strict-only things + test_panic_msg_only_if_strict( + || mem::uninitialized::<i32>(), + "attempted to leave type `i32` uninitialized, which is invalid" ); - test_panic_msg( - || mem::zeroed::<NoNullVariant>(), - "attempted to zero-initialize type `NoNullVariant`, \ - which is invalid" + test_panic_msg_only_if_strict( + || mem::uninitialized::<*const ()>(), + "attempted to leave type `*const ()` uninitialized, which is invalid" ); - // Types that can be zero, but not uninit. - test_panic_msg( - || mem::uninitialized::<bool>(), - "attempted to leave type `bool` uninitialized, which is invalid" + test_panic_msg_only_if_strict( + || mem::uninitialized::<[i32; 1]>(), + "attempted to leave type `[i32; 1]` uninitialized, which is invalid" ); + test_panic_msg_only_if_strict( + || mem::zeroed::<[NonNull<()>; 1]>(), + "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid" + ); + + // Types that can be zero, but not uninit (though some are mitigated). + let _val = mem::zeroed::<LR>(); test_panic_msg( || mem::uninitialized::<LR>(), "attempted to leave type `LR` uninitialized, which is invalid" ); + let _val = mem::zeroed::<ManuallyDrop<LR>>(); test_panic_msg( || mem::uninitialized::<ManuallyDrop<LR>>(), "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid" ); - // Some things that should work. let _val = mem::zeroed::<bool>(); - let _val = mem::zeroed::<LR>(); - let _val = mem::zeroed::<ManuallyDrop<LR>>(); + test_panic_msg_only_if_strict( + || mem::uninitialized::<bool>(), + "attempted to leave type `bool` uninitialized, which is invalid" + ); + let _val = mem::zeroed::<OneVariant>(); + test_panic_msg_only_if_strict( + || mem::uninitialized::<OneVariant>(), + "attempted to leave type `OneVariant` uninitialized, which is invalid" + ); + + // Some things that are actually allowed. let _val = mem::zeroed::<Option<&'static i32>>(); let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>(); let _val = mem::zeroed::<[!; 0]>(); @@ -233,59 +373,5 @@ fn main() { let _val = mem::uninitialized::<[!; 0]>(); let _val = mem::uninitialized::<()>(); let _val = mem::uninitialized::<ZeroSized>(); - - if cfg!(strict) { - test_panic_msg( - || mem::uninitialized::<i32>(), - "attempted to leave type `i32` uninitialized, which is invalid" - ); - - test_panic_msg( - || mem::uninitialized::<*const ()>(), - "attempted to leave type `*const ()` uninitialized, which is invalid" - ); - - test_panic_msg( - || mem::uninitialized::<[i32; 1]>(), - "attempted to leave type `[i32; 1]` uninitialized, which is invalid" - ); - - test_panic_msg( - || mem::zeroed::<NonNull<()>>(), - "attempted to zero-initialize type `core::ptr::non_null::NonNull<()>`, which is invalid" - ); - - test_panic_msg( - || mem::zeroed::<[NonNull<()>; 1]>(), - "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid" - ); - - // FIXME(#66151) we conservatively do not error here yet (by default). - test_panic_msg( - || mem::zeroed::<LR_NonZero>(), - "attempted to zero-initialize type `LR_NonZero`, which is invalid" - ); - - test_panic_msg( - || mem::zeroed::<ManuallyDrop<LR_NonZero>>(), - "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \ - which is invalid" - ); - } else { - // These are UB because they have not been officially blessed, but we await the resolution - // of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing - // anything about that. - let _val = mem::uninitialized::<i32>(); - let _val = mem::uninitialized::<*const ()>(); - - // These are UB, but best to test them to ensure we don't become unintentionally - // stricter. - - // It's currently unchecked to create invalid enums and values inside arrays. - let _val = mem::zeroed::<LR_NonZero>(); - let _val = mem::zeroed::<[LR_NonZero; 1]>(); - let _val = mem::zeroed::<[NonNull<()>; 1]>(); - let _val = mem::uninitialized::<[NonNull<()>; 1]>(); - } } } diff --git a/src/test/ui/intrinsics/safe-intrinsic-mismatch.rs b/src/test/ui/intrinsics/safe-intrinsic-mismatch.rs new file mode 100644 index 00000000000..50e12eaeb5c --- /dev/null +++ b/src/test/ui/intrinsics/safe-intrinsic-mismatch.rs @@ -0,0 +1,11 @@ +#![feature(intrinsics)] +#![feature(rustc_attrs)] + +extern "rust-intrinsic" { + fn size_of<T>() -> usize; //~ ERROR intrinsic safety mismatch + + #[rustc_safe_intrinsic] + fn assume(b: bool); //~ ERROR intrinsic safety mismatch +} + +fn main() {} diff --git a/src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr b/src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr new file mode 100644 index 00000000000..0c2f3be491d --- /dev/null +++ b/src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr @@ -0,0 +1,14 @@ +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of` + --> $DIR/safe-intrinsic-mismatch.rs:5:5 + | +LL | fn size_of<T>() -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume` + --> $DIR/safe-intrinsic-mismatch.rs:8:5 + | +LL | fn assume(b: bool); + | ^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/issues/issue-11958.stderr b/src/test/ui/issues/issue-11958.stderr index 25de6ff4c11..5dca4c2f01d 100644 --- a/src/test/ui/issues/issue-11958.stderr +++ b/src/test/ui/issues/issue-11958.stderr @@ -4,8 +4,8 @@ warning: value assigned to `x` is never read LL | let _thunk = Box::new(move|| { x = 2; }); | ^ | - = note: `#[warn(unused_assignments)]` on by default = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` on by default warning: unused variable: `x` --> $DIR/issue-11958.rs:8:36 @@ -13,8 +13,8 @@ warning: unused variable: `x` LL | let _thunk = Box::new(move|| { x = 2; }); | ^ | - = note: `#[warn(unused_variables)]` on by default = help: did you mean to capture by reference instead? + = note: `#[warn(unused_variables)]` on by default warning: 2 warnings emitted diff --git a/src/test/ui/issues/issue-1460.stderr b/src/test/ui/issues/issue-1460.stderr index 26f95f5af3d..f0ff2cafd44 100644 --- a/src/test/ui/issues/issue-1460.stderr +++ b/src/test/ui/issues/issue-1460.stderr @@ -4,8 +4,8 @@ warning: unused closure that must be used LL | {|i: u32| if 1 == i { }}; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unused_must_use)]` on by default = note: closures are lazy and do nothing unless called + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/issues/issue-16250.stderr b/src/test/ui/issues/issue-16250.stderr index ae3b7f334c6..5eb5e0864ad 100644 --- a/src/test/ui/issues/issue-16250.stderr +++ b/src/test/ui/issues/issue-16250.stderr @@ -4,12 +4,6 @@ error: `extern` block uses type `Foo`, which is not FFI-safe LL | pub fn foo(x: (Foo)); | ^^^ not FFI-safe | -note: the lint level is defined here - --> $DIR/issue-16250.rs:1:9 - | -LL | #![deny(warnings)] - | ^^^^^^^^ - = note: `#[deny(improper_ctypes)]` implied by `#[deny(warnings)]` = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout note: the type is defined here @@ -17,6 +11,12 @@ note: the type is defined here | LL | pub struct Foo; | ^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/issue-16250.rs:1:9 + | +LL | #![deny(warnings)] + | ^^^^^^^^ + = note: `#[deny(improper_ctypes)]` implied by `#[deny(warnings)]` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-16256.stderr b/src/test/ui/issues/issue-16256.stderr index 9c7312461c4..ca8e9a1bed3 100644 --- a/src/test/ui/issues/issue-16256.stderr +++ b/src/test/ui/issues/issue-16256.stderr @@ -4,8 +4,8 @@ warning: unused closure that must be used LL | |c: u8| buf.push(c); | ^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unused_must_use)]` on by default = note: closures are lazy and do nothing unless called + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/issues/issue-24013.stderr b/src/test/ui/issues/issue-24013.stderr index 995dce552e3..72102f460e0 100644 --- a/src/test/ui/issues/issue-24013.stderr +++ b/src/test/ui/issues/issue-24013.stderr @@ -3,11 +3,6 @@ error[E0282]: type annotations needed | LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; | ^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `swap` - | -help: consider specifying the generic argument - | -LL | unsafe {swap::<&mut _>(transmute(&a), transmute(&b))}; - | ~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index 85a8698afc5..f398a5da3e9 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | ^^^^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8); diff --git a/src/test/ui/issues/issue-47094.stderr b/src/test/ui/issues/issue-47094.stderr index e323ce66029..970e3184710 100644 --- a/src/test/ui/issues/issue-47094.stderr +++ b/src/test/ui/issues/issue-47094.stderr @@ -4,9 +4,9 @@ error[E0566]: conflicting representation hints LL | #[repr(C, u8)] | ^ ^^ | - = note: `#[deny(conflicting_repr_hints)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/68585> + = note: `#[deny(conflicting_repr_hints)]` on by default error[E0566]: conflicting representation hints --> $DIR/issue-47094.rs:8:8 diff --git a/src/test/ui/issues/issue-47486.stderr b/src/test/ui/issues/issue-47486.stderr index b45f57b7b84..2bd24f08c1e 100644 --- a/src/test/ui/issues/issue-47486.stderr +++ b/src/test/ui/issues/issue-47486.stderr @@ -9,11 +9,6 @@ error[E0282]: type annotations needed | LL | [0u8; std::mem::size_of::<_>()]; | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `size_of` - | -help: consider specifying the generic argument - | -LL | [0u8; std::mem::size_of::<_>()]; - | ~~~~~ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-47725.stderr b/src/test/ui/issues/issue-47725.stderr index c7a9bfe317f..7143fb4d6e1 100644 --- a/src/test/ui/issues/issue-47725.stderr +++ b/src/test/ui/issues/issue-47725.stderr @@ -13,12 +13,12 @@ LL | #[link_name = "foo"] LL | struct Foo; | ----------- not a foreign function or static | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! note: the lint level is defined here --> $DIR/issue-47725.rs:1:9 | LL | #![warn(unused_attributes)] | ^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! warning: attribute should be applied to a foreign function or static --> $DIR/issue-47725.rs:8:1 diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr index 93bd951d3fa..e185ecdda23 100644 --- a/src/test/ui/issues/issue-50781.stderr +++ b/src/test/ui/issues/issue-50781.stderr @@ -4,11 +4,6 @@ error: the trait `X` cannot be made into an object LL | fn foo(&self) where Self: Trait; | ^^^ | -note: the lint level is defined here - --> $DIR/issue-50781.rs:1:9 - | -LL | #![deny(where_clauses_object_safety)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #51443 <https://github.com/rust-lang/rust/issues/51443> note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety> @@ -19,6 +14,11 @@ LL | trait X { LL | fn foo(&self) where Self: Trait; | ^^^ ...because method `foo` references the `Self` type in its `where` clause = help: consider moving `foo` to another trait +note: the lint level is defined here + --> $DIR/issue-50781.rs:1:9 + | +LL | #![deny(where_clauses_object_safety)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-54044.stderr b/src/test/ui/issues/issue-54044.stderr index 100965de1aa..8bd94a041d0 100644 --- a/src/test/ui/issues/issue-54044.stderr +++ b/src/test/ui/issues/issue-54044.stderr @@ -7,12 +7,12 @@ LL | #[cold] LL | struct Foo; | ----------- not a function definition | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! note: the lint level is defined here --> $DIR/issue-54044.rs:1:9 | LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error: attribute should be applied to a function definition --> $DIR/issue-54044.rs:9:5 diff --git a/src/test/ui/issues/issue-55380.stderr b/src/test/ui/issues/issue-55380.stderr index 65e94d79670..403844c726f 100644 --- a/src/test/ui/issues/issue-55380.stderr +++ b/src/test/ui/issues/issue-55380.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/issues/issue-58734.stderr b/src/test/ui/issues/issue-58734.stderr index a91a1b3778e..d2314626d3e 100644 --- a/src/test/ui/issues/issue-58734.stderr +++ b/src/test/ui/issues/issue-58734.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | Trait::nonexistent(()); | ^^^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | <dyn Trait>::nonexistent(()); diff --git a/src/test/ui/issues/issue-60622.stderr b/src/test/ui/issues/issue-60622.stderr index b305cc78535..ecf1ae758dd 100644 --- a/src/test/ui/issues/issue-60622.stderr +++ b/src/test/ui/issues/issue-60622.stderr @@ -7,14 +7,14 @@ LL | fn a(&self) {} LL | b.a::<'_, T>(); | ^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> note: the lint level is defined here --> $DIR/issue-60622.rs:1:9 | LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(late_bound_lifetime_arguments)]` implied by `#[deny(warnings)]` - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-60622.rs:10:7 diff --git a/src/test/ui/issues/issue-6458-4.stderr b/src/test/ui/issues/issue-6458-4.stderr index d6e74d10e03..168ececac31 100644 --- a/src/test/ui/issues/issue-6458-4.stderr +++ b/src/test/ui/issues/issue-6458-4.stderr @@ -6,7 +6,7 @@ LL | fn foo(b: bool) -> Result<bool,String> { | | | implicitly returns `()` as its body has no tail or `return` expression LL | Err("bar".to_string()); - | - help: remove this semicolon + | - help: remove this semicolon to return this value | = note: expected enum `Result<bool, String>` found unit type `()` diff --git a/src/test/ui/issues/issue-72278.stderr b/src/test/ui/issues/issue-72278.stderr index 41dff686bc4..5468837a305 100644 --- a/src/test/ui/issues/issue-72278.stderr +++ b/src/test/ui/issues/issue-72278.stderr @@ -7,9 +7,9 @@ LL | fn func<'a, U>(&'a self) -> U { LL | S.func::<'a, U>() | ^^ | - = note: `#[warn(late_bound_lifetime_arguments)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> + = note: `#[warn(late_bound_lifetime_arguments)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/issues/issue-78957.stderr b/src/test/ui/issues/issue-78957.stderr index 45fa69d6fd7..6de22d6bf79 100644 --- a/src/test/ui/issues/issue-78957.stderr +++ b/src/test/ui/issues/issue-78957.stderr @@ -10,12 +10,12 @@ error: attribute should be applied to a function definition LL | pub struct Bar<#[cold] const N: usize>; | ^^^^^^^ -------------- not a function definition | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! note: the lint level is defined here --> $DIR/issue-78957.rs:1:9 | LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! error[E0517]: attribute should be applied to a struct, enum, or union --> $DIR/issue-78957.rs:10:23 diff --git a/src/test/ui/issues/issue-86756.stderr b/src/test/ui/issues/issue-86756.stderr index b26c1834d84..693cfecedc4 100644 --- a/src/test/ui/issues/issue-86756.stderr +++ b/src/test/ui/issues/issue-86756.stderr @@ -20,9 +20,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | eq::<dyn, Foo> | ^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | eq::<dyn, dyn Foo> diff --git a/src/test/ui/issues/issue-8727.stderr b/src/test/ui/issues/issue-8727.stderr index 10daba5ef3d..5e1fdad60cb 100644 --- a/src/test/ui/issues/issue-8727.stderr +++ b/src/test/ui/issues/issue-8727.stderr @@ -6,8 +6,8 @@ LL | fn generic<T>() { LL | generic::<Option<T>>(); | ---------------------- recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default error: reached the recursion limit while instantiating `generic::<Option<Option<Option<O...>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` --> $DIR/issue-8727.rs:8:5 diff --git a/src/test/ui/iterators/into-iter-on-arrays-2018.stderr b/src/test/ui/iterators/into-iter-on-arrays-2018.stderr index 9b312505837..2378476e5d0 100644 --- a/src/test/ui/iterators/into-iter-on-arrays-2018.stderr +++ b/src/test/ui/iterators/into-iter-on-arrays-2018.stderr @@ -4,9 +4,9 @@ warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (du LL | let _: Iter<'_, i32> = array.into_iter(); | ^^^^^^^^^ | - = note: `#[warn(array_into_iter)]` on by default = warning: this changes meaning in Rust 2021 = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html> + = note: `#[warn(array_into_iter)]` on by default help: use `.iter()` instead of `.into_iter()` to avoid ambiguity | LL | let _: Iter<'_, i32> = array.iter(); diff --git a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr index e32d35d8638..2fde276faa3 100644 --- a/src/test/ui/iterators/into-iter-on-arrays-lint.stderr +++ b/src/test/ui/iterators/into-iter-on-arrays-lint.stderr @@ -4,9 +4,9 @@ warning: this method call resolves to `<&[T; N] as IntoIterator>::into_iter` (du LL | small.into_iter(); | ^^^^^^^^^ | - = note: `#[warn(array_into_iter)]` on by default = warning: this changes meaning in Rust 2021 = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html> + = note: `#[warn(array_into_iter)]` on by default help: use `.iter()` instead of `.into_iter()` to avoid ambiguity | LL | small.iter(); diff --git a/src/test/ui/lang-items/issue-83471.stderr b/src/test/ui/lang-items/issue-83471.stderr index 6d796fe7f50..fc9ab293f99 100644 --- a/src/test/ui/lang-items/issue-83471.stderr +++ b/src/test/ui/lang-items/issue-83471.stderr @@ -32,9 +32,9 @@ warning: anonymous parameters are deprecated and will be removed in the next edi LL | fn call(export_name); | ^^^^^^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: export_name` | - = note: `#[warn(anonymous_parameters)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686> + = note: `#[warn(anonymous_parameters)]` on by default error[E0718]: `fn` language item must be applied to a trait with 1 generic argument --> $DIR/issue-83471.rs:11:1 diff --git a/src/test/ui/let-else/let-else-irrefutable.stderr b/src/test/ui/let-else/let-else-irrefutable.stderr index e030c50d45d..e0581f4d9ab 100644 --- a/src/test/ui/let-else/let-else-irrefutable.stderr +++ b/src/test/ui/let-else/let-else-irrefutable.stderr @@ -4,9 +4,9 @@ warning: irrefutable `let...else` pattern LL | let x = 1 else { return }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(irrefutable_let_patterns)]` on by default = note: this pattern will always match, so the `else` clause is useless = help: consider removing the `else` clause + = note: `#[warn(irrefutable_let_patterns)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/limits/issue-55878.stderr b/src/test/ui/limits/issue-55878.stderr index 6c3683d7896..4f165b1d9fe 100644 --- a/src/test/ui/limits/issue-55878.stderr +++ b/src/test/ui/limits/issue-55878.stderr @@ -15,9 +15,9 @@ error: erroneous constant used LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors @@ -30,8 +30,8 @@ error: erroneous constant used LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/linkage-attr/link-attr-validation-early.stderr b/src/test/ui/linkage-attr/link-attr-validation-early.stderr index 903141e439d..24ad9d825f8 100644 --- a/src/test/ui/linkage-attr/link-attr-validation-early.stderr +++ b/src/test/ui/linkage-attr/link-attr-validation-early.stderr @@ -4,9 +4,9 @@ error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib LL | #[link] | ^^^^^^^ | - = note: `#[deny(ill_formed_attribute_input)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default error: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated")]` --> $DIR/link-attr-validation-early.rs:4:1 diff --git a/src/test/ui/lint/auxiliary/trivial-cast-ice.rs b/src/test/ui/lint/auxiliary/trivial-cast-ice.rs new file mode 100644 index 00000000000..ab2332d0656 --- /dev/null +++ b/src/test/ui/lint/auxiliary/trivial-cast-ice.rs @@ -0,0 +1,7 @@ +#[macro_export] +macro_rules! foo { + () => { + let x: &Option<i32> = &Some(1); + let _y = x as *const Option<i32>; + } +} diff --git a/src/test/ui/lint/bare-trait-objects-path.stderr b/src/test/ui/lint/bare-trait-objects-path.stderr index 4b8c2b539d5..8ed303ca606 100644 --- a/src/test/ui/lint/bare-trait-objects-path.stderr +++ b/src/test/ui/lint/bare-trait-objects-path.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | let _: Dyn::Ty; | ^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | let _: <dyn Dyn>::Ty; diff --git a/src/test/ui/lint/clashing-extern-fn.stderr b/src/test/ui/lint/clashing-extern-fn.stderr index 4607f684993..217eed6c92c 100644 --- a/src/test/ui/lint/clashing-extern-fn.stderr +++ b/src/test/ui/lint/clashing-extern-fn.stderr @@ -7,13 +7,13 @@ LL | fn clash(x: u8); LL | fn clash(x: u64); | ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | + = note: expected `unsafe extern "C" fn(u8)` + found `unsafe extern "C" fn(u64)` note: the lint level is defined here --> $DIR/clashing-extern-fn.rs:4:9 | LL | #![warn(clashing_extern_declarations)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `unsafe extern "C" fn(u8)` - found `unsafe extern "C" fn(u64)` warning: `extern_link_name` redeclared with a different signature --> $DIR/clashing-extern-fn.rs:52:9 @@ -219,9 +219,9 @@ warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI LL | fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | - = note: `#[warn(improper_ctypes)]` on by default = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint + = note: `#[warn(improper_ctypes)]` on by default warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe --> $DIR/clashing-extern-fn.rs:412:46 diff --git a/src/test/ui/lint/cli-lint-override.forbid_warn.stderr b/src/test/ui/lint/cli-lint-override.forbid_warn.stderr index ff4dc4abc74..d1c66a81cd8 100644 --- a/src/test/ui/lint/cli-lint-override.forbid_warn.stderr +++ b/src/test/ui/lint/cli-lint-override.forbid_warn.stderr @@ -4,8 +4,8 @@ error: extern declarations without an explicit ABI are deprecated LL | extern fn foo() {} | ^^^^^^^^^^^^^^^ ABI should be specified here | - = note: requested on the command line with `-F missing-abi` = help: the default ABI is C + = note: requested on the command line with `-F missing-abi` error: aborting due to previous error diff --git a/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr b/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr index 74e7823e1ff..779c24c93f2 100644 --- a/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr +++ b/src/test/ui/lint/cli-lint-override.force_warn_deny.stderr @@ -4,8 +4,8 @@ warning: extern declarations without an explicit ABI are deprecated LL | extern fn foo() {} | ^^^^^^^^^^^^^^^ ABI should be specified here | - = note: requested on the command line with `--force-warn missing-abi` = help: the default ABI is C + = note: requested on the command line with `--force-warn missing-abi` warning: 1 warning emitted diff --git a/src/test/ui/lint/cli-lint-override.warn_deny.stderr b/src/test/ui/lint/cli-lint-override.warn_deny.stderr index 2d869adfd37..f034cfa9338 100644 --- a/src/test/ui/lint/cli-lint-override.warn_deny.stderr +++ b/src/test/ui/lint/cli-lint-override.warn_deny.stderr @@ -4,8 +4,8 @@ error: extern declarations without an explicit ABI are deprecated LL | extern fn foo() {} | ^^^^^^^^^^^^^^^ ABI should be specified here | - = note: requested on the command line with `-D missing-abi` = help: the default ABI is C + = note: requested on the command line with `-D missing-abi` error: aborting due to previous error diff --git a/src/test/ui/lint/dead-code/issue-85071-2.stderr b/src/test/ui/lint/dead-code/issue-85071-2.stderr index 86fbd1d75e8..5e963183d09 100644 --- a/src/test/ui/lint/dead-code/issue-85071-2.stderr +++ b/src/test/ui/lint/dead-code/issue-85071-2.stderr @@ -7,16 +7,16 @@ LL | LL | let _y = x; | ^^ unreachable definition | -note: the lint level is defined here - --> $DIR/issue-85071-2.rs:7:26 - | -LL | #![warn(unused_variables,unreachable_code)] - | ^^^^^^^^^^^^^^^^ note: this expression has type `Foo`, which is uninhabited --> $DIR/issue-85071-2.rs:18:13 | LL | let x = s.f(); | ^^^^^ +note: the lint level is defined here + --> $DIR/issue-85071-2.rs:7:26 + | +LL | #![warn(unused_variables,unreachable_code)] + | ^^^^^^^^^^^^^^^^ warning: unused variable: `x` --> $DIR/issue-85071-2.rs:18:9 diff --git a/src/test/ui/lint/dead-code/issue-85071.stderr b/src/test/ui/lint/dead-code/issue-85071.stderr index 49555fdaa35..721fb8148d9 100644 --- a/src/test/ui/lint/dead-code/issue-85071.stderr +++ b/src/test/ui/lint/dead-code/issue-85071.stderr @@ -7,16 +7,16 @@ LL | LL | let _ = x; | ^ unreachable expression | -note: the lint level is defined here - --> $DIR/issue-85071.rs:9:26 - | -LL | #![warn(unused_variables,unreachable_code)] - | ^^^^^^^^^^^^^^^^ note: this expression has type `Foo`, which is uninhabited --> $DIR/issue-85071.rs:15:13 | LL | let x = f(); | ^^^ +note: the lint level is defined here + --> $DIR/issue-85071.rs:9:26 + | +LL | #![warn(unused_variables,unreachable_code)] + | ^^^^^^^^^^^^^^^^ warning: unused variable: `x` --> $DIR/issue-85071.rs:15:9 diff --git a/src/test/ui/lint/dead-code/unused-variant.stderr b/src/test/ui/lint/dead-code/unused-variant.stderr index a68f64775ad..6029bf26856 100644 --- a/src/test/ui/lint/dead-code/unused-variant.stderr +++ b/src/test/ui/lint/dead-code/unused-variant.stderr @@ -6,12 +6,12 @@ LL | enum Enum { LL | Variant1, | ^^^^^^^^ | + = note: `Enum` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis note: the lint level is defined here --> $DIR/unused-variant.rs:1:9 | LL | #![deny(dead_code)] | ^^^^^^^^^ - = note: `Enum` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis error: aborting due to previous error diff --git a/src/test/ui/lint/deny-overflowing-literals.stderr b/src/test/ui/lint/deny-overflowing-literals.stderr index 127dd4127c2..beb0ad79560 100644 --- a/src/test/ui/lint/deny-overflowing-literals.stderr +++ b/src/test/ui/lint/deny-overflowing-literals.stderr @@ -4,8 +4,8 @@ error: literal out of range for `u8` LL | let x: u8 = 256; | ^^^ | - = note: `#[deny(overflowing_literals)]` on by default = note: the literal `256` does not fit into the type `u8` whose range is `0..=255` + = note: `#[deny(overflowing_literals)]` on by default error: range endpoint is out of range for `u8` --> $DIR/deny-overflowing-literals.rs:5:14 diff --git a/src/test/ui/lint/expansion-time.stderr b/src/test/ui/lint/expansion-time.stderr index b0fc1f8e5ee..064ee5fadb1 100644 --- a/src/test/ui/lint/expansion-time.stderr +++ b/src/test/ui/lint/expansion-time.stderr @@ -18,13 +18,13 @@ warning: missing fragment specifier LL | macro_rules! m { ($i) => {} } | ^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> note: the lint level is defined here --> $DIR/expansion-time.rs:8:8 | LL | #[warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> warning: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable --> $DIR/expansion-time.rs:14:7 @@ -32,13 +32,13 @@ warning: use of unstable library feature 'test': `bench` is a part of custom tes LL | #[bench] | ^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266> note: the lint level is defined here --> $DIR/expansion-time.rs:12:8 | LL | #[warn(soft_unstable)] | ^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266> warning: include macro expected single expression in source --> $DIR/expansion-time-include.rs:4:1 diff --git a/src/test/ui/lint/fn_must_use.stderr b/src/test/ui/lint/fn_must_use.stderr index 61b7993d2ae..2805720f035 100644 --- a/src/test/ui/lint/fn_must_use.stderr +++ b/src/test/ui/lint/fn_must_use.stderr @@ -4,12 +4,12 @@ warning: unused return value of `need_to_use_this_value` that must be used LL | need_to_use_this_value(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: it's important note: the lint level is defined here --> $DIR/fn_must_use.rs:3:9 | LL | #![warn(unused_must_use)] | ^^^^^^^^^^^^^^^ - = note: it's important warning: unused return value of `MyStruct::need_to_use_this_method_value` that must be used --> $DIR/fn_must_use.rs:60:5 diff --git a/src/test/ui/lint/forbid-group-group-2.stderr b/src/test/ui/lint/forbid-group-group-2.stderr index 214e949c11a..b2e2bcea1b4 100644 --- a/src/test/ui/lint/forbid-group-group-2.stderr +++ b/src/test/ui/lint/forbid-group-group-2.stderr @@ -7,13 +7,13 @@ LL | #![forbid(warnings)] LL | #[allow(nonstandard_style)] | ^^^^^^^^^^^^^^^^^ overruled by previous forbid | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> note: the lint level is defined here --> $DIR/forbid-group-group-2.rs:5:9 | LL | #![deny(forbidden_lint_groups)] | ^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> error: allow(nonstandard_style) incompatible with previous forbid --> $DIR/forbid-group-group-2.rs:7:9 diff --git a/src/test/ui/lint/forbid-group-member.stderr b/src/test/ui/lint/forbid-group-member.stderr index 891fa9885f3..47336d4d890 100644 --- a/src/test/ui/lint/forbid-group-member.stderr +++ b/src/test/ui/lint/forbid-group-member.stderr @@ -7,9 +7,9 @@ LL | LL | #[allow(unused_variables)] | ^^^^^^^^^^^^^^^^ overruled by previous forbid | - = note: `#[warn(forbidden_lint_groups)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> + = note: `#[warn(forbidden_lint_groups)]` on by default warning: allow(unused_variables) incompatible with previous forbid --> $DIR/forbid-group-member.rs:8:9 diff --git a/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr index 915b3b86fe8..97c2dee46dd 100644 --- a/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr @@ -4,9 +4,9 @@ warning: any use of this value will cause an error LL | const C: i32 = 1 / 0; | ------------ ^^^^^ attempt to divide `1_i32` by zero | - = note: requested on the command line with `--force-warn const-err` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: requested on the command line with `--force-warn const-err` warning: 1 warning emitted @@ -17,7 +17,7 @@ warning: any use of this value will cause an error LL | const C: i32 = 1 / 0; | ------------ ^^^^^ attempt to divide `1_i32` by zero | - = note: requested on the command line with `--force-warn const-err` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: requested on the command line with `--force-warn const-err` diff --git a/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr index 3b36d1d0227..f293b78119e 100644 --- a/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr @@ -4,9 +4,9 @@ warning: any use of this value will cause an error LL | const C: i32 = 1 / 0; | ------------ ^^^^^ attempt to divide `1_i32` by zero | - = note: requested on the command line with `--force-warn const-err` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: requested on the command line with `--force-warn const-err` warning: 1 warning emitted @@ -17,7 +17,7 @@ warning: any use of this value will cause an error LL | const C: i32 = 1 / 0; | ------------ ^^^^^ attempt to divide `1_i32` by zero | - = note: requested on the command line with `--force-warn const-err` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: requested on the command line with `--force-warn const-err` diff --git a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr index 94d81c3aa71..0f58953a54b 100644 --- a/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | pub fn function(_x: Box<SomeTrait>) {} | ^^^^^^^^^ | - = note: requested on the command line with `--force-warn bare-trait-objects` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: requested on the command line with `--force-warn bare-trait-objects` help: use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} diff --git a/src/test/ui/lint/force-warn/cap-lints-allow.stderr b/src/test/ui/lint/force-warn/cap-lints-allow.stderr index 7f0fd8530e2..03a32fa6f08 100644 --- a/src/test/ui/lint/force-warn/cap-lints-allow.stderr +++ b/src/test/ui/lint/force-warn/cap-lints-allow.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | pub fn function(_x: Box<SomeTrait>) {} | ^^^^^^^^^ | - = note: requested on the command line with `--force-warn bare-trait-objects` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: requested on the command line with `--force-warn bare-trait-objects` help: use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} diff --git a/src/test/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr index 3dafaf7055f..d1b764b3414 100644 --- a/src/test/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/cap-lints-warn-allowed-warn-by-default-lint.stderr @@ -4,9 +4,9 @@ warning: `...` range patterns are deprecated LL | 0...100 => true, | ^^^ help: use `..=` for an inclusive range | - = note: `--force-warn ellipsis-inclusive-range-patterns` implied by `--force-warn rust-2021-compatibility` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `--force-warn ellipsis-inclusive-range-patterns` implied by `--force-warn rust-2021-compatibility` warning: 1 warning emitted diff --git a/src/test/ui/lint/force-warn/deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/deny-by-default-lint.stderr index a2e5baa8b9d..703d0afd608 100644 --- a/src/test/ui/lint/force-warn/deny-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/deny-by-default-lint.stderr @@ -4,9 +4,9 @@ warning: any use of this value will cause an error LL | const C: i32 = 1 / 0; | ------------ ^^^^^ attempt to divide `1_i32` by zero | - = note: requested on the command line with `--force-warn const-err` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: requested on the command line with `--force-warn const-err` warning: 1 warning emitted @@ -17,7 +17,7 @@ warning: any use of this value will cause an error LL | const C: i32 = 1 / 0; | ------------ ^^^^^ attempt to divide `1_i32` by zero | - = note: requested on the command line with `--force-warn const-err` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: requested on the command line with `--force-warn const-err` diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr index eb2bca7b84d..e17630fd358 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | pub fn function(_x: Box<SomeTrait>) {} | ^^^^^^^^^ | - = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` help: use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr index ed01937a57b..72198541a70 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr +++ b/src/test/ui/lint/force-warn/lint-group-allowed-lint-group.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | pub fn function(_x: Box<SomeTrait>) {} | ^^^^^^^^^ | - = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` help: use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} diff --git a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr index 8db7c12757b..52c870ac28a 100644 --- a/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | pub fn function(_x: Box<SomeTrait>) {} | ^^^^^^^^^ | - = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms` help: use `dyn` | LL | pub fn function(_x: Box<dyn SomeTrait>) {} diff --git a/src/test/ui/lint/inclusive-range-pattern-syntax.stderr b/src/test/ui/lint/inclusive-range-pattern-syntax.stderr index 91b8d2b5afc..ed9fa0d4101 100644 --- a/src/test/ui/lint/inclusive-range-pattern-syntax.stderr +++ b/src/test/ui/lint/inclusive-range-pattern-syntax.stderr @@ -4,13 +4,13 @@ warning: `...` range patterns are deprecated LL | 1...2 => {} | ^^^ help: use `..=` for an inclusive range | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> note: the lint level is defined here --> $DIR/inclusive-range-pattern-syntax.rs:4:9 | LL | #![warn(ellipsis_inclusive_range_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> warning: `...` range patterns are deprecated --> $DIR/inclusive-range-pattern-syntax.rs:16:9 diff --git a/src/test/ui/lint/inert-attr-macro.stderr b/src/test/ui/lint/inert-attr-macro.stderr index 3b3aa5d0bc0..5ccb4ffe792 100644 --- a/src/test/ui/lint/inert-attr-macro.stderr +++ b/src/test/ui/lint/inert-attr-macro.stderr @@ -4,17 +4,17 @@ warning: unused attribute `inline` LL | #[inline] foo!(); | ^^^^^^^^^ | +note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo` + --> $DIR/inert-attr-macro.rs:10:15 + | +LL | #[inline] foo!(); + | ^^^ note: the lint level is defined here --> $DIR/inert-attr-macro.rs:3:9 | LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_attributes)]` implied by `#[warn(unused)]` -note: the built-in attribute `inline` will be ignored, since it's applied to the macro invocation `foo` - --> $DIR/inert-attr-macro.rs:10:15 - | -LL | #[inline] foo!(); - | ^^^ warning: unused attribute `allow` --> $DIR/inert-attr-macro.rs:14:5 diff --git a/src/test/ui/lint/inline-trait-and-foreign-items.stderr b/src/test/ui/lint/inline-trait-and-foreign-items.stderr index fc7e89e4f4c..27399746bed 100644 --- a/src/test/ui/lint/inline-trait-and-foreign-items.stderr +++ b/src/test/ui/lint/inline-trait-and-foreign-items.stderr @@ -4,13 +4,13 @@ warning: `#[inline]` is ignored on constants LL | #[inline] | ^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: see issue #65833 <https://github.com/rust-lang/rust/issues/65833> for more information note: the lint level is defined here --> $DIR/inline-trait-and-foreign-items.rs:4:9 | LL | #![warn(unused_attributes)] | ^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: see issue #65833 <https://github.com/rust-lang/rust/issues/65833> for more information error[E0518]: attribute should be applied to function or closure --> $DIR/inline-trait-and-foreign-items.rs:11:5 diff --git a/src/test/ui/lint/invalid_value.rs b/src/test/ui/lint/invalid_value.rs index 51edb2b7baf..946a0e38861 100644 --- a/src/test/ui/lint/invalid_value.rs +++ b/src/test/ui/lint/invalid_value.rs @@ -88,6 +88,9 @@ fn main() { let _val: NonNull<i32> = mem::zeroed(); //~ ERROR: does not permit zero-initialization let _val: NonNull<i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: (NonZeroU32, i32) = mem::zeroed(); //~ ERROR: does not permit zero-initialization + let _val: (NonZeroU32, i32) = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized + let _val: *const dyn Send = mem::zeroed(); //~ ERROR: does not permit zero-initialization let _val: *const dyn Send = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized @@ -133,7 +136,7 @@ fn main() { let _val: Result<i32, i32> = mem::zeroed(); let _val: Result<i32, i32> = mem::uninitialized(); //~ ERROR: does not permit being left uninitialized - // Some things that happen to work due to rustc implementation details, + // Some things that happen to be UB-free due to rustc implementation details, // but are not guaranteed to keep working. let _val: OneFruit = mem::zeroed(); let _val: OneFruit = mem::uninitialized(); diff --git a/src/test/ui/lint/invalid_value.stderr b/src/test/ui/lint/invalid_value.stderr index 750b3c76c44..3901692001a 100644 --- a/src/test/ui/lint/invalid_value.stderr +++ b/src/test/ui/lint/invalid_value.stderr @@ -7,12 +7,12 @@ LL | let _val: &'static T = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | + = note: references must be non-null note: the lint level is defined here --> $DIR/invalid_value.rs:6:9 | LL | #![deny(invalid_value)] | ^^^^^^^^^^^^^ - = note: references must be non-null error: the type `&T` does not permit being left uninitialized --> $DIR/invalid_value.rs:51:32 @@ -315,8 +315,30 @@ LL | let _val: NonNull<i32> = mem::uninitialized(); | = note: `std::ptr::NonNull<i32>` must be non-null +error: the type `(NonZeroU32, i32)` does not permit zero-initialization + --> $DIR/invalid_value.rs:91:39 + | +LL | let _val: (NonZeroU32, i32) = mem::zeroed(); + | ^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | + = note: `std::num::NonZeroU32` must be non-null + +error: the type `(NonZeroU32, i32)` does not permit being left uninitialized + --> $DIR/invalid_value.rs:92:39 + | +LL | let _val: (NonZeroU32, i32) = mem::uninitialized(); + | ^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | + = note: `std::num::NonZeroU32` must be non-null + error: the type `*const dyn Send` does not permit zero-initialization - --> $DIR/invalid_value.rs:91:37 + --> $DIR/invalid_value.rs:94:37 | LL | let _val: *const dyn Send = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -327,7 +349,7 @@ LL | let _val: *const dyn Send = mem::zeroed(); = note: the vtable of a wide raw pointer must be non-null error: the type `*const dyn Send` does not permit being left uninitialized - --> $DIR/invalid_value.rs:92:37 + --> $DIR/invalid_value.rs:95:37 | LL | let _val: *const dyn Send = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -338,7 +360,7 @@ LL | let _val: *const dyn Send = mem::uninitialized(); = note: the vtable of a wide raw pointer must be non-null error: the type `[fn(); 2]` does not permit zero-initialization - --> $DIR/invalid_value.rs:94:31 + --> $DIR/invalid_value.rs:97:31 | LL | let _val: [fn(); 2] = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -349,7 +371,7 @@ LL | let _val: [fn(); 2] = mem::zeroed(); = note: function pointers must be non-null error: the type `[fn(); 2]` does not permit being left uninitialized - --> $DIR/invalid_value.rs:95:31 + --> $DIR/invalid_value.rs:98:31 | LL | let _val: [fn(); 2] = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -360,7 +382,7 @@ LL | let _val: [fn(); 2] = mem::uninitialized(); = note: function pointers must be non-null error: the type `TwoUninhabited` does not permit zero-initialization - --> $DIR/invalid_value.rs:97:36 + --> $DIR/invalid_value.rs:100:36 | LL | let _val: TwoUninhabited = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -375,7 +397,7 @@ LL | enum TwoUninhabited { | ^^^^^^^^^^^^^^^^^^^ error: the type `TwoUninhabited` does not permit being left uninitialized - --> $DIR/invalid_value.rs:98:36 + --> $DIR/invalid_value.rs:101:36 | LL | let _val: TwoUninhabited = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -390,7 +412,7 @@ LL | enum TwoUninhabited { | ^^^^^^^^^^^^^^^^^^^ error: the type `OneFruitNonZero` does not permit zero-initialization - --> $DIR/invalid_value.rs:100:37 + --> $DIR/invalid_value.rs:103:37 | LL | let _val: OneFruitNonZero = mem::zeroed(); | ^^^^^^^^^^^^^ @@ -405,7 +427,7 @@ LL | Banana(NonZeroU32), | ^^^^^^^^^^ error: the type `OneFruitNonZero` does not permit being left uninitialized - --> $DIR/invalid_value.rs:101:37 + --> $DIR/invalid_value.rs:104:37 | LL | let _val: OneFruitNonZero = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -420,7 +442,7 @@ LL | Banana(NonZeroU32), | ^^^^^^^^^^ error: the type `bool` does not permit being left uninitialized - --> $DIR/invalid_value.rs:105:26 + --> $DIR/invalid_value.rs:108:26 | LL | let _val: bool = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -431,7 +453,7 @@ LL | let _val: bool = mem::uninitialized(); = note: booleans must be either `true` or `false` error: the type `Wrap<char>` does not permit being left uninitialized - --> $DIR/invalid_value.rs:108:32 + --> $DIR/invalid_value.rs:111:32 | LL | let _val: Wrap<char> = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -446,7 +468,7 @@ LL | struct Wrap<T> { wrapped: T } | ^^^^^^^^^^ error: the type `NonBig` does not permit being left uninitialized - --> $DIR/invalid_value.rs:111:28 + --> $DIR/invalid_value.rs:114:28 | LL | let _val: NonBig = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -457,7 +479,7 @@ LL | let _val: NonBig = mem::uninitialized(); = note: `NonBig` must be initialized inside its custom valid range error: the type `Fruit` does not permit being left uninitialized - --> $DIR/invalid_value.rs:114:27 + --> $DIR/invalid_value.rs:117:27 | LL | let _val: Fruit = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -472,7 +494,7 @@ LL | enum Fruit { | ^^^^^^^^^^ error: the type `[bool; 2]` does not permit being left uninitialized - --> $DIR/invalid_value.rs:117:31 + --> $DIR/invalid_value.rs:120:31 | LL | let _val: [bool; 2] = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -483,7 +505,7 @@ LL | let _val: [bool; 2] = mem::uninitialized(); = note: booleans must be either `true` or `false` error: the type `i32` does not permit being left uninitialized - --> $DIR/invalid_value.rs:120:25 + --> $DIR/invalid_value.rs:123:25 | LL | let _val: i32 = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -494,7 +516,7 @@ LL | let _val: i32 = mem::uninitialized(); = note: integers must not be uninitialized error: the type `f32` does not permit being left uninitialized - --> $DIR/invalid_value.rs:123:25 + --> $DIR/invalid_value.rs:126:25 | LL | let _val: f32 = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -505,7 +527,7 @@ LL | let _val: f32 = mem::uninitialized(); = note: floats must not be uninitialized error: the type `*const ()` does not permit being left uninitialized - --> $DIR/invalid_value.rs:126:31 + --> $DIR/invalid_value.rs:129:31 | LL | let _val: *const () = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -516,7 +538,7 @@ LL | let _val: *const () = mem::uninitialized(); = note: raw pointers must not be uninitialized error: the type `*const [()]` does not permit being left uninitialized - --> $DIR/invalid_value.rs:129:33 + --> $DIR/invalid_value.rs:132:33 | LL | let _val: *const [()] = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -527,7 +549,7 @@ LL | let _val: *const [()] = mem::uninitialized(); = note: raw pointers must not be uninitialized error: the type `Result<i32, i32>` does not permit being left uninitialized - --> $DIR/invalid_value.rs:134:38 + --> $DIR/invalid_value.rs:137:38 | LL | let _val: Result<i32, i32> = mem::uninitialized(); | ^^^^^^^^^^^^^^^^^^^^ @@ -542,7 +564,7 @@ LL | pub enum Result<T, E> { | ^^^^^^^^^^^^^^^^^^^^^ error: the type `&i32` does not permit zero-initialization - --> $DIR/invalid_value.rs:142:34 + --> $DIR/invalid_value.rs:145:34 | LL | let _val: &'static i32 = mem::transmute(0usize); | ^^^^^^^^^^^^^^^^^^^^^^ @@ -553,7 +575,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize); = note: references must be non-null error: the type `&[i32]` does not permit zero-initialization - --> $DIR/invalid_value.rs:143:36 + --> $DIR/invalid_value.rs:146:36 | LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -564,7 +586,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); = note: references must be non-null error: the type `NonZeroU32` does not permit zero-initialization - --> $DIR/invalid_value.rs:144:32 + --> $DIR/invalid_value.rs:147:32 | LL | let _val: NonZeroU32 = mem::transmute(0); | ^^^^^^^^^^^^^^^^^ @@ -575,7 +597,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0); = note: `std::num::NonZeroU32` must be non-null error: the type `NonNull<i32>` does not permit zero-initialization - --> $DIR/invalid_value.rs:147:34 + --> $DIR/invalid_value.rs:150:34 | LL | let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -586,7 +608,7 @@ LL | let _val: NonNull<i32> = MaybeUninit::zeroed().assume_init(); = note: `std::ptr::NonNull<i32>` must be non-null error: the type `NonNull<i32>` does not permit being left uninitialized - --> $DIR/invalid_value.rs:148:34 + --> $DIR/invalid_value.rs:151:34 | LL | let _val: NonNull<i32> = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -597,7 +619,7 @@ LL | let _val: NonNull<i32> = MaybeUninit::uninit().assume_init(); = note: `std::ptr::NonNull<i32>` must be non-null error: the type `bool` does not permit being left uninitialized - --> $DIR/invalid_value.rs:149:26 + --> $DIR/invalid_value.rs:152:26 | LL | let _val: bool = MaybeUninit::uninit().assume_init(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -607,5 +629,5 @@ LL | let _val: bool = MaybeUninit::uninit().assume_init(); | = note: booleans must be either `true` or `false` -error: aborting due to 48 previous errors +error: aborting due to 50 previous errors diff --git a/src/test/ui/lint/issue-14309.stderr b/src/test/ui/lint/issue-14309.stderr index a9538b5e3a4..9ce62a6b804 100644 --- a/src/test/ui/lint/issue-14309.stderr +++ b/src/test/ui/lint/issue-14309.stderr @@ -4,11 +4,6 @@ error: `extern` block uses type `A`, which is not FFI-safe LL | fn foo(x: A); | ^ not FFI-safe | -note: the lint level is defined here - --> $DIR/issue-14309.rs:1:9 - | -LL | #![deny(improper_ctypes)] - | ^^^^^^^^^^^^^^^ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout note: the type is defined here @@ -16,6 +11,11 @@ note: the type is defined here | LL | struct A { | ^^^^^^^^ +note: the lint level is defined here + --> $DIR/issue-14309.rs:1:9 + | +LL | #![deny(improper_ctypes)] + | ^^^^^^^^^^^^^^^ error: `extern` block uses type `A`, which is not FFI-safe --> $DIR/issue-14309.rs:31:15 diff --git a/src/test/ui/lint/issue-1866.stderr b/src/test/ui/lint/issue-1866.stderr index 5edae48a10f..d19a1349668 100644 --- a/src/test/ui/lint/issue-1866.stderr +++ b/src/test/ui/lint/issue-1866.stderr @@ -7,13 +7,13 @@ LL | pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool; LL | pub fn rust_task_is_unwinding(rt: *const rust_task) -> bool; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | + = note: expected `unsafe extern "C" fn(*const usize) -> bool` + found `unsafe extern "C" fn(*const bool) -> bool` note: the lint level is defined here --> $DIR/issue-1866.rs:4:9 | LL | #![warn(clashing_extern_declarations)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `unsafe extern "C" fn(*const usize) -> bool` - found `unsafe extern "C" fn(*const bool) -> bool` warning: 1 warning emitted diff --git a/src/test/ui/lint/issue-63364.stderr b/src/test/ui/lint/issue-63364.stderr index 0375359aeab..9b5453fa82d 100644 --- a/src/test/ui/lint/issue-63364.stderr +++ b/src/test/ui/lint/issue-63364.stderr @@ -4,8 +4,8 @@ error: literal out of range for `u16` LL | for n in 100_000.. { | ^^^^^^^ | - = note: `#[deny(overflowing_literals)]` on by default = note: the literal `100_000` does not fit into the type `u16` whose range is `0..=65535` + = note: `#[deny(overflowing_literals)]` on by default error: aborting due to previous error diff --git a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr index 5093715decf..cc44f8aa58b 100644 --- a/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr +++ b/src/test/ui/lint/issue-70819-dont-override-forbid-in-same-scope.stderr @@ -6,13 +6,13 @@ LL | #![forbid(unused)] LL | #![deny(unused)] | ^^^^^^ overruled by previous forbid | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> note: the lint level is defined here --> $DIR/issue-70819-dont-override-forbid-in-same-scope.rs:17:11 | LL | #![forbid(forbidden_lint_groups)] | ^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> error: aborting due to previous error diff --git a/src/test/ui/lint/issue-79744.stderr b/src/test/ui/lint/issue-79744.stderr index 6f6dd44d236..c1b56250d3e 100644 --- a/src/test/ui/lint/issue-79744.stderr +++ b/src/test/ui/lint/issue-79744.stderr @@ -4,9 +4,9 @@ error: literal out of range for `i8` LL | let e2 = 230; | ^^^ | - = note: `#[deny(overflowing_literals)]` on by default = note: the literal `230` does not fit into the type `i8` whose range is `-128..=127` = help: consider using the type `u8` instead + = note: `#[deny(overflowing_literals)]` on by default error: aborting due to previous error diff --git a/src/test/ui/lint/issue-80988.stderr b/src/test/ui/lint/issue-80988.stderr index 1d397f43133..73e27ffda7f 100644 --- a/src/test/ui/lint/issue-80988.stderr +++ b/src/test/ui/lint/issue-80988.stderr @@ -7,9 +7,9 @@ LL | LL | #[deny(warnings)] | ^^^^^^^^ overruled by previous forbid | - = note: `#[warn(forbidden_lint_groups)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> + = note: `#[warn(forbidden_lint_groups)]` on by default warning: deny(warnings) incompatible with previous forbid --> $DIR/issue-80988.rs:7:8 diff --git a/src/test/ui/lint/issue-83477.stderr b/src/test/ui/lint/issue-83477.stderr index e619bcfe23f..f824fc09e72 100644 --- a/src/test/ui/lint/issue-83477.stderr +++ b/src/test/ui/lint/issue-83477.stderr @@ -18,13 +18,13 @@ warning: prefer `FxHashMap` over `HashMap`, it has better performance LL | let _ = std::collections::HashMap::<String, String>::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary note: the lint level is defined here --> $DIR/issue-83477.rs:3:9 | LL | #![warn(rustc::internal)] | ^^^^^^^^^^^^^^^ = note: `#[warn(rustc::default_hash_types)]` implied by `#[warn(rustc::internal)]` - = note: a `use rustc_data_structures::fx::FxHashMap` may be necessary warning: 3 warnings emitted diff --git a/src/test/ui/lint/issue-86600-lint-twice.stderr b/src/test/ui/lint/issue-86600-lint-twice.stderr index 8da3fb5a839..5a65c612128 100644 --- a/src/test/ui/lint/issue-86600-lint-twice.stderr +++ b/src/test/ui/lint/issue-86600-lint-twice.stderr @@ -4,9 +4,9 @@ warning: floating-point types cannot be used in patterns LL | 5.0 => {} | ^^^ | - = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> + = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/lint/lint-attr-everywhere-early.stderr b/src/test/ui/lint/lint-attr-everywhere-early.stderr index 1d6e3cda4e5..d6c6d5faef2 100644 --- a/src/test/ui/lint/lint-attr-everywhere-early.stderr +++ b/src/test/ui/lint/lint-attr-everywhere-early.stderr @@ -474,13 +474,13 @@ error: `...` range patterns are deprecated LL | f1: 0...100, | ^^^ help: use `..=` for an inclusive range | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> note: the lint level is defined here --> $DIR/lint-attr-everywhere-early.rs:166:20 | LL | #[deny(ellipsis_inclusive_range_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> error: aborting due to 36 previous errors diff --git a/src/test/ui/lint/lint-attr-everywhere-late.stderr b/src/test/ui/lint/lint-attr-everywhere-late.stderr index 977843997c6..a69c2e0ef2b 100644 --- a/src/test/ui/lint/lint-attr-everywhere-late.stderr +++ b/src/test/ui/lint/lint-attr-everywhere-late.stderr @@ -163,13 +163,13 @@ LL | fn clashing1(); LL | fn clashing1(_: i32); | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | + = note: expected `unsafe extern "C" fn()` + found `unsafe extern "C" fn(i32)` note: the lint level is defined here --> $DIR/lint-attr-everywhere-late.rs:122:13 | LL | #![deny(clashing_extern_declarations)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `unsafe extern "C" fn()` - found `unsafe extern "C" fn(i32)` error: `clashing2` redeclared with a different signature --> $DIR/lint-attr-everywhere-late.rs:128:5 @@ -180,13 +180,13 @@ LL | fn clashing2(); LL | fn clashing2(_: i32); | ^^^^^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration | + = note: expected `unsafe extern "C" fn()` + found `unsafe extern "C" fn(i32)` note: the lint level is defined here --> $DIR/lint-attr-everywhere-late.rs:127:12 | LL | #[deny(clashing_extern_declarations)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: expected `unsafe extern "C" fn()` - found `unsafe extern "C" fn(i32)` error: types that do not implement `Drop` can still have drop glue, consider instead using `std::mem::needs_drop` to detect whether a type is trivially dropped --> $DIR/lint-attr-everywhere-late.rs:93:38 @@ -206,16 +206,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | fn assoc_fn() { discriminant::<i32>(&123); } | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:95:12 - | -LL | #[deny(enum_intrinsics_non_enums)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:96:41 | LL | fn assoc_fn() { discriminant::<i32>(&123); } | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:95:12 + | +LL | #[deny(enum_intrinsics_non_enums)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: literal out of range for `u8` --> $DIR/lint-attr-everywhere-late.rs:98:59 @@ -223,12 +223,12 @@ error: literal out of range for `u8` LL | #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000; | ^^^^ | + = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255` note: the lint level is defined here --> $DIR/lint-attr-everywhere-late.rs:98:12 | LL | #[deny(overflowing_literals)] const ASSOC_CONST: u8 = 1000; | ^^^^^^^^^^^^^^^^^^^^ - = note: the literal `1000` does not fit into the type `u8` whose range is `0..=255` error: variable `PARAM` should have a snake case name --> $DIR/lint-attr-everywhere-late.rs:131:37 @@ -248,16 +248,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | let _ = discriminant::<i32>(&123); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:138:12 - | -LL | #[deny(enum_intrinsics_non_enums)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:139:33 | LL | let _ = discriminant::<i32>(&123); | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:138:12 + | +LL | #[deny(enum_intrinsics_non_enums)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: variable `PARAM` should have a snake case name --> $DIR/lint-attr-everywhere-late.rs:145:44 @@ -277,16 +277,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | discriminant::<i32>(&123); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:153:17 - | -LL | #![deny(enum_intrinsics_non_enums)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:155:33 | LL | discriminant::<i32>(&123); | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:153:17 + | +LL | #![deny(enum_intrinsics_non_enums)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type --> $DIR/lint-attr-everywhere-late.rs:161:13 @@ -294,16 +294,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | discriminant::<i32>(&123); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:159:16 - | -LL | #[deny(enum_intrinsics_non_enums)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:161:33 | LL | discriminant::<i32>(&123); | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:159:16 + | +LL | #[deny(enum_intrinsics_non_enums)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type --> $DIR/lint-attr-everywhere-late.rs:168:9 @@ -311,16 +311,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | discriminant::<i32>(&123); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:167:17 - | -LL | #![deny(enum_intrinsics_non_enums)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:168:29 | LL | discriminant::<i32>(&123); | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:167:17 + | +LL | #![deny(enum_intrinsics_non_enums)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type --> $DIR/lint-attr-everywhere-late.rs:172:9 @@ -328,16 +328,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | discriminant::<i32>(&123); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:171:16 - | -LL | #[deny(enum_intrinsics_non_enums)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:172:29 | LL | discriminant::<i32>(&123); | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:171:16 + | +LL | #[deny(enum_intrinsics_non_enums)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type --> $DIR/lint-attr-everywhere-late.rs:177:5 @@ -345,16 +345,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | discriminant::<i32>(&123); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:176:12 - | -LL | #[deny(enum_intrinsics_non_enums)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:177:25 | LL | discriminant::<i32>(&123); | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:176:12 + | +LL | #[deny(enum_intrinsics_non_enums)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type --> $DIR/lint-attr-everywhere-late.rs:179:41 @@ -362,16 +362,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)]; | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:179:13 - | -LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:179:61 | LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)]; | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:179:13 + | +LL | [#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type --> $DIR/lint-attr-everywhere-late.rs:180:41 @@ -379,16 +379,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:180:13 - | -LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:180:61 | LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),); | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:180:13 + | +LL | (#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123),); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type --> $DIR/lint-attr-everywhere-late.rs:182:45 @@ -396,16 +396,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:182:17 - | -LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:182:65 | LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:182:17 + | +LL | call(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: the return value of `mem::discriminant` is unspecified when called with a non-enum type --> $DIR/lint-attr-everywhere-late.rs:184:52 @@ -413,16 +413,16 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/lint-attr-everywhere-late.rs:184:24 - | -LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `i32`, which is not an enum. --> $DIR/lint-attr-everywhere-late.rs:184:72 | LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); | ^^^^ +note: the lint level is defined here + --> $DIR/lint-attr-everywhere-late.rs:184:24 + | +LL | TupleStruct(#[deny(enum_intrinsics_non_enums)] discriminant::<i32>(&123)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 31 previous errors diff --git a/src/test/ui/lint/lint-const-item-mutation.stderr b/src/test/ui/lint/lint-const-item-mutation.stderr index 94d876423e7..9f4360e6763 100644 --- a/src/test/ui/lint/lint-const-item-mutation.stderr +++ b/src/test/ui/lint/lint-const-item-mutation.stderr @@ -4,13 +4,13 @@ warning: attempting to modify a `const` item LL | ARRAY[0] = 5; | ^^^^^^^^^^^^ | - = note: `#[warn(const_item_mutation)]` on by default = note: each usage of a `const` item creates a new temporary; the original `const` item will not be modified note: `const` item defined here --> $DIR/lint-const-item-mutation.rs:26:1 | LL | const ARRAY: [u8; 1] = [25]; | ^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(const_item_mutation)]` on by default warning: attempting to modify a `const` item --> $DIR/lint-const-item-mutation.rs:38:5 diff --git a/src/test/ui/lint/lint-ctypes-73249-2.stderr b/src/test/ui/lint/lint-ctypes-73249-2.stderr index 7c85e9fa85c..8073c33dd46 100644 --- a/src/test/ui/lint/lint-ctypes-73249-2.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-2.stderr @@ -4,12 +4,12 @@ error: `extern` block uses type `Qux`, which is not FFI-safe LL | pub fn lint_me() -> A<()>; | ^^^^^ not FFI-safe | + = note: opaque types have no C equivalent note: the lint level is defined here --> $DIR/lint-ctypes-73249-2.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ - = note: opaque types have no C equivalent error: aborting due to previous error diff --git a/src/test/ui/lint/lint-ctypes-73249-3.stderr b/src/test/ui/lint/lint-ctypes-73249-3.stderr index 83e2a233c43..c41ce666db8 100644 --- a/src/test/ui/lint/lint-ctypes-73249-3.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-3.stderr @@ -4,12 +4,12 @@ error: `extern` block uses type `Qux`, which is not FFI-safe LL | pub fn lint_me() -> A; | ^ not FFI-safe | + = note: opaque types have no C equivalent note: the lint level is defined here --> $DIR/lint-ctypes-73249-3.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ - = note: opaque types have no C equivalent error: aborting due to previous error diff --git a/src/test/ui/lint/lint-ctypes-73249-5.stderr b/src/test/ui/lint/lint-ctypes-73249-5.stderr index 37781d78cf2..98245c4f144 100644 --- a/src/test/ui/lint/lint-ctypes-73249-5.stderr +++ b/src/test/ui/lint/lint-ctypes-73249-5.stderr @@ -4,12 +4,12 @@ error: `extern` block uses type `Qux`, which is not FFI-safe LL | pub fn lint_me() -> A; | ^ not FFI-safe | + = note: opaque types have no C equivalent note: the lint level is defined here --> $DIR/lint-ctypes-73249-5.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ - = note: opaque types have no C equivalent error: aborting due to previous error diff --git a/src/test/ui/lint/lint-ctypes-73251-1.stderr b/src/test/ui/lint/lint-ctypes-73251-1.stderr index 76b19d37e21..9f43576ad73 100644 --- a/src/test/ui/lint/lint-ctypes-73251-1.stderr +++ b/src/test/ui/lint/lint-ctypes-73251-1.stderr @@ -4,12 +4,12 @@ error: `extern` block uses type `Qux`, which is not FFI-safe LL | pub fn lint_me() -> <u32 as Foo>::Assoc; | ^^^^^^^^^^^^^^^^^^^ not FFI-safe | + = note: opaque types have no C equivalent note: the lint level is defined here --> $DIR/lint-ctypes-73251-1.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ - = note: opaque types have no C equivalent error: aborting due to previous error diff --git a/src/test/ui/lint/lint-ctypes-73251-2.stderr b/src/test/ui/lint/lint-ctypes-73251-2.stderr index 64f0fb2d892..0b3de379c19 100644 --- a/src/test/ui/lint/lint-ctypes-73251-2.stderr +++ b/src/test/ui/lint/lint-ctypes-73251-2.stderr @@ -4,12 +4,12 @@ error: `extern` block uses type `AliasA`, which is not FFI-safe LL | pub fn lint_me() -> <AliasB as TraitB>::Assoc; | ^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe | + = note: opaque types have no C equivalent note: the lint level is defined here --> $DIR/lint-ctypes-73251-2.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ - = note: opaque types have no C equivalent error: aborting due to previous error diff --git a/src/test/ui/lint/lint-ctypes-enum.stderr b/src/test/ui/lint/lint-ctypes-enum.stderr index de532f69ac0..8554e261778 100644 --- a/src/test/ui/lint/lint-ctypes-enum.stderr +++ b/src/test/ui/lint/lint-ctypes-enum.stderr @@ -4,11 +4,6 @@ error: `extern` block uses type `U`, which is not FFI-safe LL | fn uf(x: U); | ^ not FFI-safe | -note: the lint level is defined here - --> $DIR/lint-ctypes-enum.rs:3:9 - | -LL | #![deny(improper_ctypes)] - | ^^^^^^^^^^^^^^^ = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum = note: enum has no representation hint note: the type is defined here @@ -16,6 +11,11 @@ note: the type is defined here | LL | enum U { | ^^^^^^ +note: the lint level is defined here + --> $DIR/lint-ctypes-enum.rs:3:9 + | +LL | #![deny(improper_ctypes)] + | ^^^^^^^^^^^^^^^ error: `extern` block uses type `B`, which is not FFI-safe --> $DIR/lint-ctypes-enum.rs:61:13 diff --git a/src/test/ui/lint/lint-ctypes-fn.stderr b/src/test/ui/lint/lint-ctypes-fn.stderr index 6f8d76411aa..a05206bf18d 100644 --- a/src/test/ui/lint/lint-ctypes-fn.stderr +++ b/src/test/ui/lint/lint-ctypes-fn.stderr @@ -4,13 +4,13 @@ error: `extern` fn uses type `[u32]`, which is not FFI-safe LL | pub extern "C" fn slice_type(p: &[u32]) { } | ^^^^^^ not FFI-safe | + = help: consider using a raw pointer instead + = note: slices have no C equivalent note: the lint level is defined here --> $DIR/lint-ctypes-fn.rs:4:9 | LL | #![deny(improper_ctypes_definitions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: consider using a raw pointer instead - = note: slices have no C equivalent error: `extern` fn uses type `str`, which is not FFI-safe --> $DIR/lint-ctypes-fn.rs:76:31 diff --git a/src/test/ui/lint/lint-ctypes.stderr b/src/test/ui/lint/lint-ctypes.stderr index bfec40e1955..121ad0ce8fa 100644 --- a/src/test/ui/lint/lint-ctypes.stderr +++ b/src/test/ui/lint/lint-ctypes.stderr @@ -4,11 +4,6 @@ error: `extern` block uses type `Foo`, which is not FFI-safe LL | pub fn ptr_type1(size: *const Foo); | ^^^^^^^^^^ not FFI-safe | -note: the lint level is defined here - --> $DIR/lint-ctypes.rs:4:9 - | -LL | #![deny(improper_ctypes)] - | ^^^^^^^^^^^^^^^ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this struct = note: this struct has unspecified layout note: the type is defined here @@ -16,6 +11,11 @@ note: the type is defined here | LL | pub struct Foo; | ^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/lint-ctypes.rs:4:9 + | +LL | #![deny(improper_ctypes)] + | ^^^^^^^^^^^^^^^ error: `extern` block uses type `Foo`, which is not FFI-safe --> $DIR/lint-ctypes.rs:49:28 diff --git a/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr b/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr index bec9fb62efa..63ed2503cf3 100644 --- a/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr +++ b/src/test/ui/lint/lint-enum-intrinsics-non-enums.stderr @@ -4,12 +4,12 @@ error: the return value of `mem::discriminant` is unspecified when called with a LL | discriminant(&()); | ^^^^^^^^^^^^^^^^^ | - = note: `#[deny(enum_intrinsics_non_enums)]` on by default note: the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `()`, which is not an enum. --> $DIR/lint-enum-intrinsics-non-enums.rs:26:18 | LL | discriminant(&()); | ^^^ + = note: `#[deny(enum_intrinsics_non_enums)]` on by default error: the return value of `mem::discriminant` is unspecified when called with a non-enum type --> $DIR/lint-enum-intrinsics-non-enums.rs:29:5 diff --git a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr index afbab989676..3f366bedbf3 100644 --- a/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr +++ b/src/test/ui/lint/lint-incoherent-auto-trait-objects.stderr @@ -7,9 +7,9 @@ LL | LL | impl Foo for dyn Send + Send {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + 'static)` | - = note: `#[deny(order_dependent_trait_objects)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> + = note: `#[deny(order_dependent_trait_objects)]` on by default error: conflicting implementations of trait `Foo` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) --> $DIR/lint-incoherent-auto-trait-objects.rs:11:1 diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-bool.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-bool.stderr index 2a1847b9801..9f38dcb0b22 100644 --- a/src/test/ui/lint/lint-invalid-atomic-ordering-bool.stderr +++ b/src/test/ui/lint/lint-invalid-atomic-ordering-bool.stderr @@ -4,8 +4,8 @@ error: atomic loads cannot have `Release` or `AcqRel` ordering LL | let _ = x.load(Ordering::Release); | ^^^^^^^^^^^^^^^^^ | - = note: `#[deny(invalid_atomic_ordering)]` on by default = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` + = note: `#[deny(invalid_atomic_ordering)]` on by default error: atomic loads cannot have `Release` or `AcqRel` ordering --> $DIR/lint-invalid-atomic-ordering-bool.rs:15:20 diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr index 021654cf35e..cc075ce9e41 100644 --- a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr +++ b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange-weak.stderr @@ -4,8 +4,8 @@ error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRe LL | let _ = x.compare_exchange_weak(ptr2, ptr, Ordering::Relaxed, Ordering::AcqRel); | ^^^^^^^^^^^^^^^^ invalid failure ordering | - = note: `#[deny(invalid_atomic_ordering)]` on by default = help: consider using `Acquire` or `Relaxed` failure ordering instead + = note: `#[deny(invalid_atomic_ordering)]` on by default error: `compare_exchange_weak`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange_weak` does not result in a write --> $DIR/lint-invalid-atomic-ordering-exchange-weak.rs:30:67 diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr index f6f8f88e884..fe6c7e55c62 100644 --- a/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr +++ b/src/test/ui/lint/lint-invalid-atomic-ordering-exchange.stderr @@ -4,8 +4,8 @@ error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, s LL | let _ = x.compare_exchange(0, 0, Ordering::Relaxed, Ordering::AcqRel); | ^^^^^^^^^^^^^^^^ invalid failure ordering | - = note: `#[deny(invalid_atomic_ordering)]` on by default = help: consider using `Acquire` or `Relaxed` failure ordering instead + = note: `#[deny(invalid_atomic_ordering)]` on by default error: `compare_exchange`'s failure ordering may not be `Release` or `AcqRel`, since a failed `compare_exchange` does not result in a write --> $DIR/lint-invalid-atomic-ordering-exchange.rs:28:57 diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-fence.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-fence.stderr index e0741ffedd9..38327d607c9 100644 --- a/src/test/ui/lint/lint-invalid-atomic-ordering-fence.stderr +++ b/src/test/ui/lint/lint-invalid-atomic-ordering-fence.stderr @@ -4,8 +4,8 @@ error: memory fences cannot have `Relaxed` ordering LL | fence(Ordering::Relaxed); | ^^^^^^^^^^^^^^^^^ | - = note: `#[deny(invalid_atomic_ordering)]` on by default = help: consider using ordering modes `Acquire`, `Release`, `AcqRel` or `SeqCst` + = note: `#[deny(invalid_atomic_ordering)]` on by default error: memory fences cannot have `Relaxed` ordering --> $DIR/lint-invalid-atomic-ordering-fence.rs:19:20 diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr index 267b1c706ef..33829d68fd5 100644 --- a/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr +++ b/src/test/ui/lint/lint-invalid-atomic-ordering-fetch-update.stderr @@ -4,8 +4,8 @@ error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since LL | let _ = x.fetch_update(Ordering::Relaxed, Ordering::AcqRel, |old| Some(old + 1)); | ^^^^^^^^^^^^^^^^ invalid failure ordering | - = note: `#[deny(invalid_atomic_ordering)]` on by default = help: consider using `Acquire` or `Relaxed` failure ordering instead + = note: `#[deny(invalid_atomic_ordering)]` on by default error: `fetch_update`'s failure ordering may not be `Release` or `AcqRel`, since a failed `fetch_update` does not result in a write --> $DIR/lint-invalid-atomic-ordering-fetch-update.rs:28:47 diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-int.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-int.stderr index dfd9990455a..36930e2f440 100644 --- a/src/test/ui/lint/lint-invalid-atomic-ordering-int.stderr +++ b/src/test/ui/lint/lint-invalid-atomic-ordering-int.stderr @@ -4,8 +4,8 @@ error: atomic loads cannot have `Release` or `AcqRel` ordering LL | let _ = x.load(Ordering::Release); | ^^^^^^^^^^^^^^^^^ | - = note: `#[deny(invalid_atomic_ordering)]` on by default = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` + = note: `#[deny(invalid_atomic_ordering)]` on by default error: atomic loads cannot have `Release` or `AcqRel` ordering --> $DIR/lint-invalid-atomic-ordering-int.rs:22:20 diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-ptr.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-ptr.stderr index f00cb8e4082..12f4cad90fe 100644 --- a/src/test/ui/lint/lint-invalid-atomic-ordering-ptr.stderr +++ b/src/test/ui/lint/lint-invalid-atomic-ordering-ptr.stderr @@ -4,8 +4,8 @@ error: atomic loads cannot have `Release` or `AcqRel` ordering LL | let _ = x.load(Ordering::Release); | ^^^^^^^^^^^^^^^^^ | - = note: `#[deny(invalid_atomic_ordering)]` on by default = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` + = note: `#[deny(invalid_atomic_ordering)]` on by default error: atomic loads cannot have `Release` or `AcqRel` ordering --> $DIR/lint-invalid-atomic-ordering-ptr.rs:17:20 diff --git a/src/test/ui/lint/lint-invalid-atomic-ordering-uint.stderr b/src/test/ui/lint/lint-invalid-atomic-ordering-uint.stderr index 36672e434b9..d26621f2a88 100644 --- a/src/test/ui/lint/lint-invalid-atomic-ordering-uint.stderr +++ b/src/test/ui/lint/lint-invalid-atomic-ordering-uint.stderr @@ -4,8 +4,8 @@ error: atomic loads cannot have `Release` or `AcqRel` ordering LL | let _ = x.load(Ordering::Release); | ^^^^^^^^^^^^^^^^^ | - = note: `#[deny(invalid_atomic_ordering)]` on by default = help: consider using ordering modes `Acquire`, `SeqCst` or `Relaxed` + = note: `#[deny(invalid_atomic_ordering)]` on by default error: atomic loads cannot have `Release` or `AcqRel` ordering --> $DIR/lint-invalid-atomic-ordering-uint.rs:21:20 diff --git a/src/test/ui/lint/lint-non-snake-case-crate-2.stderr b/src/test/ui/lint/lint-non-snake-case-crate-2.stderr index e2951129327..4b42145bbed 100644 --- a/src/test/ui/lint/lint-non-snake-case-crate-2.stderr +++ b/src/test/ui/lint/lint-non-snake-case-crate-2.stderr @@ -1,11 +1,11 @@ error: crate `NonSnakeCase` should have a snake case name | + = help: convert the identifier to snake case: `non_snake_case` note: the lint level is defined here --> $DIR/lint-non-snake-case-crate-2.rs:4:9 | LL | #![deny(non_snake_case)] | ^^^^^^^^^^^^^^ - = help: convert the identifier to snake case: `non_snake_case` error: aborting due to previous error diff --git a/src/test/ui/lint/lint-pre-expansion-extern-module.stderr b/src/test/ui/lint/lint-pre-expansion-extern-module.stderr index 3355bb4e4ff..ce3e8806a9e 100644 --- a/src/test/ui/lint/lint-pre-expansion-extern-module.stderr +++ b/src/test/ui/lint/lint-pre-expansion-extern-module.stderr @@ -4,9 +4,9 @@ warning: `try` is a keyword in the 2018 edition LL | pub fn try() {} | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | - = note: `-W keyword-idents` implied by `-W rust-2018-compatibility` = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> + = note: `-W keyword-idents` implied by `-W rust-2018-compatibility` warning: 1 warning emitted diff --git a/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr b/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr index c85934aa3ba..383623b4831 100644 --- a/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr +++ b/src/test/ui/lint/lint-strict-provenance-fuzzy-casts.stderr @@ -4,12 +4,12 @@ error: strict provenance disallows casting integer `usize` to pointer `*const u8 LL | let dangling = 16_usize as *const u8; | ^^^^^^^^^^^^^^^^^^^^^ | + = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead note: the lint level is defined here --> $DIR/lint-strict-provenance-fuzzy-casts.rs:2:9 | LL | #![deny(fuzzy_provenance_casts)] | ^^^^^^^^^^^^^^^^^^^^^^ - = help: if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::from_exposed_addr()` instead help: use `.with_addr()` to adjust a valid pointer in the same allocation, to this address | LL | let dangling = (...).with_addr(16_usize); diff --git a/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr b/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr index 05178b34b11..aa151fe2d21 100644 --- a/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr +++ b/src/test/ui/lint/lint-strict-provenance-lossy-casts.stderr @@ -4,12 +4,12 @@ error: under strict provenance it is considered bad style to cast pointer `*cons LL | let addr: usize = &x as *const u8 as usize; | ^^^^^^^^^^^^^^^^^^^^^^^^ | + = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead note: the lint level is defined here --> $DIR/lint-strict-provenance-lossy-casts.rs:2:9 | LL | #![deny(lossy_provenance_casts)] | ^^^^^^^^^^^^^^^^^^^^^^ - = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead help: use `.addr()` to obtain the address of a pointer | LL | let addr: usize = (&x as *const u8).addr(); diff --git a/src/test/ui/lint/lint-temporary-cstring-as-param.stderr b/src/test/ui/lint/lint-temporary-cstring-as-param.stderr index 0a9e5a4bf4a..838b3bc13fe 100644 --- a/src/test/ui/lint/lint-temporary-cstring-as-param.stderr +++ b/src/test/ui/lint/lint-temporary-cstring-as-param.stderr @@ -6,13 +6,13 @@ LL | some_function(CString::new("").unwrap().as_ptr()); | | | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime | + = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html note: the lint level is defined here --> $DIR/lint-temporary-cstring-as-param.rs:1:9 | LL | #![deny(temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: for more information, see https://doc.rust-lang.org/reference/destructors.html error: aborting due to previous error diff --git a/src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr b/src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr index e69d2dd533a..79ef57dd1a3 100644 --- a/src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr +++ b/src/test/ui/lint/lint-temporary-cstring-as-ptr.stderr @@ -6,13 +6,13 @@ LL | let s = CString::new("some text").unwrap().as_ptr(); | | | this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime | + = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned + = help: for more information, see https://doc.rust-lang.org/reference/destructors.html note: the lint level is defined here --> $DIR/lint-temporary-cstring-as-ptr.rs:2:9 | LL | #![deny(temporary_cstring_as_ptr)] | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: pointers do not have a lifetime; when calling `as_ptr` the `CString` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned - = help: for more information, see https://doc.rust-lang.org/reference/destructors.html error: aborting due to previous error diff --git a/src/test/ui/lint/lint-type-limits2.stderr b/src/test/ui/lint/lint-type-limits2.stderr index 3562cb440a6..b3420ad8afd 100644 --- a/src/test/ui/lint/lint-type-limits2.stderr +++ b/src/test/ui/lint/lint-type-limits2.stderr @@ -12,13 +12,13 @@ warning: literal out of range for `i8` LL | 128 > bar() | ^^^ | + = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using the type `u8` instead note: the lint level is defined here --> $DIR/lint-type-limits2.rs:2:9 | LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ - = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using the type `u8` instead error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/lint/lint-type-limits3.stderr b/src/test/ui/lint/lint-type-limits3.stderr index 823d1a4c76f..db46e7ae714 100644 --- a/src/test/ui/lint/lint-type-limits3.stderr +++ b/src/test/ui/lint/lint-type-limits3.stderr @@ -12,13 +12,13 @@ warning: literal out of range for `i8` LL | while 200 != i { | ^^^ | + = note: the literal `200` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using the type `u8` instead note: the lint level is defined here --> $DIR/lint-type-limits3.rs:2:9 | LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ - = note: the literal `200` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using the type `u8` instead error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/lint/lint-type-overflow.stderr b/src/test/ui/lint/lint-type-overflow.stderr index 1bb1ec54776..48d8228b802 100644 --- a/src/test/ui/lint/lint-type-overflow.stderr +++ b/src/test/ui/lint/lint-type-overflow.stderr @@ -4,12 +4,12 @@ error: literal out of range for `u8` LL | let x1: u8 = 256; | ^^^ | + = note: the literal `256` does not fit into the type `u8` whose range is `0..=255` note: the lint level is defined here --> $DIR/lint-type-overflow.rs:1:9 | LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ - = note: the literal `256` does not fit into the type `u8` whose range is `0..=255` error: literal out of range for `u8` --> $DIR/lint-type-overflow.rs:13:14 diff --git a/src/test/ui/lint/lint-type-overflow2.stderr b/src/test/ui/lint/lint-type-overflow2.stderr index 3d40cdf96ef..117bfc3ced7 100644 --- a/src/test/ui/lint/lint-type-overflow2.stderr +++ b/src/test/ui/lint/lint-type-overflow2.stderr @@ -4,13 +4,13 @@ error: literal out of range for `i8` LL | let x2: i8 = --128; | ^^^ | + = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using the type `u8` instead note: the lint level is defined here --> $DIR/lint-type-overflow2.rs:3:9 | LL | #![deny(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ - = note: the literal `128` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using the type `u8` instead error: literal out of range for `f32` --> $DIR/lint-type-overflow2.rs:9:14 diff --git a/src/test/ui/lint/lint-unconditional-recursion.stderr b/src/test/ui/lint/lint-unconditional-recursion.stderr index c11b73f41ca..9d200a7898e 100644 --- a/src/test/ui/lint/lint-unconditional-recursion.stderr +++ b/src/test/ui/lint/lint-unconditional-recursion.stderr @@ -6,12 +6,12 @@ LL | fn foo() { LL | foo(); | ----- recursive call site | + = help: a `loop` may express intention better if this is on purpose note: the lint level is defined here --> $DIR/lint-unconditional-recursion.rs:1:9 | LL | #![deny(unconditional_recursion)] | ^^^^^^^^^^^^^^^^^^^^^^^ - = help: a `loop` may express intention better if this is on purpose error: function cannot return without recursing --> $DIR/lint-unconditional-recursion.rs:14:1 diff --git a/src/test/ui/lint/lint-unsafe-code.stderr b/src/test/ui/lint/lint-unsafe-code.stderr index 8dde05fc4de..037f0a8323a 100644 --- a/src/test/ui/lint/lint-unsafe-code.stderr +++ b/src/test/ui/lint/lint-unsafe-code.stderr @@ -4,12 +4,12 @@ error: declaration of a `no_mangle` function LL | #[no_mangle] fn foo() {} | ^^^^^^^^^^^^ | + = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them note: the lint level is defined here --> $DIR/lint-unsafe-code.rs:3:9 | LL | #![deny(unsafe_code)] | ^^^^^^^^^^^ - = note: the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them error: declaration of a `no_mangle` static --> $DIR/lint-unsafe-code.rs:32:1 diff --git a/src/test/ui/lint/must_not_suspend/boxed.stderr b/src/test/ui/lint/must_not_suspend/boxed.stderr index b3c9b43810c..9efc7b0693b 100644 --- a/src/test/ui/lint/must_not_suspend/boxed.stderr +++ b/src/test/ui/lint/must_not_suspend/boxed.stderr @@ -6,11 +6,6 @@ LL | let _guard = bar(); LL | other().await; | ------ the value is held across this suspend point | -note: the lint level is defined here - --> $DIR/boxed.rs:3:9 - | -LL | #![deny(must_not_suspend)] - | ^^^^^^^^^^^^^^^^ note: You gotta use Umm's, ya know? --> $DIR/boxed.rs:20:9 | @@ -21,6 +16,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef | LL | let _guard = bar(); | ^^^^^^ +note: the lint level is defined here + --> $DIR/boxed.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/must_not_suspend/dedup.stderr b/src/test/ui/lint/must_not_suspend/dedup.stderr index 13fa3ae3008..f8978ba57f1 100644 --- a/src/test/ui/lint/must_not_suspend/dedup.stderr +++ b/src/test/ui/lint/must_not_suspend/dedup.stderr @@ -4,16 +4,16 @@ error: `No` held across a suspend point, but should not be LL | wheeee(&No {}).await; | ^^^^^ ------ the value is held across this suspend point | -note: the lint level is defined here - --> $DIR/dedup.rs:3:9 - | -LL | #![deny(must_not_suspend)] - | ^^^^^^^^^^^^^^^^ help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point --> $DIR/dedup.rs:16:13 | LL | wheeee(&No {}).await; | ^^^^^ +note: the lint level is defined here + --> $DIR/dedup.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/must_not_suspend/gated.stderr b/src/test/ui/lint/must_not_suspend/gated.stderr index b58ecb55596..64de1ebeaab 100644 --- a/src/test/ui/lint/must_not_suspend/gated.stderr +++ b/src/test/ui/lint/must_not_suspend/gated.stderr @@ -4,10 +4,10 @@ warning: unknown lint: `must_not_suspend` LL | #![deny(must_not_suspend)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_lints)]` on by default = note: the `must_not_suspend` lint is unstable = note: see issue #83310 <https://github.com/rust-lang/rust/issues/83310> for more information = help: add `#![feature(must_not_suspend)]` to the crate attributes to enable + = note: `#[warn(unknown_lints)]` on by default warning: unknown lint: `must_not_suspend` --> $DIR/gated.rs:4:1 diff --git a/src/test/ui/lint/must_not_suspend/mutex.stderr b/src/test/ui/lint/must_not_suspend/mutex.stderr index a968b7ca033..c251cb84589 100644 --- a/src/test/ui/lint/must_not_suspend/mutex.stderr +++ b/src/test/ui/lint/must_not_suspend/mutex.stderr @@ -6,11 +6,6 @@ LL | let _guard = m.lock().unwrap(); LL | other().await; | ------ the value is held across this suspend point | -note: the lint level is defined here - --> $DIR/mutex.rs:3:9 - | -LL | #![deny(must_not_suspend)] - | ^^^^^^^^^^^^^^^^ note: holding a MutexGuard across suspend points can cause deadlocks, delays, and cause Futures to not implement `Send` --> $DIR/mutex.rs:8:9 | @@ -21,6 +16,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef | LL | let _guard = m.lock().unwrap(); | ^^^^^^ +note: the lint level is defined here + --> $DIR/mutex.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr index c49d2712853..180e187c1b0 100644 --- a/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr +++ b/src/test/ui/lint/must_not_suspend/ref-drop-tracking.stderr @@ -7,11 +7,6 @@ LL | LL | other().await; | ------ the value is held across this suspend point | -note: the lint level is defined here - --> $DIR/ref-drop-tracking.rs:4:9 - | -LL | #![deny(must_not_suspend)] - | ^^^^^^^^^^^^^^^^ note: You gotta use Umm's, ya know? --> $DIR/ref-drop-tracking.rs:19:13 | @@ -22,6 +17,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef | LL | let guard = &mut self.u; | ^^^^^ +note: the lint level is defined here + --> $DIR/ref-drop-tracking.rs:4:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr b/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr index 0157c8b7fe1..abf76711bf0 100644 --- a/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr +++ b/src/test/ui/lint/must_not_suspend/ref.drop_tracking.stderr @@ -7,11 +7,6 @@ LL | LL | other().await; | ------ the value is held across this suspend point | -note: the lint level is defined here - --> $DIR/ref.rs:6:9 - | -LL | #![deny(must_not_suspend)] - | ^^^^^^^^^^^^^^^^ note: You gotta use Umm's, ya know? --> $DIR/ref.rs:21:13 | @@ -22,6 +17,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef | LL | let guard = &mut self.u; | ^^^^^ +note: the lint level is defined here + --> $DIR/ref.rs:6:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr b/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr index 438e6489e31..41ac09ea72a 100644 --- a/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr +++ b/src/test/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr @@ -7,11 +7,6 @@ LL | LL | other().await; | ------ the value is held across this suspend point | -note: the lint level is defined here - --> $DIR/ref.rs:6:9 - | -LL | #![deny(must_not_suspend)] - | ^^^^^^^^^^^^^^^^ note: You gotta use Umm's, ya know? --> $DIR/ref.rs:21:26 | @@ -22,6 +17,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef | LL | let guard = &mut self.u; | ^^^^^^ +note: the lint level is defined here + --> $DIR/ref.rs:6:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/must_not_suspend/trait.stderr b/src/test/ui/lint/must_not_suspend/trait.stderr index 60369430a3e..d64d25aae52 100644 --- a/src/test/ui/lint/must_not_suspend/trait.stderr +++ b/src/test/ui/lint/must_not_suspend/trait.stderr @@ -7,16 +7,16 @@ LL | let _guard1 = r#impl(); LL | other().await; | ------ the value is held across this suspend point | -note: the lint level is defined here - --> $DIR/trait.rs:3:9 - | -LL | #![deny(must_not_suspend)] - | ^^^^^^^^^^^^^^^^ help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point --> $DIR/trait.rs:21:9 | LL | let _guard1 = r#impl(); | ^^^^^^^ +note: the lint level is defined here + --> $DIR/trait.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ error: boxed `Wow` trait object held across a suspend point, but should not be --> $DIR/trait.rs:22:9 diff --git a/src/test/ui/lint/must_not_suspend/unit.stderr b/src/test/ui/lint/must_not_suspend/unit.stderr index 42d037b350b..c967dbac56c 100644 --- a/src/test/ui/lint/must_not_suspend/unit.stderr +++ b/src/test/ui/lint/must_not_suspend/unit.stderr @@ -6,11 +6,6 @@ LL | let _guard = bar(); LL | other().await; | ------ the value is held across this suspend point | -note: the lint level is defined here - --> $DIR/unit.rs:3:9 - | -LL | #![deny(must_not_suspend)] - | ^^^^^^^^^^^^^^^^ note: You gotta use Umm's, ya know? --> $DIR/unit.rs:20:9 | @@ -21,6 +16,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef | LL | let _guard = bar(); | ^^^^^^ +note: the lint level is defined here + --> $DIR/unit.rs:3:9 + | +LL | #![deny(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/lint/must_not_suspend/warn.stderr b/src/test/ui/lint/must_not_suspend/warn.stderr index 417c397dad0..fe551c6521d 100644 --- a/src/test/ui/lint/must_not_suspend/warn.stderr +++ b/src/test/ui/lint/must_not_suspend/warn.stderr @@ -6,11 +6,6 @@ LL | let _guard = bar(); LL | other().await; | ------ the value is held across this suspend point | -note: the lint level is defined here - --> $DIR/warn.rs:4:9 - | -LL | #![warn(must_not_suspend)] - | ^^^^^^^^^^^^^^^^ note: You gotta use Umm's, ya know? --> $DIR/warn.rs:21:9 | @@ -21,6 +16,11 @@ help: consider using a block (`{ ... }`) to shrink the value's scope, ending bef | LL | let _guard = bar(); | ^^^^^^ +note: the lint level is defined here + --> $DIR/warn.rs:4:9 + | +LL | #![warn(must_not_suspend)] + | ^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/src/test/ui/lint/noop-method-call.rs b/src/test/ui/lint/noop-method-call.rs index 9870c813572..89b29663595 100644 --- a/src/test/ui/lint/noop-method-call.rs +++ b/src/test/ui/lint/noop-method-call.rs @@ -46,6 +46,7 @@ fn main() { fn generic<T>(non_clone_type: &PlainType<T>) { non_clone_type.clone(); + //~^ WARNING call to `.clone()` on a reference in this situation does nothing } fn non_generic(non_clone_type: &PlainType<u32>) { diff --git a/src/test/ui/lint/noop-method-call.stderr b/src/test/ui/lint/noop-method-call.stderr index 7f6f96bf1d1..6a904d01abc 100644 --- a/src/test/ui/lint/noop-method-call.stderr +++ b/src/test/ui/lint/noop-method-call.stderr @@ -4,12 +4,12 @@ warning: call to `.clone()` on a reference in this situation does nothing LL | let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone(); | ^^^^^^^^ unnecessary method call | + = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed note: the lint level is defined here --> $DIR/noop-method-call.rs:4:9 | LL | #![warn(noop_method_call)] | ^^^^^^^^^^^^^^^^ - = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed warning: call to `.deref()` on a reference in this situation does nothing --> $DIR/noop-method-call.rs:28:63 @@ -28,12 +28,20 @@ LL | let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow(); = note: the type `&PlainType<u32>` which `borrow` is being called on is the same as the type returned from `borrow`, so the method call does not do anything and can be removed warning: call to `.clone()` on a reference in this situation does nothing - --> $DIR/noop-method-call.rs:52:19 + --> $DIR/noop-method-call.rs:48:19 + | +LL | non_clone_type.clone(); + | ^^^^^^^^ unnecessary method call + | + = note: the type `&PlainType<T>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed + +warning: call to `.clone()` on a reference in this situation does nothing + --> $DIR/noop-method-call.rs:53:19 | LL | non_clone_type.clone(); | ^^^^^^^^ unnecessary method call | = note: the type `&PlainType<u32>` which `clone` is being called on is the same as the type returned from `clone`, so the method call does not do anything and can be removed -warning: 4 warnings emitted +warning: 5 warnings emitted diff --git a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr index 62d00fd6835..33aa95854e3 100644 --- a/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr +++ b/src/test/ui/lint/opaque-ty-ffi-unsafe.stderr @@ -4,12 +4,12 @@ error: `extern` block uses type `A`, which is not FFI-safe LL | pub fn a(_: A); | ^ not FFI-safe | + = note: opaque types have no C equivalent note: the lint level is defined here --> $DIR/opaque-ty-ffi-unsafe.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ - = note: opaque types have no C equivalent error: aborting due to previous error diff --git a/src/test/ui/lint/outer-forbid.stderr b/src/test/ui/lint/outer-forbid.stderr index 78145732105..a47877980a0 100644 --- a/src/test/ui/lint/outer-forbid.stderr +++ b/src/test/ui/lint/outer-forbid.stderr @@ -7,13 +7,13 @@ LL | #![forbid(unused, non_snake_case)] LL | #[allow(unused_variables)] | ^^^^^^^^^^^^^^^^ overruled by previous forbid | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> note: the lint level is defined here --> $DIR/outer-forbid.rs:18:11 | LL | #![forbid(forbidden_lint_groups)] | ^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #81670 <https://github.com/rust-lang/rust/issues/81670> error: allow(unused) incompatible with previous forbid --> $DIR/outer-forbid.rs:25:9 diff --git a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr index bc0c5330324..e31d14c5596 100644 --- a/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr +++ b/src/test/ui/lint/redundant-semicolon/redundant-semi-proc-macro.stderr @@ -1,4 +1,4 @@ -TokenStream [Ident { ident: "fn", span: #0 bytes(198..200) }, Ident { ident: "span_preservation", span: #0 bytes(201..218) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(218..220) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(228..231) }, Ident { ident: "tst", span: #0 bytes(232..235) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(236..237) }, Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(238..241) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(241..242) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(242..243) }, Ident { ident: "match", span: #0 bytes(289..294) }, Ident { ident: "tst", span: #0 bytes(295..298) }, Group { delimiter: Brace, stream: TokenStream [Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(483..486) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(487..489) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(487..489) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(490..492) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(492..493) }, Ident { ident: "_", span: #0 bytes(502..503) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(504..506) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(504..506) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(507..509) }], span: #0 bytes(299..515) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(515..516) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(516..517) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(517..518) }], span: #0 bytes(222..562) }] +TokenStream [Ident { ident: "fn", span: #0 bytes(198..200) }, Ident { ident: "span_preservation", span: #0 bytes(201..218) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(218..220) }, Group { delimiter: Brace, stream: TokenStream [Ident { ident: "let", span: #0 bytes(228..231) }, Ident { ident: "tst", span: #0 bytes(232..235) }, Punct { ch: '=', spacing: Alone, span: #0 bytes(236..237) }, Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(238..241) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(241..242) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(242..243) }, Ident { ident: "match", span: #0 bytes(289..294) }, Ident { ident: "tst", span: #0 bytes(295..298) }, Group { delimiter: Brace, stream: TokenStream [Literal { kind: Integer, symbol: "123", suffix: None, span: #0 bytes(483..486) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(487..488) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(488..489) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(490..492) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(492..493) }, Ident { ident: "_", span: #0 bytes(502..503) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(504..505) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(505..506) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(507..509) }], span: #0 bytes(299..515) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(515..516) }, Punct { ch: ';', spacing: Joint, span: #0 bytes(516..517) }, Punct { ch: ';', spacing: Alone, span: #0 bytes(517..518) }], span: #0 bytes(222..562) }] error: unnecessary trailing semicolon --> $DIR/redundant-semi-proc-macro.rs:9:19 | diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr index 370e51bf70a..2c35647b8a3 100644 --- a/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr @@ -31,8 +31,8 @@ warning: this lint expectation is unfulfilled LL | unused_mut, | ^^^^^^^^^^ | - = note: `#[warn(unfulfilled_lint_expectations)]` on by default = note: this `expect` is overridden by a `allow` attribute before the `unused_mut` lint is triggered + = note: `#[warn(unfulfilled_lint_expectations)]` on by default warning: this lint expectation is unfulfilled --> $DIR/expect_nested_lint_levels.rs:24:5 diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr index 9bfee79b03d..9a1c3e442bb 100644 --- a/src/test/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_unfulfilled_expectation.stderr @@ -4,9 +4,9 @@ warning: this lint expectation is unfulfilled LL | #![expect(unfulfilled_lint_expectations, reason = "idk why you would expect this")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unfulfilled_lint_expectations)]` on by default = note: idk why you would expect this = note: the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message + = note: `#[warn(unfulfilled_lint_expectations)]` on by default warning: this lint expectation is unfulfilled --> $DIR/expect_unfulfilled_expectation.rs:13:10 diff --git a/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr b/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr index 82c1a4c08bb..e349e4081f8 100644 --- a/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr +++ b/src/test/ui/lint/rfc-2383-lint-reason/expect_with_reason.stderr @@ -4,8 +4,8 @@ warning: this lint expectation is unfulfilled LL | #![expect(unused_variables, reason = "<This should fail and display this reason>")] | ^^^^^^^^^^^^^^^^ | - = note: `#[warn(unfulfilled_lint_expectations)]` on by default = note: <This should fail and display this reason> + = note: `#[warn(unfulfilled_lint_expectations)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr b/src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr index 06befcbb511..5942fa8aeb4 100644 --- a/src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr +++ b/src/test/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr @@ -1,11 +1,3 @@ -warning: denote infinite loops with `loop { ... }` - --> $DIR/force_warn_expected_lints_fulfilled.rs:10:5 - | -LL | while true { - | ^^^^^^^^^^ help: use `loop` - | - = note: requested on the command line with `--force-warn while-true` - warning: unused variable: `x` --> $DIR/force_warn_expected_lints_fulfilled.rs:20:9 | @@ -36,5 +28,13 @@ LL | let mut what_does_the_fox_say = "*ding* *deng* *dung*"; | = note: requested on the command line with `--force-warn unused-mut` +warning: denote infinite loops with `loop { ... }` + --> $DIR/force_warn_expected_lints_fulfilled.rs:10:5 + | +LL | while true { + | ^^^^^^^^^^ help: use `loop` + | + = note: requested on the command line with `--force-warn while-true` + warning: 5 warnings emitted diff --git a/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr b/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr index 3bf8137dc6e..3e9d70821b5 100644 --- a/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr +++ b/src/test/ui/lint/rfc-2383-lint-reason/lint-attribute-only-with-reason.stderr @@ -4,12 +4,12 @@ error: unused attribute LL | #[allow(reason = "I want to allow something")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute | + = note: attribute `allow` without any lints has no effect note: the lint level is defined here --> $DIR/lint-attribute-only-with-reason.rs:3:9 | LL | #![deny(unused_attributes)] | ^^^^^^^^^^^^^^^^^ - = note: attribute `allow` without any lints has no effect error: unused attribute --> $DIR/lint-attribute-only-with-reason.rs:6:1 diff --git a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr index 9ca034b71b2..884a4a45382 100644 --- a/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr +++ b/src/test/ui/lint/rfc-2457-non-ascii-idents/lint-mixed-script-confusables.stderr @@ -4,13 +4,13 @@ error: the usage of Script Group `Greek` in this crate consists solely of mixed LL | struct ΑctuallyNotLatin; | ^^^^^^^^^^^^^^^^ | + = note: the usage includes 'Α' (U+0391) + = note: please recheck to make sure their usages are indeed what you want note: the lint level is defined here --> $DIR/lint-mixed-script-confusables.rs:1:9 | LL | #![deny(mixed_script_confusables)] | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the usage includes 'Α' (U+0391) - = note: please recheck to make sure their usages are indeed what you want error: the usage of Script Group `Cyrillic` in this crate consists solely of mixed script confusables --> $DIR/lint-mixed-script-confusables.rs:10:5 diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr b/src/test/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr index 84ad32bddd5..49608c20524 100644 --- a/src/test/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/semicolon-in-expressions-from-macros.stderr @@ -7,15 +7,15 @@ LL | true; LL | foo!(warn_in_block) | ------------------- in this macro invocation | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> + = note: macro invocations at the end of a block are treated as expressions + = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo` note: the lint level is defined here --> $DIR/semicolon-in-expressions-from-macros.rs:4:9 | LL | #![warn(semicolon_in_expressions_from_macros)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> - = note: macro invocations at the end of a block are treated as expressions - = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo` = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) warning: trailing semicolon in macro used in expression position diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr index d770a8c8f36..16c152eb23c 100644 --- a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr +++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr @@ -7,9 +7,9 @@ LL | true; LL | _ => foo!() | ------ in this macro invocation | - = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/src/test/ui/lint/trivial-cast-ice.rs b/src/test/ui/lint/trivial-cast-ice.rs new file mode 100644 index 00000000000..f781fab2212 --- /dev/null +++ b/src/test/ui/lint/trivial-cast-ice.rs @@ -0,0 +1,12 @@ +// aux-build:trivial-cast-ice.rs +// check-pass + +// Demonstrates the ICE in #102561 + +#![deny(trivial_casts)] + +extern crate trivial_cast_ice; + +fn main() { + trivial_cast_ice::foo!(); +} diff --git a/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr b/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr index f7c42acb344..5087807b6c7 100644 --- a/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr +++ b/src/test/ui/lint/trivial-casts-featuring-type-ascription.stderr @@ -4,12 +4,12 @@ error: trivial numeric cast: `i32` as `i32` LL | let lugubrious = 12i32 as i32; | ^^^^^^^^^^^^ | + = help: cast can be replaced by coercion; this might require type ascription or a temporary variable note: the lint level is defined here --> $DIR/trivial-casts-featuring-type-ascription.rs:1:24 | LL | #![deny(trivial_casts, trivial_numeric_casts)] | ^^^^^^^^^^^^^^^^^^^^^ - = help: cast can be replaced by coercion; this might require type ascription or a temporary variable error: trivial cast: `&u32` as `*const u32` --> $DIR/trivial-casts-featuring-type-ascription.rs:8:13 @@ -17,12 +17,12 @@ error: trivial cast: `&u32` as `*const u32` LL | let _ = haunted as *const u32; | ^^^^^^^^^^^^^^^^^^^^^ | + = help: cast can be replaced by coercion; this might require type ascription or a temporary variable note: the lint level is defined here --> $DIR/trivial-casts-featuring-type-ascription.rs:1:9 | LL | #![deny(trivial_casts, trivial_numeric_casts)] | ^^^^^^^^^^^^^ - = help: cast can be replaced by coercion; this might require type ascription or a temporary variable error: aborting due to 2 previous errors diff --git a/src/test/ui/lint/trivial-casts.stderr b/src/test/ui/lint/trivial-casts.stderr index 1544f553cee..7ace353de68 100644 --- a/src/test/ui/lint/trivial-casts.stderr +++ b/src/test/ui/lint/trivial-casts.stderr @@ -4,12 +4,12 @@ error: trivial numeric cast: `i32` as `i32` LL | let lugubrious = 12i32 as i32; | ^^^^^^^^^^^^ | + = help: cast can be replaced by coercion; this might require a temporary variable note: the lint level is defined here --> $DIR/trivial-casts.rs:1:24 | LL | #![deny(trivial_casts, trivial_numeric_casts)] | ^^^^^^^^^^^^^^^^^^^^^ - = help: cast can be replaced by coercion; this might require a temporary variable error: trivial cast: `&u32` as `*const u32` --> $DIR/trivial-casts.rs:7:13 @@ -17,12 +17,12 @@ error: trivial cast: `&u32` as `*const u32` LL | let _ = haunted as *const u32; | ^^^^^^^^^^^^^^^^^^^^^ | + = help: cast can be replaced by coercion; this might require a temporary variable note: the lint level is defined here --> $DIR/trivial-casts.rs:1:9 | LL | #![deny(trivial_casts, trivial_numeric_casts)] | ^^^^^^^^^^^^^ - = help: cast can be replaced by coercion; this might require a temporary variable error: aborting due to 2 previous errors diff --git a/src/test/ui/lint/trivial_casts.stderr b/src/test/ui/lint/trivial_casts.stderr index 8a216360f4e..74f962835c2 100644 --- a/src/test/ui/lint/trivial_casts.stderr +++ b/src/test/ui/lint/trivial_casts.stderr @@ -4,12 +4,12 @@ error: trivial numeric cast: `i32` as `i32` LL | let _ = 42_i32 as i32; | ^^^^^^^^^^^^^ | + = help: cast can be replaced by coercion; this might require a temporary variable note: the lint level is defined here --> $DIR/trivial_casts.rs:4:24 | LL | #![deny(trivial_casts, trivial_numeric_casts)] | ^^^^^^^^^^^^^^^^^^^^^ - = help: cast can be replaced by coercion; this might require a temporary variable error: trivial numeric cast: `u8` as `u8` --> $DIR/trivial_casts.rs:19:13 @@ -25,12 +25,12 @@ error: trivial cast: `&u32` as `*const u32` LL | let _ = x as *const u32; | ^^^^^^^^^^^^^^^ | + = help: cast can be replaced by coercion; this might require a temporary variable note: the lint level is defined here --> $DIR/trivial_casts.rs:4:9 | LL | #![deny(trivial_casts, trivial_numeric_casts)] | ^^^^^^^^^^^^^ - = help: cast can be replaced by coercion; this might require a temporary variable error: trivial cast: `&mut u32` as `*mut u32` --> $DIR/trivial_casts.rs:28:13 diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index 8a31fd44746..62cb1f7f4aa 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -4,13 +4,13 @@ warning: literal out of range for `i8` LL | let error = 255i8; | ^^^^^ | + = note: the literal `255i8` does not fit into the type `i8` whose range is `-128..=127` + = help: consider using the type `u8` instead note: the lint level is defined here --> $DIR/type-overflow.rs:2:9 | LL | #![warn(overflowing_literals)] | ^^^^^^^^^^^^^^^^^^^^ - = note: the literal `255i8` does not fit into the type `i8` whose range is `-128..=127` - = help: consider using the type `u8` instead warning: literal out of range for `i8` --> $DIR/type-overflow.rs:10:16 diff --git a/src/test/ui/lint/unaligned_references.stderr b/src/test/ui/lint/unaligned_references.stderr index 97dbec2861c..346f49b921e 100644 --- a/src/test/ui/lint/unaligned_references.stderr +++ b/src/test/ui/lint/unaligned_references.stderr @@ -4,15 +4,15 @@ error: reference to packed field is unaligned LL | let _ = &good.ptr; | ^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) error: reference to packed field is unaligned --> $DIR/unaligned_references.rs:24:17 @@ -111,15 +111,15 @@ error: reference to packed field is unaligned LL | let _ = &good.ptr; | ^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: error: reference to packed field is unaligned @@ -128,15 +128,15 @@ error: reference to packed field is unaligned LL | let _ = &good.data; | ^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: error: reference to packed field is unaligned @@ -145,15 +145,15 @@ error: reference to packed field is unaligned LL | let _ = &good.data as *const _; | ^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: error: reference to packed field is unaligned @@ -162,15 +162,15 @@ error: reference to packed field is unaligned LL | let _: *const _ = &good.data; | ^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: error: reference to packed field is unaligned @@ -179,15 +179,15 @@ error: reference to packed field is unaligned LL | let _ = good.data.clone(); | ^^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: error: reference to packed field is unaligned @@ -196,15 +196,15 @@ error: reference to packed field is unaligned LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: error: reference to packed field is unaligned @@ -213,15 +213,15 @@ error: reference to packed field is unaligned LL | let _ = &packed2.x; | ^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: error: reference to packed field is unaligned @@ -230,15 +230,15 @@ error: reference to packed field is unaligned LL | let _ref = &m1.1.a; | ^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: error: reference to packed field is unaligned @@ -247,13 +247,13 @@ error: reference to packed field is unaligned LL | let _ref = &m2.1.a; | ^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references.rs:1:9 | LL | #![deny(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/src/test/ui/lint/unaligned_references_external_macro.stderr b/src/test/ui/lint/unaligned_references_external_macro.stderr index 1262c21ee78..c46ca6742a5 100644 --- a/src/test/ui/lint/unaligned_references_external_macro.stderr +++ b/src/test/ui/lint/unaligned_references_external_macro.stderr @@ -10,6 +10,10 @@ LL | | } LL | | } | |_^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references_external_macro.rs:5:1 | @@ -21,10 +25,6 @@ LL | | pub field: u16 LL | | } LL | | } | |_^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) = note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error @@ -42,6 +42,10 @@ LL | | } LL | | } | |_^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/unaligned_references_external_macro.rs:5:1 | @@ -53,9 +57,5 @@ LL | | pub field: u16 LL | | } LL | | } | |_^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) = note: this error originates in the macro `unaligned_references_external_crate::mac` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/lint/unreachable_pub.stderr b/src/test/ui/lint/unreachable_pub.stderr index e021f500c66..762834b97b9 100644 --- a/src/test/ui/lint/unreachable_pub.stderr +++ b/src/test/ui/lint/unreachable_pub.stderr @@ -6,12 +6,12 @@ LL | pub use std::fmt; | | | help: consider restricting its visibility: `pub(crate)` | + = help: or consider exporting it for use by other crates note: the lint level is defined here --> $DIR/unreachable_pub.rs:4:9 | LL | #![warn(unreachable_pub)] | ^^^^^^^^^^^^^^^ - = help: or consider exporting it for use by other crates warning: unreachable `pub` item --> $DIR/unreachable_pub.rs:9:24 diff --git a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr index 26fa6eb9b9b..fe2e3afc82e 100644 --- a/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr +++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr @@ -49,8 +49,8 @@ warning: value assigned to `hours_are_suns` is never read LL | hours_are_suns = false; | ^^^^^^^^^^^^^^ | - = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` warning: unused variable: `fire` --> $DIR/issue-47390-unused-variable-in-struct-pattern.rs:52:32 diff --git a/src/test/ui/lint/unused/must-use-box-from-raw.stderr b/src/test/ui/lint/unused/must-use-box-from-raw.stderr index 7769f09aa52..011acc3bf5d 100644 --- a/src/test/ui/lint/unused/must-use-box-from-raw.stderr +++ b/src/test/ui/lint/unused/must-use-box-from-raw.stderr @@ -4,12 +4,12 @@ warning: unused return value of `Box::<T>::from_raw` that must be used LL | Box::from_raw(ptr); | ^^^^^^^^^^^^^^^^^^^ | + = note: call `drop(from_raw(ptr))` if you intend to drop the `Box` note: the lint level is defined here --> $DIR/must-use-box-from-raw.rs:5:9 | LL | #![warn(unused_must_use)] | ^^^^^^^^^^^^^^^ - = note: call `drop(from_raw(ptr))` if you intend to drop the `Box` warning: 1 warning emitted diff --git a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr index 76978d29dc8..f5199f43c74 100644 --- a/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr +++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr @@ -4,12 +4,12 @@ error: unused implementer of `Iterator` that must be used LL | iterator(); | ^^^^^^^^^^^ | + = note: iterators are lazy and do nothing unless consumed note: the lint level is defined here --> $DIR/must_use-in-stdlib-traits.rs:1:9 | LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ - = note: iterators are lazy and do nothing unless consumed error: unused implementer of `Future` that must be used --> $DIR/must_use-in-stdlib-traits.rs:43:4 diff --git a/src/test/ui/lint/unused/must_use-tuple.stderr b/src/test/ui/lint/unused/must_use-tuple.stderr index e5709a5f0af..63e0318fbb5 100644 --- a/src/test/ui/lint/unused/must_use-tuple.stderr +++ b/src/test/ui/lint/unused/must_use-tuple.stderr @@ -4,12 +4,12 @@ error: unused `Result` in tuple element 0 that must be used LL | (Ok::<(), ()>(()),); | ^^^^^^^^^^^^^^^^ | + = note: this `Result` may be an `Err` variant, which should be handled note: the lint level is defined here --> $DIR/must_use-tuple.rs:1:9 | LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ - = note: this `Result` may be an `Err` variant, which should be handled error: unused `Result` in tuple element 0 that must be used --> $DIR/must_use-tuple.rs:10:6 diff --git a/src/test/ui/lint/unused/unused-attr-duplicate.stderr b/src/test/ui/lint/unused/unused-attr-duplicate.stderr index f592323b550..769b174874b 100644 --- a/src/test/ui/lint/unused/unused-attr-duplicate.stderr +++ b/src/test/ui/lint/unused/unused-attr-duplicate.stderr @@ -4,16 +4,16 @@ error: unused attribute LL | #[no_link] | ^^^^^^^^^^ help: remove this attribute | -note: the lint level is defined here - --> $DIR/unused-attr-duplicate.rs:12:9 - | -LL | #![deny(unused_attributes)] - | ^^^^^^^^^^^^^^^^^ note: attribute also specified here --> $DIR/unused-attr-duplicate.rs:32:1 | LL | #[no_link] | ^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/unused-attr-duplicate.rs:12:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ error: unused attribute --> $DIR/unused-attr-duplicate.rs:37:1 diff --git a/src/test/ui/lint/unused/unused-closure.stderr b/src/test/ui/lint/unused/unused-closure.stderr index 265d3e8e075..4362abd2037 100644 --- a/src/test/ui/lint/unused/unused-closure.stderr +++ b/src/test/ui/lint/unused/unused-closure.stderr @@ -6,12 +6,12 @@ LL | | println!("Hello!"); LL | | }; | |______^ | + = note: closures are lazy and do nothing unless called note: the lint level is defined here --> $DIR/unused-closure.rs:6:9 | LL | #![deny(unused_must_use)] | ^^^^^^^^^^^^^^^ - = note: closures are lazy and do nothing unless called error: unused implementer of `Future` that must be used --> $DIR/unused-closure.rs:13:5 diff --git a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr index 1a022c30938..078b780d8b9 100644 --- a/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr +++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr @@ -23,12 +23,12 @@ LL | LL | _ => false, | ---------- rustdoc does not generate documentation for match arms | + = help: use `//` for a plain comment note: the lint level is defined here --> $DIR/unused-doc-comments-edge-cases.rs:1:9 | LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ - = help: use `//` for a plain comment error: unused doc comment --> $DIR/unused-doc-comments-edge-cases.rs:23:5 diff --git a/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr index f4f5bb71e55..26b1c2b058c 100644 --- a/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr +++ b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr @@ -8,12 +8,12 @@ LL | | /// line3 | | | rustdoc does not generate documentation for macro invocations | + = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion note: the lint level is defined here --> $DIR/unused-doc-comments-for-macros.rs:1:9 | LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ - = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion error: unused doc comment --> $DIR/unused-doc-comments-for-macros.rs:13:5 diff --git a/src/test/ui/lint/unused/unused_attributes-must_use.stderr b/src/test/ui/lint/unused/unused_attributes-must_use.stderr index dd112c23e5d..ce959ddbc46 100644 --- a/src/test/ui/lint/unused/unused_attributes-must_use.stderr +++ b/src/test/ui/lint/unused/unused_attributes-must_use.stderr @@ -4,16 +4,16 @@ error: unused attribute `must_use` LL | #[must_use] | ^^^^^^^^^^^ | -note: the lint level is defined here - --> $DIR/unused_attributes-must_use.rs:2:9 - | -LL | #![deny(unused_attributes, unused_must_use)] - | ^^^^^^^^^^^^^^^^^ note: the built-in attribute `must_use` will be ignored, since it's applied to the macro invocation `global_asm` --> $DIR/unused_attributes-must_use.rs:59:1 | LL | global_asm!(""); | ^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/unused_attributes-must_use.rs:2:9 + | +LL | #![deny(unused_attributes, unused_must_use)] + | ^^^^^^^^^^^^^^^^^ error: `#[must_use]` has no effect when applied to an extern crate --> $DIR/unused_attributes-must_use.rs:5:1 diff --git a/src/test/ui/lint/unused/useless-comment.stderr b/src/test/ui/lint/unused/useless-comment.stderr index 0054426fb1e..8bb5bdaeb25 100644 --- a/src/test/ui/lint/unused/useless-comment.stderr +++ b/src/test/ui/lint/unused/useless-comment.stderr @@ -4,12 +4,12 @@ error: unused doc comment LL | /// foo | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ rustdoc does not generate documentation for macro invocations | + = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion note: the lint level is defined here --> $DIR/useless-comment.rs:3:9 | LL | #![deny(unused_doc_comments)] | ^^^^^^^^^^^^^^^^^^^ - = help: to document an item produced by a macro, the macro must produce the documentation as part of its expansion error: unused doc comment --> $DIR/useless-comment.rs:32:5 diff --git a/src/test/ui/liveness/liveness-asm.stderr b/src/test/ui/liveness/liveness-asm.stderr index d052aca338c..57d89e44dcb 100644 --- a/src/test/ui/liveness/liveness-asm.stderr +++ b/src/test/ui/liveness/liveness-asm.stderr @@ -4,12 +4,12 @@ warning: value assigned to `src` is never read LL | asm!("/*{0}*/", inout(reg) src); | ^^^ | + = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/liveness-asm.rs:7:9 | LL | #![warn(unused_assignments)] | ^^^^^^^^^^^^^^^^^^ - = help: maybe it is overwritten before being read? warning: value assigned to `src` is never read --> $DIR/liveness-asm.rs:24:39 diff --git a/src/test/ui/liveness/liveness-consts.stderr b/src/test/ui/liveness/liveness-consts.stderr index 16209d16c19..6199ea96c98 100644 --- a/src/test/ui/liveness/liveness-consts.stderr +++ b/src/test/ui/liveness/liveness-consts.stderr @@ -4,13 +4,13 @@ warning: variable `a` is assigned to, but never used LL | let mut a = 0; | ^ | + = note: consider using `_a` instead note: the lint level is defined here --> $DIR/liveness-consts.rs:2:9 | LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` - = note: consider using `_a` instead warning: value assigned to `b` is never read --> $DIR/liveness-consts.rs:17:5 @@ -18,8 +18,8 @@ warning: value assigned to `b` is never read LL | b += 1; | ^ | - = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` warning: unused variable: `e` --> $DIR/liveness-consts.rs:24:13 diff --git a/src/test/ui/liveness/liveness-dead.stderr b/src/test/ui/liveness/liveness-dead.stderr index 12680ab1156..de6d5bd993d 100644 --- a/src/test/ui/liveness/liveness-dead.stderr +++ b/src/test/ui/liveness/liveness-dead.stderr @@ -4,12 +4,12 @@ error: value assigned to `x` is never read LL | let mut x: isize = 3; | ^ | + = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/liveness-dead.rs:2:9 | LL | #![deny(unused_assignments)] | ^^^^^^^^^^^^^^^^^^ - = help: maybe it is overwritten before being read? error: value assigned to `x` is never read --> $DIR/liveness-dead.rs:17:5 diff --git a/src/test/ui/liveness/liveness-return-last-stmt-semi.rs b/src/test/ui/liveness/liveness-return-last-stmt-semi.rs index e8909c4a5ae..dff859429c9 100644 --- a/src/test/ui/liveness/liveness-return-last-stmt-semi.rs +++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.rs @@ -1,4 +1,3 @@ -// // regression test for #8005 macro_rules! test { () => { fn foo() -> i32 { 1; } } } diff --git a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr index 82d136bd318..de0843aa637 100644 --- a/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr +++ b/src/test/ui/liveness/liveness-return-last-stmt-semi.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/liveness-return-last-stmt-semi.rs:7:19 + --> $DIR/liveness-return-last-stmt-semi.rs:6:19 | LL | fn no_return() -> i32 {} | --------- ^^^ expected `i32`, found `()` @@ -7,17 +7,17 @@ LL | fn no_return() -> i32 {} | implicitly returns `()` as its body has no tail or `return` expression error[E0308]: mismatched types - --> $DIR/liveness-return-last-stmt-semi.rs:9:19 + --> $DIR/liveness-return-last-stmt-semi.rs:8:19 | LL | fn bar(x: u32) -> u32 { | --- ^^^ expected `u32`, found `()` | | | implicitly returns `()` as its body has no tail or `return` expression LL | x * 2; - | - help: remove this semicolon + | - help: remove this semicolon to return this value error[E0308]: mismatched types - --> $DIR/liveness-return-last-stmt-semi.rs:13:19 + --> $DIR/liveness-return-last-stmt-semi.rs:12:19 | LL | fn baz(x: u64) -> u32 { | --- ^^^ expected `u32`, found `()` @@ -25,7 +25,7 @@ LL | fn baz(x: u64) -> u32 { | implicitly returns `()` as its body has no tail or `return` expression error[E0308]: mismatched types - --> $DIR/liveness-return-last-stmt-semi.rs:4:41 + --> $DIR/liveness-return-last-stmt-semi.rs:3:41 | LL | macro_rules! test { () => { fn foo() -> i32 { 1; } } } | --- ^^^ expected `i32`, found `()` diff --git a/src/test/ui/liveness/liveness-unused.stderr b/src/test/ui/liveness/liveness-unused.stderr index 4a6122681a9..f6c478ddbc7 100644 --- a/src/test/ui/liveness/liveness-unused.stderr +++ b/src/test/ui/liveness/liveness-unused.stderr @@ -57,12 +57,12 @@ error: value assigned to `x` is never read LL | x += 4; | ^ | + = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/liveness-unused.rs:3:9 | LL | #![deny(unused_assignments)] | ^^^^^^^^^^^^^^^^^^ - = help: maybe it is overwritten before being read? error: variable `z` is assigned to, but never used --> $DIR/liveness-unused.rs:37:13 diff --git a/src/test/ui/liveness/liveness-upvars.stderr b/src/test/ui/liveness/liveness-upvars.stderr index cb104e0a3fd..82f62371ec5 100644 --- a/src/test/ui/liveness/liveness-upvars.stderr +++ b/src/test/ui/liveness/liveness-upvars.stderr @@ -4,13 +4,13 @@ warning: value assigned to `last` is never read LL | last = Some(s); | ^^^^ | + = help: maybe it is overwritten before being read? note: the lint level is defined here --> $DIR/liveness-upvars.rs:4:9 | LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` - = help: maybe it is overwritten before being read? warning: unused variable: `last` --> $DIR/liveness-upvars.rs:10:9 @@ -18,8 +18,8 @@ warning: unused variable: `last` LL | last = Some(s); | ^^^^ | - = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` = help: did you mean to capture by reference instead? + = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` warning: unused variable: `sum` --> $DIR/liveness-upvars.rs:22:9 diff --git a/src/test/ui/macros/issue-39404.stderr b/src/test/ui/macros/issue-39404.stderr index d2f2a823c2a..3886a70bb15 100644 --- a/src/test/ui/macros/issue-39404.stderr +++ b/src/test/ui/macros/issue-39404.stderr @@ -4,9 +4,9 @@ error: missing fragment specifier LL | macro_rules! m { ($i) => {} } | ^^ | - = note: `#[deny(missing_fragment_specifier)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> + = note: `#[deny(missing_fragment_specifier)]` on by default error: aborting due to previous error diff --git a/src/test/ui/macros/issue-84195-lint-anon-const.stderr b/src/test/ui/macros/issue-84195-lint-anon-const.stderr index 39485d74e5e..306c08b1357 100644 --- a/src/test/ui/macros/issue-84195-lint-anon-const.stderr +++ b/src/test/ui/macros/issue-84195-lint-anon-const.stderr @@ -7,13 +7,13 @@ LL | () => { 0; }; LL | let val: [u8; len!()] = []; | ------ in this macro invocation | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> note: the lint level is defined here --> $DIR/issue-84195-lint-anon-const.rs:5:9 | LL | #![deny(semicolon_in_expressions_from_macros)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> = note: this error originates in the macro `len` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/macros/lint-trailing-macro-call.stderr b/src/test/ui/macros/lint-trailing-macro-call.stderr index a98a559c8af..6ab121f7c06 100644 --- a/src/test/ui/macros/lint-trailing-macro-call.stderr +++ b/src/test/ui/macros/lint-trailing-macro-call.stderr @@ -7,11 +7,11 @@ LL | #[cfg(FALSE)] 25; LL | expand_it!() | ------------ in this macro invocation | - = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> = note: macro invocations at the end of a block are treated as expressions = note: to ignore the value produced by the macro, add a semicolon after the invocation of `expand_it` + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default = note: this warning originates in the macro `expand_it` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr index 5dc17807031..2a2e0c6c66a 100644 --- a/src/test/ui/macros/macro-context.stderr +++ b/src/test/ui/macros/macro-context.stderr @@ -73,9 +73,9 @@ LL | () => ( i ; typeof ); LL | let i = m!(); | ---- in this macro invocation | - = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors; 1 warning emitted diff --git a/src/test/ui/macros/macro-in-expression-context.stderr b/src/test/ui/macros/macro-in-expression-context.stderr index 1840babd61d..1023189eaa3 100644 --- a/src/test/ui/macros/macro-in-expression-context.stderr +++ b/src/test/ui/macros/macro-in-expression-context.stderr @@ -20,11 +20,11 @@ LL | assert_eq!("A", "A"); LL | foo!() | ------ in this macro invocation | - = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813> = note: macro invocations at the end of a block are treated as expressions = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo` + = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/macros/macro-match-nonterminal.stderr b/src/test/ui/macros/macro-match-nonterminal.stderr index 48b9bc6ff6a..ef7261c0239 100644 --- a/src/test/ui/macros/macro-match-nonterminal.stderr +++ b/src/test/ui/macros/macro-match-nonterminal.stderr @@ -10,9 +10,9 @@ error: missing fragment specifier LL | ($a, $b) => { | ^ | - = note: `#[deny(missing_fragment_specifier)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> + = note: `#[deny(missing_fragment_specifier)]` on by default error: missing fragment specifier --> $DIR/macro-match-nonterminal.rs:2:10 diff --git a/src/test/ui/macros/macro-missing-fragment-deduplication.stderr b/src/test/ui/macros/macro-missing-fragment-deduplication.stderr index 7622ca054c8..3b9e716e194 100644 --- a/src/test/ui/macros/macro-missing-fragment-deduplication.stderr +++ b/src/test/ui/macros/macro-missing-fragment-deduplication.stderr @@ -10,9 +10,9 @@ error: missing fragment specifier LL | ($name) => {} | ^^^^^ | - = note: `#[deny(missing_fragment_specifier)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> + = note: `#[deny(missing_fragment_specifier)]` on by default error: aborting due to 2 previous errors diff --git a/src/test/ui/macros/macro-missing-fragment.stderr b/src/test/ui/macros/macro-missing-fragment.stderr index 1bf6f04ec7f..2aa1e58f6b1 100644 --- a/src/test/ui/macros/macro-missing-fragment.stderr +++ b/src/test/ui/macros/macro-missing-fragment.stderr @@ -10,13 +10,13 @@ warning: missing fragment specifier LL | ( $( any_token $field_rust_type )* ) => {}; | ^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> note: the lint level is defined here --> $DIR/macro-missing-fragment.rs:1:9 | LL | #![warn(missing_fragment_specifier)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> warning: missing fragment specifier --> $DIR/macro-missing-fragment.rs:12:7 diff --git a/src/test/ui/macros/macro-or-patterns-back-compat.stderr b/src/test/ui/macros/macro-or-patterns-back-compat.stderr index 9a5b8009f32..e04dfefa4e8 100644 --- a/src/test/ui/macros/macro-or-patterns-back-compat.stderr +++ b/src/test/ui/macros/macro-or-patterns-back-compat.stderr @@ -4,13 +4,13 @@ error: the meaning of the `pat` fragment specifier is changing in Rust 2021, whi LL | macro_rules! foo { ($x:pat | $y:pat) => {} } | ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html> note: the lint level is defined here --> $DIR/macro-or-patterns-back-compat.rs:4:9 | LL | #![deny(rust_2021_incompatible_or_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/or-patterns-macro-rules.html> error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro --> $DIR/macro-or-patterns-back-compat.rs:13:23 diff --git a/src/test/ui/macros/macro-use-all-and-none.stderr b/src/test/ui/macros/macro-use-all-and-none.stderr index 6de7ffb2f63..00b10dccd00 100644 --- a/src/test/ui/macros/macro-use-all-and-none.stderr +++ b/src/test/ui/macros/macro-use-all-and-none.stderr @@ -4,12 +4,12 @@ warning: unused attribute LL | #[macro_use()] | ^^^^^^^^^^^^^^ help: remove this attribute | + = note: attribute `macro_use` with an empty list has no effect note: the lint level is defined here --> $DIR/macro-use-all-and-none.rs:4:9 | LL | #![warn(unused_attributes)] | ^^^^^^^^^^^^^^^^^ - = note: attribute `macro_use` with an empty list has no effect warning: 1 warning emitted diff --git a/src/test/ui/macros/macros-nonfatal-errors.rs b/src/test/ui/macros/macros-nonfatal-errors.rs index e7a01f105de..140cc5b0fd8 100644 --- a/src/test/ui/macros/macros-nonfatal-errors.rs +++ b/src/test/ui/macros/macros-nonfatal-errors.rs @@ -116,3 +116,24 @@ fn main() { trace_macros!(invalid); //~ ERROR } + +/// Check that `#[derive(Default)]` does use a `T : Default` bound when the +/// `#[default]` variant is `#[non_exhaustive]` (should this end up allowed). +const _: () = { + #[derive(Default)] + enum NonExhaustiveDefaultGeneric<T> { + #[default] + #[non_exhaustive] + Foo, //~ ERROR default variant must be exhaustive + Bar(T), + } + + fn assert_impls_default<T: Default>() {} + + enum NotDefault {} + + // Note: the `derive(Default)` currently bails early enough for trait-checking + // not to happen. Should it bail late enough, or even pass, make sure to + // assert that the following line fails. + let _ = assert_impls_default::<NonExhaustiveDefaultGeneric<NotDefault>>; +}; diff --git a/src/test/ui/macros/macros-nonfatal-errors.stderr b/src/test/ui/macros/macros-nonfatal-errors.stderr index b3c6d07f967..d42f6c179b7 100644 --- a/src/test/ui/macros/macros-nonfatal-errors.stderr +++ b/src/test/ui/macros/macros-nonfatal-errors.stderr @@ -215,11 +215,21 @@ error: trace_macros! accepts only `true` or `false` LL | trace_macros!(invalid); | ^^^^^^^^^^^^^^^^^^^^^^ +error: default variant must be exhaustive + --> $DIR/macros-nonfatal-errors.rs:127:9 + | +LL | #[non_exhaustive] + | ----------------- declared `#[non_exhaustive]` here +LL | Foo, + | ^^^ + | + = help: consider a manual implementation of `Default` + error: cannot find macro `llvm_asm` in this scope --> $DIR/macros-nonfatal-errors.rs:99:5 | LL | llvm_asm!(invalid); | ^^^^^^^^ -error: aborting due to 27 previous errors +error: aborting due to 28 previous errors diff --git a/src/test/ui/macros/must-use-in-macro-55516.stderr b/src/test/ui/macros/must-use-in-macro-55516.stderr index b56b00cc7d9..8878b0eea0f 100644 --- a/src/test/ui/macros/must-use-in-macro-55516.stderr +++ b/src/test/ui/macros/must-use-in-macro-55516.stderr @@ -4,8 +4,8 @@ warning: unused `Result` that must be used LL | write!(&mut example, "{}", 42); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-W unused-must-use` implied by `-W unused` = note: this `Result` may be an `Err` variant, which should be handled + = note: `-W unused-must-use` implied by `-W unused` = note: this warning originates in the macro `write` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/src/test/ui/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr index 8c2625bdf0d..9bfbe7ebafd 100644 --- a/src/test/ui/malformed/malformed-regressions.stderr +++ b/src/test/ui/malformed/malformed-regressions.stderr @@ -4,9 +4,9 @@ error: attribute must be of the form `#[doc(hidden|inline|...)]` or `#[doc = "st LL | #[doc] | ^^^^^^ | - = note: `#[deny(ill_formed_attribute_input)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> + = note: `#[deny(ill_formed_attribute_input)]` on by default error: attribute must be of the form `#[ignore]` or `#[ignore = "reason"]` --> $DIR/malformed-regressions.rs:3:1 diff --git a/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr b/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr index fca98662708..649e58915d0 100644 --- a/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr +++ b/src/test/ui/marker_trait_attr/overlap-doesnt-conflict-with-specialization.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/match/issue-41255.stderr b/src/test/ui/match/issue-41255.stderr index bf81c8d371c..596d6fad38b 100644 --- a/src/test/ui/match/issue-41255.stderr +++ b/src/test/ui/match/issue-41255.stderr @@ -4,13 +4,13 @@ error: floating-point types cannot be used in patterns LL | 5.0 => {}, | ^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> note: the lint level is defined here --> $DIR/issue-41255.rs:6:11 | LL | #![forbid(illegal_floating_point_literal_pattern)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> error: floating-point types cannot be used in patterns --> $DIR/issue-41255.rs:13:9 diff --git a/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr b/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr index 9e07d5ea31e..394c1ac3c09 100644 --- a/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-lint-fail.stderr @@ -7,13 +7,13 @@ LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} LL | S.late::<'static>(&0, &0); | ^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> note: the lint level is defined here --> $DIR/method-call-lifetime-args-lint-fail.rs:1:9 | LL | #![deny(late_bound_lifetime_arguments)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present --> $DIR/method-call-lifetime-args-lint-fail.rs:26:14 diff --git a/src/test/ui/methods/method-call-lifetime-args-lint.stderr b/src/test/ui/methods/method-call-lifetime-args-lint.stderr index f31f510a3a7..b4fc2d71761 100644 --- a/src/test/ui/methods/method-call-lifetime-args-lint.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-lint.stderr @@ -7,13 +7,13 @@ LL | fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} LL | S.late::<'static>(&0, &0); | ^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> note: the lint level is defined here --> $DIR/method-call-lifetime-args-lint.rs:1:9 | LL | #![deny(late_bound_lifetime_arguments)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present --> $DIR/method-call-lifetime-args-lint.rs:16:23 diff --git a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr index 78af19586a1..62f20d6d50c 100644 --- a/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr +++ b/src/test/ui/methods/method-call-lifetime-args-unresolved.stderr @@ -17,9 +17,9 @@ LL | 0.clone::<'a>(); LL | fn clone(&self) -> Self; | - the late bound lifetime parameter is introduced here | - = note: `#[warn(late_bound_lifetime_arguments)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868> + = note: `#[warn(late_bound_lifetime_arguments)]` on by default error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index 59075397ea5..82addab9479 100644 --- a/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/src/test/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a LL | #![feature(unsized_locals, unsized_fn_params)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + = note: `#[warn(incomplete_features)]` on by default error[E0308]: mismatched types --> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:87:24 diff --git a/src/test/ui/mir/thir-constparam-temp.stderr b/src/test/ui/mir/thir-constparam-temp.stderr index ed2766c000e..b77d67e084f 100644 --- a/src/test/ui/mir/thir-constparam-temp.stderr +++ b/src/test/ui/mir/thir-constparam-temp.stderr @@ -4,7 +4,6 @@ warning: taking a mutable reference to a `const` item LL | YIKES.mut_self() | ^^^^^^^^^^^^^^^^ | - = note: `#[warn(const_item_mutation)]` on by default = note: each usage of a `const` item creates a new temporary = note: the mutable reference will refer to this temporary, not the original `const` item note: mutable reference created due to call to this method @@ -17,6 +16,7 @@ note: `const` item defined here | LL | fn foo<const YIKES: Yikes>() { | ^^^^^^^^^^^^^^^^^^ + = note: `#[warn(const_item_mutation)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/modules/special_module_name.stderr b/src/test/ui/modules/special_module_name.stderr index 8b3da29386d..bc4b4f1b318 100644 --- a/src/test/ui/modules/special_module_name.stderr +++ b/src/test/ui/modules/special_module_name.stderr @@ -20,9 +20,9 @@ warning: found module declaration for lib.rs LL | mod lib; | ^^^^^^^^ | - = note: `#[warn(special_module_name)]` on by default = note: lib.rs is the root of this crate's library target = help: to refer to it from other targets, use the library's name as the path + = note: `#[warn(special_module_name)]` on by default warning: found module declaration for main.rs --> $DIR/special_module_name.rs:4:1 diff --git a/src/test/ui/moves/move-out-of-slice-2.stderr b/src/test/ui/moves/move-out-of-slice-2.stderr index 93b0dcfc2d1..46357ce6f2e 100644 --- a/src/test/ui/moves/move-out-of-slice-2.stderr +++ b/src/test/ui/moves/move-out-of-slice-2.stderr @@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a LL | #![feature(unsized_locals)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + = note: `#[warn(incomplete_features)]` on by default error[E0508]: cannot move out of type `[A]`, a non-copy slice --> $DIR/move-out-of-slice-2.rs:10:11 diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr index 3c0daa4c55f..0910e9ad77a 100644 --- a/src/test/ui/never_type/issue-52443.stderr +++ b/src/test/ui/never_type/issue-52443.stderr @@ -47,8 +47,8 @@ LL | [(); { for _ in 0usize.. {}; 0}]; note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | -LL | impl<I: ~const Iterator> const IntoIterator for I { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<I: Iterator> const IntoIterator for I { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0658]: mutable references are not allowed in constants diff --git a/src/test/ui/nll/issue-48623-generator.stderr b/src/test/ui/nll/issue-48623-generator.stderr index 70a83e46ff0..1b35165db45 100644 --- a/src/test/ui/nll/issue-48623-generator.stderr +++ b/src/test/ui/nll/issue-48623-generator.stderr @@ -4,8 +4,8 @@ warning: unused generator that must be used LL | move || { d; yield; &mut *r }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unused_must_use)]` on by default = note: generators are lazy and do nothing unless resumed + = note: `#[warn(unused_must_use)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/nll/issue-51191.stderr b/src/test/ui/nll/issue-51191.stderr index 9f4e971f909..63ca6ae5c28 100644 --- a/src/test/ui/nll/issue-51191.stderr +++ b/src/test/ui/nll/issue-51191.stderr @@ -7,8 +7,8 @@ LL | fn bar(self: &mut Self) { LL | (&mut self).bar(); | ----------------- recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default error[E0596]: cannot borrow `self` as mutable, as it is not declared as mutable --> $DIR/issue-51191.rs:7:9 diff --git a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr index 330c6fafa2d..6a8a1ad1caa 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-captures.stderr @@ -1,14 +1,14 @@ -error[E0700]: hidden type for `Opaque(DefId(0:11 ~ impl_trait_captures[1afc]::foo::{opaque#0}), [ReStatic, T, ReEarlyBound(0, 'a)])` captures lifetime that does not appear in bounds +error[E0700]: hidden type for `Opaque(DefId(0:13 ~ impl_trait_captures[1afc]::foo::{opaque#0}), [ReStatic, T, ReEarlyBound(0, 'a)])` captures lifetime that does not appear in bounds --> $DIR/impl-trait-captures.rs:11:5 | LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> { - | -- hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_)) T` captures the anonymous lifetime defined here + | -- hidden type `&ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[1afc]::foo::'_), '_)) T` captures the anonymous lifetime defined here LL | x | ^ | -help: to declare that the `impl Trait` captures `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_))`, you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_))` lifetime bound +help: to declare that the `impl Trait` captures `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[1afc]::foo::'_), '_))`, you can add an explicit `ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[1afc]::foo::'_), '_))` lifetime bound | -LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:13 ~ impl_trait_captures[1afc]::foo::'_), '_)) { +LL | fn foo<'a, T>(x: &T) -> impl Foo<'a> + ReFree(DefId(0:8 ~ impl_trait_captures[1afc]::foo), BrNamed(DefId(0:12 ~ impl_trait_captures[1afc]::foo::'_), '_)) { | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/no-patterns-in-args-2.stderr b/src/test/ui/no-patterns-in-args-2.stderr index 98932349a79..6adcbb9dccd 100644 --- a/src/test/ui/no-patterns-in-args-2.stderr +++ b/src/test/ui/no-patterns-in-args-2.stderr @@ -10,13 +10,13 @@ error: patterns aren't allowed in functions without bodies LL | fn f1(mut arg: u8); | ^^^^^^^ help: remove `mut` from the parameter: `arg` | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203> note: the lint level is defined here --> $DIR/no-patterns-in-args-2.rs:1:9 | LL | #![deny(patterns_in_fns_without_body)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203> error: aborting due to 2 previous errors diff --git a/src/test/ui/non-fmt-panic.stderr b/src/test/ui/non-fmt-panic.stderr index 6e4434e6f33..162802b7f61 100644 --- a/src/test/ui/non-fmt-panic.stderr +++ b/src/test/ui/non-fmt-panic.stderr @@ -4,8 +4,8 @@ warning: panic message contains a brace LL | panic!("here's a brace: {"); | ^ | - = note: `#[warn(non_fmt_panics)]` on by default = note: this message is not used as a format string, but will be in Rust 2021 + = note: `#[warn(non_fmt_panics)]` on by default help: add a "{}" format string to use the message literally | LL | panic!("{}", "here's a brace: {"); diff --git a/src/test/ui/packed/issue-27060-rpass.stderr b/src/test/ui/packed/issue-27060-rpass.stderr index 667b70afb87..adf9ae9f56f 100644 --- a/src/test/ui/packed/issue-27060-rpass.stderr +++ b/src/test/ui/packed/issue-27060-rpass.stderr @@ -5,15 +5,15 @@ warning: reference to packed field is unaligned LL | let _ = &good.data; // ok | ^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/issue-27060-rpass.rs:11:9 | LL | #[allow(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: warning: reference to packed field is unaligned @@ -22,15 +22,15 @@ warning: reference to packed field is unaligned LL | let _ = &good.data2[0]; // ok | ^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/issue-27060-rpass.rs:11:9 | LL | #[allow(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: warning: reference to packed field is unaligned @@ -39,15 +39,15 @@ warning: reference to packed field is unaligned LL | let _ = &good.data; | ^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/issue-27060-rpass.rs:11:9 | LL | #[allow(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: warning: reference to packed field is unaligned @@ -56,13 +56,13 @@ warning: reference to packed field is unaligned LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/issue-27060-rpass.rs:11:9 | LL | #[allow(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/src/test/ui/packed/issue-27060.stderr b/src/test/ui/packed/issue-27060.stderr index 1bab16e6dda..85e08fa02dd 100644 --- a/src/test/ui/packed/issue-27060.stderr +++ b/src/test/ui/packed/issue-27060.stderr @@ -4,11 +4,11 @@ error: reference to packed field is unaligned LL | let _ = &good.data; | ^^^^^^^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default error: reference to packed field is unaligned --> $DIR/issue-27060.rs:17:13 @@ -52,11 +52,11 @@ error: reference to packed field is unaligned LL | let _ = &good.data; | ^^^^^^^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default Future breakage diagnostic: error: reference to packed field is unaligned @@ -65,11 +65,11 @@ error: reference to packed field is unaligned LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default Future breakage diagnostic: error: reference to packed field is unaligned @@ -78,11 +78,11 @@ error: reference to packed field is unaligned LL | let _ = &good.data; | ^^^^^^^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default Future breakage diagnostic: error: reference to packed field is unaligned @@ -91,9 +91,9 @@ error: reference to packed field is unaligned LL | let _ = &good.data2[0]; | ^^^^^^^^^^^^^^ | - = note: `#[deny(unaligned_references)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) + = note: `#[deny(unaligned_references)]` on by default diff --git a/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr index dcd1c19fa16..fb2f5615c53 100644 --- a/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr +++ b/src/test/ui/packed/packed-struct-borrow-element-64bit.stderr @@ -4,15 +4,15 @@ warning: reference to packed field is unaligned LL | let brw = &foo.baz; | ^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/packed-struct-borrow-element-64bit.rs:12:8 | LL | #[warn(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) warning: 1 warning emitted @@ -23,13 +23,13 @@ warning: reference to packed field is unaligned LL | let brw = &foo.baz; | ^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/packed-struct-borrow-element-64bit.rs:12:8 | LL | #[warn(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/src/test/ui/packed/packed-struct-borrow-element.stderr b/src/test/ui/packed/packed-struct-borrow-element.stderr index fb483227e20..75d55c4f693 100644 --- a/src/test/ui/packed/packed-struct-borrow-element.stderr +++ b/src/test/ui/packed/packed-struct-borrow-element.stderr @@ -4,15 +4,15 @@ warning: reference to packed field is unaligned LL | let brw = &foo.baz; | ^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/packed-struct-borrow-element.rs:23:8 | LL | #[warn(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) warning: reference to packed field is unaligned --> $DIR/packed-struct-borrow-element.rs:31:15 @@ -34,15 +34,15 @@ warning: reference to packed field is unaligned LL | let brw = &foo.baz; | ^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/packed-struct-borrow-element.rs:23:8 | LL | #[warn(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) Future breakage diagnostic: warning: reference to packed field is unaligned @@ -51,13 +51,13 @@ warning: reference to packed field is unaligned LL | let brw = &foo.baz; | ^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> + = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) + = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) note: the lint level is defined here --> $DIR/packed-struct-borrow-element.rs:23:8 | LL | #[warn(unaligned_references)] | ^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> - = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced) - = help: copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers) diff --git a/src/test/ui/parser/assoc-static-semantic-fail.stderr b/src/test/ui/parser/assoc-static-semantic-fail.stderr index 7ae092cee67..8a74f49b95c 100644 --- a/src/test/ui/parser/assoc-static-semantic-fail.stderr +++ b/src/test/ui/parser/assoc-static-semantic-fail.stderr @@ -168,9 +168,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error: aborting due to 24 previous errors; 1 warning emitted diff --git a/src/test/ui/parser/default.stderr b/src/test/ui/parser/default.stderr index 5b763ae72f5..37aa48ccf52 100644 --- a/src/test/ui/parser/default.stderr +++ b/src/test/ui/parser/default.stderr @@ -29,9 +29,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0046]: not all trait items implemented, missing: `foo` --> $DIR/default.rs:22:1 diff --git a/src/test/ui/parser/doc-after-struct-field.rs b/src/test/ui/parser/doc-after-struct-field.rs index 5b6f0803603..03faa6733e2 100644 --- a/src/test/ui/parser/doc-after-struct-field.rs +++ b/src/test/ui/parser/doc-after-struct-field.rs @@ -1,13 +1,13 @@ struct X { a: u8 /** document a */, //~^ ERROR found a documentation comment that doesn't document anything - //~| HELP maybe a comment was intended + //~| HELP if a comment was intended use `//` } struct Y { a: u8 /// document a //~^ ERROR found a documentation comment that doesn't document anything - //~| HELP maybe a comment was intended + //~| HELP if a comment was intended use `//` } fn main() { diff --git a/src/test/ui/parser/doc-after-struct-field.stderr b/src/test/ui/parser/doc-after-struct-field.stderr index e3b32a7f035..ae177f1a2d1 100644 --- a/src/test/ui/parser/doc-after-struct-field.stderr +++ b/src/test/ui/parser/doc-after-struct-field.stderr @@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything LL | a: u8 /** document a */, | ^^^^^^^^^^^^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error[E0585]: found a documentation comment that doesn't document anything --> $DIR/doc-after-struct-field.rs:8:11 @@ -12,7 +12,7 @@ error[E0585]: found a documentation comment that doesn't document anything LL | a: u8 /// document a | ^^^^^^^^^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to 2 previous errors diff --git a/src/test/ui/parser/doc-before-extern-rbrace.stderr b/src/test/ui/parser/doc-before-extern-rbrace.stderr index 0edceb268a7..8fa12ec261e 100644 --- a/src/test/ui/parser/doc-before-extern-rbrace.stderr +++ b/src/test/ui/parser/doc-before-extern-rbrace.stderr @@ -4,7 +4,7 @@ error[E0584]: found a documentation comment that doesn't document anything LL | /// hi | ^^^^^^ this doc comment doesn't document anything | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/parser/doc-before-fn-rbrace.rs b/src/test/ui/parser/doc-before-fn-rbrace.rs index eb355136f1e..c8502164854 100644 --- a/src/test/ui/parser/doc-before-fn-rbrace.rs +++ b/src/test/ui/parser/doc-before-fn-rbrace.rs @@ -1,5 +1,5 @@ fn main() { /// document //~^ ERROR found a documentation comment that doesn't document anything - //~| HELP maybe a comment was intended + //~| HELP if a comment was intended use `//` } diff --git a/src/test/ui/parser/doc-before-fn-rbrace.stderr b/src/test/ui/parser/doc-before-fn-rbrace.stderr index 56241de7092..6ea68e42b4c 100644 --- a/src/test/ui/parser/doc-before-fn-rbrace.stderr +++ b/src/test/ui/parser/doc-before-fn-rbrace.stderr @@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything LL | /// document | ^^^^^^^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/parser/doc-before-rbrace.rs b/src/test/ui/parser/doc-before-rbrace.rs index 8ff946344ae..570306f2cdf 100644 --- a/src/test/ui/parser/doc-before-rbrace.rs +++ b/src/test/ui/parser/doc-before-rbrace.rs @@ -1,5 +1,5 @@ fn main() { println!("Hi"); /// hi //~^ ERROR found a documentation comment that doesn't document anything - //~| HELP maybe a comment was intended + //~| HELP if a comment was intended use `//` } diff --git a/src/test/ui/parser/doc-before-rbrace.stderr b/src/test/ui/parser/doc-before-rbrace.stderr index 55719cf6411..4d4741dfe59 100644 --- a/src/test/ui/parser/doc-before-rbrace.stderr +++ b/src/test/ui/parser/doc-before-rbrace.stderr @@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything LL | println!("Hi"); /// hi | ^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/parser/doc-before-semi.rs b/src/test/ui/parser/doc-before-semi.rs index 405a7e1e2a3..444b5874ea2 100644 --- a/src/test/ui/parser/doc-before-semi.rs +++ b/src/test/ui/parser/doc-before-semi.rs @@ -1,6 +1,6 @@ fn main() { /// hi //~^ ERROR found a documentation comment that doesn't document anything - //~| HELP maybe a comment was intended + //~| HELP if a comment was intended use `//` ; } diff --git a/src/test/ui/parser/doc-before-semi.stderr b/src/test/ui/parser/doc-before-semi.stderr index e6bade18d0a..a879e13ffbd 100644 --- a/src/test/ui/parser/doc-before-semi.stderr +++ b/src/test/ui/parser/doc-before-semi.stderr @@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything LL | /// hi | ^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/parser/doc-before-struct-rbrace-1.rs b/src/test/ui/parser/doc-before-struct-rbrace-1.rs index 3866a3105c2..0c8d90c3b03 100644 --- a/src/test/ui/parser/doc-before-struct-rbrace-1.rs +++ b/src/test/ui/parser/doc-before-struct-rbrace-1.rs @@ -2,7 +2,7 @@ struct X { a: u8, /// document //~^ ERROR found a documentation comment that doesn't document anything - //~| HELP maybe a comment was intended + //~| HELP if a comment was intended use `//` } fn main() { diff --git a/src/test/ui/parser/doc-before-struct-rbrace-1.stderr b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr index 92b5133b74d..94934f734b3 100644 --- a/src/test/ui/parser/doc-before-struct-rbrace-1.stderr +++ b/src/test/ui/parser/doc-before-struct-rbrace-1.stderr @@ -7,7 +7,7 @@ LL | a: u8, LL | /// document | ^^^^^^^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/parser/doc-before-struct-rbrace-2.rs b/src/test/ui/parser/doc-before-struct-rbrace-2.rs index dda138f1a88..2b2aadf7984 100644 --- a/src/test/ui/parser/doc-before-struct-rbrace-2.rs +++ b/src/test/ui/parser/doc-before-struct-rbrace-2.rs @@ -1,7 +1,7 @@ struct X { a: u8 /// document //~^ ERROR found a documentation comment that doesn't document anything - //~| HELP maybe a comment was intended + //~| HELP if a comment was intended use `//` } fn main() { diff --git a/src/test/ui/parser/doc-before-struct-rbrace-2.stderr b/src/test/ui/parser/doc-before-struct-rbrace-2.stderr index b25ccab79f9..6b5c8c1f8b5 100644 --- a/src/test/ui/parser/doc-before-struct-rbrace-2.stderr +++ b/src/test/ui/parser/doc-before-struct-rbrace-2.stderr @@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything LL | a: u8 /// document | ^^^^^^^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/parser/doc-inside-trait-item.stderr b/src/test/ui/parser/doc-inside-trait-item.stderr index 246255a0a46..900124adcc3 100644 --- a/src/test/ui/parser/doc-inside-trait-item.stderr +++ b/src/test/ui/parser/doc-inside-trait-item.stderr @@ -4,7 +4,7 @@ error[E0584]: found a documentation comment that doesn't document anything LL | /// empty doc | ^^^^^^^^^^^^^ this doc comment doesn't document anything | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr index 9b939f05e02..2b6314c38ce 100644 --- a/src/test/ui/parser/expr-as-stmt-2.stderr +++ b/src/test/ui/parser/expr-as-stmt-2.stderr @@ -36,11 +36,6 @@ LL | / && LL | | if let Some(y) = a { true } else { false } | |______________________________________________^ expected `bool`, found `&&bool` | -help: consider removing the `&&` - | -LL - && -LL + if let Some(y) = a { true } else { false } - | help: parentheses are required to parse this as an expression | LL | (if let Some(x) = a { true } else { false }) diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr index 858b4e8db05..6da4ac34067 100644 --- a/src/test/ui/parser/expr-as-stmt.stderr +++ b/src/test/ui/parser/expr-as-stmt.stderr @@ -170,11 +170,6 @@ LL | fn revenge_from_mars() -> bool { LL | { true } && { true } | ^^^^^^^^^^^ expected `bool`, found `&&bool` | -help: consider removing the `&&` - | -LL - { true } && { true } -LL + { true } { true } - | help: parentheses are required to parse this as an expression | LL | ({ true }) && { true } @@ -201,10 +196,6 @@ LL | { true } || { true } | = note: expected type `bool` found closure `[closure@$DIR/expr-as-stmt.rs:51:14: 51:16]` -help: use parentheses to call this closure - | -LL | { true } (|| { true })() - | + +++ help: parentheses are required to parse this as an expression | LL | ({ true }) || { true } diff --git a/src/test/ui/parser/fn-field-parse-error-ice.rs b/src/test/ui/parser/fn-field-parse-error-ice.rs index 4ea55062fc4..188257ea53a 100644 --- a/src/test/ui/parser/fn-field-parse-error-ice.rs +++ b/src/test/ui/parser/fn-field-parse-error-ice.rs @@ -3,7 +3,7 @@ struct Baz { inner : dyn fn () //~^ ERROR expected `,`, or `}`, found keyword `fn` - //~| ERROR functions are not allowed in struct definitions + //~| ERROR expected identifier, found keyword `fn` //~| ERROR cannot find type `dyn` in this scope } diff --git a/src/test/ui/parser/fn-field-parse-error-ice.stderr b/src/test/ui/parser/fn-field-parse-error-ice.stderr index e9583f55b8e..3bf68e8cc04 100644 --- a/src/test/ui/parser/fn-field-parse-error-ice.stderr +++ b/src/test/ui/parser/fn-field-parse-error-ice.stderr @@ -4,16 +4,18 @@ error: expected `,`, or `}`, found keyword `fn` LL | inner : dyn fn () | ^ help: try adding a comma: `,` -error: functions are not allowed in struct definitions +error: expected identifier, found keyword `fn` --> $DIR/fn-field-parse-error-ice.rs:4:17 | LL | struct Baz { | --- while parsing this struct LL | inner : dyn fn () - | ^^ + | ^^ expected identifier, found keyword | - = help: unlike in C++, Java, and C#, functions are declared in `impl` blocks - = help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information +help: escape `fn` to use it as an identifier + | +LL | inner : dyn r#fn () + | ++ error[E0412]: cannot find type `dyn` in this scope --> $DIR/fn-field-parse-error-ice.rs:4:13 diff --git a/src/test/ui/parser/issues/issue-34222-1.stderr b/src/test/ui/parser/issues/issue-34222-1.stderr index 0799656b06b..b451484ba22 100644 --- a/src/test/ui/parser/issues/issue-34222-1.stderr +++ b/src/test/ui/parser/issues/issue-34222-1.stderr @@ -4,7 +4,7 @@ error[E0585]: found a documentation comment that doesn't document anything LL | /// comment | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/parser/issues/issue-48636.stderr b/src/test/ui/parser/issues/issue-48636.stderr index 1a6e4cfd2b2..6177870d1ce 100644 --- a/src/test/ui/parser/issues/issue-48636.stderr +++ b/src/test/ui/parser/issues/issue-48636.stderr @@ -8,7 +8,7 @@ LL | x: u8 LL | /// The ID of the parent core | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: doc comments must come before what they document, maybe a comment was intended with `//`? + = help: doc comments must come before what they document, if a comment was intended use `//` error: aborting due to previous error diff --git a/src/test/ui/parser/macro/issue-33569.stderr b/src/test/ui/parser/macro/issue-33569.stderr index 39d49fd03f1..0dca090fb87 100644 --- a/src/test/ui/parser/macro/issue-33569.stderr +++ b/src/test/ui/parser/macro/issue-33569.stderr @@ -22,9 +22,9 @@ error: missing fragment specifier LL | { $+ } => { | ^ | - = note: `#[deny(missing_fragment_specifier)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107> + = note: `#[deny(missing_fragment_specifier)]` on by default error: aborting due to 4 previous errors diff --git a/src/test/ui/parser/recover-range-pats.stderr b/src/test/ui/parser/recover-range-pats.stderr index d0979b23f60..6c081052ddf 100644 --- a/src/test/ui/parser/recover-range-pats.stderr +++ b/src/test/ui/parser/recover-range-pats.stderr @@ -199,13 +199,13 @@ error: `...` range patterns are deprecated LL | if let 0...3 = 0 {} | ^^^ help: use `..=` for an inclusive range | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> note: the lint level is defined here --> $DIR/recover-range-pats.rs:8:9 | LL | #![deny(ellipsis_inclusive_range_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> error: `...` range patterns are deprecated --> $DIR/recover-range-pats.rs:45:13 diff --git a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr index 76fa860334d..be858cd651d 100644 --- a/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr +++ b/src/test/ui/parser/trait-item-with-defaultness-fail-semantic.stderr @@ -52,9 +52,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error: aborting due to 6 previous errors; 1 warning emitted diff --git a/src/test/ui/parser/trait-object-trait-parens.stderr b/src/test/ui/parser/trait-object-trait-parens.stderr index 823f75bfac8..5e07a3fe6c7 100644 --- a/src/test/ui/parser/trait-object-trait-parens.stderr +++ b/src/test/ui/parser/trait-object-trait-parens.stderr @@ -22,9 +22,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>; diff --git a/src/test/ui/parser/type-alias-where-fixable.stderr b/src/test/ui/parser/type-alias-where-fixable.stderr index 2e516d5c478..f0acb388b97 100644 --- a/src/test/ui/parser/type-alias-where-fixable.stderr +++ b/src/test/ui/parser/type-alias-where-fixable.stderr @@ -4,8 +4,8 @@ warning: where clause not allowed here LL | type Assoc where u32: Copy = (); | ^^^^^^^^^^^^^^^ | - = note: `#[warn(deprecated_where_clause_location)]` on by default = note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information + = note: `#[warn(deprecated_where_clause_location)]` on by default help: move it to the end of the type declaration | LL - type Assoc where u32: Copy = (); diff --git a/src/test/ui/parser/unicode-control-codepoints.stderr b/src/test/ui/parser/unicode-control-codepoints.stderr index 71509fe41a8..44548c72ff5 100644 --- a/src/test/ui/parser/unicode-control-codepoints.stderr +++ b/src/test/ui/parser/unicode-control-codepoints.stderr @@ -92,8 +92,8 @@ LL | // if access_level != "user" { // Check if admin | | '\u{202b}' | this comment contains invisible unicode text flow control codepoints | - = note: `#[deny(text_direction_codepoint_in_comment)]` on by default = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = note: `#[deny(text_direction_codepoint_in_comment)]` on by default = help: if their presence wasn't intentional, you can remove them error: unicode codepoint changing visible direction of text present in comment @@ -123,8 +123,8 @@ LL | println!("{:?}", "/* } if isAdmin begin admins only "); | | '\u{202e}' | this literal contains invisible unicode text flow control codepoints | - = note: `#[deny(text_direction_codepoint_in_literal)]` on by default = note: these kind of unicode codepoints change the way text flows on applications that support them, but can cause confusion because they change the order of characters on the screen + = note: `#[deny(text_direction_codepoint_in_literal)]` on by default = help: if their presence wasn't intentional, you can remove them help: if you want to keep them but make them visible in your source code, you can escape them | diff --git a/src/test/ui/pattern/usefulness/consts-opaque.stderr b/src/test/ui/pattern/usefulness/consts-opaque.stderr index 05c009a6f3f..35396751abe 100644 --- a/src/test/ui/pattern/usefulness/consts-opaque.stderr +++ b/src/test/ui/pattern/usefulness/consts-opaque.stderr @@ -40,9 +40,9 @@ warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated w LL | FOO_REF_REF => {} | ^^^^^^^^^^^ | - = note: `#[warn(indirect_structural_match)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> + = note: `#[warn(indirect_structural_match)]` on by default error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/consts-opaque.rs:53:9 diff --git a/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr index b97683526ba..cdb6b5c7a49 100644 --- a/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr +++ b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr @@ -4,13 +4,13 @@ error: irrefutable `if let` pattern LL | if let _ = 5 {} | ^^^^^^^^^ | + = note: this pattern will always match, so the `if let` is useless + = help: consider replacing the `if let` with a `let` note: the lint level is defined here --> $DIR/deny-irrefutable-let-patterns.rs:3:9 | LL | #![deny(irrefutable_let_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this pattern will always match, so the `if let` is useless - = help: consider replacing the `if let` with a `let` error: irrefutable `while let` pattern --> $DIR/deny-irrefutable-let-patterns.rs:8:11 diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr index 24c0419e1dd..ea0e8f6e49e 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -6,12 +6,12 @@ LL | m!(0u8, 20..=30, 30..=40); | | | this range overlaps on `30_u8`... | + = note: you likely meant to write mutually exclusive ranges note: the lint level is defined here --> $DIR/overlapping_range_endpoints.rs:2:9 | LL | #![deny(overlapping_range_endpoints)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: you likely meant to write mutually exclusive ranges error: multiple patterns overlap on their endpoints --> $DIR/overlapping_range_endpoints.rs:16:22 diff --git a/src/test/ui/polymorphization/const_parameters/closures.stderr b/src/test/ui/polymorphization/const_parameters/closures.stderr index fdf817caea7..4e927f7732f 100644 --- a/src/test/ui/polymorphization/const_parameters/closures.stderr +++ b/src/test/ui/polymorphization/const_parameters/closures.stderr @@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to LL | #![feature(generic_const_exprs, rustc_attrs)] | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information + = note: `#[warn(incomplete_features)]` on by default error: item has unused generic parameters --> $DIR/closures.rs:19:19 diff --git a/src/test/ui/polymorphization/const_parameters/functions.stderr b/src/test/ui/polymorphization/const_parameters/functions.stderr index f2b5a730738..9d0922ac7ca 100644 --- a/src/test/ui/polymorphization/const_parameters/functions.stderr +++ b/src/test/ui/polymorphization/const_parameters/functions.stderr @@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to LL | #![feature(generic_const_exprs, rustc_attrs)] | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information + = note: `#[warn(incomplete_features)]` on by default error: item has unused generic parameters --> $DIR/functions.rs:15:8 diff --git a/src/test/ui/polymorphization/generators.stderr b/src/test/ui/polymorphization/generators.stderr index a24eee5fed1..84888f6fb2f 100644 --- a/src/test/ui/polymorphization/generators.stderr +++ b/src/test/ui/polymorphization/generators.stderr @@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to LL | #![feature(generic_const_exprs, generators, generator_trait, rustc_attrs)] | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information + = note: `#[warn(incomplete_features)]` on by default error: item has unused generic parameters --> $DIR/generators.rs:35:5 diff --git a/src/test/ui/polymorphization/promoted-function-2.stderr b/src/test/ui/polymorphization/promoted-function-2.stderr index 4d7bab6aaa0..547569df7dc 100644 --- a/src/test/ui/polymorphization/promoted-function-2.stderr +++ b/src/test/ui/polymorphization/promoted-function-2.stderr @@ -4,8 +4,8 @@ warning: the feature `generic_const_exprs` is incomplete and may not be safe to LL | #![feature(generic_const_exprs, rustc_attrs)] | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information + = note: `#[warn(incomplete_features)]` on by default error: item has unused generic parameters --> $DIR/promoted-function-2.rs:8:4 diff --git a/src/test/ui/privacy/issue-30079.stderr b/src/test/ui/privacy/issue-30079.stderr index dc98cfe3bb6..9179ff339bf 100644 --- a/src/test/ui/privacy/issue-30079.stderr +++ b/src/test/ui/privacy/issue-30079.stderr @@ -4,9 +4,9 @@ warning: private type `m1::Priv` in public interface (error E0446) LL | pub fn f(_: Priv) {} | ^^^^^^^^^^^^^^^^^ | - = note: `#[warn(private_in_public)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + = note: `#[warn(private_in_public)]` on by default error[E0446]: private type `m2::Priv` in public interface --> $DIR/issue-30079.rs:18:9 diff --git a/src/test/ui/privacy/private-in-public-assoc-ty.stderr b/src/test/ui/privacy/private-in-public-assoc-ty.stderr index 1abeafe398f..a59027d81d2 100644 --- a/src/test/ui/privacy/private-in-public-assoc-ty.stderr +++ b/src/test/ui/privacy/private-in-public-assoc-ty.stderr @@ -13,9 +13,9 @@ warning: private trait `PrivTr` in public interface (error E0445) LL | type Alias1: PrivTr; | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(private_in_public)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + = note: `#[warn(private_in_public)]` on by default warning: private type `Priv` in public interface (error E0446) --> $DIR/private-in-public-assoc-ty.rs:27:9 diff --git a/src/test/ui/privacy/private-in-public-non-principal.stderr b/src/test/ui/privacy/private-in-public-non-principal.stderr index 5b4123ea82a..de20cada42e 100644 --- a/src/test/ui/privacy/private-in-public-non-principal.stderr +++ b/src/test/ui/privacy/private-in-public-non-principal.stderr @@ -4,9 +4,9 @@ warning: private trait `PrivNonPrincipal` in public interface (error E0445) LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(private_in_public)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + = note: `#[warn(private_in_public)]` on by default error: missing documentation for an associated function --> $DIR/private-in-public-non-principal.rs:14:9 diff --git a/src/test/ui/privacy/private-in-public-warn.stderr b/src/test/ui/privacy/private-in-public-warn.stderr index f2ff6cf2fdb..66f91ce6fd6 100644 --- a/src/test/ui/privacy/private-in-public-warn.stderr +++ b/src/test/ui/privacy/private-in-public-warn.stderr @@ -4,13 +4,13 @@ error: private type `types::Priv` in public interface (error E0446) LL | pub type Alias = Priv; | ^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> note: the lint level is defined here --> $DIR/private-in-public-warn.rs:5:9 | LL | #![deny(private_in_public)] | ^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> error: private type `types::Priv` in public interface (error E0446) --> $DIR/private-in-public-warn.rs:18:12 diff --git a/src/test/ui/privacy/where-priv-type.stderr b/src/test/ui/privacy/where-priv-type.stderr index 7eb71346ae9..c5fb2cdb0cf 100644 --- a/src/test/ui/privacy/where-priv-type.stderr +++ b/src/test/ui/privacy/where-priv-type.stderr @@ -4,9 +4,9 @@ warning: private type `PrivTy` in public interface (error E0446) LL | pub struct S | ^^^^^^^^^^^^ | - = note: `#[warn(private_in_public)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + = note: `#[warn(private_in_public)]` on by default warning: private type `PrivTy` in public interface (error E0446) --> $DIR/where-priv-type.rs:27:1 diff --git a/src/test/ui/proc-macro/attr-complex-fn.stdout b/src/test/ui/proc-macro/attr-complex-fn.stdout index fc69a13ddb9..b12eb587fc7 100644 --- a/src/test/ui/proc-macro/attr-complex-fn.stdout +++ b/src/test/ui/proc-macro/attr-complex-fn.stdout @@ -53,12 +53,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '>', spacing: Joint, - span: $DIR/attr-complex-fn.rs:19:36: 19:38 (#0), + span: $DIR/attr-complex-fn.rs:19:36: 19:37 (#0), }, Punct { ch: '>', spacing: Joint, - span: $DIR/attr-complex-fn.rs:19:36: 19:38 (#0), + span: $DIR/attr-complex-fn.rs:19:37: 19:38 (#0), }, Punct { ch: '>', diff --git a/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout b/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout index 4de8746a1b4..b88fbd3e897 100644 --- a/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout +++ b/src/test/ui/proc-macro/capture-macro-rules-invoke.stdout @@ -177,12 +177,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/capture-macro-rules-invoke.rs:45:16: 45:18 (#0), + span: $DIR/capture-macro-rules-invoke.rs:45:16: 45:17 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:45:16: 45:18 (#0), + span: $DIR/capture-macro-rules-invoke.rs:45:17: 45:18 (#0), }, Ident { ident: "option", @@ -191,12 +191,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/capture-macro-rules-invoke.rs:45:24: 45:26 (#0), + span: $DIR/capture-macro-rules-invoke.rs:45:24: 45:25 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:45:24: 45:26 (#0), + span: $DIR/capture-macro-rules-invoke.rs:45:25: 45:26 (#0), }, Ident { ident: "Option", @@ -231,12 +231,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/capture-macro-rules-invoke.rs:46:24: 46:26 (#0), + span: $DIR/capture-macro-rules-invoke.rs:46:24: 46:25 (#0), }, Punct { ch: ':', spacing: Alone, - span: $DIR/capture-macro-rules-invoke.rs:46:24: 46:26 (#0), + span: $DIR/capture-macro-rules-invoke.rs:46:25: 46:26 (#0), }, Ident { ident: "path", diff --git a/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs b/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs index fd34eb974c0..102bd6b7b17 100644 --- a/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs +++ b/src/test/ui/proc-macro/debug/dump-debug-span-debug.rs @@ -2,6 +2,7 @@ // aux-build:macro-dump-debug.rs // compile-flags: -Z span-debug + extern crate macro_dump_debug; use macro_dump_debug::dump_debug; @@ -9,7 +10,11 @@ dump_debug! { ident // ident r#ident // raw ident , // alone punct - ==> // joint punct + && // joint punct, two-char op + ||> // joint punct, two-char op + one-char op + ||<< // joint punct, two-char op + two-char op + ..= // joint punct, three-char op + <<=! // joint punct, three-char op + one-char-op () // empty group [_] // nonempty group diff --git a/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr index 2c05bdbc492..fa65cbbf1ea 100644 --- a/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr +++ b/src/test/ui/proc-macro/debug/dump-debug-span-debug.stderr @@ -1,166 +1,231 @@ -TokenStream [Ident { ident: "ident", span: $DIR/dump-debug-span-debug.rs:9:5: 9:10 (#0) }, Ident { ident: "r#ident", span: $DIR/dump-debug-span-debug.rs:10:5: 10:12 (#0) }, Punct { ch: ',', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:11:5: 11:6 (#0) }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0) }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0) }, Punct { ch: '>', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:12:7: 12:8 (#0) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/dump-debug-span-debug.rs:13:5: 13:7 (#0) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0) }], span: $DIR/dump-debug-span-debug.rs:14:5: 14:8 (#0) }, Literal { kind: Integer, symbol: "0", suffix: None, span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: $DIR/dump-debug-span-debug.rs:18:5: 18:8 (#0) }, Literal { kind: Str, symbol: "S", suffix: None, span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:20:5: 20:9 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:21:5: 21:9 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:22:5: 22:13 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:23:5: 23:11 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:24:5: 24:15 (#0) }, Literal { kind: Char, symbol: "C", suffix: None, span: $DIR/dump-debug-span-debug.rs:25:5: 25:8 (#0) }, Literal { kind: Byte, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:29:5: 29:7 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:30:5: 30:9 (#0) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:32:5: 32:10 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:33:5: 33:10 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:34:5: 34:14 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:35:5: 35:12 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:36:5: 36:16 (#0) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:37:5: 37:9 (#0) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0) }] +TokenStream [Ident { ident: "ident", span: $DIR/dump-debug-span-debug.rs:10:5: 10:10 (#0) }, Ident { ident: "r#ident", span: $DIR/dump-debug-span-debug.rs:11:5: 11:12 (#0) }, Punct { ch: ',', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:12:5: 12:6 (#0) }, Punct { ch: '&', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:13:5: 13:6 (#0) }, Punct { ch: '&', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:13:6: 13:7 (#0) }, Punct { ch: '|', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:14:5: 14:6 (#0) }, Punct { ch: '|', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0) }, Punct { ch: '>', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:14:7: 14:8 (#0) }, Punct { ch: '|', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:15:5: 15:6 (#0) }, Punct { ch: '|', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:15:6: 15:7 (#0) }, Punct { ch: '<', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:15:7: 15:8 (#0) }, Punct { ch: '<', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:15:8: 15:9 (#0) }, Punct { ch: '.', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:16:5: 16:6 (#0) }, Punct { ch: '.', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:16:6: 16:7 (#0) }, Punct { ch: '=', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:16:7: 16:8 (#0) }, Punct { ch: '<', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0) }, Punct { ch: '<', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:17:6: 17:7 (#0) }, Punct { ch: '=', spacing: Joint, span: $DIR/dump-debug-span-debug.rs:17:7: 17:8 (#0) }, Punct { ch: '!', spacing: Alone, span: $DIR/dump-debug-span-debug.rs:17:8: 17:9 (#0) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/dump-debug-span-debug.rs:18:5: 18:7 (#0) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: $DIR/dump-debug-span-debug.rs:19:6: 19:7 (#0) }], span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0) }, Literal { kind: Integer, symbol: "0", suffix: None, span: $DIR/dump-debug-span-debug.rs:22:5: 22:6 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: $DIR/dump-debug-span-debug.rs:23:5: 23:8 (#0) }, Literal { kind: Str, symbol: "S", suffix: None, span: $DIR/dump-debug-span-debug.rs:24:5: 24:8 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:25:5: 25:9 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: $DIR/dump-debug-span-debug.rs:27:5: 27:13 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:28:5: 28:11 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: $DIR/dump-debug-span-debug.rs:29:5: 29:15 (#0) }, Literal { kind: Char, symbol: "C", suffix: None, span: $DIR/dump-debug-span-debug.rs:30:5: 30:8 (#0) }, Literal { kind: Byte, symbol: "B", suffix: None, span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:34:5: 34:7 (#0) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:35:5: 35:9 (#0) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:36:5: 36:9 (#0) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:37:5: 37:10 (#0) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:39:5: 39:14 (#0) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:40:5: 40:12 (#0) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:41:5: 41:16 (#0) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:42:5: 42:9 (#0) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: $DIR/dump-debug-span-debug.rs:43:5: 43:10 (#0) }] TokenStream [ Ident { ident: "ident", - span: $DIR/dump-debug-span-debug.rs:9:5: 9:10 (#0), + span: $DIR/dump-debug-span-debug.rs:10:5: 10:10 (#0), }, Ident { ident: "r#ident", - span: $DIR/dump-debug-span-debug.rs:10:5: 10:12 (#0), + span: $DIR/dump-debug-span-debug.rs:11:5: 11:12 (#0), }, Punct { ch: ',', spacing: Alone, - span: $DIR/dump-debug-span-debug.rs:11:5: 11:6 (#0), + span: $DIR/dump-debug-span-debug.rs:12:5: 12:6 (#0), + }, + Punct { + ch: '&', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:13:5: 13:6 (#0), + }, + Punct { + ch: '&', + spacing: Alone, + span: $DIR/dump-debug-span-debug.rs:13:6: 13:7 (#0), + }, + Punct { + ch: '|', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:14:5: 14:6 (#0), + }, + Punct { + ch: '|', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0), + }, + Punct { + ch: '>', + spacing: Alone, + span: $DIR/dump-debug-span-debug.rs:14:7: 14:8 (#0), + }, + Punct { + ch: '|', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:15:5: 15:6 (#0), + }, + Punct { + ch: '|', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:15:6: 15:7 (#0), + }, + Punct { + ch: '<', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:15:7: 15:8 (#0), + }, + Punct { + ch: '<', + spacing: Alone, + span: $DIR/dump-debug-span-debug.rs:15:8: 15:9 (#0), + }, + Punct { + ch: '.', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:16:5: 16:6 (#0), + }, + Punct { + ch: '.', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:16:6: 16:7 (#0), }, Punct { ch: '=', + spacing: Alone, + span: $DIR/dump-debug-span-debug.rs:16:7: 16:8 (#0), + }, + Punct { + ch: '<', spacing: Joint, - span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0), + span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0), + }, + Punct { + ch: '<', + spacing: Joint, + span: $DIR/dump-debug-span-debug.rs:17:6: 17:7 (#0), }, Punct { ch: '=', spacing: Joint, - span: $DIR/dump-debug-span-debug.rs:12:5: 12:7 (#0), + span: $DIR/dump-debug-span-debug.rs:17:7: 17:8 (#0), }, Punct { - ch: '>', + ch: '!', spacing: Alone, - span: $DIR/dump-debug-span-debug.rs:12:7: 12:8 (#0), + span: $DIR/dump-debug-span-debug.rs:17:8: 17:9 (#0), }, Group { delimiter: Parenthesis, stream: TokenStream [], - span: $DIR/dump-debug-span-debug.rs:13:5: 13:7 (#0), + span: $DIR/dump-debug-span-debug.rs:18:5: 18:7 (#0), }, Group { delimiter: Bracket, stream: TokenStream [ Ident { ident: "_", - span: $DIR/dump-debug-span-debug.rs:14:6: 14:7 (#0), + span: $DIR/dump-debug-span-debug.rs:19:6: 19:7 (#0), }, ], - span: $DIR/dump-debug-span-debug.rs:14:5: 14:8 (#0), + span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0), }, Literal { kind: Integer, symbol: "0", suffix: None, - span: $DIR/dump-debug-span-debug.rs:17:5: 17:6 (#0), + span: $DIR/dump-debug-span-debug.rs:22:5: 22:6 (#0), }, Literal { kind: Float, symbol: "1.0", suffix: None, - span: $DIR/dump-debug-span-debug.rs:18:5: 18:8 (#0), + span: $DIR/dump-debug-span-debug.rs:23:5: 23:8 (#0), }, Literal { kind: Str, symbol: "S", suffix: None, - span: $DIR/dump-debug-span-debug.rs:19:5: 19:8 (#0), + span: $DIR/dump-debug-span-debug.rs:24:5: 24:8 (#0), }, Literal { kind: ByteStr, symbol: "B", suffix: None, - span: $DIR/dump-debug-span-debug.rs:20:5: 20:9 (#0), + span: $DIR/dump-debug-span-debug.rs:25:5: 25:9 (#0), }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, - span: $DIR/dump-debug-span-debug.rs:21:5: 21:9 (#0), + span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0), }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, - span: $DIR/dump-debug-span-debug.rs:22:5: 22:13 (#0), + span: $DIR/dump-debug-span-debug.rs:27:5: 27:13 (#0), }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, - span: $DIR/dump-debug-span-debug.rs:23:5: 23:11 (#0), + span: $DIR/dump-debug-span-debug.rs:28:5: 28:11 (#0), }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, - span: $DIR/dump-debug-span-debug.rs:24:5: 24:15 (#0), + span: $DIR/dump-debug-span-debug.rs:29:5: 29:15 (#0), }, Literal { kind: Char, symbol: "C", suffix: None, - span: $DIR/dump-debug-span-debug.rs:25:5: 25:8 (#0), + span: $DIR/dump-debug-span-debug.rs:30:5: 30:8 (#0), }, Literal { kind: Byte, symbol: "B", suffix: None, - span: $DIR/dump-debug-span-debug.rs:26:5: 26:9 (#0), + span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0), }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:29:5: 29:7 (#0), + span: $DIR/dump-debug-span-debug.rs:34:5: 34:7 (#0), }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:30:5: 30:9 (#0), + span: $DIR/dump-debug-span-debug.rs:35:5: 35:9 (#0), }, Literal { kind: Str, symbol: "S", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:31:5: 31:9 (#0), + span: $DIR/dump-debug-span-debug.rs:36:5: 36:9 (#0), }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:32:5: 32:10 (#0), + span: $DIR/dump-debug-span-debug.rs:37:5: 37:10 (#0), }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:33:5: 33:10 (#0), + span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0), }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:34:5: 34:14 (#0), + span: $DIR/dump-debug-span-debug.rs:39:5: 39:14 (#0), }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:35:5: 35:12 (#0), + span: $DIR/dump-debug-span-debug.rs:40:5: 40:12 (#0), }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:36:5: 36:16 (#0), + span: $DIR/dump-debug-span-debug.rs:41:5: 41:16 (#0), }, Literal { kind: Char, symbol: "C", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:37:5: 37:9 (#0), + span: $DIR/dump-debug-span-debug.rs:42:5: 42:9 (#0), }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), - span: $DIR/dump-debug-span-debug.rs:38:5: 38:10 (#0), + span: $DIR/dump-debug-span-debug.rs:43:5: 43:10 (#0), }, ] diff --git a/src/test/ui/proc-macro/debug/dump-debug.stderr b/src/test/ui/proc-macro/debug/dump-debug.stderr index 0aedefd4e60..db422b6012a 100644 --- a/src/test/ui/proc-macro/debug/dump-debug.stderr +++ b/src/test/ui/proc-macro/debug/dump-debug.stderr @@ -1,4 +1,4 @@ -TokenStream [Ident { ident: "ident", span: #0 bytes(130..135) }, Ident { ident: "r#ident", span: #0 bytes(151..158) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(176..177) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(203..205) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(203..205) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(205..206) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(230..232) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: #0 bytes(258..259) }], span: #0 bytes(257..260) }, Literal { kind: Integer, symbol: "0", suffix: None, span: #0 bytes(315..316) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: #0 bytes(321..324) }, Literal { kind: Str, symbol: "S", suffix: None, span: #0 bytes(329..332) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: #0 bytes(337..341) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: #0 bytes(346..350) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: #0 bytes(355..363) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: #0 bytes(368..374) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: #0 bytes(379..389) }, Literal { kind: Char, symbol: "C", suffix: None, span: #0 bytes(394..397) }, Literal { kind: Byte, symbol: "B", suffix: None, span: #0 bytes(402..406) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: #0 bytes(437..439) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: #0 bytes(444..448) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: #0 bytes(453..457) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: #0 bytes(462..467) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: #0 bytes(472..477) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: #0 bytes(482..491) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: #0 bytes(496..503) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: #0 bytes(508..519) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: #0 bytes(524..528) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: #0 bytes(533..538) }] +TokenStream [Ident { ident: "ident", span: #0 bytes(130..135) }, Ident { ident: "r#ident", span: #0 bytes(151..158) }, Punct { ch: ',', spacing: Alone, span: #0 bytes(176..177) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(203..204) }, Punct { ch: '=', spacing: Joint, span: #0 bytes(204..205) }, Punct { ch: '>', spacing: Alone, span: #0 bytes(205..206) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: #0 bytes(230..232) }, Group { delimiter: Bracket, stream: TokenStream [Ident { ident: "_", span: #0 bytes(258..259) }], span: #0 bytes(257..260) }, Literal { kind: Integer, symbol: "0", suffix: None, span: #0 bytes(315..316) }, Literal { kind: Float, symbol: "1.0", suffix: None, span: #0 bytes(321..324) }, Literal { kind: Str, symbol: "S", suffix: None, span: #0 bytes(329..332) }, Literal { kind: ByteStr, symbol: "B", suffix: None, span: #0 bytes(337..341) }, Literal { kind: StrRaw(0), symbol: "R", suffix: None, span: #0 bytes(346..350) }, Literal { kind: StrRaw(2), symbol: "R", suffix: None, span: #0 bytes(355..363) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: None, span: #0 bytes(368..374) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: None, span: #0 bytes(379..389) }, Literal { kind: Char, symbol: "C", suffix: None, span: #0 bytes(394..397) }, Literal { kind: Byte, symbol: "B", suffix: None, span: #0 bytes(402..406) }, Literal { kind: Integer, symbol: "0", suffix: Some("q"), span: #0 bytes(437..439) }, Literal { kind: Float, symbol: "1.0", suffix: Some("q"), span: #0 bytes(444..448) }, Literal { kind: Str, symbol: "S", suffix: Some("q"), span: #0 bytes(453..457) }, Literal { kind: ByteStr, symbol: "B", suffix: Some("q"), span: #0 bytes(462..467) }, Literal { kind: StrRaw(0), symbol: "R", suffix: Some("q"), span: #0 bytes(472..477) }, Literal { kind: StrRaw(2), symbol: "R", suffix: Some("q"), span: #0 bytes(482..491) }, Literal { kind: ByteStrRaw(0), symbol: "BR", suffix: Some("q"), span: #0 bytes(496..503) }, Literal { kind: ByteStrRaw(2), symbol: "BR", suffix: Some("q"), span: #0 bytes(508..519) }, Literal { kind: Char, symbol: "C", suffix: Some("q"), span: #0 bytes(524..528) }, Literal { kind: Byte, symbol: "B", suffix: Some("q"), span: #0 bytes(533..538) }] TokenStream [ Ident { ident: "ident", @@ -16,12 +16,12 @@ TokenStream [ Punct { ch: '=', spacing: Joint, - span: #0 bytes(203..205), + span: #0 bytes(203..204), }, Punct { ch: '=', spacing: Joint, - span: #0 bytes(203..205), + span: #0 bytes(204..205), }, Punct { ch: '>', diff --git a/src/test/ui/proc-macro/derive-helper-shadowing.stderr b/src/test/ui/proc-macro/derive-helper-shadowing.stderr index d8287eb73db..9c52ca42241 100644 --- a/src/test/ui/proc-macro/derive-helper-shadowing.stderr +++ b/src/test/ui/proc-macro/derive-helper-shadowing.stderr @@ -80,9 +80,9 @@ LL | #[empty_helper] LL | #[derive(Empty)] | ----- the attribute is introduced here | - = note: `#[warn(legacy_derive_helpers)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202> + = note: `#[warn(legacy_derive_helpers)]` on by default error: aborting due to 5 previous errors; 1 warning emitted diff --git a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout index c0c9ed72c5a..2622c005d93 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout +++ b/src/test/ui/proc-macro/dollar-crate-issue-57089.stdout @@ -18,12 +18,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/dollar-crate-issue-57089.rs:17:28: 17:30 (#4), + span: $DIR/dollar-crate-issue-57089.rs:17:28: 17:29 (#4), }, Punct { ch: ':', spacing: Alone, - span: $DIR/dollar-crate-issue-57089.rs:17:28: 17:30 (#4), + span: $DIR/dollar-crate-issue-57089.rs:17:29: 17:30 (#4), }, Ident { ident: "S", @@ -58,12 +58,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/dollar-crate-issue-57089.rs:21:24: 21:26 (#4), + span: $DIR/dollar-crate-issue-57089.rs:21:24: 21:25 (#4), }, Punct { ch: ':', spacing: Alone, - span: $DIR/dollar-crate-issue-57089.rs:21:24: 21:26 (#4), + span: $DIR/dollar-crate-issue-57089.rs:21:25: 21:26 (#4), }, Ident { ident: "S", diff --git a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout index e6148a687fd..a91908239c3 100644 --- a/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout +++ b/src/test/ui/proc-macro/dollar-crate-issue-62325.stdout @@ -30,12 +30,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/dollar-crate-issue-62325.rs:19:30: 19:32 (#4), + span: $DIR/dollar-crate-issue-62325.rs:19:30: 19:31 (#4), }, Punct { ch: ':', spacing: Alone, - span: $DIR/dollar-crate-issue-62325.rs:19:30: 19:32 (#4), + span: $DIR/dollar-crate-issue-62325.rs:19:31: 19:32 (#4), }, Ident { ident: "S", @@ -85,12 +85,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:32 (#12), + span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:31 (#12), }, Punct { ch: ':', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:21:30: 21:32 (#12), + span: $DIR/auxiliary/dollar-crate-external.rs:21:31: 21:32 (#12), }, Ident { ident: "S", diff --git a/src/test/ui/proc-macro/dollar-crate.stdout b/src/test/ui/proc-macro/dollar-crate.stdout index d01fcb9d0e4..4e169d47e1a 100644 --- a/src/test/ui/proc-macro/dollar-crate.stdout +++ b/src/test/ui/proc-macro/dollar-crate.stdout @@ -18,12 +18,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/dollar-crate.rs:20:32: 20:34 (#4), + span: $DIR/dollar-crate.rs:20:32: 20:33 (#4), }, Punct { ch: ':', spacing: Alone, - span: $DIR/dollar-crate.rs:20:32: 20:34 (#4), + span: $DIR/dollar-crate.rs:20:33: 20:34 (#4), }, Ident { ident: "S", @@ -58,12 +58,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/dollar-crate.rs:24:28: 24:30 (#4), + span: $DIR/dollar-crate.rs:24:28: 24:29 (#4), }, Punct { ch: ':', spacing: Alone, - span: $DIR/dollar-crate.rs:24:28: 24:30 (#4), + span: $DIR/dollar-crate.rs:24:29: 24:30 (#4), }, Ident { ident: "S", @@ -98,12 +98,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/dollar-crate.rs:27:28: 27:30 (#4), + span: $DIR/dollar-crate.rs:27:28: 27:29 (#4), }, Punct { ch: ':', spacing: Alone, - span: $DIR/dollar-crate.rs:27:28: 27:30 (#4), + span: $DIR/dollar-crate.rs:27:29: 27:30 (#4), }, Ident { ident: "S", @@ -138,12 +138,12 @@ PRINT-BANG INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:30 (#15), + span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:29 (#15), }, Punct { ch: ':', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:7:28: 7:30 (#15), + span: $DIR/auxiliary/dollar-crate-external.rs:7:29: 7:30 (#15), }, Ident { ident: "S", @@ -178,12 +178,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:26 (#15), + span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:25 (#15), }, Punct { ch: ':', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:11:24: 11:26 (#15), + span: $DIR/auxiliary/dollar-crate-external.rs:11:25: 11:26 (#15), }, Ident { ident: "S", @@ -218,12 +218,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: ':', spacing: Joint, - span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:26 (#15), + span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:25 (#15), }, Punct { ch: ':', spacing: Alone, - span: $DIR/auxiliary/dollar-crate-external.rs:14:24: 14:26 (#15), + span: $DIR/auxiliary/dollar-crate-external.rs:14:25: 14:26 (#15), }, Ident { ident: "S", diff --git a/src/test/ui/proc-macro/generate-mod.stderr b/src/test/ui/proc-macro/generate-mod.stderr index f1a167e37b4..39bf28dba96 100644 --- a/src/test/ui/proc-macro/generate-mod.stderr +++ b/src/test/ui/proc-macro/generate-mod.stderr @@ -44,9 +44,9 @@ error: cannot find type `FromOutside` in this scope LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> + = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) error: cannot find type `OuterDerive` in this scope @@ -89,9 +89,9 @@ error: cannot find type `FromOutside` in this scope LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> + = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -101,9 +101,9 @@ error: cannot find type `OuterDerive` in this scope LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> + = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -113,9 +113,9 @@ error: cannot find type `FromOutside` in this scope LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> + = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -125,9 +125,9 @@ error: cannot find type `OuterDerive` in this scope LL | #[derive(generate_mod::CheckDerive)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | - = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> + = note: `#[deny(proc_macro_derive_resolution_fallback)]` on by default = note: this error originates in the derive macro `generate_mod::CheckDerive` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -137,13 +137,13 @@ warning: cannot find type `FromOutside` in this scope LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> note: the lint level is defined here --> $DIR/generate-mod.rs:30:10 | LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) Future breakage diagnostic: @@ -153,12 +153,12 @@ warning: cannot find type `OuterDeriveLint` in this scope LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ names from parent modules are not accessible without an explicit import | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> note: the lint level is defined here --> $DIR/generate-mod.rs:30:10 | LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583> = note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr b/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr index 45b014c4b69..9441cdcc8cf 100644 --- a/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr +++ b/src/test/ui/proc-macro/helper-attr-blocked-by-import-ambig.stderr @@ -26,9 +26,9 @@ LL | #[empty_helper] LL | #[derive(Empty)] | ----- the attribute is introduced here | - = note: `#[warn(legacy_derive_helpers)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202> + = note: `#[warn(legacy_derive_helpers)]` on by default error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/proc-macro/inner-attr-non-inline-mod.stderr b/src/test/ui/proc-macro/inner-attr-non-inline-mod.stderr index 4286896dfc3..2d357d04d5c 100644 --- a/src/test/ui/proc-macro/inner-attr-non-inline-mod.stderr +++ b/src/test/ui/proc-macro/inner-attr-non-inline-mod.stderr @@ -31,9 +31,9 @@ error: custom inner attributes are unstable LL | #![rustfmt::skip] | ^^^^^^^^^^^^^ | - = note: `#[deny(soft_unstable)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266> + = note: `#[deny(soft_unstable)]` on by default error: aborting due to 4 previous errors diff --git a/src/test/ui/proc-macro/inner-attrs.stdout b/src/test/ui/proc-macro/inner-attrs.stdout index 490fc02f510..ee8adf0b4a9 100644 --- a/src/test/ui/proc-macro/inner-attrs.stdout +++ b/src/test/ui/proc-macro/inner-attrs.stdout @@ -627,12 +627,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '=', spacing: Joint, - span: $DIR/inner-attrs.rs:39:15: 39:17 (#0), + span: $DIR/inner-attrs.rs:39:15: 39:16 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/inner-attrs.rs:39:15: 39:17 (#0), + span: $DIR/inner-attrs.rs:39:16: 39:17 (#0), }, Group { delimiter: Brace, diff --git a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr index be4239089e8..ebb8e825e6a 100644 --- a/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr +++ b/src/test/ui/proc-macro/issue-73933-procedural-masquerade.stderr @@ -4,10 +4,10 @@ error: using `procedural-masquerade` crate LL | enum ProceduralMasqueradeDummyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling. + = note: `#[deny(proc_macro_back_compat)]` on by default error: using `procedural-masquerade` crate --> $DIR/issue-73933-procedural-masquerade.rs:7:6 @@ -48,10 +48,10 @@ error: using `procedural-masquerade` crate LL | enum ProceduralMasqueradeDummyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling. + = note: `#[deny(proc_macro_back_compat)]` on by default Future breakage diagnostic: error: using `procedural-masquerade` crate @@ -60,10 +60,10 @@ error: using `procedural-masquerade` crate LL | enum ProceduralMasqueradeDummyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling. + = note: `#[deny(proc_macro_back_compat)]` on by default Future breakage diagnostic: error: using `procedural-masquerade` crate @@ -72,10 +72,10 @@ error: using `procedural-masquerade` crate LL | enum ProceduralMasqueradeDummyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling. + = note: `#[deny(proc_macro_back_compat)]` on by default Future breakage diagnostic: error: using `procedural-masquerade` crate @@ -84,8 +84,8 @@ error: using `procedural-masquerade` crate LL | enum ProceduralMasqueradeDummyType { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(proc_macro_back_compat)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> = note: The `procedural-masquerade` crate has been unnecessary since Rust 1.30.0. Versions of this crate below 0.1.7 will eventually stop compiling. + = note: `#[deny(proc_macro_back_compat)]` on by default diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stderr b/src/test/ui/proc-macro/issue-75930-derive-cfg.stderr index 69d72b55cdf..6d1efb0dc28 100644 --- a/src/test/ui/proc-macro/issue-75930-derive-cfg.stderr +++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stderr @@ -7,9 +7,9 @@ LL | #[print_helper(a)] LL | #[derive(Print)] | ----- the attribute is introduced here | - = note: `#[warn(legacy_derive_helpers)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202> + = note: `#[warn(legacy_derive_helpers)]` on by default warning: derive helper attribute is used before it is introduced --> $DIR/issue-75930-derive-cfg.rs:19:3 diff --git a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout index c81fa201cbc..83afd0d3eae 100644 --- a/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout +++ b/src/test/ui/proc-macro/issue-75930-derive-cfg.stdout @@ -489,12 +489,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:33:32: 33:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:33:32: 33:33 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:33:32: 33:34 (#0), + span: $DIR/issue-75930-derive-cfg.rs:33:33: 33:34 (#0), }, Group { delimiter: Brace, @@ -567,12 +567,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:62 (#0), + span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:61 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:62 (#0), + span: $DIR/issue-75930-derive-cfg.rs:34:61: 34:62 (#0), }, Group { delimiter: Brace, @@ -591,12 +591,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:16 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:35:16: 35:17 (#0), }, Group { delimiter: Brace, @@ -1519,12 +1519,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:62 (#0), + span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:61 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:34:60: 34:62 (#0), + span: $DIR/issue-75930-derive-cfg.rs:34:61: 34:62 (#0), }, Group { delimiter: Brace, @@ -1543,12 +1543,12 @@ PRINT-DERIVE INPUT (DEBUG): TokenStream [ Punct { ch: '=', spacing: Joint, - span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:16 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-75930-derive-cfg.rs:35:15: 35:17 (#0), + span: $DIR/issue-75930-derive-cfg.rs:35:16: 35:17 (#0), }, Group { delimiter: Brace, diff --git a/src/test/ui/proc-macro/issue-76182-leading-vert-pat.stdout b/src/test/ui/proc-macro/issue-76182-leading-vert-pat.stdout index 5493f9c7b60..09eb33f7e31 100644 --- a/src/test/ui/proc-macro/issue-76182-leading-vert-pat.stdout +++ b/src/test/ui/proc-macro/issue-76182-leading-vert-pat.stdout @@ -41,12 +41,12 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [ Punct { ch: '=', spacing: Joint, - span: $DIR/issue-76182-leading-vert-pat.rs:15:21: 15:23 (#0), + span: $DIR/issue-76182-leading-vert-pat.rs:15:21: 15:22 (#0), }, Punct { ch: '>', spacing: Alone, - span: $DIR/issue-76182-leading-vert-pat.rs:15:21: 15:23 (#0), + span: $DIR/issue-76182-leading-vert-pat.rs:15:22: 15:23 (#0), }, Group { delimiter: Parenthesis, diff --git a/src/test/ui/proc-macro/meta-macro-hygiene.stdout b/src/test/ui/proc-macro/meta-macro-hygiene.stdout index 5d04fe1e3de..2494af1208f 100644 --- a/src/test/ui/proc-macro/meta-macro-hygiene.stdout +++ b/src/test/ui/proc-macro/meta-macro-hygiene.stdout @@ -1,5 +1,5 @@ Def site: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) -Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:24:37: 24:43 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:24:43: 24:45 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:43: 24:45 (#4) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:24:45: 24:50 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:50: 24:51 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:24:51: 24:53 (#4) }] +Input: TokenStream [Ident { ident: "$crate", span: $DIR/meta-macro-hygiene.rs:24:37: 24:43 (#4) }, Punct { ch: ':', spacing: Joint, span: $DIR/meta-macro-hygiene.rs:24:43: 24:44 (#4) }, Punct { ch: ':', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:44: 24:45 (#4) }, Ident { ident: "dummy", span: $DIR/meta-macro-hygiene.rs:24:45: 24:50 (#4) }, Punct { ch: '!', spacing: Alone, span: $DIR/meta-macro-hygiene.rs:24:50: 24:51 (#4) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/meta-macro-hygiene.rs:24:51: 24:53 (#4) }] Respanned: TokenStream [Ident { ident: "$crate", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: ':', spacing: Joint, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: ':', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Ident { ident: "dummy", span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Punct { ch: '!', spacing: Alone, span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }, Group { delimiter: Parenthesis, stream: TokenStream [], span: $DIR/auxiliary/make-macro.rs:7:9: 7:56 (#5) }] #![feature /* 0#0 */(prelude_import)] // aux-build:make-macro.rs diff --git a/src/test/ui/proc-macro/proc-macro-attributes.stderr b/src/test/ui/proc-macro/proc-macro-attributes.stderr index b66e4575e11..140d8790690 100644 --- a/src/test/ui/proc-macro/proc-macro-attributes.stderr +++ b/src/test/ui/proc-macro/proc-macro-attributes.stderr @@ -85,9 +85,9 @@ LL | #[B] LL | #[derive(B)] | - the attribute is introduced here | - = note: `#[warn(legacy_derive_helpers)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #79202 <https://github.com/rust-lang/rust/issues/79202> + = note: `#[warn(legacy_derive_helpers)]` on by default warning: derive helper attribute is used before it is introduced --> $DIR/proc-macro-attributes.rs:10:3 diff --git a/src/test/ui/proc-macro/proc-macro-gates.stderr b/src/test/ui/proc-macro/proc-macro-gates.stderr index 118213a17d4..3feb9b8290f 100644 --- a/src/test/ui/proc-macro/proc-macro-gates.stderr +++ b/src/test/ui/proc-macro/proc-macro-gates.stderr @@ -82,9 +82,9 @@ error: inner macro attributes are unstable LL | #![test] | ^^^^ | - = note: `#[deny(soft_unstable)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #64266 <https://github.com/rust-lang/rust/issues/64266> + = note: `#[deny(soft_unstable)]` on by default error: aborting due to 10 previous errors diff --git a/src/test/ui/proc-macro/three-equals.stderr b/src/test/ui/proc-macro/three-equals.stderr index 1ce5e02bd82..9cdb2a21b04 100644 --- a/src/test/ui/proc-macro/three-equals.stderr +++ b/src/test/ui/proc-macro/three-equals.stderr @@ -8,16 +8,16 @@ LL | three_equals!(==); = note: this error originates in the macro `three_equals` (in Nightly builds, run with -Z macro-backtrace for more info) error: expected EOF, found `=`. - --> $DIR/three-equals.rs:15:21 + --> $DIR/three-equals.rs:15:22 | LL | three_equals!(=====); - | ^^ + | ^ | note: last good input was here --> $DIR/three-equals.rs:15:21 | LL | three_equals!(=====); - | ^^ + | ^ = help: input must be: `===` error: expected `=`, found `abc`. diff --git a/src/test/ui/process/process-panic-after-fork.rs b/src/test/ui/process/process-panic-after-fork.rs index 08b30b600e7..d0a938c03e8 100644 --- a/src/test/ui/process/process-panic-after-fork.rs +++ b/src/test/ui/process/process-panic-after-fork.rs @@ -6,6 +6,7 @@ // ignore-emscripten no processes // ignore-sgx no processes // ignore-android: FIXME(#85261) +// ignore-fuchsia no fork #![feature(rustc_private)] #![feature(never_type)] diff --git a/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr b/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr index e4d73c6475d..c7fadc6f929 100644 --- a/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr +++ b/src/test/ui/pub/pub-reexport-priv-extern-crate.stderr @@ -28,9 +28,9 @@ error: extern crate `core` is private, and cannot be re-exported (error E0365), LL | pub use core as reexported_core; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(pub_use_of_private_extern_crate)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537> + = note: `#[deny(pub_use_of_private_extern_crate)]` on by default error: aborting due to 3 previous errors diff --git a/src/test/ui/range/range-inclusive-pattern-precedence.stderr b/src/test/ui/range/range-inclusive-pattern-precedence.stderr index 10513374cf8..f6788d034e6 100644 --- a/src/test/ui/range/range-inclusive-pattern-precedence.stderr +++ b/src/test/ui/range/range-inclusive-pattern-precedence.stderr @@ -10,13 +10,13 @@ warning: `...` range patterns are deprecated LL | &0...9 => {} | ^^^^^^ help: use `..=` for an inclusive range: `&(0..=9)` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> note: the lint level is defined here --> $DIR/range-inclusive-pattern-precedence.rs:7:9 | LL | #![warn(ellipsis_inclusive_range_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/range/range-inclusive-pattern-precedence2.stderr b/src/test/ui/range/range-inclusive-pattern-precedence2.stderr index cdec41d7f75..bb4e3a13a5c 100644 --- a/src/test/ui/range/range-inclusive-pattern-precedence2.stderr +++ b/src/test/ui/range/range-inclusive-pattern-precedence2.stderr @@ -10,13 +10,13 @@ warning: `...` range patterns are deprecated LL | box 0...9 => {} | ^^^ help: use `..=` for an inclusive range | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> note: the lint level is defined here --> $DIR/range-inclusive-pattern-precedence2.rs:5:9 | LL | #![warn(ellipsis_inclusive_range_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/recursion/issue-83150.stderr b/src/test/ui/recursion/issue-83150.stderr index 32f25faf3e8..59fba5af00e 100644 --- a/src/test/ui/recursion/issue-83150.stderr +++ b/src/test/ui/recursion/issue-83150.stderr @@ -6,8 +6,8 @@ LL | fn func<T: Iterator<Item = u8>>(iter: &mut T) { LL | func(&mut iter.map(|x| x + 1)) | ------------------------------ recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default error[E0275]: overflow evaluating the requirement `<std::ops::Range<u8> as Iterator>::Item` | diff --git a/src/test/ui/regions/issue-102374.rs b/src/test/ui/regions/issue-102374.rs new file mode 100644 index 00000000000..e0a1164211a --- /dev/null +++ b/src/test/ui/regions/issue-102374.rs @@ -0,0 +1,20 @@ +use std::cell::Cell; + +#[rustfmt::skip] +fn f( + f: for<'a, 'b, 'c, 'd, 'e, 'f, 'g, + 'h, 'i, 'j, 'k, 'l, 'm, 'n, + 'o, 'p, 'q, 'r, 's, 't, 'u, + 'v, 'w, 'x, 'y, 'z, 'z0> + fn(Cell<(& i32, &'a i32, &'b i32, &'c i32, &'d i32, + &'e i32, &'f i32, &'g i32, &'h i32, &'i i32, + &'j i32, &'k i32, &'l i32, &'m i32, &'n i32, + &'o i32, &'p i32, &'q i32, &'r i32, &'s i32, + &'t i32, &'u i32, &'v i32, &'w i32, &'x i32, + &'y i32, &'z i32, &'z0 i32)>), +) -> i32 { + f + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/regions/issue-102374.stderr b/src/test/ui/regions/issue-102374.stderr new file mode 100644 index 00000000000..31b855c36be --- /dev/null +++ b/src/test/ui/regions/issue-102374.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-102374.rs:16:5 + | +LL | ) -> i32 { + | --- expected `i32` because of return type +LL | f + | ^ expected `i32`, found fn pointer + | + = note: expected type `i32` + found fn pointer `for<'z1, 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, 'o, 'p, 'q, 'r, 's, 't, 'u, 'v, 'w, 'x, 'y, 'z, 'z0> fn(Cell<(&'z1 i32, &'a i32, &'b i32, &'c i32, &'d i32, &'e i32, &'f i32, &'g i32, &'h i32, &'i i32, &'j i32, &'k i32, &'l i32, &'m i32, &'n i32, &'o i32, &'p i32, &'q i32, &'r i32, &'s i32, &'t i32, &'u i32, &'v i32, &'w i32, &'x i32, &'y i32, &'z i32, &'z0 i32)>)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr b/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr index a2396ad4286..ea43dde11f8 100644 --- a/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr +++ b/src/test/ui/regions/region-bound-on-closure-outlives-call.stderr @@ -7,8 +7,8 @@ LL | LL | (|x| f(x))(call_rec(f)) | ----------- recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default error[E0505]: cannot move out of `f` because it is borrowed --> $DIR/region-bound-on-closure-outlives-call.rs:3:25 diff --git a/src/test/ui/repr/repr-transparent-issue-87496.stderr b/src/test/ui/repr/repr-transparent-issue-87496.stderr index 3dc13b1c13c..aee31212b4e 100644 --- a/src/test/ui/repr/repr-transparent-issue-87496.stderr +++ b/src/test/ui/repr/repr-transparent-issue-87496.stderr @@ -4,13 +4,13 @@ warning: `extern` block uses type `TransparentCustomZst`, which is not FFI-safe LL | fn good17(p: TransparentCustomZst); | ^^^^^^^^^^^^^^^^^^^^ not FFI-safe | - = note: `#[warn(improper_ctypes)]` on by default = note: this struct contains only zero-sized fields note: the type is defined here --> $DIR/repr-transparent-issue-87496.rs:6:1 | LL | struct TransparentCustomZst(()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[warn(improper_ctypes)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/repr/repr-transparent-non-exhaustive.rs b/src/test/ui/repr/repr-transparent-non-exhaustive.rs index 9ccd8610dad..506f1dcf3fc 100644 --- a/src/test/ui/repr/repr-transparent-non-exhaustive.rs +++ b/src/test/ui/repr/repr-transparent-non-exhaustive.rs @@ -35,62 +35,62 @@ pub struct T4(Sized, ExternalIndirection<(InternalPrivate, InternalNonExhaustive #[repr(transparent)] pub struct T5(Sized, Private); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T6(Sized, NonExhaustive); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T7(Sized, NonExhaustiveEnum); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T8(Sized, NonExhaustiveVariant); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T9(Sized, InternalIndirection<Private>); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T10(Sized, InternalIndirection<NonExhaustive>); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T11(Sized, InternalIndirection<NonExhaustiveEnum>); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T12(Sized, InternalIndirection<NonExhaustiveVariant>); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T13(Sized, ExternalIndirection<Private>); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T14(Sized, ExternalIndirection<NonExhaustive>); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T15(Sized, ExternalIndirection<NonExhaustiveEnum>); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler #[repr(transparent)] pub struct T16(Sized, ExternalIndirection<NonExhaustiveVariant>); -//~^ ERROR zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +//~^ ERROR zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types //~| WARN this was previously accepted by the compiler fn main() {} diff --git a/src/test/ui/repr/repr-transparent-non-exhaustive.stderr b/src/test/ui/repr/repr-transparent-non-exhaustive.stderr index 3b1e334a0cb..16edf59c7cc 100644 --- a/src/test/ui/repr/repr-transparent-non-exhaustive.stderr +++ b/src/test/ui/repr/repr-transparent-non-exhaustive.stderr @@ -1,19 +1,19 @@ -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:37:22 | LL | pub struct T5(Sized, Private); | ^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> + = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. note: the lint level is defined here --> $DIR/repr-transparent-non-exhaustive.rs:1:9 | LL | #![deny(repr_transparent_external_private_fields)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> - = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:42:22 | LL | pub struct T6(Sized, NonExhaustive); @@ -23,7 +23,7 @@ LL | pub struct T6(Sized, NonExhaustive); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:47:22 | LL | pub struct T7(Sized, NonExhaustiveEnum); @@ -33,7 +33,7 @@ LL | pub struct T7(Sized, NonExhaustiveEnum); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:52:22 | LL | pub struct T8(Sized, NonExhaustiveVariant); @@ -43,7 +43,7 @@ LL | pub struct T8(Sized, NonExhaustiveVariant); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:57:22 | LL | pub struct T9(Sized, InternalIndirection<Private>); @@ -53,7 +53,7 @@ LL | pub struct T9(Sized, InternalIndirection<Private>); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:62:23 | LL | pub struct T10(Sized, InternalIndirection<NonExhaustive>); @@ -63,7 +63,7 @@ LL | pub struct T10(Sized, InternalIndirection<NonExhaustive>); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:67:23 | LL | pub struct T11(Sized, InternalIndirection<NonExhaustiveEnum>); @@ -73,7 +73,7 @@ LL | pub struct T11(Sized, InternalIndirection<NonExhaustiveEnum>); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:72:23 | LL | pub struct T12(Sized, InternalIndirection<NonExhaustiveVariant>); @@ -83,7 +83,7 @@ LL | pub struct T12(Sized, InternalIndirection<NonExhaustiveVariant>); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this enum contains `NonExhaustiveVariant`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:77:23 | LL | pub struct T13(Sized, ExternalIndirection<Private>); @@ -93,7 +93,7 @@ LL | pub struct T13(Sized, ExternalIndirection<Private>); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this struct contains `Private`, which contains private fields, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:82:23 | LL | pub struct T14(Sized, ExternalIndirection<NonExhaustive>); @@ -103,7 +103,7 @@ LL | pub struct T14(Sized, ExternalIndirection<NonExhaustive>); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this struct contains `NonExhaustive`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:87:23 | LL | pub struct T15(Sized, ExternalIndirection<NonExhaustiveEnum>); @@ -113,7 +113,7 @@ LL | pub struct T15(Sized, ExternalIndirection<NonExhaustiveEnum>); = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586> = note: this enum contains `NonExhaustiveEnum`, which is marked with `#[non_exhaustive]`, and makes it not a breaking change to become non-zero-sized in the future. -error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types +error: zero-sized fields in `repr(transparent)` cannot contain external non-exhaustive types --> $DIR/repr-transparent-non-exhaustive.rs:92:23 | LL | pub struct T16(Sized, ExternalIndirection<NonExhaustiveVariant>); diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr index 659a9812672..10dd635ff96 100644 --- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr @@ -4,13 +4,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> note: the lint level is defined here --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 | LL | #![warn(indirect_structural_match)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> warning: 1 warning emitted diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr index c8c36510542..66aecbc4f30 100644 --- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr +++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr @@ -4,13 +4,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> note: the lint level is defined here --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 | LL | #![warn(indirect_structural_match)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> warning: 1 warning emitted diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr index 8abbd5d342b..ee92954a693 100644 --- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr +++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr @@ -4,13 +4,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> note: the lint level is defined here --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9 | LL | #![warn(indirect_structural_match)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> warning: 1 warning emitted diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr index 3a716d54fcc..f0c492d6a73 100644 --- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr +++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr @@ -4,13 +4,13 @@ warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be a LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> note: the lint level is defined here --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9 | LL | #![warn(indirect_structural_match)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> warning: 1 warning emitted diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr index a50093a5b11..955ab4b548b 100644 --- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -4,13 +4,13 @@ warning: to use a constant of type `B` in a pattern, `B` must be annotated with LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); } | ^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> note: the lint level is defined here --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 | LL | #![warn(indirect_structural_match, nontrivial_structural_match)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9 diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr index 8cf87cc85a1..d6afc0255ec 100644 --- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr +++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr @@ -4,13 +4,13 @@ warning: function pointers and unsized pointers in patterns behave unpredictably LL | B(TEST) => println!("matched"), | ^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861> note: the lint level is defined here --> $DIR/issue-63479-match-fnptr.rs:8:9 | LL | #![warn(pointer_structural_match)] | ^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861> warning: 1 warning emitted diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr index 4e2961e5e23..f37255d0828 100644 --- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr +++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/issue-6804.stderr @@ -4,13 +4,13 @@ error: floating-point types cannot be used in patterns LL | NAN => {}, | ^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> note: the lint level is defined here --> $DIR/issue-6804.rs:4:9 | LL | #![deny(illegal_floating_point_literal_pattern)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> error: floating-point types cannot be used in patterns --> $DIR/issue-6804.rs:17:10 diff --git a/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr b/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr index df4809dabf1..616ed9e484b 100644 --- a/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr +++ b/src/test/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr @@ -10,9 +10,9 @@ warning: floating-point types cannot be used in patterns LL | f32::INFINITY => { } | ^^^^^^^^^^^^^ | - = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> + = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr index 7d81de43854..7c1390cdc64 100644 --- a/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr +++ b/src/test/ui/rfc-1937-termination-trait/termination-trait-test-wrong-type.stderr @@ -13,7 +13,7 @@ LL | | } note: required by a bound in `assert_test_result` --> $SRC_DIR/test/src/lib.rs:LL:COL | -LL | pub fn assert_test_result<T: Termination>(result: T) { +LL | pub fn assert_test_result<T: Termination>(result: T) -> Result<(), String> { | ^^^^^^^^^^^ required by this bound in `assert_test_result` = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr index 8a18ebc16fe..43c8e1015e6 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/improper_ctypes/extern_crate_improper.stderr @@ -4,12 +4,12 @@ error: `extern` block uses type `NonExhaustiveEnum`, which is not FFI-safe LL | pub fn non_exhaustive_enum(_: NonExhaustiveEnum); | ^^^^^^^^^^^^^^^^^ not FFI-safe | + = note: this enum is non-exhaustive note: the lint level is defined here --> $DIR/extern_crate_improper.rs:2:9 | LL | #![deny(improper_ctypes)] | ^^^^^^^^^^^^^^^ - = note: this enum is non-exhaustive error: `extern` block uses type `NormalStruct`, which is not FFI-safe --> $DIR/extern_crate_improper.rs:14:44 diff --git a/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr index 4b9f8564d23..996bd4a1298 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr @@ -4,13 +4,13 @@ warning: some fields are not explicitly listed LL | VariantNonExhaustive::Bar { x, .. } => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `y` not listed | + = help: ensure that all fields are mentioned explicitly by adding the suggested fields + = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:99:12 | LL | #[warn(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all fields are mentioned explicitly by adding the suggested fields - = note: the pattern is of type `VariantNonExhaustive` and the `non_exhaustive_omitted_patterns` attribute was found warning: some fields are not explicitly listed --> $DIR/omitted-patterns.rs:107:9 @@ -18,13 +18,13 @@ warning: some fields are not explicitly listed LL | let FunctionalRecord { first_field, second_field, .. } = FunctionalRecord::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `third_field` not listed | + = help: ensure that all fields are mentioned explicitly by adding the suggested fields + = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:106:12 | LL | #[warn(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all fields are mentioned explicitly by adding the suggested fields - = note: the pattern is of type `FunctionalRecord` and the `non_exhaustive_omitted_patterns` attribute was found warning: some fields are not explicitly listed --> $DIR/omitted-patterns.rs:115:29 @@ -32,13 +32,13 @@ warning: some fields are not explicitly listed LL | let NestedStruct { bar: NormalStruct { first_field, .. }, .. } = NestedStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `second_field` not listed | + = help: ensure that all fields are mentioned explicitly by adding the suggested fields + = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:114:12 | LL | #[warn(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all fields are mentioned explicitly by adding the suggested fields - = note: the pattern is of type `NormalStruct` and the `non_exhaustive_omitted_patterns` attribute was found warning: some fields are not explicitly listed --> $DIR/omitted-patterns.rs:115:9 @@ -55,13 +55,13 @@ warning: some fields are not explicitly listed LL | let OnlyUnstableStruct { unstable, .. } = OnlyUnstableStruct::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable2` not listed | + = help: ensure that all fields are mentioned explicitly by adding the suggested fields + = note: the pattern is of type `OnlyUnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:172:12 | LL | #[warn(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all fields are mentioned explicitly by adding the suggested fields - = note: the pattern is of type `OnlyUnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found warning: some fields are not explicitly listed --> $DIR/omitted-patterns.rs:181:9 @@ -69,13 +69,13 @@ warning: some fields are not explicitly listed LL | let UnstableStruct { stable, stable2, .. } = UnstableStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `unstable` not listed | + = help: ensure that all fields are mentioned explicitly by adding the suggested fields + = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:180:12 | LL | #[warn(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all fields are mentioned explicitly by adding the suggested fields - = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly --> $DIR/omitted-patterns.rs:58:9 @@ -83,13 +83,13 @@ error: some variants are not matched explicitly LL | _ => {} | ^ pattern `NonExhaustiveEnum::Struct { .. }` not covered | + = help: ensure that all variants are matched explicitly by adding the suggested match arms + = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:57:16 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all variants are matched explicitly by adding the suggested match arms - = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly --> $DIR/omitted-patterns.rs:65:9 @@ -97,13 +97,13 @@ error: some variants are not matched explicitly LL | _ => {} | ^ pattern `NonExhaustiveEnum::Tuple(_)` not covered | + = help: ensure that all variants are matched explicitly by adding the suggested match arms + = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:64:16 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all variants are matched explicitly by adding the suggested match arms - = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly --> $DIR/omitted-patterns.rs:75:9 @@ -111,13 +111,13 @@ error: some variants are not matched explicitly LL | _ => {} | ^ pattern `NonExhaustiveEnum::Unit` not covered | + = help: ensure that all variants are matched explicitly by adding the suggested match arms + = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:74:16 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all variants are matched explicitly by adding the suggested match arms - = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly --> $DIR/omitted-patterns.rs:92:32 @@ -125,13 +125,13 @@ error: some variants are not matched explicitly LL | NestedNonExhaustive::A(_) => {} | ^ patterns `NonExhaustiveEnum::Tuple(_)` and `NonExhaustiveEnum::Struct { .. }` not covered | + = help: ensure that all variants are matched explicitly by adding the suggested match arms + = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:89:12 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all variants are matched explicitly by adding the suggested match arms - = note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly --> $DIR/omitted-patterns.rs:94:9 @@ -148,13 +148,13 @@ error: some variants are not matched explicitly LL | _ => {} | ^ pattern `NonExhaustiveSingleVariant::A(_)` not covered | + = help: ensure that all variants are matched explicitly by adding the suggested match arms + = note: the matched value is of type `NonExhaustiveSingleVariant` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:130:12 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all variants are matched explicitly by adding the suggested match arms - = note: the matched value is of type `NonExhaustiveSingleVariant` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly --> $DIR/omitted-patterns.rs:144:9 @@ -162,13 +162,13 @@ error: some variants are not matched explicitly LL | _ => {} | ^ pattern `UnstableEnum::Unstable` not covered | + = help: ensure that all variants are matched explicitly by adding the suggested match arms + = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:143:16 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all variants are matched explicitly by adding the suggested match arms - = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly --> $DIR/omitted-patterns.rs:168:9 @@ -176,13 +176,13 @@ error: some variants are not matched explicitly LL | _ => {} | ^ pattern `OnlyUnstableEnum::Unstable2` not covered | + = help: ensure that all variants are matched explicitly by adding the suggested match arms + = note: the matched value is of type `OnlyUnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/omitted-patterns.rs:165:12 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all variants are matched explicitly by adding the suggested match arms - = note: the matched value is of type `OnlyUnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: aborting due to 8 previous errors; 6 warnings emitted diff --git a/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr index 533e8abf2d6..f38368590fb 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/stable-omitted-patterns.stderr @@ -4,13 +4,13 @@ warning: some fields are not explicitly listed LL | let UnstableStruct { stable, .. } = UnstableStruct::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ field `stable2` not listed | + = help: ensure that all fields are mentioned explicitly by adding the suggested fields + = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/stable-omitted-patterns.rs:38:12 | LL | #[warn(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all fields are mentioned explicitly by adding the suggested fields - = note: the pattern is of type `UnstableStruct` and the `non_exhaustive_omitted_patterns` attribute was found error: some variants are not matched explicitly --> $DIR/stable-omitted-patterns.rs:23:9 @@ -18,13 +18,13 @@ error: some variants are not matched explicitly LL | _ => {} | ^ pattern `UnstableEnum::Stable2` not covered | + = help: ensure that all variants are matched explicitly by adding the suggested match arms + = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found note: the lint level is defined here --> $DIR/stable-omitted-patterns.rs:22:16 | LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: ensure that all variants are matched explicitly by adding the suggested match arms - = note: the matched value is of type `UnstableEnum` and the `non_exhaustive_omitted_patterns` attribute was found error: aborting due to previous error; 1 warning emitted diff --git a/src/test/ui/rfc-2294-if-let-guard/warns.stderr b/src/test/ui/rfc-2294-if-let-guard/warns.stderr index cf64513f9c8..75f22ac8dc0 100644 --- a/src/test/ui/rfc-2294-if-let-guard/warns.stderr +++ b/src/test/ui/rfc-2294-if-let-guard/warns.stderr @@ -4,13 +4,13 @@ error: irrefutable `if let` guard pattern LL | Some(x) if let () = x => {} | ^^ | + = note: this pattern will always match, so the guard is useless + = help: consider removing the guard and adding a `let` inside the match arm note: the lint level is defined here --> $DIR/warns.rs:3:8 | LL | #[deny(irrefutable_let_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this pattern will always match, so the guard is useless - = help: consider removing the guard and adding a `let` inside the match arm error: unreachable pattern --> $DIR/warns.rs:15:25 diff --git a/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr b/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr index d1d5288aea3..2570c36b810 100644 --- a/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/irrefutable-lets.disallowed.stderr @@ -4,13 +4,13 @@ error: leading irrefutable pattern in let chain LL | if let first = &opt && let Some(ref second) = first && let None = second.start {} | ^^^^^^^^^^^^^^^^ | + = note: this pattern will always match + = help: consider moving it outside of the construct note: the lint level is defined here --> $DIR/irrefutable-lets.rs:6:30 | LL | #![cfg_attr(disallowed, deny(irrefutable_let_patterns))] | ^^^^^^^^^^^^^^^^^^^^^^^^ - = note: this pattern will always match - = help: consider moving it outside of the construct error: irrefutable `if let` patterns --> $DIR/irrefutable-lets.rs:19:8 diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs index d3e14a53a2f..414a8c87d2c 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.rs @@ -2,13 +2,18 @@ struct S; -impl PartialEq for S { +#[const_trait] +trait Foo { + fn eq(&self, _: &Self) -> bool; +} + +impl Foo for S { fn eq(&self, _: &S) -> bool { true } } -const fn equals_self<T: ~const PartialEq>(t: &T) -> bool { +const fn equals_self<T: ~const Foo>(t: &T) -> bool { true } diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index 0a2a5f0f245..706f5234365 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -1,26 +1,21 @@ -error[E0277]: can't compare `S` with `S` in const contexts - --> $DIR/call-generic-method-nonconst.rs:18:34 +error[E0277]: the trait bound `S: ~const Foo` is not satisfied + --> $DIR/call-generic-method-nonconst.rs:23:34 | LL | pub const EQ: bool = equals_self(&S); - | ----------- ^^ no implementation for `S == S` + | ----------- ^^ the trait `~const Foo` is not implemented for `S` | | | required by a bound introduced by this call | - = help: the trait `~const PartialEq` is not implemented for `S` -note: the trait `PartialEq` is implemented for `S`, but that implementation is not `const` - --> $DIR/call-generic-method-nonconst.rs:18:34 +note: the trait `Foo` is implemented for `S`, but that implementation is not `const` + --> $DIR/call-generic-method-nonconst.rs:23:34 | LL | pub const EQ: bool = equals_self(&S); | ^^ note: required by a bound in `equals_self` - --> $DIR/call-generic-method-nonconst.rs:11:25 - | -LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool { - | ^^^^^^^^^^^^^^^^ required by this bound in `equals_self` -help: consider annotating `S` with `#[derive(PartialEq)]` - | -LL | #[derive(PartialEq)] + --> $DIR/call-generic-method-nonconst.rs:16:25 | +LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool { + | ^^^^^^^^^^ required by this bound in `equals_self` error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index 2295a822fa4..ddf0e2d91c0 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -1,5 +1,5 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:43:5 + --> $DIR/const-drop-fail.rs:44:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -9,7 +9,7 @@ LL | NonTrivialDrop, | = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check<T: ~const Destruct>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` @@ -21,7 +21,7 @@ LL | &mut NonTrivialDrop, | ++++ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:45:5 + --> $DIR/const-drop-fail.rs:46:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -30,7 +30,7 @@ LL | ConstImplWithDropGlue(NonTrivialDrop), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:45:5 + --> $DIR/const-drop-fail.rs:46:5 | LL | ConstImplWithDropGlue(NonTrivialDrop), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue` LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check<T: ~const Destruct>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied - --> $DIR/const-drop-fail.rs:47:5 + --> $DIR/const-drop-fail.rs:48:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -55,14 +55,14 @@ LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>` | note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct` - --> $DIR/const-drop-fail.rs:28:25 + --> $DIR/const-drop-fail.rs:29:25 | LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> { | ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: 1 redundant requirement hidden = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct` note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check<T: ~const Destruct>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs index 001dd430a86..565e2c77ac5 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.rs @@ -19,7 +19,8 @@ impl const Drop for ConstImplWithDropGlue { fn drop(&mut self) {} } -trait A { fn a() { println!("A"); } } +#[const_trait] +trait A { fn a() { } } impl A for NonTrivialDrop {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index 2295a822fa4..ddf0e2d91c0 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -1,5 +1,5 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:43:5 + --> $DIR/const-drop-fail.rs:44:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -9,7 +9,7 @@ LL | NonTrivialDrop, | = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check<T: ~const Destruct>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` @@ -21,7 +21,7 @@ LL | &mut NonTrivialDrop, | ++++ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:45:5 + --> $DIR/const-drop-fail.rs:46:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -30,7 +30,7 @@ LL | ConstImplWithDropGlue(NonTrivialDrop), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:45:5 + --> $DIR/const-drop-fail.rs:46:5 | LL | ConstImplWithDropGlue(NonTrivialDrop), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,13 +40,13 @@ note: required because it appears within the type `ConstImplWithDropGlue` LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check<T: ~const Destruct>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` error[E0277]: the trait bound `ConstDropImplWithBounds<NonTrivialDrop>: ~const Destruct` is not satisfied - --> $DIR/const-drop-fail.rs:47:5 + --> $DIR/const-drop-fail.rs:48:5 | LL | const _: () = check($exp); | ----- required by a bound introduced by this call @@ -55,14 +55,14 @@ LL | ConstDropImplWithBounds::<NonTrivialDrop>(PhantomData), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `ConstDropImplWithBounds<NonTrivialDrop>` | note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct` - --> $DIR/const-drop-fail.rs:28:25 + --> $DIR/const-drop-fail.rs:29:25 | LL | impl<T: ~const A> const Drop for ConstDropImplWithBounds<T> { | ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: 1 redundant requirement hidden = note: required for `ConstDropImplWithBounds<NonTrivialDrop>` to implement `~const Destruct` note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:34:19 + --> $DIR/const-drop-fail.rs:35:19 | LL | const fn check<T: ~const Destruct>(_: T) {} | ^^^^^^^^^^^^^^^ required by this bound in `check` diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs index 1aff0562785..2b4963991db 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.rs @@ -1,9 +1,9 @@ #![feature(const_trait_impl)] pub trait A {} -//~^ NOTE: this trait must be annotated with `#[const_trait]` +//~^ HELP: mark `A` as const impl const A for () {} -//~^ ERROR: const `impl`s must be for traits marked with `#[const_trait]` +//~^ ERROR: const `impl` for trait `A` which is not marked with `#[const_trait]` fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr index 6b465a9c62e..478adcf3e9e 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-impl-requires-const-trait.stderr @@ -1,14 +1,14 @@ -error: const `impl`s must be for traits marked with `#[const_trait]` - --> $DIR/const-impl-requires-const-trait.rs:6:1 +error: const `impl` for trait `A` which is not marked with `#[const_trait]` + --> $DIR/const-impl-requires-const-trait.rs:6:12 | +LL | pub trait A {} + | - help: mark `A` as const: `#[const_trait]` +... LL | impl const A for () {} - | ^^^^^^^^^^^^^^^^^^^ - | -note: this trait must be annotated with `#[const_trait]` - --> $DIR/const-impl-requires-const-trait.rs:3:1 + | ^ | -LL | pub trait A {} - | ^^^^^^^^^^^ + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs index d27291231fb..96acdc300e0 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.rs @@ -1,5 +1,6 @@ #![feature(const_trait_impl)] +#[const_trait] trait Tr {} impl Tr for () {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr index 7542b81fe2a..d102956cd2e 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr @@ -1,16 +1,16 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied - --> $DIR/default-method-body-is-const-body-checking.rs:11:15 + --> $DIR/default-method-body-is-const-body-checking.rs:12:15 | LL | foo::<()>(); | ^^ the trait `~const Tr` is not implemented for `()` | note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/default-method-body-is-const-body-checking.rs:11:15 + --> $DIR/default-method-body-is-const-body-checking.rs:12:15 | LL | foo::<()>(); | ^^ note: required by a bound in `foo` - --> $DIR/default-method-body-is-const-body-checking.rs:6:28 + --> $DIR/default-method-body-is-const-body-checking.rs:7:28 | LL | const fn foo<T>() where T: ~const Tr {} | ^^^^^^^^^ required by this bound in `foo` diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-102156.rs b/src/test/ui/rfc-2632-const-trait-impl/issue-102156.rs new file mode 100644 index 00000000000..fe4e9108130 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/issue-102156.rs @@ -0,0 +1,15 @@ +#![feature(allocator_api)] +#![feature(const_trait_impl)] + +use core::convert::{From, TryFrom}; +//~^ ERROR +//~| ERROR + +use std::pin::Pin; +use std::alloc::Allocator; +impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>> +where + A: 'static, +{} + +pub fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/issue-102156.stderr b/src/test/ui/rfc-2632-const-trait-impl/issue-102156.stderr new file mode 100644 index 00000000000..8bf00eaff1f --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/issue-102156.stderr @@ -0,0 +1,19 @@ +error[E0433]: failed to resolve: maybe a missing crate `core`? + --> $DIR/issue-102156.rs:4:5 + | +LL | use core::convert::{From, TryFrom}; + | ^^^^ maybe a missing crate `core`? + | + = help: consider adding `extern crate core` to use the `core` crate + +error[E0433]: failed to resolve: maybe a missing crate `core`? + --> $DIR/issue-102156.rs:4:5 + | +LL | use core::convert::{From, TryFrom}; + | ^^^^ maybe a missing crate `core`? + | + = help: consider adding `extern crate core` to use the `core` crate + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr new file mode 100644 index 00000000000..b86acb2cc9a --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:11:12 + | +LL | trait Bar: ~const Foo {} + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr new file mode 100644 index 00000000000..b86acb2cc9a --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-2.rs:11:12 + | +LL | trait Bar: ~const Foo {} + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs index 7b38c15afc2..d183efde2df 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -1,14 +1,19 @@ #![feature(const_trait_impl)] +// revisions: yy yn ny nn + +#[cfg_attr(any(yy, yn), const_trait)] trait Foo { fn a(&self); } + +#[cfg_attr(any(yy, ny), const_trait)] trait Bar: ~const Foo {} +//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` const fn foo<T: Bar>(x: &T) { x.a(); - //~^ ERROR the trait bound - //~| ERROR cannot call + //[yn,yy]~^ ERROR the trait bound } fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr deleted file mode 100644 index 1766cdbee8a..00000000000 --- a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0277]: the trait bound `T: ~const Foo` is not satisfied - --> $DIR/super-traits-fail-2.rs:9:7 - | -LL | x.a(); - | ^^^ the trait `~const Foo` is not implemented for `T` - | -note: the trait `Foo` is implemented for `T`, but that implementation is not `const` - --> $DIR/super-traits-fail-2.rs:9:7 - | -LL | x.a(); - | ^^^ - -error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions - --> $DIR/super-traits-fail-2.rs:9:7 - | -LL | x.a(); - | ^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0015, E0277. -For more information about an error, try `rustc --explain E0015`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr new file mode 100644 index 00000000000..b52eb2c0332 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `T: ~const Foo` is not satisfied + --> $DIR/super-traits-fail-2.rs:15:5 + | +LL | x.a(); + | ^ - required by a bound introduced by this call + | | + | the trait `~const Foo` is not implemented for `T` + | +note: the trait `Foo` is implemented for `T`, but that implementation is not `const` + --> $DIR/super-traits-fail-2.rs:15:5 + | +LL | x.a(); + | ^ +help: consider further restricting this bound + | +LL | const fn foo<T: Bar + ~const Foo>(x: &T) { + | ++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr new file mode 100644 index 00000000000..b52eb2c0332 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `T: ~const Foo` is not satisfied + --> $DIR/super-traits-fail-2.rs:15:5 + | +LL | x.a(); + | ^ - required by a bound introduced by this call + | | + | the trait `~const Foo` is not implemented for `T` + | +note: the trait `Foo` is implemented for `T`, but that implementation is not `const` + --> $DIR/super-traits-fail-2.rs:15:5 + | +LL | x.a(); + | ^ +help: consider further restricting this bound + | +LL | const fn foo<T: Bar + ~const Foo>(x: &T) { + | ++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr new file mode 100644 index 00000000000..191edca1761 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -0,0 +1,14 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:12:12 + | +LL | trait Bar: ~const Foo {} + | ^^^^^^^^^^ + +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:15:17 + | +LL | const fn foo<T: ~const Bar>(x: &T) { + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr new file mode 100644 index 00000000000..a3b4c302a57 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:12:12 + | +LL | trait Bar: ~const Foo {} + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs new file mode 100644 index 00000000000..70d2936d3b2 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -0,0 +1,20 @@ +#![feature(const_trait_impl)] + +// revisions: yy yn ny nn +//[yy] check-pass + +#[cfg_attr(any(yy, yn), const_trait)] +trait Foo { + fn a(&self); +} + +#[cfg_attr(any(yy, ny), const_trait)] +trait Bar: ~const Foo {} +//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` + +const fn foo<T: ~const Bar>(x: &T) { + //[yn,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` + x.a(); +} + +fn main() {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr new file mode 100644 index 00000000000..9d611665465 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -0,0 +1,8 @@ +error: ~const can only be applied to `#[const_trait]` traits + --> $DIR/super-traits-fail-3.rs:15:17 + | +LL | const fn foo<T: ~const Bar>(x: &T) { + | ^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs index 350be4d8250..5bd52151f42 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.rs @@ -1,6 +1,7 @@ #![feature(const_trait_impl)] #![feature(associated_type_bounds)] +#[const_trait] trait T {} struct S; impl T for S {} diff --git a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr index 8d781d063d1..5d213315634 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/tilde-const-invalid-places.stderr @@ -1,5 +1,5 @@ error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:8:19 + --> $DIR/tilde-const-invalid-places.rs:9:19 | LL | fn rpit() -> impl ~const T { S } | ^^^^^^^^ @@ -7,7 +7,7 @@ LL | fn rpit() -> impl ~const T { S } = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:11:17 + --> $DIR/tilde-const-invalid-places.rs:12:17 | LL | fn apit(_: impl ~const T) {} | ^^^^^^^^ @@ -15,7 +15,7 @@ LL | fn apit(_: impl ~const T) {} = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:14:50 + --> $DIR/tilde-const-invalid-places.rs:15:50 | LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) } | ^^^^^^^^ @@ -23,7 +23,7 @@ LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) } = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions error: `~const` is not allowed here - --> $DIR/tilde-const-invalid-places.rs:17:48 + --> $DIR/tilde-const-invalid-places.rs:18:48 | LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {} | ^^^^^^^^ @@ -31,7 +31,7 @@ LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {} = note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions error: `~const` and `?` are mutually exclusive - --> $DIR/tilde-const-invalid-places.rs:20:25 + --> $DIR/tilde-const-invalid-places.rs:21:25 | LL | struct TildeQuestion<T: ~const ?Sized>(std::marker::PhantomData<T>); | ^^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs index 47c38c979c3..bfe98b98c74 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.rs @@ -4,8 +4,10 @@ // test is not enough. #![feature(const_trait_impl)] +#[const_trait] trait Bar {} +#[const_trait] trait Foo { fn a(); fn b() where Self: ~const Bar; diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr index 13d8639de30..f2846b6a662 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-const.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: ~const Bar` is not satisfied - --> $DIR/trait-where-clause-const.rs:17:5 + --> $DIR/trait-where-clause-const.rs:19:5 | LL | T::b(); | ^^^^^^ the trait `~const Bar` is not implemented for `T` | note: the trait `Bar` is implemented for `T`, but that implementation is not `const` - --> $DIR/trait-where-clause-const.rs:17:5 + --> $DIR/trait-where-clause-const.rs:19:5 | LL | T::b(); | ^^^^^^ @@ -15,13 +15,13 @@ LL | const fn test1<T: ~const Foo + Bar + ~const Bar>() { | ++++++++++++ error[E0277]: the trait bound `T: ~const Bar` is not satisfied - --> $DIR/trait-where-clause-const.rs:19:5 + --> $DIR/trait-where-clause-const.rs:21:5 | LL | T::c::<T>(); | ^^^^^^^^^^^ the trait `~const Bar` is not implemented for `T` | note: the trait `Bar` is implemented for `T`, but that implementation is not `const` - --> $DIR/trait-where-clause-const.rs:19:5 + --> $DIR/trait-where-clause-const.rs:21:5 | LL | T::c::<T>(); | ^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs index acea58eaecb..3b028ac48db 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause-self-referential.rs @@ -2,6 +2,7 @@ #![feature(const_trait_impl)] +#[const_trait] trait Foo { fn bar() where Self: ~const Foo; } diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs index 5bd23a8cb20..85ca5fc9048 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.rs @@ -1,5 +1,6 @@ #![feature(const_trait_impl)] +#[const_trait] trait Bar {} trait Foo { diff --git a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr index 96365d33433..11f0c40160d 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/trait-where-clause.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:13:5 + --> $DIR/trait-where-clause.rs:14:5 | LL | T::b(); | ^^^^ the trait `Bar` is not implemented for `T` | note: required by a bound in `Foo::b` - --> $DIR/trait-where-clause.rs:7:24 + --> $DIR/trait-where-clause.rs:8:24 | LL | fn b() where Self: ~const Bar; | ^^^^^^^^^^ required by this bound in `Foo::b` @@ -15,13 +15,13 @@ LL | fn test1<T: Foo + Bar>() { | +++++ error[E0277]: the trait bound `T: Bar` is not satisfied - --> $DIR/trait-where-clause.rs:15:12 + --> $DIR/trait-where-clause.rs:16:12 | LL | T::c::<T>(); | ^ the trait `Bar` is not implemented for `T` | note: required by a bound in `Foo::c` - --> $DIR/trait-where-clause.rs:8:13 + --> $DIR/trait-where-clause.rs:9:13 | LL | fn c<T: ~const Bar>(); | ^^^^^^^^^^ required by this bound in `Foo::c` diff --git a/src/test/ui/rust-2018/async-ident-allowed.stderr b/src/test/ui/rust-2018/async-ident-allowed.stderr index 5b63eab8e46..992b2975009 100644 --- a/src/test/ui/rust-2018/async-ident-allowed.stderr +++ b/src/test/ui/rust-2018/async-ident-allowed.stderr @@ -4,14 +4,14 @@ error: `async` is a keyword in the 2018 edition LL | let async = 3; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> note: the lint level is defined here --> $DIR/async-ident-allowed.rs:3:9 | LL | #![deny(rust_2018_compatibility)] | ^^^^^^^^^^^^^^^^^^^^^^^ = note: `#[deny(keyword_idents)]` implied by `#[deny(rust_2018_compatibility)]` - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: aborting due to previous error diff --git a/src/test/ui/rust-2018/async-ident.stderr b/src/test/ui/rust-2018/async-ident.stderr index 6396e9deee2..d15250c54ec 100644 --- a/src/test/ui/rust-2018/async-ident.stderr +++ b/src/test/ui/rust-2018/async-ident.stderr @@ -4,13 +4,13 @@ error: `async` is a keyword in the 2018 edition LL | fn async() {} | ^^^^^ help: you can use a raw identifier to stay compatible: `r#async` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> note: the lint level is defined here --> $DIR/async-ident.rs:2:9 | LL | #![deny(keyword_idents)] | ^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `async` is a keyword in the 2018 edition --> $DIR/async-ident.rs:12:7 diff --git a/src/test/ui/rust-2018/dyn-keyword.stderr b/src/test/ui/rust-2018/dyn-keyword.stderr index 699242f2dcb..b6f5b10cf03 100644 --- a/src/test/ui/rust-2018/dyn-keyword.stderr +++ b/src/test/ui/rust-2018/dyn-keyword.stderr @@ -4,13 +4,13 @@ error: `dyn` is a keyword in the 2018 edition LL | let dyn = (); | ^^^ help: you can use a raw identifier to stay compatible: `r#dyn` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> note: the lint level is defined here --> $DIR/dyn-keyword.rs:5:9 | LL | #![deny(keyword_idents)] | ^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: aborting due to previous error diff --git a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr index 6f529fa9114..e1709db0990 100644 --- a/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-fully-qualified-paths.stderr @@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | let _: <foo::Baz as ::foo::Foo>::Bar = (); | ^^^^^^^^^^ help: use `crate`: `crate::foo::Foo` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> note: the lint level is defined here --> $DIR/edition-lint-fully-qualified-paths.rs:4:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-fully-qualified-paths.rs:23:13 diff --git a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr index e47c320f78f..8769cbb35b0 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-nested-empty-paths.stderr @@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use foo::{bar::{baz::{}}}; | ^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::foo::{bar::{baz::{}}}` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> note: the lint level is defined here --> $DIR/edition-lint-nested-empty-paths.rs:4:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-empty-paths.rs:21:5 diff --git a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr index 24b17f212eb..354a6fe3252 100644 --- a/src/test/ui/rust-2018/edition-lint-nested-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-nested-paths.stderr @@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use foo::{a, b}; | ^^^^^^^^^^^ help: use `crate`: `crate::foo::{a, b}` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> note: the lint level is defined here --> $DIR/edition-lint-nested-paths.rs:4:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-nested-paths.rs:6:5 diff --git a/src/test/ui/rust-2018/edition-lint-paths.stderr b/src/test/ui/rust-2018/edition-lint-paths.stderr index 1ded8cd3694..42652be9401 100644 --- a/src/test/ui/rust-2018/edition-lint-paths.stderr +++ b/src/test/ui/rust-2018/edition-lint-paths.stderr @@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use bar::Bar; | ^^^^^^^^ help: use `crate`: `crate::bar::Bar` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> note: the lint level is defined here --> $DIR/edition-lint-paths.rs:5:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: absolute paths must start with `self`, `super`, `crate`, or an external crate name in the 2018 edition --> $DIR/edition-lint-paths.rs:19:9 diff --git a/src/test/ui/rust-2018/extern-crate-rename.stderr b/src/test/ui/rust-2018/extern-crate-rename.stderr index 4bccbc51223..eb040f5de54 100644 --- a/src/test/ui/rust-2018/extern-crate-rename.stderr +++ b/src/test/ui/rust-2018/extern-crate-rename.stderr @@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use my_crate::foo; | ^^^^^^^^^^^^^ help: use `crate`: `crate::my_crate::foo` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> note: the lint level is defined here --> $DIR/extern-crate-rename.rs:8:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: aborting due to previous error diff --git a/src/test/ui/rust-2018/extern-crate-submod.stderr b/src/test/ui/rust-2018/extern-crate-submod.stderr index 3c75319aeda..1a9aa75787a 100644 --- a/src/test/ui/rust-2018/extern-crate-submod.stderr +++ b/src/test/ui/rust-2018/extern-crate-submod.stderr @@ -4,13 +4,13 @@ error: absolute paths must start with `self`, `super`, `crate`, or an external c LL | use m::edition_lint_paths::foo; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `crate`: `crate::m::edition_lint_paths::foo` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> note: the lint level is defined here --> $DIR/extern-crate-submod.rs:9:9 | LL | #![deny(absolute_paths_not_starting_with_crate)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #53130 <https://github.com/rust-lang/rust/issues/53130> error: aborting due to previous error diff --git a/src/test/ui/rust-2018/try-ident.stderr b/src/test/ui/rust-2018/try-ident.stderr index 3d93b433cf2..74015ac9da4 100644 --- a/src/test/ui/rust-2018/try-ident.stderr +++ b/src/test/ui/rust-2018/try-ident.stderr @@ -4,14 +4,14 @@ warning: `try` is a keyword in the 2018 edition LL | try(); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> note: the lint level is defined here --> $DIR/try-ident.rs:4:9 | LL | #![warn(rust_2018_compatibility)] | ^^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(keyword_idents)]` implied by `#[warn(rust_2018_compatibility)]` - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> warning: `try` is a keyword in the 2018 edition --> $DIR/try-ident.rs:12:4 diff --git a/src/test/ui/rust-2018/try-macro.stderr b/src/test/ui/rust-2018/try-macro.stderr index f315b4d4a9e..760378f0955 100644 --- a/src/test/ui/rust-2018/try-macro.stderr +++ b/src/test/ui/rust-2018/try-macro.stderr @@ -4,14 +4,14 @@ warning: `try` is a keyword in the 2018 edition LL | try!(x); | ^^^ help: you can use a raw identifier to stay compatible: `r#try` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! + = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> note: the lint level is defined here --> $DIR/try-macro.rs:6:9 | LL | #![warn(rust_2018_compatibility)] | ^^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(keyword_idents)]` implied by `#[warn(rust_2018_compatibility)]` - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2018! - = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> warning: 1 warning emitted diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr index fac8d21c7b4..2a724bd3072 100644 --- a/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr +++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr @@ -4,13 +4,13 @@ warning: trait method `into_iter` will become ambiguous in Rust 2021 LL | let y = points.into_iter(); | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)` | + = warning: this changes meaning in Rust 2021 + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html> note: the lint level is defined here --> $DIR/array-into-iter-ambiguous.rs:5:9 | LL | #![warn(array_into_iter)] | ^^^^^^^^^^^^^^^ - = warning: this changes meaning in Rust 2021 - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html> warning: 1 warning emitted diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr index 14ad9b017b6..f38da132b5e 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr @@ -4,13 +4,13 @@ warning: trait-associated function `try_from` will become ambiguous in Rust 2021 LL | U::try_from(self) | ^^^^^^^^^^^ help: disambiguate the associated function: `<U as PyTryFrom<'_, _>>::try_from` | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> note: the lint level is defined here --> $DIR/future-prelude-collision-generic-trait.rs:5:9 | LL | #![warn(rust_2021_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> warning: 1 warning emitted diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr index e1d3f3c0a46..9893b3ebaa6 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr @@ -4,13 +4,13 @@ warning: trait-associated function `from_iter` will become ambiguous in Rust 202 LL | Generic::from_iter(1); | ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<'_, _> as MyFromIter>::from_iter` | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> note: the lint level is defined here --> $DIR/future-prelude-collision-generic.rs:5:9 | LL | #![warn(rust_2021_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision-generic.rs:31:5 diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr index 56abb8abd4d..c1d72d0df21 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr @@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021 LL | let _: u32 = 3u8.try_into().unwrap(); | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)` | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> note: the lint level is defined here --> $DIR/future-prelude-collision-imported.rs:4:9 | LL | #![warn(rust_2021_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> warning: trait method `try_into` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision-imported.rs:40:22 diff --git a/src/test/ui/rust-2021/future-prelude-collision-macros.stderr b/src/test/ui/rust-2021/future-prelude-collision-macros.stderr index 4c3543ca782..4d4a0769958 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-macros.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision-macros.stderr @@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021 LL | foo!().try_into(todo!()); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyTry::try_into(foo!(), todo!())` | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> note: the lint level is defined here --> $DIR/future-prelude-collision-macros.rs:4:9 | LL | #![warn(rust_2021_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> warning: trait-associated function `try_from` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision-macros.rs:42:5 diff --git a/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr b/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr index 2de9020bce7..c0ef80fd841 100644 --- a/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision-turbofish.stderr @@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021 LL | x.try_into::<usize>().or(Err("foo"))?.checked_sub(1); | ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `AnnotatableTryInto::try_into::<usize>(x)` | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> note: the lint level is defined here --> $DIR/future-prelude-collision-turbofish.rs:6:9 | LL | #![warn(rust_2021_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> warning: trait method `try_into` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision-turbofish.rs:23:5 diff --git a/src/test/ui/rust-2021/future-prelude-collision.stderr b/src/test/ui/rust-2021/future-prelude-collision.stderr index 889e66de03f..cae113ff711 100644 --- a/src/test/ui/rust-2021/future-prelude-collision.stderr +++ b/src/test/ui/rust-2021/future-prelude-collision.stderr @@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021 LL | let _: u32 = 3u8.try_into().unwrap(); | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)` | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> note: the lint level is defined here --> $DIR/future-prelude-collision.rs:4:9 | LL | #![warn(rust_2021_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> warning: trait-associated function `try_from` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision.rs:61:13 diff --git a/src/test/ui/rust-2021/generic-type-collision.stderr b/src/test/ui/rust-2021/generic-type-collision.stderr index e6ea28d718d..1ec61044f4a 100644 --- a/src/test/ui/rust-2021/generic-type-collision.stderr +++ b/src/test/ui/rust-2021/generic-type-collision.stderr @@ -4,13 +4,13 @@ warning: trait-associated function `from_iter` will become ambiguous in Rust 202 LL | <Vec<i32>>::from_iter(None); | ^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Vec<i32> as MyTrait<_>>::from_iter` | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> note: the lint level is defined here --> $DIR/generic-type-collision.rs:4:9 | LL | #![warn(rust_2021_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> warning: 1 warning emitted diff --git a/src/test/ui/rust-2021/inherent-dyn-collision.stderr b/src/test/ui/rust-2021/inherent-dyn-collision.stderr index 77b4c385132..f5905574ac3 100644 --- a/src/test/ui/rust-2021/inherent-dyn-collision.stderr +++ b/src/test/ui/rust-2021/inherent-dyn-collision.stderr @@ -4,13 +4,13 @@ warning: trait method `try_into` will become ambiguous in Rust 2021 LL | get_dyn_trait().try_into().unwrap() | ^^^^^^^^^^^^^^^ help: disambiguate the method call: `(&*get_dyn_trait())` | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> note: the lint level is defined here --> $DIR/inherent-dyn-collision.rs:8:9 | LL | #![warn(rust_2021_prelude_collisions)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html> warning: 1 warning emitted diff --git a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr index c6bc082cf18..20914d1b9d1 100644 --- a/src/test/ui/rust-2021/reserved-prefixes-migration.stderr +++ b/src/test/ui/rust-2021/reserved-prefixes-migration.stderr @@ -4,13 +4,13 @@ warning: prefix `z` is unknown LL | m2!(z"hey"); | ^ unknown prefix | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html> note: the lint level is defined here --> $DIR/reserved-prefixes-migration.rs:5:9 | LL | #![warn(rust_2021_prefixes_incompatible_syntax)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/reserving-syntax.html> help: insert whitespace here to avoid this being parsed as a prefix in Rust 2021 | LL | m2!(z "hey"); diff --git a/src/test/ui/rustdoc/deny-invalid-doc-attrs.stderr b/src/test/ui/rustdoc/deny-invalid-doc-attrs.stderr index a14ab8fe4bc..e9a4c1dd52f 100644 --- a/src/test/ui/rustdoc/deny-invalid-doc-attrs.stderr +++ b/src/test/ui/rustdoc/deny-invalid-doc-attrs.stderr @@ -4,13 +4,13 @@ error: unknown `doc` attribute `x` LL | #![doc(x)] | ^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> note: the lint level is defined here --> $DIR/deny-invalid-doc-attrs.rs:1:9 | LL | #![deny(invalid_doc_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> error: aborting due to previous error diff --git a/src/test/ui/rustdoc/doc-test-attr.stderr b/src/test/ui/rustdoc/doc-test-attr.stderr index 7f5e2d6bc70..5e6014954a4 100644 --- a/src/test/ui/rustdoc/doc-test-attr.stderr +++ b/src/test/ui/rustdoc/doc-test-attr.stderr @@ -4,13 +4,13 @@ error: `#[doc(test(...)]` takes a list of attributes LL | #![doc(test)] | ^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> note: the lint level is defined here --> $DIR/doc-test-attr.rs:2:9 | LL | #![deny(invalid_doc_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> error: `#[doc(test(...)]` takes a list of attributes --> $DIR/doc-test-attr.rs:7:8 diff --git a/src/test/ui/rustdoc/feature-gate-doc_primitive.stderr b/src/test/ui/rustdoc/feature-gate-doc_primitive.stderr index 736bf29c580..194b2d87db2 100644 --- a/src/test/ui/rustdoc/feature-gate-doc_primitive.stderr +++ b/src/test/ui/rustdoc/feature-gate-doc_primitive.stderr @@ -4,9 +4,9 @@ warning: `doc(primitive)` should never have been stable LL | #[doc(primitive = "usize")] | ^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(invalid_doc_attributes)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> + = note: `#[warn(invalid_doc_attributes)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/sanitize/inline-always.stderr b/src/test/ui/sanitize/inline-always.stderr index 918762d1f66..74fba3c0e0e 100644 --- a/src/test/ui/sanitize/inline-always.stderr +++ b/src/test/ui/sanitize/inline-always.stderr @@ -4,12 +4,12 @@ warning: `no_sanitize` will have no effect after inlining LL | #[no_sanitize(address)] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(inline_no_sanitize)]` on by default note: inlining requested here --> $DIR/inline-always.rs:5:1 | LL | #[inline(always)] | ^^^^^^^^^^^^^^^^^ + = note: `#[warn(inline_no_sanitize)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/simd/target-feature-mixup.rs b/src/test/ui/simd/target-feature-mixup.rs index 6d7688191b7..5dd163715eb 100644 --- a/src/test/ui/simd/target-feature-mixup.rs +++ b/src/test/ui/simd/target-feature-mixup.rs @@ -5,6 +5,7 @@ // ignore-emscripten // ignore-sgx no processes +// ignore-fuchsia must translate zircon signal to SIGILL, FIXME (#58590) #![feature(repr_simd, target_feature, cfg_target_feature)] #![feature(avx512_target_feature)] diff --git a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr index 2c1fa7b36b6..ee72a0c65c8 100644 --- a/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr +++ b/src/test/ui/span/drop-location-span-error-rust-2021-incompatible-closure-captures-93117.stderr @@ -67,8 +67,8 @@ LL | | crate(move || {} ).await LL | | } | |_____^ | - = note: requested on the command line with `-W rust-2021-incompatible-closure-captures` = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/disjoint-capture-in-closures.html> + = note: requested on the command line with `-W rust-2021-incompatible-closure-captures` help: add a dummy let to cause `path` to be fully captured | LL | async fn create(path: impl AsRef<std::path::Path>) { let _ = &path; diff --git a/src/test/ui/specialization/assoc-ty-graph-cycle.stderr b/src/test/ui/specialization/assoc-ty-graph-cycle.stderr index 17da34caa70..f5529c24d3e 100644 --- a/src/test/ui/specialization/assoc-ty-graph-cycle.stderr +++ b/src/test/ui/specialization/assoc-ty-graph-cycle.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/cross-crate-defaults.stderr b/src/test/ui/specialization/cross-crate-defaults.stderr index e368c2e73b6..ee5c77a76be 100644 --- a/src/test/ui/specialization/cross-crate-defaults.stderr +++ b/src/test/ui/specialization/cross-crate-defaults.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/default-associated-type-bound-1.stderr b/src/test/ui/specialization/default-associated-type-bound-1.stderr index af9f2f7c2e9..e498187c0a1 100644 --- a/src/test/ui/specialization/default-associated-type-bound-1.stderr +++ b/src/test/ui/specialization/default-associated-type-bound-1.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `str: Clone` is not satisfied --> $DIR/default-associated-type-bound-1.rs:18:22 diff --git a/src/test/ui/specialization/default-associated-type-bound-2.stderr b/src/test/ui/specialization/default-associated-type-bound-2.stderr index 91778ed0f4c..4dbe251ed5e 100644 --- a/src/test/ui/specialization/default-associated-type-bound-2.stderr +++ b/src/test/ui/specialization/default-associated-type-bound-2.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0277]: can't compare `&'static B` with `B` --> $DIR/default-associated-type-bound-2.rs:16:22 diff --git a/src/test/ui/specialization/default-generic-associated-type-bound.stderr b/src/test/ui/specialization/default-generic-associated-type-bound.stderr index 44c24c1e578..c597eed3790 100644 --- a/src/test/ui/specialization/default-generic-associated-type-bound.stderr +++ b/src/test/ui/specialization/default-generic-associated-type-bound.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0277]: can't compare `T` with `T` --> $DIR/default-generic-associated-type-bound.rs:17:26 diff --git a/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr b/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr index d8b9c48c72e..02f13d461c3 100644 --- a/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr +++ b/src/test/ui/specialization/defaultimpl/allowed-cross-crate.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/out-of-order.stderr b/src/test/ui/specialization/defaultimpl/out-of-order.stderr index 9ca915686e8..2cf1ac90959 100644 --- a/src/test/ui/specialization/defaultimpl/out-of-order.stderr +++ b/src/test/ui/specialization/defaultimpl/out-of-order.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/overlap-projection.stderr b/src/test/ui/specialization/defaultimpl/overlap-projection.stderr index 31d0e6e3882..75fdfafd9d1 100644 --- a/src/test/ui/specialization/defaultimpl/overlap-projection.stderr +++ b/src/test/ui/specialization/defaultimpl/overlap-projection.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/projection.stderr b/src/test/ui/specialization/defaultimpl/projection.stderr index 2d5c80d05f0..cc3fe8237a7 100644 --- a/src/test/ui/specialization/defaultimpl/projection.stderr +++ b/src/test/ui/specialization/defaultimpl/projection.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr index 360b7bc787a..770be2af281 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-no-default.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/specialization-no-default.rs:20:5 diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr index 163c93550fb..407c1ab7720 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented-rpass.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr index 250f0017bea..f19975060a4 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-item-not-implemented.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0046]: not all trait items implemented, missing: `foo_two` --> $DIR/specialization-trait-item-not-implemented.rs:18:1 diff --git a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr index d1004a69058..33ca7a2c210 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-trait-not-implemented.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0599]: the method `foo_one` exists for struct `MyStruct`, but its trait bounds were not satisfied --> $DIR/specialization-trait-not-implemented.rs:22:29 diff --git a/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr index a8fdbc52884..e7801603493 100644 --- a/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr +++ b/src/test/ui/specialization/defaultimpl/specialization-wfcheck.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `U: Eq` is not satisfied --> $DIR/specialization-wfcheck.rs:7:17 diff --git a/src/test/ui/specialization/defaultimpl/validation.stderr b/src/test/ui/specialization/defaultimpl/validation.stderr index cbf0cef5e74..eb6dc9355a3 100644 --- a/src/test/ui/specialization/defaultimpl/validation.stderr +++ b/src/test/ui/specialization/defaultimpl/validation.stderr @@ -14,9 +14,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error: impls of auto traits cannot be default --> $DIR/validation.rs:9:21 diff --git a/src/test/ui/specialization/issue-35376.stderr b/src/test/ui/specialization/issue-35376.stderr index 835277d408e..6c4167f3f9f 100644 --- a/src/test/ui/specialization/issue-35376.stderr +++ b/src/test/ui/specialization/issue-35376.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/issue-36804.stderr b/src/test/ui/specialization/issue-36804.stderr index 783a38e6bdc..c2113b25f19 100644 --- a/src/test/ui/specialization/issue-36804.stderr +++ b/src/test/ui/specialization/issue-36804.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/issue-38091-2.stderr b/src/test/ui/specialization/issue-38091-2.stderr index 31ae4b26e45..117fb10bb7e 100644 --- a/src/test/ui/specialization/issue-38091-2.stderr +++ b/src/test/ui/specialization/issue-38091-2.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0275]: overflow evaluating the requirement `i32: Check` | diff --git a/src/test/ui/specialization/issue-38091.stderr b/src/test/ui/specialization/issue-38091.stderr index cc5536c9e9a..f2210a40719 100644 --- a/src/test/ui/specialization/issue-38091.stderr +++ b/src/test/ui/specialization/issue-38091.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0277]: the trait bound `(): Valid` is not satisfied --> $DIR/issue-38091.rs:12:23 diff --git a/src/test/ui/specialization/issue-39448.stderr b/src/test/ui/specialization/issue-39448.stderr index 9b74f684b8f..60157d9a3e1 100644 --- a/src/test/ui/specialization/issue-39448.stderr +++ b/src/test/ui/specialization/issue-39448.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0275]: overflow evaluating the requirement `T: FromA<U>` --> $DIR/issue-39448.rs:45:13 diff --git a/src/test/ui/specialization/issue-39618.stderr b/src/test/ui/specialization/issue-39618.stderr index 77a45806edb..19de60c7c17 100644 --- a/src/test/ui/specialization/issue-39618.stderr +++ b/src/test/ui/specialization/issue-39618.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/issue-50452-fail.stderr b/src/test/ui/specialization/issue-50452-fail.stderr index 7249ad73871..5c136adc451 100644 --- a/src/test/ui/specialization/issue-50452-fail.stderr +++ b/src/test/ui/specialization/issue-50452-fail.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/issue-50452-fail.rs:10:5 diff --git a/src/test/ui/specialization/issue-50452.stderr b/src/test/ui/specialization/issue-50452.stderr index 2f05c41346f..48cab9dcdb7 100644 --- a/src/test/ui/specialization/issue-50452.stderr +++ b/src/test/ui/specialization/issue-50452.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/issue-52050.stderr b/src/test/ui/specialization/issue-52050.stderr index 6d24997a5bf..c263fe46724 100644 --- a/src/test/ui/specialization/issue-52050.stderr +++ b/src/test/ui/specialization/issue-52050.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0119]: conflicting implementations of trait `IntoPyDictPointer` for type `()` --> $DIR/issue-52050.rs:28:1 diff --git a/src/test/ui/specialization/issue-63716-parse-async.stderr b/src/test/ui/specialization/issue-63716-parse-async.stderr index cde17872d6b..a00572da8f5 100644 --- a/src/test/ui/specialization/issue-63716-parse-async.stderr +++ b/src/test/ui/specialization/issue-63716-parse-async.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/issue-70442.stderr b/src/test/ui/specialization/issue-70442.stderr index 5ee82e9915b..aa72c32866a 100644 --- a/src/test/ui/specialization/issue-70442.stderr +++ b/src/test/ui/specialization/issue-70442.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/non-defaulted-item-fail.stderr b/src/test/ui/specialization/non-defaulted-item-fail.stderr index 8b7d6797275..faa14555a4f 100644 --- a/src/test/ui/specialization/non-defaulted-item-fail.stderr +++ b/src/test/ui/specialization/non-defaulted-item-fail.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization, associated_type_defaults)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0520]: `Ty` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/non-defaulted-item-fail.rs:30:5 diff --git a/src/test/ui/specialization/specialization-allowed-cross-crate.stderr b/src/test/ui/specialization/specialization-allowed-cross-crate.stderr index 9605bd08935..3eea4a53bf5 100644 --- a/src/test/ui/specialization/specialization-allowed-cross-crate.stderr +++ b/src/test/ui/specialization/specialization-allowed-cross-crate.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-assoc-fns.stderr b/src/test/ui/specialization/specialization-assoc-fns.stderr index a7c0661a825..69f7cece79d 100644 --- a/src/test/ui/specialization/specialization-assoc-fns.stderr +++ b/src/test/ui/specialization/specialization-assoc-fns.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-basics.stderr b/src/test/ui/specialization/specialization-basics.stderr index afb2af3803f..7714d4af4c6 100644 --- a/src/test/ui/specialization/specialization-basics.stderr +++ b/src/test/ui/specialization/specialization-basics.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-cross-crate.stderr b/src/test/ui/specialization/specialization-cross-crate.stderr index c69130c0aef..06818bb5627 100644 --- a/src/test/ui/specialization/specialization-cross-crate.stderr +++ b/src/test/ui/specialization/specialization-cross-crate.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-default-methods.stderr b/src/test/ui/specialization/specialization-default-methods.stderr index ef6365ed31f..d78d30bd802 100644 --- a/src/test/ui/specialization/specialization-default-methods.stderr +++ b/src/test/ui/specialization/specialization-default-methods.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-default-projection.stderr b/src/test/ui/specialization/specialization-default-projection.stderr index 7a2b75a1c1f..b8b81876d81 100644 --- a/src/test/ui/specialization/specialization-default-projection.stderr +++ b/src/test/ui/specialization/specialization-default-projection.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:21:5 diff --git a/src/test/ui/specialization/specialization-default-types.stderr b/src/test/ui/specialization/specialization-default-types.stderr index 5ba38facee0..61a556a9311 100644 --- a/src/test/ui/specialization/specialization-default-types.stderr +++ b/src/test/ui/specialization/specialization-default-types.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:15:9 diff --git a/src/test/ui/specialization/specialization-no-default.stderr b/src/test/ui/specialization/specialization-no-default.stderr index 28c869a7055..842cec9c79f 100644 --- a/src/test/ui/specialization/specialization-no-default.stderr +++ b/src/test/ui/specialization/specialization-no-default.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0520]: `foo` specializes an item from a parent `impl`, but that item is not marked `default` --> $DIR/specialization-no-default.rs:20:5 diff --git a/src/test/ui/specialization/specialization-on-projection.stderr b/src/test/ui/specialization/specialization-on-projection.stderr index d051ffe0a02..00fc7ffc547 100644 --- a/src/test/ui/specialization/specialization-on-projection.stderr +++ b/src/test/ui/specialization/specialization-on-projection.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-out-of-order.stderr b/src/test/ui/specialization/specialization-out-of-order.stderr index 785ec29239b..b524e00f01c 100644 --- a/src/test/ui/specialization/specialization-out-of-order.stderr +++ b/src/test/ui/specialization/specialization-out-of-order.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-overlap-negative.stderr b/src/test/ui/specialization/specialization-overlap-negative.stderr index 552b04a6019..fb3d9723aff 100644 --- a/src/test/ui/specialization/specialization-overlap-negative.stderr +++ b/src/test/ui/specialization/specialization-overlap-negative.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0751]: found both positive and negative implementation of trait `std::marker::Send` for type `TestType<_>`: --> $DIR/specialization-overlap-negative.rs:9:1 diff --git a/src/test/ui/specialization/specialization-overlap-projection.stderr b/src/test/ui/specialization/specialization-overlap-projection.stderr index c92db73074d..708c0817fd9 100644 --- a/src/test/ui/specialization/specialization-overlap-projection.stderr +++ b/src/test/ui/specialization/specialization-overlap-projection.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-overlap.stderr b/src/test/ui/specialization/specialization-overlap.stderr index 3ccbe1616e8..98926446765 100644 --- a/src/test/ui/specialization/specialization-overlap.stderr +++ b/src/test/ui/specialization/specialization-overlap.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0119]: conflicting implementations of trait `Foo` for type `std::vec::Vec<_>` --> $DIR/specialization-overlap.rs:5:1 diff --git a/src/test/ui/specialization/specialization-polarity.stderr b/src/test/ui/specialization/specialization-polarity.stderr index be013552f5d..f287018ba7f 100644 --- a/src/test/ui/specialization/specialization-polarity.stderr +++ b/src/test/ui/specialization/specialization-polarity.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0751]: found both positive and negative implementation of trait `Foo` for type `u8`: --> $DIR/specialization-polarity.rs:10:1 diff --git a/src/test/ui/specialization/specialization-projection-alias.stderr b/src/test/ui/specialization/specialization-projection-alias.stderr index 6d2bca5d2df..c94d9ed07b1 100644 --- a/src/test/ui/specialization/specialization-projection-alias.stderr +++ b/src/test/ui/specialization/specialization-projection-alias.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-projection.stderr b/src/test/ui/specialization/specialization-projection.stderr index 0f1ecf5e379..bfc4e0a0f5d 100644 --- a/src/test/ui/specialization/specialization-projection.stderr +++ b/src/test/ui/specialization/specialization-projection.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-supertraits.stderr b/src/test/ui/specialization/specialization-supertraits.stderr index d32e47a24c2..e716bc21596 100644 --- a/src/test/ui/specialization/specialization-supertraits.stderr +++ b/src/test/ui/specialization/specialization-supertraits.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr index d30f7af2cbd..c7aad3c0fee 100644 --- a/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr +++ b/src/test/ui/specialization/specialization-translate-projections-with-lifetimes.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-translate-projections-with-params.stderr b/src/test/ui/specialization/specialization-translate-projections-with-params.stderr index 1762248f695..1c4fd9325a6 100644 --- a/src/test/ui/specialization/specialization-translate-projections-with-params.stderr +++ b/src/test/ui/specialization/specialization-translate-projections-with-params.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/specialization-translate-projections.stderr b/src/test/ui/specialization/specialization-translate-projections.stderr index 94a0e79dd56..22bbb12a09b 100644 --- a/src/test/ui/specialization/specialization-translate-projections.stderr +++ b/src/test/ui/specialization/specialization-translate-projections.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/specialization/transmute-specialization.stderr b/src/test/ui/specialization/transmute-specialization.stderr index a0ea72415a1..b1c26d7dacc 100644 --- a/src/test/ui/specialization/transmute-specialization.stderr +++ b/src/test/ui/specialization/transmute-specialization.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr b/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr index 310f02024ca..7645f3c7ef5 100644 --- a/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-trait-impl.stderr @@ -4,8 +4,8 @@ error: an `#[unstable]` annotation here has no effect LL | #[unstable(feature = "h", issue = "none")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[deny(ineffective_unstable_trait_impl)]` on by default = note: see issue #55436 <https://github.com/rust-lang/rust/issues/55436> for more information + = note: `#[deny(ineffective_unstable_trait_impl)]` on by default error: module has missing stability attribute --> $DIR/stability-attribute-trait-impl.rs:1:1 diff --git a/src/test/ui/statics/uninhabited-static.stderr b/src/test/ui/statics/uninhabited-static.stderr index 6d37de8ff3f..ef794bb36ac 100644 --- a/src/test/ui/statics/uninhabited-static.stderr +++ b/src/test/ui/statics/uninhabited-static.stderr @@ -4,14 +4,14 @@ error: static of uninhabited type LL | static VOID: Void; | ^^^^^^^^^^^^^^^^^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840> + = note: uninhabited statics cannot be initialized, and any access would be an immediate error note: the lint level is defined here --> $DIR/uninhabited-static.rs:2:9 | LL | #![deny(uninhabited_static)] | ^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840> - = note: uninhabited statics cannot be initialized, and any access would be an immediate error error: static of uninhabited type --> $DIR/uninhabited-static.rs:8:5 @@ -58,12 +58,12 @@ LL | static VOID2: Void = unsafe { std::mem::transmute(()) }; | this code causes undefined behavior when executed | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | - = note: `#[warn(invalid_value)]` on by default note: enums with no inhabited variants have no valid value --> $DIR/uninhabited-static.rs:4:1 | LL | enum Void {} | ^^^^^^^^^ + = note: `#[warn(invalid_value)]` on by default error[E0080]: could not evaluate static initializer --> $DIR/uninhabited-static.rs:16:32 diff --git a/src/test/ui/stats/hir-stats.rs b/src/test/ui/stats/hir-stats.rs index 5102574d4be..a24b3ada57e 100644 --- a/src/test/ui/stats/hir-stats.rs +++ b/src/test/ui/stats/hir-stats.rs @@ -1,7 +1,6 @@ // check-pass // compile-flags: -Zhir-stats // only-x86_64 -// ignore-stage1 // The aim here is to include at least one of every different type of top-level // AST/HIR node reported by `-Zhir-stats`. diff --git a/src/test/ui/stats/hir-stats.stderr b/src/test/ui/stats/hir-stats.stderr index 8d977606530..350b140aada 100644 --- a/src/test/ui/stats/hir-stats.stderr +++ b/src/test/ui/stats/hir-stats.stderr @@ -118,61 +118,61 @@ ast-stats-2 hir-stats HIR STATS hir-stats Name Accumulated Size Count Item Size hir-stats ---------------------------------------------------------------- -hir-stats ForeignItemRef 24 ( 0.2%) 1 24 -hir-stats Lifetime 32 ( 0.3%) 1 32 -hir-stats Mod 32 ( 0.3%) 1 32 +hir-stats ForeignItemRef 24 ( 0.3%) 1 24 +hir-stats Lifetime 32 ( 0.4%) 1 32 +hir-stats Mod 32 ( 0.4%) 1 32 hir-stats ExprField 40 ( 0.4%) 1 40 hir-stats TraitItemRef 56 ( 0.6%) 2 28 hir-stats Local 64 ( 0.7%) 1 64 hir-stats Param 64 ( 0.7%) 2 32 -hir-stats InlineAsm 72 ( 0.7%) 1 72 -hir-stats ImplItemRef 72 ( 0.7%) 2 36 -hir-stats Body 96 ( 1.0%) 3 32 -hir-stats GenericArg 96 ( 1.0%) 4 24 -hir-stats - Type 24 ( 0.2%) 1 -hir-stats - Lifetime 72 ( 0.7%) 3 -hir-stats FieldDef 96 ( 1.0%) 2 48 -hir-stats Arm 96 ( 1.0%) 2 48 -hir-stats Stmt 96 ( 1.0%) 3 32 -hir-stats - Local 32 ( 0.3%) 1 -hir-stats - Semi 32 ( 0.3%) 1 -hir-stats - Expr 32 ( 0.3%) 1 -hir-stats FnDecl 120 ( 1.2%) 3 40 -hir-stats Attribute 128 ( 1.3%) 4 32 -hir-stats GenericArgs 144 ( 1.5%) 3 48 -hir-stats Variant 160 ( 1.7%) 2 80 -hir-stats WherePredicate 168 ( 1.7%) 3 56 -hir-stats - BoundPredicate 168 ( 1.7%) 3 -hir-stats GenericBound 192 ( 2.0%) 4 48 -hir-stats - Trait 192 ( 2.0%) 4 -hir-stats Block 288 ( 3.0%) 6 48 -hir-stats Pat 360 ( 3.7%) 5 72 -hir-stats - Wild 72 ( 0.7%) 1 -hir-stats - Struct 72 ( 0.7%) 1 -hir-stats - Binding 216 ( 2.2%) 3 -hir-stats GenericParam 400 ( 4.1%) 5 80 -hir-stats Generics 560 ( 5.8%) 10 56 -hir-stats Ty 720 ( 7.4%) 15 48 +hir-stats InlineAsm 72 ( 0.8%) 1 72 +hir-stats ImplItemRef 72 ( 0.8%) 2 36 +hir-stats Body 96 ( 1.1%) 3 32 +hir-stats GenericArg 96 ( 1.1%) 4 24 +hir-stats - Type 24 ( 0.3%) 1 +hir-stats - Lifetime 72 ( 0.8%) 3 +hir-stats FieldDef 96 ( 1.1%) 2 48 +hir-stats Arm 96 ( 1.1%) 2 48 +hir-stats Stmt 96 ( 1.1%) 3 32 +hir-stats - Local 32 ( 0.4%) 1 +hir-stats - Semi 32 ( 0.4%) 1 +hir-stats - Expr 32 ( 0.4%) 1 +hir-stats FnDecl 120 ( 1.3%) 3 40 +hir-stats Attribute 128 ( 1.4%) 4 32 +hir-stats GenericArgs 144 ( 1.6%) 3 48 +hir-stats Variant 160 ( 1.8%) 2 80 +hir-stats GenericBound 192 ( 2.1%) 4 48 +hir-stats - Trait 192 ( 2.1%) 4 +hir-stats WherePredicate 192 ( 2.1%) 3 64 +hir-stats - BoundPredicate 192 ( 2.1%) 3 +hir-stats Block 288 ( 3.2%) 6 48 +hir-stats Pat 360 ( 3.9%) 5 72 +hir-stats - Wild 72 ( 0.8%) 1 +hir-stats - Struct 72 ( 0.8%) 1 +hir-stats - Binding 216 ( 2.4%) 3 +hir-stats GenericParam 400 ( 4.4%) 5 80 +hir-stats Generics 560 ( 6.1%) 10 56 +hir-stats Ty 720 ( 7.9%) 15 48 hir-stats - Ptr 48 ( 0.5%) 1 hir-stats - Rptr 48 ( 0.5%) 1 -hir-stats - Path 624 ( 6.4%) 13 -hir-stats Expr 768 ( 7.9%) 12 64 +hir-stats - Path 624 ( 6.8%) 13 +hir-stats Expr 768 ( 8.4%) 12 64 hir-stats - Path 64 ( 0.7%) 1 hir-stats - Struct 64 ( 0.7%) 1 hir-stats - Match 64 ( 0.7%) 1 hir-stats - InlineAsm 64 ( 0.7%) 1 -hir-stats - Lit 128 ( 1.3%) 2 -hir-stats - Block 384 ( 4.0%) 6 -hir-stats Item 960 ( 9.9%) 12 80 -hir-stats - Trait 80 ( 0.8%) 1 -hir-stats - Enum 80 ( 0.8%) 1 -hir-stats - ExternCrate 80 ( 0.8%) 1 -hir-stats - ForeignMod 80 ( 0.8%) 1 -hir-stats - Impl 80 ( 0.8%) 1 -hir-stats - Fn 160 ( 1.7%) 2 -hir-stats - Use 400 ( 4.1%) 5 -hir-stats Path 1_536 (15.9%) 32 48 -hir-stats PathSegment 2_240 (23.1%) 40 56 +hir-stats - Lit 128 ( 1.4%) 2 +hir-stats - Block 384 ( 4.2%) 6 +hir-stats Item 960 (10.5%) 12 80 +hir-stats - Trait 80 ( 0.9%) 1 +hir-stats - Enum 80 ( 0.9%) 1 +hir-stats - ExternCrate 80 ( 0.9%) 1 +hir-stats - ForeignMod 80 ( 0.9%) 1 +hir-stats - Impl 80 ( 0.9%) 1 +hir-stats - Fn 160 ( 1.8%) 2 +hir-stats - Use 400 ( 4.4%) 5 +hir-stats Path 1_280 (14.0%) 32 40 +hir-stats PathSegment 1_920 (21.0%) 40 48 hir-stats ---------------------------------------------------------------- -hir-stats Total 9_680 +hir-stats Total 9_128 hir-stats diff --git a/src/test/ui/structs-enums/rec-align-u32.rs b/src/test/ui/structs-enums/rec-align-u32.rs index 889294daa34..ee704198d19 100644 --- a/src/test/ui/structs-enums/rec-align-u32.rs +++ b/src/test/ui/structs-enums/rec-align-u32.rs @@ -10,6 +10,7 @@ use std::mem; mod rusti { extern "rust-intrinsic" { pub fn pref_align_of<T>() -> usize; + #[rustc_safe_intrinsic] pub fn min_align_of<T>() -> usize; } } diff --git a/src/test/ui/structs-enums/rec-align-u64.rs b/src/test/ui/structs-enums/rec-align-u64.rs index 3bc2d16cf9d..40ede9705f1 100644 --- a/src/test/ui/structs-enums/rec-align-u64.rs +++ b/src/test/ui/structs-enums/rec-align-u64.rs @@ -12,6 +12,7 @@ use std::mem; mod rusti { extern "rust-intrinsic" { pub fn pref_align_of<T>() -> usize; + #[rustc_safe_intrinsic] pub fn min_align_of<T>() -> usize; } } diff --git a/src/test/ui/structs/incomplete-fn-in-struct-definition.rs b/src/test/ui/structs/incomplete-fn-in-struct-definition.rs new file mode 100644 index 00000000000..cd8a79ba687 --- /dev/null +++ b/src/test/ui/structs/incomplete-fn-in-struct-definition.rs @@ -0,0 +1,5 @@ +fn main() {} + +struct S { + fn: u8 //~ ERROR expected identifier, found keyword `fn` +} diff --git a/src/test/ui/structs/incomplete-fn-in-struct-definition.stderr b/src/test/ui/structs/incomplete-fn-in-struct-definition.stderr new file mode 100644 index 00000000000..0d12ba9c916 --- /dev/null +++ b/src/test/ui/structs/incomplete-fn-in-struct-definition.stderr @@ -0,0 +1,15 @@ +error: expected identifier, found keyword `fn` + --> $DIR/incomplete-fn-in-struct-definition.rs:4:5 + | +LL | struct S { + | - while parsing this struct +LL | fn: u8 + | ^^ expected identifier, found keyword + | +help: escape `fn` to use it as an identifier + | +LL | r#fn: u8 + | ++ + +error: aborting due to previous error + diff --git a/src/test/ui/suggestions/boxed-variant-field.rs b/src/test/ui/suggestions/boxed-variant-field.rs index e79be2f6127..6050963c4ee 100644 --- a/src/test/ui/suggestions/boxed-variant-field.rs +++ b/src/test/ui/suggestions/boxed-variant-field.rs @@ -9,7 +9,6 @@ fn foo(x: Ty) -> Ty { Ty::List(elem) => foo(elem), //~^ ERROR mismatched types //~| HELP consider unboxing the value - //~| HELP try wrapping } } diff --git a/src/test/ui/suggestions/boxed-variant-field.stderr b/src/test/ui/suggestions/boxed-variant-field.stderr index 6dfb73480a2..9ae36a06a71 100644 --- a/src/test/ui/suggestions/boxed-variant-field.stderr +++ b/src/test/ui/suggestions/boxed-variant-field.stderr @@ -17,10 +17,6 @@ help: consider unboxing the value | LL | Ty::List(elem) => foo(*elem), | + -help: try wrapping the expression in `Ty::List` - | -LL | Ty::List(elem) => foo(Ty::List(elem)), - | +++++++++ + error: aborting due to previous error diff --git a/src/test/ui/suggestions/into-convert.rs b/src/test/ui/suggestions/into-convert.rs new file mode 100644 index 00000000000..1c9a9e0aaf5 --- /dev/null +++ b/src/test/ui/suggestions/into-convert.rs @@ -0,0 +1,26 @@ +use std::path::{Path, PathBuf}; +use std::sync::atomic::AtomicU32; +use std::sync::Arc; + +fn main() { + let x: A = B; + //~^ ERROR mismatched types + //~| HELP call `Into::into` on this expression to convert `B` into `A` + + let y: Arc<Path> = PathBuf::new(); + //~^ ERROR mismatched types + //~| HELP call `Into::into` on this expression to convert `PathBuf` into `Arc<Path>` + + let z: AtomicU32 = 1; + //~^ ERROR mismatched types + //~| HELP call `Into::into` on this expression to convert `{integer}` into `AtomicU32` +} + +struct A; +struct B; + +impl From<B> for A { + fn from(_: B) -> Self { + A + } +} diff --git a/src/test/ui/suggestions/into-convert.stderr b/src/test/ui/suggestions/into-convert.stderr new file mode 100644 index 00000000000..d43104a2172 --- /dev/null +++ b/src/test/ui/suggestions/into-convert.stderr @@ -0,0 +1,44 @@ +error[E0308]: mismatched types + --> $DIR/into-convert.rs:6:16 + | +LL | let x: A = B; + | - ^ expected struct `A`, found struct `B` + | | + | expected due to this + | +help: call `Into::into` on this expression to convert `B` into `A` + | +LL | let x: A = B.into(); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/into-convert.rs:10:24 + | +LL | let y: Arc<Path> = PathBuf::new(); + | --------- ^^^^^^^^^^^^^^ expected struct `Arc`, found struct `PathBuf` + | | + | expected due to this + | + = note: expected struct `Arc<Path>` + found struct `PathBuf` +help: call `Into::into` on this expression to convert `PathBuf` into `Arc<Path>` + | +LL | let y: Arc<Path> = PathBuf::new().into(); + | +++++++ + +error[E0308]: mismatched types + --> $DIR/into-convert.rs:14:24 + | +LL | let z: AtomicU32 = 1; + | --------- ^ expected struct `AtomicU32`, found integer + | | + | expected due to this + | +help: call `Into::into` on this expression to convert `{integer}` into `AtomicU32` + | +LL | let z: AtomicU32 = 1.into(); + | +++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/issue-61963.stderr b/src/test/ui/suggestions/issue-61963.stderr index a788cab6e4e..b99b1b0b9b3 100644 --- a/src/test/ui/suggestions/issue-61963.stderr +++ b/src/test/ui/suggestions/issue-61963.stderr @@ -4,13 +4,13 @@ error: trait objects without an explicit `dyn` are deprecated LL | bar: Box<Bar>, | ^^^ | + = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! + = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> note: the lint level is defined here --> $DIR/issue-61963.rs:3:9 | LL | #![deny(bare_trait_objects)] | ^^^^^^^^^^^^^^^^^^ - = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! - = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> help: use `dyn` | LL | bar: Box<dyn Bar>, diff --git a/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr b/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr index be6fc261562..00aa7d18a96 100644 --- a/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr +++ b/src/test/ui/suggestions/match-with-different-arm-types-as-stmt-instead-of-expr.stderr @@ -7,7 +7,7 @@ LL | fn not_all_paths(a: &str) -> u32 { | implicitly returns `()` as its body has no tail or `return` expression ... LL | }; - | - help: remove this semicolon + | - help: remove this semicolon to return this value error[E0308]: `match` arms have incompatible types --> $DIR/match-with-different-arm-types-as-stmt-instead-of-expr.rs:26:14 diff --git a/src/test/ui/suggestions/sugg-else-for-closure.fixed b/src/test/ui/suggestions/sugg-else-for-closure.fixed new file mode 100644 index 00000000000..cf381d9da8b --- /dev/null +++ b/src/test/ui/suggestions/sugg-else-for-closure.fixed @@ -0,0 +1,8 @@ +// run-rustfix + +fn main() { + let x = "com.example.app"; + let y: Option<&str> = None; + let _s = y.unwrap_or_else(|| x.split('.').nth(1).unwrap()); + //~^ ERROR: mismatched types [E0308] +} diff --git a/src/test/ui/suggestions/sugg-else-for-closure.rs b/src/test/ui/suggestions/sugg-else-for-closure.rs new file mode 100644 index 00000000000..540ced91fc9 --- /dev/null +++ b/src/test/ui/suggestions/sugg-else-for-closure.rs @@ -0,0 +1,8 @@ +// run-rustfix + +fn main() { + let x = "com.example.app"; + let y: Option<&str> = None; + let _s = y.unwrap_or(|| x.split('.').nth(1).unwrap()); + //~^ ERROR: mismatched types [E0308] +} diff --git a/src/test/ui/suggestions/sugg-else-for-closure.stderr b/src/test/ui/suggestions/sugg-else-for-closure.stderr new file mode 100644 index 00000000000..55a0eee1817 --- /dev/null +++ b/src/test/ui/suggestions/sugg-else-for-closure.stderr @@ -0,0 +1,23 @@ +error[E0308]: mismatched types + --> $DIR/sugg-else-for-closure.rs:6:26 + | +LL | let _s = y.unwrap_or(|| x.split('.').nth(1).unwrap()); + | --------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found closure + | | + | arguments to this function are incorrect + | + = note: expected reference `&str` + found closure `[closure@$DIR/sugg-else-for-closure.rs:6:26: 6:28]` +note: associated function defined here + --> $SRC_DIR/core/src/option.rs:LL:COL + | +LL | pub const fn unwrap_or(self, default: T) -> T + | ^^^^^^^^^ +help: try calling `unwrap_or_else` instead + | +LL | let _s = y.unwrap_or_else(|| x.split('.').nth(1).unwrap()); + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr index f716e6c17e2..ffd505fffb4 100644 --- a/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr +++ b/src/test/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr @@ -37,9 +37,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | impl<'a, T> Struct<T> for Trait<'a, T> {} | ^^^^^^^^^^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {} diff --git a/src/test/ui/test-attrs/test-on-not-fn.stderr b/src/test/ui/test-attrs/test-on-not-fn.stderr index 23efd5bc0d9..fc2c5f62bed 100644 --- a/src/test/ui/test-attrs/test-on-not-fn.stderr +++ b/src/test/ui/test-attrs/test-on-not-fn.stderr @@ -2,7 +2,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:3:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | mod test {} | ----------- expected a non-associated function, found a module | @@ -15,7 +15,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:6:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | / mod loooooooooooooong_teeeeeeeeeest { LL | | /* LL | | this is a comment @@ -34,7 +34,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:20:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | extern "C" {} | ------------- expected a non-associated function, found an extern block | @@ -47,7 +47,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:23:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | trait Foo {} | ------------ expected a non-associated function, found a trait | @@ -60,7 +60,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:26:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | impl Foo for i32 {} | ------------------- expected a non-associated function, found an implementation | @@ -73,7 +73,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:29:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | const FOO: i32 = -1_i32; | ------------------------ expected a non-associated function, found a constant item | @@ -86,7 +86,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:32:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | static BAR: u64 = 10_000_u64; | ----------------------------- expected a non-associated function, found a static item | @@ -99,7 +99,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:35:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | / enum MyUnit { LL | | Unit, LL | | } @@ -114,7 +114,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:40:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | struct NewI32(i32); | ------------------- expected a non-associated function, found a struct | @@ -127,7 +127,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:43:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | / union Spooky { LL | | x: i32, LL | | y: u32, @@ -143,7 +143,7 @@ error: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:50:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | #[derive(Copy, Clone, Debug)] LL | / struct MoreAttrs { LL | | a: i32, @@ -160,7 +160,7 @@ warning: the `#[test]` attribute may only be used on a non-associated function --> $DIR/test-on-not-fn.rs:61:1 | LL | #[test] - | ^^^^^^^ the `#[test]` macro causes a a function to be run on a test and has no effect on non-functions + | ^^^^^^^ the `#[test]` macro causes a function to be run on a test and has no effect on non-functions LL | foo!(); | ------- expected a non-associated function, found an item macro invocation | diff --git a/src/test/ui/traits/bound/not-on-bare-trait.stderr b/src/test/ui/traits/bound/not-on-bare-trait.stderr index 1c52629daa4..8da0b6d6b85 100644 --- a/src/test/ui/traits/bound/not-on-bare-trait.stderr +++ b/src/test/ui/traits/bound/not-on-bare-trait.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | fn foo(_x: Foo + Send) { | ^^^^^^^^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | fn foo(_x: dyn Foo + Send) { diff --git a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr index 6acf2fe65ce..61b6d4b08bb 100644 --- a/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr +++ b/src/test/ui/traits/issue-91949-hangs-on-recursion.stderr @@ -9,8 +9,8 @@ LL | { LL | recurse(IteratorOfWrapped(elements).map(|t| t.0)) | ------------------------------------------------- recursive call site | - = note: `#[warn(unconditional_recursion)]` on by default = help: a `loop` may express intention better if this is on purpose + = note: `#[warn(unconditional_recursion)]` on by default error[E0275]: overflow evaluating the requirement `(): Sized` | diff --git a/src/test/ui/traits/negative-impls/negative-default-impls.stderr b/src/test/ui/traits/negative-impls/negative-default-impls.stderr index ceb86559d85..7b54cf54222 100644 --- a/src/test/ui/traits/negative-impls/negative-default-impls.stderr +++ b/src/test/ui/traits/negative-impls/negative-default-impls.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0750]: negative impls cannot be default impls --> $DIR/negative-default-impls.rs:9:1 diff --git a/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr b/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr index 9a846143d3d..751e29c3b23 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr +++ b/src/test/ui/traits/negative-impls/negative-specializes-negative.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default warning: 1 warning emitted diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr index 77b4373a273..1cfa49b20f3 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive-item.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/negative-specializes-positive-item.rs:11:1 diff --git a/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr b/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr index e5dc81b3eb7..9f9e28678ab 100644 --- a/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr +++ b/src/test/ui/traits/negative-impls/negative-specializes-positive.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/negative-specializes-positive.rs:7:1 diff --git a/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr b/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr index c091bc81da3..545f94143ad 100644 --- a/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr +++ b/src/test/ui/traits/negative-impls/positive-specializes-negative.stderr @@ -4,9 +4,9 @@ warning: the feature `specialization` is incomplete and may not be safe to use a LL | #![feature(specialization)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default error[E0751]: found both positive and negative implementation of trait `MyTrait` for type `u32`: --> $DIR/positive-specializes-negative.rs:7:1 diff --git a/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr b/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr index 77d71360b80..4ab777bd4df 100644 --- a/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr +++ b/src/test/ui/traits/object/issue-33140-traitobject-crate.stderr @@ -6,13 +6,13 @@ LL | unsafe impl Trait for dyn (::std::marker::Send) + Sync { } LL | unsafe impl Trait for dyn (::std::marker::Send) + Send + Sync { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(dyn std::marker::Send + std::marker::Sync + 'static)` | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> note: the lint level is defined here --> $DIR/issue-33140-traitobject-crate.rs:3:9 | LL | #![warn(order_dependent_trait_objects)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484> warning: conflicting implementations of trait `Trait` for type `(dyn std::marker::Send + std::marker::Sync + 'static)`: (E0119) --> $DIR/issue-33140-traitobject-crate.rs:89:1 diff --git a/src/test/ui/traits/static-method-generic-inference.stderr b/src/test/ui/traits/static-method-generic-inference.stderr index f1b8f23ecc7..5f74d0c3b92 100644 --- a/src/test/ui/traits/static-method-generic-inference.stderr +++ b/src/test/ui/traits/static-method-generic-inference.stderr @@ -9,8 +9,8 @@ LL | let _f: base::Foo = base::HasNew::new(); | help: use the fully-qualified path to the only available implementation | -LL | let _f: base::Foo = base::<::base::Foo as HasNew>::new(); - | +++++++++++++++ + +LL | let _f: base::Foo = base::<Foo as HasNew>::new(); + | +++++++ + error: aborting due to previous error diff --git a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr index 35af9112a27..6c359b69836 100644 --- a/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr +++ b/src/test/ui/traits/trait-upcasting/migrate-lint-deny.stderr @@ -4,13 +4,13 @@ error: `dyn B` implements `Deref` with supertrait `(dyn A + 'static)` as output LL | take_a(b) | ^ | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460> note: the lint level is defined here --> $DIR/migrate-lint-deny.rs:1:9 | LL | #![deny(deref_into_dyn_supertrait)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #89460 <https://github.com/rust-lang/rust/issues/89460> error: aborting due to previous error diff --git a/src/test/ui/traits/unspecified-self-in-trait-ref.stderr b/src/test/ui/traits/unspecified-self-in-trait-ref.stderr index 7869176bb3a..b5e8e88676c 100644 --- a/src/test/ui/traits/unspecified-self-in-trait-ref.stderr +++ b/src/test/ui/traits/unspecified-self-in-trait-ref.stderr @@ -4,9 +4,9 @@ warning: trait objects without an explicit `dyn` are deprecated LL | let a = Foo::lol(); | ^^^ | - = note: `#[warn(bare_trait_objects)]` on by default = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html> + = note: `#[warn(bare_trait_objects)]` on by default help: use `dyn` | LL | let a = <dyn Foo>::lol(); diff --git a/src/test/ui/transmutability/issue-101739-1.rs b/src/test/ui/transmutability/issue-101739-1.rs new file mode 100644 index 00000000000..bcb8b158edf --- /dev/null +++ b/src/test/ui/transmutability/issue-101739-1.rs @@ -0,0 +1,21 @@ +#![feature(transmutability)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable<Src, Context, const ASSUME_ALIGNMENT: bool>() + where + Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, //~ ERROR cannot find type `Dst` in this scope + //~^ ERROR mismatched types + { + } +} + +fn via_const() { + struct Context; + struct Src; + + assert::is_transmutable::<Src, Context, false>(); +} + +fn main() {} diff --git a/src/test/ui/transmutability/issue-101739-1.stderr b/src/test/ui/transmutability/issue-101739-1.stderr new file mode 100644 index 00000000000..5fa741f26fd --- /dev/null +++ b/src/test/ui/transmutability/issue-101739-1.stderr @@ -0,0 +1,16 @@ +error[E0412]: cannot find type `Dst` in this scope + --> $DIR/issue-101739-1.rs:8:9 + | +LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, + | ^^^ not found in this scope + +error[E0308]: mismatched types + --> $DIR/issue-101739-1.rs:8:50 + | +LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>, + | ^^^^^^^^^^^^^^^^ expected struct `Assume`, found `bool` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0412. +For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/transmutability/issue-101739-2.rs b/src/test/ui/transmutability/issue-101739-2.rs new file mode 100644 index 00000000000..964a7e49ee6 --- /dev/null +++ b/src/test/ui/transmutability/issue-101739-2.rs @@ -0,0 +1,37 @@ +#![crate_type = "lib"] +#![feature(transmutability)] +#![allow(dead_code, incomplete_features, non_camel_case_types)] + +mod assert { + use std::mem::BikeshedIntrinsicFrom; + + pub fn is_transmutable< + Src, + Dst, + Context, + const ASSUME_ALIGNMENT: bool, + const ASSUME_LIFETIMES: bool, + const ASSUME_VALIDITY: bool, + const ASSUME_VISIBILITY: bool, + >() + where + Dst: BikeshedIntrinsicFrom< //~ ERROR this trait takes at most 3 generic arguments but 6 generic arguments were supplied + Src, + Context, + ASSUME_ALIGNMENT, + ASSUME_LIFETIMES, + ASSUME_VALIDITY, + ASSUME_VISIBILITY, + >, + {} +} + +fn via_const() { + struct Context; + #[repr(C)] struct Src; + #[repr(C)] struct Dst; + + const FALSE: bool = false; + + assert::is_transmutable::<Src, Dst, Context, FALSE, FALSE, FALSE, FALSE>(); +} diff --git a/src/test/ui/transmutability/issue-101739-2.stderr b/src/test/ui/transmutability/issue-101739-2.stderr new file mode 100644 index 00000000000..3f83d6583b0 --- /dev/null +++ b/src/test/ui/transmutability/issue-101739-2.stderr @@ -0,0 +1,20 @@ +error[E0107]: this trait takes at most 3 generic arguments but 6 generic arguments were supplied + --> $DIR/issue-101739-2.rs:18:14 + | +LL | Dst: BikeshedIntrinsicFrom< + | ^^^^^^^^^^^^^^^^^^^^^ expected at most 3 generic arguments +... +LL | / ASSUME_LIFETIMES, +LL | | ASSUME_VALIDITY, +LL | | ASSUME_VISIBILITY, + | |_____________________________- help: remove these generic arguments + | +note: trait defined here, with at most 3 generic parameters: `Src`, `Context`, `ASSUME` + --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL + | +LL | pub unsafe trait BikeshedIntrinsicFrom<Src, Context, const ASSUME: Assume = { Assume::NOTHING }> + | ^^^^^^^^^^^^^^^^^^^^^ --- ------- ------------------------------------------ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr index aaa3159e0b0..0202a2fea49 100644 --- a/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr +++ b/src/test/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr @@ -4,7 +4,6 @@ error: ambiguous associated item LL | fn f() -> Self::V { 0 } | ^^^^^^^ help: use fully-qualified syntax: `<E as Tr>::V` | - = note: `#[deny(ambiguous_associated_items)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644> note: `V` could refer to the variant defined here @@ -17,6 +16,7 @@ note: `V` could also refer to the associated type defined here | LL | type V; | ^^^^^^ + = note: `#[deny(ambiguous_associated_items)]` on by default error: ambiguous associated item --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15 diff --git a/src/test/ui/type/issue-101866.rs b/src/test/ui/type/issue-101866.rs new file mode 100644 index 00000000000..d332c4adb00 --- /dev/null +++ b/src/test/ui/type/issue-101866.rs @@ -0,0 +1,15 @@ +trait TraitA<T> { + fn func(); +} + +struct StructA {} + +impl TraitA<i32> for StructA { + fn func() {} +} + +fn main() { + TraitA::<i32>::func(); + //~^ ERROR: cannot call associated function on trait without specifying the corresponding `impl` type [E0790] + //~| help: use the fully-qualified path to the only available implementation +} diff --git a/src/test/ui/type/issue-101866.stderr b/src/test/ui/type/issue-101866.stderr new file mode 100644 index 00000000000..fe99821198e --- /dev/null +++ b/src/test/ui/type/issue-101866.stderr @@ -0,0 +1,18 @@ +error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type + --> $DIR/issue-101866.rs:12:5 + | +LL | fn func(); + | ---------- `TraitA::func` defined here +... +LL | TraitA::<i32>::func(); + | ^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait + | +help: use the fully-qualified path to the only available implementation + | +LL - TraitA::<i32>::func(); +LL + <StructA as TraitA<i32>>::func(); + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0790`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr b/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr index ba4b3dac670..6450cc30ac0 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-counter-not-moved.stderr @@ -12,8 +12,8 @@ warning: value assigned to `counter` is never read LL | counter += 1; | ^^^^^^^ | - = note: `#[warn(unused_assignments)]` on by default = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` on by default warning: unused variable: `counter` --> $DIR/unboxed-closures-counter-not-moved.rs:24:9 diff --git a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr index 1254f8dbc5e..5c06f4e621c 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-move-mutable.stderr @@ -4,8 +4,8 @@ warning: unused variable: `x` LL | move || x += 1; | ^ | - = note: `#[warn(unused_variables)]` on by default = help: did you mean to capture by reference instead? + = note: `#[warn(unused_variables)]` on by default warning: unused variable: `x` --> $DIR/unboxed-closures-move-mutable.rs:21:17 diff --git a/src/test/ui/union/union-repr-c.stderr b/src/test/ui/union/union-repr-c.stderr index 9abf440f735..49124eee5ee 100644 --- a/src/test/ui/union/union-repr-c.stderr +++ b/src/test/ui/union/union-repr-c.stderr @@ -4,11 +4,6 @@ error: `extern` block uses type `W`, which is not FFI-safe LL | static FOREIGN2: W; | ^ not FFI-safe | -note: the lint level is defined here - --> $DIR/union-repr-c.rs:2:9 - | -LL | #![deny(improper_ctypes)] - | ^^^^^^^^^^^^^^^ = help: consider adding a `#[repr(C)]` or `#[repr(transparent)]` attribute to this union = note: this union has unspecified layout note: the type is defined here @@ -16,6 +11,11 @@ note: the type is defined here | LL | union W { | ^^^^^^^ +note: the lint level is defined here + --> $DIR/union-repr-c.rs:2:9 + | +LL | #![deny(improper_ctypes)] + | ^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr b/src/test/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr index 7e6885bd706..aa73b824a57 100644 --- a/src/test/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr +++ b/src/test/ui/unknown-unstable-lints/deny-unstable-lint-command-line.stderr @@ -1,8 +1,8 @@ error: unknown lint: `test_unstable_lint` | - = note: requested on the command line with `-D unknown-lints` = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable + = note: requested on the command line with `-D unknown-lints` error: unknown lint: `test_unstable_lint` | diff --git a/src/test/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr b/src/test/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr index 2d1027dd0e0..2a2a9811bfb 100644 --- a/src/test/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr +++ b/src/test/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr @@ -4,13 +4,13 @@ error: unknown lint: `test_unstable_lint` LL | #![allow(test_unstable_lint)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: the `test_unstable_lint` lint is unstable + = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable note: the lint level is defined here --> $DIR/deny-unstable-lint-inline.rs:3:9 | LL | #![deny(unknown_lints)] | ^^^^^^^^^^^^^ - = note: the `test_unstable_lint` lint is unstable - = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable error: unknown lint: `test_unstable_lint` --> $DIR/deny-unstable-lint-inline.rs:4:1 diff --git a/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr b/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr index 799d740b00e..82851c80064 100644 --- a/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr +++ b/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-command-line.stderr @@ -1,8 +1,8 @@ warning: unknown lint: `test_unstable_lint` | - = note: requested on the command line with `-W unknown-lints` = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable + = note: requested on the command line with `-W unknown-lints` warning: unknown lint: `test_unstable_lint` | diff --git a/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr b/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr index 142558b471b..0548cd226d8 100644 --- a/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr +++ b/src/test/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr @@ -4,13 +4,13 @@ warning: unknown lint: `test_unstable_lint` LL | #![allow(test_unstable_lint)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | + = note: the `test_unstable_lint` lint is unstable + = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable note: the lint level is defined here --> $DIR/warn-unknown-unstable-lint-inline.rs:3:9 | LL | #![warn(unknown_lints)] | ^^^^^^^^^^^^^ - = note: the `test_unstable_lint` lint is unstable - = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable warning: unknown lint: `test_unstable_lint` --> $DIR/warn-unknown-unstable-lint-inline.rs:4:1 diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr index b968174dd2d..6f005fe8958 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr @@ -4,12 +4,12 @@ error: call to unsafe function is unsafe and requires unsafe block (error E0133) LL | unsf(); | ^^^^^^ call to unsafe function | + = note: consult the function's documentation for information on how to avoid undefined behavior note: the lint level is defined here --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9 | LL | #![deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ - = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5 @@ -45,13 +45,13 @@ error: call to unsafe function is unsafe and requires unsafe block (error E0133) LL | unsf(); | ^^^^^^ call to unsafe function | + = note: consult the function's documentation for information on how to avoid undefined behavior note: the lint level is defined here --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8 | LL | #[deny(warnings)] | ^^^^^^^^ = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` - = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr index e365293657e..13c080e5b6a 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr @@ -4,12 +4,12 @@ error: call to unsafe function `unsf` is unsafe and requires unsafe block (error LL | unsf(); | ^^^^^^ call to unsafe function | + = note: consult the function's documentation for information on how to avoid undefined behavior note: the lint level is defined here --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:4:9 | LL | #![deny(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ - = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5 @@ -45,13 +45,13 @@ error: call to unsafe function `unsf` is unsafe and requires unsafe block (error LL | unsf(); | ^^^^^^ call to unsafe function | + = note: consult the function's documentation for information on how to avoid undefined behavior note: the lint level is defined here --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8 | LL | #[deny(warnings)] | ^^^^^^^^ = note: `#[deny(unsafe_op_in_unsafe_fn)]` implied by `#[deny(warnings)]` - = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 diff --git a/src/test/ui/unsized-locals/borrow-after-move.stderr b/src/test/ui/unsized-locals/borrow-after-move.stderr index 4f2bc06d4ab..28ae1c0688c 100644 --- a/src/test/ui/unsized-locals/borrow-after-move.stderr +++ b/src/test/ui/unsized-locals/borrow-after-move.stderr @@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a LL | #![feature(unsized_locals, unsized_fn_params)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + = note: `#[warn(incomplete_features)]` on by default error[E0382]: borrow of moved value: `x` --> $DIR/borrow-after-move.rs:21:24 diff --git a/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr b/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr index 59d91bc0cfd..4f13ec7ac08 100644 --- a/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr +++ b/src/test/ui/unsized-locals/by-value-trait-object-safety.stderr @@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a LL | #![feature(unsized_locals)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + = note: `#[warn(incomplete_features)]` on by default error: the `foo` method cannot be invoked on a trait object --> $DIR/by-value-trait-object-safety.rs:20:7 diff --git a/src/test/ui/unsized-locals/double-move.stderr b/src/test/ui/unsized-locals/double-move.stderr index 4bb2ad88faf..dfae6cc75d9 100644 --- a/src/test/ui/unsized-locals/double-move.stderr +++ b/src/test/ui/unsized-locals/double-move.stderr @@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a LL | #![feature(unsized_locals, unsized_fn_params)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + = note: `#[warn(incomplete_features)]` on by default error[E0382]: use of moved value: `y` --> $DIR/double-move.rs:21:22 diff --git a/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr b/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr index 0f0ff579377..b6002cf895f 100644 --- a/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr +++ b/src/test/ui/unsized-locals/issue-30276-feature-flagged.stderr @@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a LL | #![feature(unsized_locals)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + = note: `#[warn(incomplete_features)]` on by default error[E0277]: the size for values of type `[i32]` cannot be known at compilation time --> $DIR/issue-30276-feature-flagged.rs:7:29 diff --git a/src/test/ui/unsized-locals/issue-50940-with-feature.stderr b/src/test/ui/unsized-locals/issue-50940-with-feature.stderr index 4523d41b600..8bbe317ec74 100644 --- a/src/test/ui/unsized-locals/issue-50940-with-feature.stderr +++ b/src/test/ui/unsized-locals/issue-50940-with-feature.stderr @@ -4,8 +4,8 @@ warning: the feature `unsized_locals` is incomplete and may not be safe to use a LL | #![feature(unsized_locals, unsized_fn_params)] | ^^^^^^^^^^^^^^ | - = note: `#[warn(incomplete_features)]` on by default = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information + = note: `#[warn(incomplete_features)]` on by default error[E0277]: the size for values of type `str` cannot be known at compilation time --> $DIR/issue-50940-with-feature.rs:6:5 diff --git a/src/test/ui/unwind-abis/feature-gate-c-unwind.stderr b/src/test/ui/unwind-abis/feature-gate-c-unwind.stderr index a67f46cd2e3..214ddc45ce9 100644 --- a/src/test/ui/unwind-abis/feature-gate-c-unwind.stderr +++ b/src/test/ui/unwind-abis/feature-gate-c-unwind.stderr @@ -4,10 +4,10 @@ warning: unknown lint: `ffi_unwind_calls` LL | #![allow(ffi_unwind_calls)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `#[warn(unknown_lints)]` on by default = note: the `ffi_unwind_calls` lint is unstable = note: see issue #74990 <https://github.com/rust-lang/rust/issues/74990> for more information = help: add `#![feature(c_unwind)]` to the crate attributes to enable + = note: `#[warn(unknown_lints)]` on by default error[E0658]: C-unwind ABI is experimental and subject to change --> $DIR/feature-gate-c-unwind.rs:8:8 diff --git a/src/test/ui/where-clauses/higher-ranked-fn-type.quiet.stderr b/src/test/ui/where-clauses/higher-ranked-fn-type.quiet.stderr new file mode 100644 index 00000000000..d9950a3d9b7 --- /dev/null +++ b/src/test/ui/where-clauses/higher-ranked-fn-type.quiet.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied + --> $DIR/higher-ranked-fn-type.rs:20:5 + | +LL | called() + | ^^^^^^ the trait `for<'b> Foo` is not implemented for `for<'b> fn(&'b ())` + | +note: required by a bound in `called` + --> $DIR/higher-ranked-fn-type.rs:12:25 + | +LL | fn called() + | ------ required by a bound in this +LL | where +LL | for<'b> fn(&'b ()): Foo, + | ^^^ required by this bound in `called` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/where-clauses/higher-ranked-fn-type.rs b/src/test/ui/where-clauses/higher-ranked-fn-type.rs new file mode 100644 index 00000000000..0d8893e08d3 --- /dev/null +++ b/src/test/ui/where-clauses/higher-ranked-fn-type.rs @@ -0,0 +1,25 @@ +// revisions: quiet verbose +// [verbose]compile-flags: -Zverbose + +#![allow(unused_parens)] + +trait Foo { + type Assoc; +} + +fn called() +where + for<'b> fn(&'b ()): Foo, +{ +} + +fn caller() +where + (for<'a> fn(&'a ())): Foo, +{ + called() + //[quiet]~^ ERROR the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied + //[verbose]~^^ ERROR the trait bound `for<'b> fn(&ReLateBound( +} + +fn main() {} diff --git a/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr b/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr new file mode 100644 index 00000000000..24660ec3539 --- /dev/null +++ b/src/test/ui/where-clauses/higher-ranked-fn-type.verbose.stderr @@ -0,0 +1,18 @@ +error[E0277]: the trait bound `for<'b> fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b) }) ()): Foo` is not satisfied + --> $DIR/higher-ranked-fn-type.rs:20:5 + | +LL | called() + | ^^^^^^ the trait `for<'b> Foo` is not implemented for `fn(&ReLateBound(DebruijnIndex(1), BoundRegion { var: 0, kind: BrNamed(DefId(0:6 ~ higher_ranked_fn_type[1209]::called::'b), 'b) }) ())` + | +note: required by a bound in `called` + --> $DIR/higher-ranked-fn-type.rs:12:25 + | +LL | fn called() + | ------ required by a bound in this +LL | where +LL | for<'b> fn(&'b ()): Foo, + | ^^^ required by this bound in `called` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 14311cff5c8..b0006cb90bd 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -193,6 +193,12 @@ macro_rules! t { Err(e) => panic!("{} failed with {}", stringify!($e), e), } }; + ($e:expr, $extra:expr) => { + match $e { + Ok(e) => e, + Err(e) => panic!("{} failed with {}: {}", stringify!($e), e, $extra), + } + }; } struct Builder { @@ -437,7 +443,7 @@ impl Builder { host_component("rustfmt-preview"), host_component("llvm-tools-preview"), host_component("rust-analysis"), - host_component("rust-docs-json"), + host_component("rust-docs-json-preview"), ]); extensions.extend( @@ -584,7 +590,7 @@ impl Builder { self.shipped_files.insert(name.clone()); let dst = self.output.join(name); - t!(fs::write(&dst, contents)); + t!(fs::write(&dst, contents), format!("failed to create manifest {}", dst.display())); } fn write_shipped_files(&self, path: &Path) { diff --git a/src/tools/build-manifest/src/versions.rs b/src/tools/build-manifest/src/versions.rs index 92ef9968fe5..0186194a41f 100644 --- a/src/tools/build-manifest/src/versions.rs +++ b/src/tools/build-manifest/src/versions.rs @@ -20,6 +20,7 @@ pub(crate) enum PkgType { Rustfmt, LlvmTools, Miri, + JsonDocs, Other(String), } @@ -36,6 +37,7 @@ impl PkgType { "rustfmt" | "rustfmt-preview" => PkgType::Rustfmt, "llvm-tools" | "llvm-tools-preview" => PkgType::LlvmTools, "miri" | "miri-preview" => PkgType::Miri, + "rust-docs-json" | "rust-docs-json-preview" => PkgType::JsonDocs, other => PkgType::Other(other.into()), } } @@ -53,6 +55,7 @@ impl PkgType { PkgType::Rustfmt => "rustfmt", PkgType::LlvmTools => "llvm-tools", PkgType::Miri => "miri", + PkgType::JsonDocs => "rust-docs-json", PkgType::Other(component) => component, } } @@ -72,6 +75,7 @@ impl PkgType { PkgType::Rust => true, PkgType::RustSrc => true, PkgType::Rustc => true, + PkgType::JsonDocs => true, PkgType::Other(_) => true, } } @@ -113,6 +117,9 @@ impl Versions { Some(version) => Ok(version.clone()), None => { let version_info = self.load_version_from_tarball(package)?; + if *package == PkgType::Rust && version_info.version.is_none() { + panic!("missing version info for toolchain"); + } self.versions.insert(package.clone(), version_info.clone()); Ok(version_info) } @@ -127,6 +134,7 @@ impl Versions { Ok(file) => file, Err(err) if err.kind() == std::io::ErrorKind::NotFound => { // Missing tarballs do not return an error, but return empty data. + println!("warning: missing tarball {}", tarball.display()); return Ok(VersionInfo::default()); } Err(err) => return Err(err.into()), diff --git a/src/tools/cargo b/src/tools/cargo -Subproject f5fed93ba24607980647962c59863bbabb03ce1 +Subproject 0b84a35c2c7d70df4875a03eb19084b0e7a543e diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index e54d71fc8e4..f0d5ed6f594 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -1238,7 +1238,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc ty::Adt(..) if ty.has_placeholders() || ty.has_opaque_types() => { Position::ReborrowStable(precedence).into() }, - ty::Adt(_, substs) if substs.has_param_types_or_consts() => { + ty::Adt(_, substs) if substs.has_non_region_param() => { TyPosition::new_deref_stable_for_result(precedence, ty) }, ty::Bool diff --git a/src/tools/clippy/clippy_lints/src/module_style.rs b/src/tools/clippy/clippy_lints/src/module_style.rs index 22071ab3044..102b9fbae83 100644 --- a/src/tools/clippy/clippy_lints/src/module_style.rs +++ b/src/tools/clippy/clippy_lints/src/module_style.rs @@ -117,11 +117,13 @@ impl EarlyLintPass for ModStyle { cx.struct_span_lint( SELF_NAMED_MODULE_FILES, Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None), - |build| { - let mut lint = - build.build(&format!("`mod.rs` files are required, found `{}`", path.display())); - lint.help(&format!("move `{}` to `{}`", path.display(), correct.display(),)); - lint.emit(); + format!("`mod.rs` files are required, found `{}`", path.display()), + |lint| { + lint.help(format!( + "move `{}` to `{}`", + path.display(), + correct.display(), + )) }, ); } @@ -156,11 +158,8 @@ fn check_self_named_mod_exists(cx: &EarlyContext<'_>, path: &Path, file: &Source cx.struct_span_lint( MOD_MODULE_FILES, Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None), - |build| { - let mut lint = build.build(&format!("`mod.rs` files are not allowed, found `{}`", path.display())); - lint.help(&format!("move `{}` to `{}`", path.display(), mod_file.display(),)); - lint.emit(); - }, + format!("`mod.rs` files are not allowed, found `{}`", path.display()), + |lint| lint.help(format!("move `{}` to `{}`", path.display(), mod_file.display())), ); } } diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index a25be93b8d6..2be22884027 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { if !bound_predicate.span.from_expansion(); if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind; if let Some(PathSegment { - res: Res::SelfTy{ trait_: Some(def_id), alias_to: _ }, .. + res: Res::SelfTyParam { trait_: def_id }, .. }) = segments.first(); if let Some( Node::Item( diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index 6a767967ef4..2c4f5075e98 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -206,7 +206,12 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { ref types_to_skip, }) = self.stack.last(); if let TyKind::Path(QPath::Resolved(_, path)) = hir_ty.kind; - if !matches!(path.res, Res::SelfTy { .. } | Res::Def(DefKind::TyParam, _)); + if !matches!( + path.res, + Res::SelfTyParam { .. } + | Res::SelfTyAlias { .. } + | Res::Def(DefKind::TyParam, _) + ); if !types_to_skip.contains(&hir_ty.hir_id); let ty = if in_body > 0 { cx.typeck_results().node_type(hir_ty.hir_id) @@ -230,7 +235,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { } match expr.kind { ExprKind::Struct(QPath::Resolved(_, path), ..) => match path.res { - Res::SelfTy { .. } => (), + Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => (), Res::Def(DefKind::Variant, _) => lint_path_to_variant(cx, path), _ => span_lint(cx, path.span), }, diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs index ad95369b9ef..78960d1ab1d 100644 --- a/src/tools/clippy/clippy_utils/src/diagnostics.rs +++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs @@ -47,10 +47,9 @@ fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) { /// | ^^^^^^^^^^^^^^^^^^^^^^^ /// ``` pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: &str) { - cx.struct_span_lint(lint, sp, |diag| { - let mut diag = diag.build(msg); - docs_link(&mut diag, lint); - diag.emit(); + cx.struct_span_lint(lint, sp, msg, |diag| { + docs_link(diag, lint); + diag }); } @@ -82,15 +81,14 @@ pub fn span_lint_and_help<'a, T: LintContext>( help_span: Option<Span>, help: &str, ) { - cx.struct_span_lint(lint, span, |diag| { - let mut diag = diag.build(msg); + cx.struct_span_lint(lint, span, msg, |diag| { if let Some(help_span) = help_span { diag.span_help(help_span, help); } else { diag.help(help); } - docs_link(&mut diag, lint); - diag.emit(); + docs_link(diag, lint); + diag }); } @@ -125,15 +123,14 @@ pub fn span_lint_and_note<'a, T: LintContext>( note_span: Option<Span>, note: &str, ) { - cx.struct_span_lint(lint, span, |diag| { - let mut diag = diag.build(msg); + cx.struct_span_lint(lint, span, msg, |diag| { if let Some(note_span) = note_span { diag.span_note(note_span, note); } else { diag.note(note); } - docs_link(&mut diag, lint); - diag.emit(); + docs_link(diag, lint); + diag }); } @@ -147,19 +144,17 @@ where S: Into<MultiSpan>, F: FnOnce(&mut Diagnostic), { - cx.struct_span_lint(lint, sp, |diag| { - let mut diag = diag.build(msg); - f(&mut diag); - docs_link(&mut diag, lint); - diag.emit(); + cx.struct_span_lint(lint, sp, msg, |diag| { + f(diag); + docs_link(diag, lint); + diag }); } pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) { - cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |diag| { - let mut diag = diag.build(msg); - docs_link(&mut diag, lint); - diag.emit(); + cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |diag| { + docs_link(diag, lint); + diag }); } @@ -171,11 +166,10 @@ pub fn span_lint_hir_and_then( msg: &str, f: impl FnOnce(&mut Diagnostic), ) { - cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |diag| { - let mut diag = diag.build(msg); - f(&mut diag); - docs_link(&mut diag, lint); - diag.emit(); + cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg, |diag| { + f(diag); + docs_link(diag, lint); + diag }); } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 627d6b51944..8f79c07c977 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1535,7 +1535,7 @@ pub fn is_self(slf: &Param<'_>) -> bool { pub fn is_self_ty(slf: &hir::Ty<'_>) -> bool { if let TyKind::Path(QPath::Resolved(None, path)) = slf.kind { - if let Res::SelfTy { .. } = path.res { + if let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path.res { return true; } } diff --git a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr index 62c45b54634..4c75998437f 100644 --- a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr +++ b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr @@ -4,8 +4,8 @@ error: `std::string::String` may not be held across an `await` point per `clippy LL | let _x = String::from("hello"); | ^^ | - = note: `-D clippy::await-holding-invalid-type` implied by `-D warnings` = note: strings are bad + = note: `-D clippy::await-holding-invalid-type` implied by `-D warnings` error: `std::net::Ipv4Addr` may not be held across an `await` point per `clippy.toml` --> $DIR/await_holding_invalid_type.rs:10:9 diff --git a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr index 4c560299ebd..b2b57bdde89 100644 --- a/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr +++ b/src/tools/clippy/tests/ui-toml/conf_deprecated_key/conf_deprecated_key.stderr @@ -8,8 +8,8 @@ error: the function has a cognitive complexity of (3/2) LL | fn cognitive_complexity() { | ^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::cognitive-complexity` implied by `-D warnings` = help: you could split it up into multiple smaller functions + = note: `-D clippy::cognitive-complexity` implied by `-D warnings` error: aborting due to previous error; 2 warnings emitted diff --git a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr index c5d95cb8a14..28a08599c67 100644 --- a/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr +++ b/src/tools/clippy/tests/ui-toml/expect_used/expect_used.stderr @@ -4,8 +4,8 @@ error: used `expect()` on `an Option` value LL | let _ = opt.expect(""); | ^^^^^^^^^^^^^^ | - = note: `-D clippy::expect-used` implied by `-D warnings` = help: if this value is `None`, it will panic + = note: `-D clippy::expect-used` implied by `-D warnings` error: used `expect()` on `a Result` value --> $DIR/expect_used.rs:11:13 diff --git a/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr b/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr index d05adc3d36e..87bdb61c6a5 100644 --- a/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr +++ b/src/tools/clippy/tests/ui-toml/fn_params_excessive_bools/test.stderr @@ -4,8 +4,8 @@ error: more than 1 bools in function parameters LL | fn g(_: bool, _: bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings` = help: consider refactoring bools into two-variant enums + = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr index 6a685a58318..7b5fb9e8765 100644 --- a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr +++ b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr @@ -4,8 +4,8 @@ error: attempted to include a large file LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::large-include-file` implied by `-D warnings` = note: the configuration allows a maximum size of 600 bytes + = note: `-D clippy::large-include-file` implied by `-D warnings` = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info) error: attempted to include a large file diff --git a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr index d80ad49f308..15fa4f42f9b 100644 --- a/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr +++ b/src/tools/clippy/tests/ui-toml/nonstandard_macro_braces/conf_nonstandard_macro_braces.stderr @@ -4,12 +4,12 @@ error: use of irregular braces for `vec!` macro LL | let _ = vec! {1, 2, 3}; | ^^^^^^^^^^^^^^ | - = note: `-D clippy::nonstandard-macro-braces` implied by `-D warnings` help: consider writing `vec![1, 2, 3]` --> $DIR/conf_nonstandard_macro_braces.rs:43:13 | LL | let _ = vec! {1, 2, 3}; | ^^^^^^^^^^^^^^ + = note: `-D clippy::nonstandard-macro-braces` implied by `-D warnings` error: use of irregular braces for `format!` macro --> $DIR/conf_nonstandard_macro_braces.rs:44:13 diff --git a/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr b/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr index 49eecf18b4c..c72f8c6488d 100644 --- a/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr +++ b/src/tools/clippy/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr @@ -4,13 +4,13 @@ error: some fields in `NoGeneric` are not safe to be sent to another thread LL | unsafe impl Send for NoGeneric {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings` note: it is not safe to send field `rc_is_not_send` to another thread --> $DIR/test.rs:8:5 | LL | rc_is_not_send: Rc<String>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: use a thread-safe type that implements `Send` + = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings` error: some fields in `MultiField<T>` are not safe to be sent to another thread --> $DIR/test.rs:19:1 diff --git a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr index 65861d10d0f..4e7c70d1838 100644 --- a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr +++ b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.stderr @@ -6,8 +6,8 @@ LL | | a: bool, LL | | } | |_^ | - = note: `-D clippy::struct-excessive-bools` implied by `-D warnings` = help: consider using a state machine or refactoring bools into two-variant enums + = note: `-D clippy::struct-excessive-bools` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr index 6bcfa0a8b56..681b5eaf54d 100644 --- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr +++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr @@ -16,8 +16,8 @@ error: used `unwrap()` on `an Option` value LL | let _ = boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::unwrap-used` implied by `-D warnings` = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + = note: `-D clippy::unwrap-used` implied by `-D warnings` error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise --> $DIR/unwrap_used.rs:36:17 diff --git a/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr b/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr index 6de554378aa..21cb11fa1bb 100644 --- a/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr +++ b/src/tools/clippy/tests/ui/absurd-extreme-comparisons.stderr @@ -4,8 +4,8 @@ error: this comparison involving the minimum or maximum element for this type co LL | u <= 0; | ^^^^^^ | - = note: `-D clippy::absurd-extreme-comparisons` implied by `-D warnings` = help: because `0` is the minimum value for this type, the case where the two sides are not equal never occurs, consider using `u == 0` instead + = note: `-D clippy::absurd-extreme-comparisons` implied by `-D warnings` error: this comparison involving the minimum or maximum element for this type contains a case that is always true or always false --> $DIR/absurd-extreme-comparisons.rs:15:5 diff --git a/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr b/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr index cd040a144aa..23f17e9a7af 100644 --- a/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr +++ b/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr @@ -4,12 +4,12 @@ error: `allow` attribute without specifying a reason LL | #[allow(dead_code)] | ^^^^^^^^^^^^^^^^^^^ | + = help: try adding a reason at the end with `, reason = ".."` note: the lint level is defined here --> $DIR/allow_attributes_without_reason.rs:2:9 | LL | #![deny(clippy::allow_attributes_without_reason)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: try adding a reason at the end with `, reason = ".."` error: `allow` attribute without specifying a reason --> $DIR/allow_attributes_without_reason.rs:6:1 diff --git a/src/tools/clippy/tests/ui/approx_const.stderr b/src/tools/clippy/tests/ui/approx_const.stderr index 4da1b8215ae..0932a2eec52 100644 --- a/src/tools/clippy/tests/ui/approx_const.stderr +++ b/src/tools/clippy/tests/ui/approx_const.stderr @@ -4,8 +4,8 @@ error: approximate value of `f{32, 64}::consts::E` found LL | let my_e = 2.7182; | ^^^^^^ | - = note: `-D clippy::approx-constant` implied by `-D warnings` = help: consider using the constant directly + = note: `-D clippy::approx-constant` implied by `-D warnings` error: approximate value of `f{32, 64}::consts::E` found --> $DIR/approx_const.rs:5:20 diff --git a/src/tools/clippy/tests/ui/as_conversions.stderr b/src/tools/clippy/tests/ui/as_conversions.stderr index d11b56171b0..f5d59e1e5d8 100644 --- a/src/tools/clippy/tests/ui/as_conversions.stderr +++ b/src/tools/clippy/tests/ui/as_conversions.stderr @@ -4,8 +4,8 @@ error: using a potentially dangerous silent `as` conversion LL | let i = 0u32 as u64; | ^^^^^^^^^^^ | - = note: `-D clippy::as-conversions` implied by `-D warnings` = help: consider using a safe wrapper for this conversion + = note: `-D clippy::as-conversions` implied by `-D warnings` error: using a potentially dangerous silent `as` conversion --> $DIR/as_conversions.rs:17:13 diff --git a/src/tools/clippy/tests/ui/asm_syntax.stderr b/src/tools/clippy/tests/ui/asm_syntax.stderr index e9b150121aa..9c7c3ba7d87 100644 --- a/src/tools/clippy/tests/ui/asm_syntax.stderr +++ b/src/tools/clippy/tests/ui/asm_syntax.stderr @@ -4,8 +4,8 @@ error: Intel x86 assembly syntax used LL | asm!(""); | ^^^^^^^^ | - = note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings` = help: use AT&T x86 assembly syntax + = note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings` error: Intel x86 assembly syntax used --> $DIR/asm_syntax.rs:9:9 @@ -29,8 +29,8 @@ error: AT&T x86 assembly syntax used LL | asm!("", options(att_syntax)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings` = help: use Intel x86 assembly syntax + = note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings` error: AT&T x86 assembly syntax used --> $DIR/asm_syntax.rs:24:9 diff --git a/src/tools/clippy/tests/ui/assertions_on_constants.stderr b/src/tools/clippy/tests/ui/assertions_on_constants.stderr index e1f818814d5..29fe009035f 100644 --- a/src/tools/clippy/tests/ui/assertions_on_constants.stderr +++ b/src/tools/clippy/tests/ui/assertions_on_constants.stderr @@ -4,8 +4,8 @@ error: `assert!(true)` will be optimized out by the compiler LL | assert!(true); | ^^^^^^^^^^^^^ | - = note: `-D clippy::assertions-on-constants` implied by `-D warnings` = help: remove it + = note: `-D clippy::assertions-on-constants` implied by `-D warnings` error: `assert!(false)` should probably be replaced --> $DIR/assertions_on_constants.rs:11:5 diff --git a/src/tools/clippy/tests/ui/await_holding_lock.stderr b/src/tools/clippy/tests/ui/await_holding_lock.stderr index 976da8d9242..81a2d052438 100644 --- a/src/tools/clippy/tests/ui/await_holding_lock.stderr +++ b/src/tools/clippy/tests/ui/await_holding_lock.stderr @@ -4,7 +4,6 @@ error: this `MutexGuard` is held across an `await` point LL | let guard = x.lock().unwrap(); | ^^^^^ | - = note: `-D clippy::await-holding-lock` implied by `-D warnings` = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await note: these are all the `await` points this lock is held through --> $DIR/await_holding_lock.rs:9:9 @@ -13,6 +12,7 @@ LL | / let guard = x.lock().unwrap(); LL | | baz().await LL | | } | |_____^ + = note: `-D clippy::await-holding-lock` implied by `-D warnings` error: this `MutexGuard` is held across an `await` point --> $DIR/await_holding_lock.rs:24:13 diff --git a/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr b/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr index 4339fca735d..25c15ab8060 100644 --- a/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr +++ b/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr @@ -4,7 +4,6 @@ error: this `RefCell` reference is held across an `await` point LL | let b = x.borrow(); | ^ | - = note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings` = help: ensure the reference is dropped before calling `await` note: these are all the `await` points this reference is held through --> $DIR/await_holding_refcell_ref.rs:6:5 @@ -13,6 +12,7 @@ LL | / let b = x.borrow(); LL | | baz().await LL | | } | |_^ + = note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings` error: this `RefCell` reference is held across an `await` point --> $DIR/await_holding_refcell_ref.rs:11:9 diff --git a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr index 537557f8b0a..e83eb4d605a 100644 --- a/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr +++ b/src/tools/clippy/tests/ui/blanket_clippy_restriction_lints.stderr @@ -4,8 +4,8 @@ error: restriction lints are not meant to be all enabled LL | #![warn(clippy::restriction)] | ^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings` = help: try enabling only the lints you really need + = note: `-D clippy::blanket-clippy-restriction-lints` implied by `-D warnings` error: restriction lints are not meant to be all enabled --> $DIR/blanket_clippy_restriction_lints.rs:5:9 diff --git a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr index e695440f668..4cb5531bef6 100644 --- a/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr +++ b/src/tools/clippy/tests/ui/bool_to_int_with_if.stderr @@ -8,8 +8,8 @@ LL | | 0 LL | | }; | |_____^ help: replace with from: `i32::from(a)` | - = note: `-D clippy::bool-to-int-with-if` implied by `-D warnings` = note: `a as i32` or `a.into()` can also be valid options + = note: `-D clippy::bool-to-int-with-if` implied by `-D warnings` error: boolean to int conversion using if --> $DIR/bool_to_int_with_if.rs:20:5 diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.stderr index 654a1ee7df6..b0cab977a03 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.stderr +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/enums.stderr @@ -4,8 +4,8 @@ error: a `const` item with interior mutability should not be borrowed LL | let _ = &UNFROZEN_VARIANT; //~ ERROR interior mutability | ^^^^^^^^^^^^^^^^ | - = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings` = help: assign this const to a local or static variable, and use the variable here + = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings` error: a `const` item with interior mutability should not be borrowed --> $DIR/enums.rs:37:18 diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr index 9a908cf30e9..c87ad206c2a 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr @@ -4,8 +4,8 @@ error: a `const` item with interior mutability should not be borrowed LL | ATOMIC.store(1, Ordering::SeqCst); //~ ERROR interior mutability | ^^^^^^ | - = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings` = help: assign this const to a local or static variable, and use the variable here + = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings` error: a `const` item with interior mutability should not be borrowed --> $DIR/others.rs:55:16 diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr index 8f26403abd3..f34ae8814c3 100644 --- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr +++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/traits.stderr @@ -4,8 +4,8 @@ error: a `const` item with interior mutability should not be borrowed LL | let _ = &Self::ATOMIC; //~ ERROR interior mutable | ^^^^^^^^^^^^ | - = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings` = help: assign this const to a local or static variable, and use the variable here + = note: `-D clippy::borrow-interior-mutable-const` implied by `-D warnings` error: a `const` item with interior mutability should not be borrowed --> $DIR/traits.rs:26:18 diff --git a/src/tools/clippy/tests/ui/box_collection.stderr b/src/tools/clippy/tests/ui/box_collection.stderr index 2b28598ded9..40b6f9be61d 100644 --- a/src/tools/clippy/tests/ui/box_collection.stderr +++ b/src/tools/clippy/tests/ui/box_collection.stderr @@ -4,8 +4,8 @@ error: you seem to be trying to use `Box<Vec<..>>`. Consider using just `Vec<..> LL | fn test1(foo: Box<Vec<bool>>) {} | ^^^^^^^^^^^^^^ | - = note: `-D clippy::box-collection` implied by `-D warnings` = help: `Vec<..>` is already on the heap, `Box<Vec<..>>` makes an extra allocation + = note: `-D clippy::box-collection` implied by `-D warnings` error: you seem to be trying to use `Box<String>`. Consider using just `String` --> $DIR/box_collection.rs:28:15 diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr index 5e1a68d216e..b919812e098 100644 --- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr +++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_bottom.stderr @@ -7,12 +7,12 @@ LL | | result LL | | }; | |_____^ | + = note: the end suggestion probably needs some adjustments to use the expression result correctly note: the lint level is defined here --> $DIR/shared_at_bottom.rs:2:36 | LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: the end suggestion probably needs some adjustments to use the expression result correctly help: consider moving these statements after the if | LL ~ } diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr index d890b12ecbb..fb3da641fb5 100644 --- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr +++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top.stderr @@ -103,11 +103,6 @@ LL | | println!("This should trigger `IS_SAME_THAN_ELSE` as usual"); LL | | } else { | |_____^ | -note: the lint level is defined here - --> $DIR/shared_at_top.rs:2:9 - | -LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: same as this --> $DIR/shared_at_top.rs:98:12 | @@ -116,6 +111,11 @@ LL | } else { LL | | println!("This should trigger `IS_SAME_THAN_ELSE` as usual"); LL | | } | |_____^ +note: the lint level is defined here + --> $DIR/shared_at_top.rs:2:9 + | +LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 7 previous errors diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr index a270f637f2b..3edb8e53a7d 100644 --- a/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr +++ b/src/tools/clippy/tests/ui/branches_sharing_code/shared_at_top_and_bottom.stderr @@ -7,17 +7,17 @@ LL | | let _overlap_start = t * 2; LL | | let _overlap_end = 2 * t; | |_________________________________^ | -note: the lint level is defined here - --> $DIR/shared_at_top_and_bottom.rs:2:36 - | -LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: this code is shared at the end --> $DIR/shared_at_top_and_bottom.rs:28:5 | LL | / let _u = 9; LL | | } | |_____^ +note: the lint level is defined here + --> $DIR/shared_at_top_and_bottom.rs:2:36 + | +LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider moving these statements before the if | LL ~ let t = 7; diff --git a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr index a815995e717..d2acd6d9735 100644 --- a/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr +++ b/src/tools/clippy/tests/ui/branches_sharing_code/valid_if_blocks.stderr @@ -6,11 +6,6 @@ LL | if false { LL | | } else { | |_____^ | -note: the lint level is defined here - --> $DIR/valid_if_blocks.rs:2:9 - | -LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: same as this --> $DIR/valid_if_blocks.rs:105:12 | @@ -18,6 +13,11 @@ LL | } else { | ____________^ LL | | } | |_____^ +note: the lint level is defined here + --> $DIR/valid_if_blocks.rs:2:9 + | +LL | #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: this `if` has identical blocks --> $DIR/valid_if_blocks.rs:115:15 diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr index 5d9a043edb9..a28dd8bd5ad 100644 --- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr +++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.stderr @@ -4,8 +4,8 @@ error: case-sensitive file extension comparison LL | filename.ends_with(".rs") | ^^^^^^^^^^^^^^^^ | - = note: `-D clippy::case-sensitive-file-extension-comparisons` implied by `-D warnings` = help: consider using a case-insensitive comparison instead + = note: `-D clippy::case-sensitive-file-extension-comparisons` implied by `-D warnings` error: case-sensitive file extension comparison --> $DIR/case_sensitive_file_extension_comparisons.rs:17:27 diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8.stderr b/src/tools/clippy/tests/ui/char_lit_as_u8.stderr index b9836d2f255..39fc9d6dda6 100644 --- a/src/tools/clippy/tests/ui/char_lit_as_u8.stderr +++ b/src/tools/clippy/tests/ui/char_lit_as_u8.stderr @@ -4,8 +4,8 @@ error: casting a character literal to `u8` truncates LL | let _ = '❤' as u8; // no suggestion, since a byte literal won't work. | ^^^^^^^^^ | - = note: `-D clippy::char-lit-as-u8` implied by `-D warnings` = note: `char` is four bytes wide, but `u8` is a single byte + = note: `-D clippy::char-lit-as-u8` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr index bf7cb1607b4..586174c5088 100644 --- a/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr +++ b/src/tools/clippy/tests/ui/char_lit_as_u8_suggestions.stderr @@ -4,8 +4,8 @@ error: casting a character literal to `u8` truncates LL | let _ = 'a' as u8; | ^^^^^^^^^ help: use a byte literal instead: `b'a'` | - = note: `-D clippy::char-lit-as-u8` implied by `-D warnings` = note: `char` is four bytes wide, but `u8` is a single byte + = note: `-D clippy::char-lit-as-u8` implied by `-D warnings` error: casting a character literal to `u8` truncates --> $DIR/char_lit_as_u8_suggestions.rs:7:13 diff --git a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr index 46c6f69708e..d44d5072e48 100644 --- a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr +++ b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals.stderr @@ -6,12 +6,12 @@ LL | if x.is_ok() && y.is_err() { LL | x.unwrap(); // unnecessary | ^^^^^^^^^^ | + = help: try using `if let` or `match` note: the lint level is defined here --> $DIR/complex_conditionals.rs:1:35 | LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: try using `if let` or `match` error: this call to `unwrap_err()` will always panic --> $DIR/complex_conditionals.rs:9:9 diff --git a/src/tools/clippy/tests/ui/cognitive_complexity.stderr b/src/tools/clippy/tests/ui/cognitive_complexity.stderr index a0ddc673abc..d7f2f24e52f 100644 --- a/src/tools/clippy/tests/ui/cognitive_complexity.stderr +++ b/src/tools/clippy/tests/ui/cognitive_complexity.stderr @@ -4,8 +4,8 @@ error: the function has a cognitive complexity of (28/25) LL | fn main() { | ^^^^ | - = note: `-D clippy::cognitive-complexity` implied by `-D warnings` = help: you could split it up into multiple smaller functions + = note: `-D clippy::cognitive-complexity` implied by `-D warnings` error: the function has a cognitive complexity of (7/1) --> $DIR/cognitive_complexity.rs:91:4 diff --git a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr index f5ff53dda60..bb48f329748 100644 --- a/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr +++ b/src/tools/clippy/tests/ui/cognitive_complexity_attr_used.stderr @@ -4,8 +4,8 @@ error: the function has a cognitive complexity of (3/0) LL | fn kaboom() { | ^^^^^^ | - = note: `-D clippy::cognitive-complexity` implied by `-D warnings` = help: you could split it up into multiple smaller functions + = note: `-D clippy::cognitive-complexity` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/collapsible_match.stderr b/src/tools/clippy/tests/ui/collapsible_match.stderr index 5f18b693502..33562e8401c 100644 --- a/src/tools/clippy/tests/ui/collapsible_match.stderr +++ b/src/tools/clippy/tests/ui/collapsible_match.stderr @@ -8,7 +8,6 @@ LL | | _ => return, LL | | }, | |_________^ | - = note: `-D clippy::collapsible-match` implied by `-D warnings` help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match.rs:12:12 | @@ -16,6 +15,7 @@ LL | Ok(val) => match val { | ^^^ replace this binding LL | Some(n) => foo(n), | ^^^^^^^ with this pattern + = note: `-D clippy::collapsible-match` implied by `-D warnings` error: this `match` can be collapsed into the outer `match` --> $DIR/collapsible_match.rs:21:20 diff --git a/src/tools/clippy/tests/ui/collapsible_match2.stderr b/src/tools/clippy/tests/ui/collapsible_match2.stderr index fe64e469379..144dbe40a7a 100644 --- a/src/tools/clippy/tests/ui/collapsible_match2.stderr +++ b/src/tools/clippy/tests/ui/collapsible_match2.stderr @@ -8,7 +8,6 @@ LL | | _ => return, LL | | }, | |_____________^ | - = note: `-D clippy::collapsible-match` implied by `-D warnings` help: the outer pattern can be modified to include the inner pattern --> $DIR/collapsible_match2.rs:13:16 | @@ -16,6 +15,7 @@ LL | Ok(val) if make() => match val { | ^^^ replace this binding LL | Some(n) => foo(n), | ^^^^^^^ with this pattern + = note: `-D clippy::collapsible-match` implied by `-D warnings` error: this `match` can be collapsed into the outer `match` --> $DIR/collapsible_match2.rs:20:24 diff --git a/src/tools/clippy/tests/ui/comparison_chain.stderr b/src/tools/clippy/tests/ui/comparison_chain.stderr index be25a80dde0..2eeb50202cd 100644 --- a/src/tools/clippy/tests/ui/comparison_chain.stderr +++ b/src/tools/clippy/tests/ui/comparison_chain.stderr @@ -8,8 +8,8 @@ LL | | b() LL | | } | |_____^ | - = note: `-D clippy::comparison-chain` implied by `-D warnings` = help: consider rewriting the `if` chain to use `cmp` and `match` + = note: `-D clippy::comparison-chain` implied by `-D warnings` error: `if` chain can be rewritten with `match` --> $DIR/comparison_chain.rs:27:5 diff --git a/src/tools/clippy/tests/ui/copy_iterator.stderr b/src/tools/clippy/tests/ui/copy_iterator.stderr index f8ce6af7961..6bc6fd6b6fa 100644 --- a/src/tools/clippy/tests/ui/copy_iterator.stderr +++ b/src/tools/clippy/tests/ui/copy_iterator.stderr @@ -10,8 +10,8 @@ LL | | } LL | | } | |_^ | - = note: `-D clippy::copy-iterator` implied by `-D warnings` = note: consider implementing `IntoIterator` instead + = note: `-D clippy::copy-iterator` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-360.stderr b/src/tools/clippy/tests/ui/crashes/ice-360.stderr index 0eb7bb12b35..a2e2ab8fd19 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-360.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-360.stderr @@ -18,8 +18,8 @@ error: empty `loop {}` wastes CPU cycles LL | loop {} | ^^^^^^^ | - = note: `-D clippy::empty-loop` implied by `-D warnings` = help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body + = note: `-D clippy::empty-loop` implied by `-D warnings` error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr index f37ab2e9b0c..22d82a30c6a 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr @@ -4,9 +4,9 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated wit LL | FOO_REF_REF => {}, | ^^^^^^^^^^^ | - = note: `-D indirect-structural-match` implied by `-D warnings` = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411> + = note: `-D indirect-structural-match` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr index 1a33e647588..1d8314e889f 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr @@ -4,8 +4,8 @@ error: unsafe block missing a safety comment LL | unsafe { 0 }; | ^^^^^^^^^^^^ | - = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` = help: consider adding a safety comment on the preceding line + = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-7869.stderr b/src/tools/clippy/tests/ui/crashes/ice-7869.stderr index 4fa9fb27e76..35d1e8fd295 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-7869.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-7869.stderr @@ -8,8 +8,8 @@ LL | | TyöValmis, LL | | } | |_^ | - = note: `-D clippy::enum-variant-names` implied by `-D warnings` = help: remove the prefixes and use full paths to the variants instead of glob imports + = note: `-D clippy::enum-variant-names` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/crashes/ice-9463.stderr b/src/tools/clippy/tests/ui/crashes/ice-9463.stderr index 7daa08aeb6c..b0ce306d683 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-9463.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-9463.stderr @@ -22,8 +22,8 @@ error: literal out of range for `u32` LL | let _y = 1u32 >> 10000000000000u32; | ^^^^^^^^^^^^^^^^^ | - = note: `#[deny(overflowing_literals)]` on by default = note: the literal `10000000000000u32` does not fit into the type `u32` whose range is `0..=4294967295` + = note: `#[deny(overflowing_literals)]` on by default error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.stderr b/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.stderr index 459cf12a1c2..3d79a115cb3 100644 --- a/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.stderr +++ b/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.stderr @@ -4,8 +4,8 @@ error: recursing into entrypoint `a` LL | a(); | ^ | - = note: `-D clippy::main-recursion` implied by `-D warnings` = help: consider using another function for this recursion + = note: `-D clippy::main-recursion` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr index 48152d8ad77..7d8ea3f76b0 100644 --- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr +++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_swap.stderr @@ -5,8 +5,8 @@ LL | / a = b; LL | | b = a; | |_________^ help: try: `core::mem::swap(&mut a, &mut b)` | - = note: `-D clippy::almost-swapped` implied by `-D warnings` = note: or maybe you should use `core::mem::replace`? + = note: `-D clippy::almost-swapped` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr index 0a260f9d230..82c68bd1cfe 100644 --- a/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr +++ b/src/tools/clippy/tests/ui/crate_level_checks/std_main_recursion.stderr @@ -4,8 +4,8 @@ error: recursing into entrypoint `main` LL | main(); | ^^^^ | - = note: `-D clippy::main-recursion` implied by `-D warnings` = help: consider using another function for this recursion + = note: `-D clippy::main-recursion` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/def_id_nocore.stderr b/src/tools/clippy/tests/ui/def_id_nocore.stderr index 6210d7c6cfd..f8fc17e872b 100644 --- a/src/tools/clippy/tests/ui/def_id_nocore.stderr +++ b/src/tools/clippy/tests/ui/def_id_nocore.stderr @@ -4,8 +4,8 @@ error: methods called `as_*` usually take `self` by reference or `self` by mutab LL | pub fn as_ref(self) -> &'static str { | ^^^^ | - = note: `-D clippy::wrong-self-convention` implied by `-D warnings` = help: consider choosing a less ambiguous name + = note: `-D clippy::wrong-self-convention` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/default_union_representation.stderr b/src/tools/clippy/tests/ui/default_union_representation.stderr index 138884af868..8b7ed94cbc6 100644 --- a/src/tools/clippy/tests/ui/default_union_representation.stderr +++ b/src/tools/clippy/tests/ui/default_union_representation.stderr @@ -7,8 +7,8 @@ LL | | b: u32, LL | | } | |_^ | - = note: `-D clippy::default-union-representation` implied by `-D warnings` = help: consider annotating `NoAttribute` with `#[repr(C)]` to explicitly specify memory layout + = note: `-D clippy::default-union-representation` implied by `-D warnings` error: this union has the default representation --> $DIR/default_union_representation.rs:16:1 diff --git a/src/tools/clippy/tests/ui/derive.stderr b/src/tools/clippy/tests/ui/derive.stderr index 82a70ceecc3..e1fbb8dcd1e 100644 --- a/src/tools/clippy/tests/ui/derive.stderr +++ b/src/tools/clippy/tests/ui/derive.stderr @@ -8,7 +8,6 @@ LL | | } LL | | } | |_^ | - = note: `-D clippy::expl-impl-clone-on-copy` implied by `-D warnings` note: consider deriving `Clone` or removing `Copy` --> $DIR/derive.rs:8:1 | @@ -18,6 +17,7 @@ LL | | Qux LL | | } LL | | } | |_^ + = note: `-D clippy::expl-impl-clone-on-copy` implied by `-D warnings` error: you are implementing `Clone` explicitly on a `Copy` type --> $DIR/derive.rs:32:1 diff --git a/src/tools/clippy/tests/ui/derive_hash_xor_eq.stderr b/src/tools/clippy/tests/ui/derive_hash_xor_eq.stderr index 2a4abb0c519..16c92397804 100644 --- a/src/tools/clippy/tests/ui/derive_hash_xor_eq.stderr +++ b/src/tools/clippy/tests/ui/derive_hash_xor_eq.stderr @@ -4,12 +4,12 @@ error: you are deriving `Hash` but have implemented `PartialEq` explicitly LL | #[derive(Hash)] | ^^^^ | - = note: `#[deny(clippy::derive_hash_xor_eq)]` on by default note: `PartialEq` implemented here --> $DIR/derive_hash_xor_eq.rs:15:1 | LL | impl PartialEq for Bar { | ^^^^^^^^^^^^^^^^^^^^^^ + = note: `#[deny(clippy::derive_hash_xor_eq)]` on by default = note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `Hash` but have implemented `PartialEq` explicitly diff --git a/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr b/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr index baf8341aba9..58efbb8541f 100644 --- a/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr +++ b/src/tools/clippy/tests/ui/derive_ord_xor_partial_ord.stderr @@ -4,12 +4,12 @@ error: you are deriving `Ord` but have implemented `PartialOrd` explicitly LL | #[derive(Ord, PartialEq, Eq)] | ^^^ | - = note: `-D clippy::derive-ord-xor-partial-ord` implied by `-D warnings` note: `PartialOrd` implemented here --> $DIR/derive_ord_xor_partial_ord.rs:24:1 | LL | impl PartialOrd for DeriveOrd { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::derive-ord-xor-partial-ord` implied by `-D warnings` = note: this error originates in the derive macro `Ord` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `Ord` but have implemented `PartialOrd` explicitly diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr index a462b98871a..f2ac6bc3269 100644 --- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr +++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr @@ -7,8 +7,8 @@ LL | | /// Because of the initial `unbalanced_tick` pair, the error message is LL | | /// very `confusing_and_misleading`. | |____________________________________^ | - = note: `-D clippy::doc-markdown` implied by `-D warnings` = help: a backtick may be missing a pair + = note: `-D clippy::doc-markdown` implied by `-D warnings` error: backticks are unbalanced --> $DIR/unbalanced_ticks.rs:13:1 diff --git a/src/tools/clippy/tests/ui/double_must_use.stderr b/src/tools/clippy/tests/ui/double_must_use.stderr index 8290ece1cad..3d34557a881 100644 --- a/src/tools/clippy/tests/ui/double_must_use.stderr +++ b/src/tools/clippy/tests/ui/double_must_use.stderr @@ -4,8 +4,8 @@ error: this function has an empty `#[must_use]` attribute, but returns a type al LL | pub fn must_use_result() -> Result<(), ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::double-must-use` implied by `-D warnings` = help: either add some descriptive text or remove the attribute + = note: `-D clippy::double-must-use` implied by `-D warnings` error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]` --> $DIR/double_must_use.rs:10:1 diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.stderr b/src/tools/clippy/tests/ui/drop_forget_copy.stderr index 88228afae89..21adb3b3a50 100644 --- a/src/tools/clippy/tests/ui/drop_forget_copy.stderr +++ b/src/tools/clippy/tests/ui/drop_forget_copy.stderr @@ -4,12 +4,12 @@ error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a LL | drop(s1); | ^^^^^^^^ | - = note: `-D clippy::drop-copy` implied by `-D warnings` note: argument has type `SomeStruct` --> $DIR/drop_forget_copy.rs:33:10 | LL | drop(s1); | ^^ + = note: `-D clippy::drop-copy` implied by `-D warnings` error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact --> $DIR/drop_forget_copy.rs:34:5 @@ -41,12 +41,12 @@ error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetti LL | forget(s1); | ^^^^^^^^^^ | - = note: `-D clippy::forget-copy` implied by `-D warnings` note: argument has type `SomeStruct` --> $DIR/drop_forget_copy.rs:39:12 | LL | forget(s1); | ^^ + = note: `-D clippy::forget-copy` implied by `-D warnings` error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact --> $DIR/drop_forget_copy.rs:40:5 diff --git a/src/tools/clippy/tests/ui/drop_non_drop.stderr b/src/tools/clippy/tests/ui/drop_non_drop.stderr index 30121033de7..b86057c0c32 100644 --- a/src/tools/clippy/tests/ui/drop_non_drop.stderr +++ b/src/tools/clippy/tests/ui/drop_non_drop.stderr @@ -4,12 +4,12 @@ error: call to `std::mem::drop` with a value that does not implement `Drop`. Dro LL | drop(Foo); | ^^^^^^^^^ | - = note: `-D clippy::drop-non-drop` implied by `-D warnings` note: argument has type `main::Foo` --> $DIR/drop_non_drop.rs:22:10 | LL | drop(Foo); | ^^^ + = note: `-D clippy::drop-non-drop` implied by `-D warnings` error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes --> $DIR/drop_non_drop.rs:37:5 diff --git a/src/tools/clippy/tests/ui/drop_ref.stderr b/src/tools/clippy/tests/ui/drop_ref.stderr index 531849f0680..4743cf79b5d 100644 --- a/src/tools/clippy/tests/ui/drop_ref.stderr +++ b/src/tools/clippy/tests/ui/drop_ref.stderr @@ -4,12 +4,12 @@ error: calls to `std::mem::drop` with a reference instead of an owned value. Dro LL | drop(&SomeStruct); | ^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::drop-ref` implied by `-D warnings` note: argument has type `&SomeStruct` --> $DIR/drop_ref.rs:11:10 | LL | drop(&SomeStruct); | ^^^^^^^^^^^ + = note: `-D clippy::drop-ref` implied by `-D warnings` error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing --> $DIR/drop_ref.rs:14:5 diff --git a/src/tools/clippy/tests/ui/else_if_without_else.stderr b/src/tools/clippy/tests/ui/else_if_without_else.stderr index 6f47658cfb1..90ccfb4fad6 100644 --- a/src/tools/clippy/tests/ui/else_if_without_else.stderr +++ b/src/tools/clippy/tests/ui/else_if_without_else.stderr @@ -8,8 +8,8 @@ LL | | println!("else if"); LL | | } | |_____^ | - = note: `-D clippy::else-if-without-else` implied by `-D warnings` = help: add an `else` block here + = note: `-D clippy::else-if-without-else` implied by `-D warnings` error: `if` expression with an `else if`, but without a final `else` --> $DIR/else_if_without_else.rs:54:12 diff --git a/src/tools/clippy/tests/ui/empty_enum.stderr b/src/tools/clippy/tests/ui/empty_enum.stderr index 7125e5f602b..0d9aa5818e2 100644 --- a/src/tools/clippy/tests/ui/empty_enum.stderr +++ b/src/tools/clippy/tests/ui/empty_enum.stderr @@ -4,8 +4,8 @@ error: enum with no variants LL | enum Empty {} | ^^^^^^^^^^^^^ | - = note: `-D clippy::empty-enum` implied by `-D warnings` = help: consider using the uninhabited type `!` (never type) or a wrapper around it to introduce a type which can't be instantiated + = note: `-D clippy::empty-enum` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/empty_loop.stderr b/src/tools/clippy/tests/ui/empty_loop.stderr index 555f3d3d884..7602412334b 100644 --- a/src/tools/clippy/tests/ui/empty_loop.stderr +++ b/src/tools/clippy/tests/ui/empty_loop.stderr @@ -4,8 +4,8 @@ error: empty `loop {}` wastes CPU cycles LL | loop {} | ^^^^^^^ | - = note: `-D clippy::empty-loop` implied by `-D warnings` = help: you should either use `panic!()` or add `std::thread::sleep(..);` to the loop body + = note: `-D clippy::empty-loop` implied by `-D warnings` error: empty `loop {}` wastes CPU cycles --> $DIR/empty_loop.rs:11:9 diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr index 5ded35a6f0d..71af64f49d5 100644 --- a/src/tools/clippy/tests/ui/empty_loop_no_std.stderr +++ b/src/tools/clippy/tests/ui/empty_loop_no_std.stderr @@ -4,8 +4,8 @@ error: empty `loop {}` wastes CPU cycles LL | loop {} | ^^^^^^^ | - = note: `-D clippy::empty-loop` implied by `-D warnings` = help: you should either use `panic!()` or add a call pausing or sleeping the thread to the loop body + = note: `-D clippy::empty-loop` implied by `-D warnings` error: empty `loop {}` wastes CPU cycles --> $DIR/empty_loop_no_std.rs:25:5 diff --git a/src/tools/clippy/tests/ui/expect.stderr b/src/tools/clippy/tests/ui/expect.stderr index 904c0904645..f6738865cac 100644 --- a/src/tools/clippy/tests/ui/expect.stderr +++ b/src/tools/clippy/tests/ui/expect.stderr @@ -4,8 +4,8 @@ error: used `expect()` on `an Option` value LL | let _ = opt.expect(""); | ^^^^^^^^^^^^^^ | - = note: `-D clippy::expect-used` implied by `-D warnings` = help: if this value is `None`, it will panic + = note: `-D clippy::expect-used` implied by `-D warnings` error: used `expect()` on `a Result` value --> $DIR/expect.rs:10:13 diff --git a/src/tools/clippy/tests/ui/fallible_impl_from.stderr b/src/tools/clippy/tests/ui/fallible_impl_from.stderr index d637dbce5d7..28a061af664 100644 --- a/src/tools/clippy/tests/ui/fallible_impl_from.stderr +++ b/src/tools/clippy/tests/ui/fallible_impl_from.stderr @@ -8,17 +8,17 @@ LL | | } LL | | } | |_^ | -note: the lint level is defined here - --> $DIR/fallible_impl_from.rs:1:9 - | -LL | #![deny(clippy::fallible_impl_from)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = help: `From` is intended for infallible conversions only. Use `TryFrom` if there's a possibility for the conversion to fail note: potential failure(s) --> $DIR/fallible_impl_from.rs:7:13 | LL | Foo(s.parse().unwrap()) | ^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/fallible_impl_from.rs:1:9 + | +LL | #![deny(clippy::fallible_impl_from)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: consider implementing `TryFrom` instead --> $DIR/fallible_impl_from.rs:26:1 diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr index 3ce4b91a548..710bb66a48a 100644 --- a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr +++ b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr @@ -4,12 +4,12 @@ error: field assignment outside of initializer for an instance created with Defa LL | a.i = 42; | ^^^^^^^^^ | - = note: `-D clippy::field-reassign-with-default` implied by `-D warnings` note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments --> $DIR/field_reassign_with_default.rs:62:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::field-reassign-with-default` implied by `-D warnings` error: field assignment outside of initializer for an instance created with Default::default() --> $DIR/field_reassign_with_default.rs:103:5 diff --git a/src/tools/clippy/tests/ui/filetype_is_file.stderr b/src/tools/clippy/tests/ui/filetype_is_file.stderr index cd1e3ac37fe..e51a90d6cfd 100644 --- a/src/tools/clippy/tests/ui/filetype_is_file.stderr +++ b/src/tools/clippy/tests/ui/filetype_is_file.stderr @@ -4,8 +4,8 @@ error: `FileType::is_file()` only covers regular files LL | if fs::metadata("foo.txt")?.file_type().is_file() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::filetype-is-file` implied by `-D warnings` = help: use `!FileType::is_dir()` instead + = note: `-D clippy::filetype-is-file` implied by `-D warnings` error: `!FileType::is_file()` only denies regular files --> $DIR/filetype_is_file.rs:13:8 diff --git a/src/tools/clippy/tests/ui/float_cmp.stderr b/src/tools/clippy/tests/ui/float_cmp.stderr index 9cc1f1b75ed..e3e9f3949fd 100644 --- a/src/tools/clippy/tests/ui/float_cmp.stderr +++ b/src/tools/clippy/tests/ui/float_cmp.stderr @@ -4,8 +4,8 @@ error: strict comparison of `f32` or `f64` LL | ONE as f64 != 2.0; | ^^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE as f64 - 2.0).abs() > error_margin` | - = note: `-D clippy::float-cmp` implied by `-D warnings` = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` + = note: `-D clippy::float-cmp` implied by `-D warnings` error: strict comparison of `f32` or `f64` --> $DIR/float_cmp.rs:62:5 diff --git a/src/tools/clippy/tests/ui/float_cmp_const.stderr b/src/tools/clippy/tests/ui/float_cmp_const.stderr index d8182cf855b..65c45648ab3 100644 --- a/src/tools/clippy/tests/ui/float_cmp_const.stderr +++ b/src/tools/clippy/tests/ui/float_cmp_const.stderr @@ -4,8 +4,8 @@ error: strict comparison of `f32` or `f64` constant LL | 1f32 == ONE; | ^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1f32 - ONE).abs() < error_margin` | - = note: `-D clippy::float-cmp-const` implied by `-D warnings` = note: `f32::EPSILON` and `f64::EPSILON` are available for the `error_margin` + = note: `-D clippy::float-cmp-const` implied by `-D warnings` error: strict comparison of `f32` or `f64` constant --> $DIR/float_cmp_const.rs:17:5 diff --git a/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr b/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr index cd9d07fa115..11627105691 100644 --- a/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr +++ b/src/tools/clippy/tests/ui/fn_params_excessive_bools.stderr @@ -4,8 +4,8 @@ error: more than 3 bools in function parameters LL | fn g(_: bool, _: bool, _: bool, _: bool) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings` = help: consider refactoring bools into two-variant enums + = note: `-D clippy::fn-params-excessive-bools` implied by `-D warnings` error: more than 3 bools in function parameters --> $DIR/fn_params_excessive_bools.rs:21:1 diff --git a/src/tools/clippy/tests/ui/for_loops_over_fallibles.stderr b/src/tools/clippy/tests/ui/for_loops_over_fallibles.stderr index 8c8c022243a..68d2735b040 100644 --- a/src/tools/clippy/tests/ui/for_loops_over_fallibles.stderr +++ b/src/tools/clippy/tests/ui/for_loops_over_fallibles.stderr @@ -4,8 +4,8 @@ error: for loop over `option`, which is an `Option`. This is more readably writt LL | for x in option { | ^^^^^^ | - = note: `-D clippy::for-loops-over-fallibles` implied by `-D warnings` = help: consider replacing `for x in option` with `if let Some(x) = option` + = note: `-D clippy::for-loops-over-fallibles` implied by `-D warnings` error: for loop over `option`, which is an `Option`. This is more readably written as an `if let` statement --> $DIR/for_loops_over_fallibles.rs:14:14 diff --git a/src/tools/clippy/tests/ui/forget_non_drop.stderr b/src/tools/clippy/tests/ui/forget_non_drop.stderr index 03fb00960a4..194e37c8b42 100644 --- a/src/tools/clippy/tests/ui/forget_non_drop.stderr +++ b/src/tools/clippy/tests/ui/forget_non_drop.stderr @@ -4,12 +4,12 @@ error: call to `std::mem::forget` with a value that does not implement `Drop`. F LL | forget(Foo); | ^^^^^^^^^^^ | - = note: `-D clippy::forget-non-drop` implied by `-D warnings` note: argument has type `main::Foo` --> $DIR/forget_non_drop.rs:13:12 | LL | forget(Foo); | ^^^ + = note: `-D clippy::forget-non-drop` implied by `-D warnings` error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it --> $DIR/forget_non_drop.rs:24:5 diff --git a/src/tools/clippy/tests/ui/forget_ref.stderr b/src/tools/clippy/tests/ui/forget_ref.stderr index df5cd8cacdb..011cdefc665 100644 --- a/src/tools/clippy/tests/ui/forget_ref.stderr +++ b/src/tools/clippy/tests/ui/forget_ref.stderr @@ -4,12 +4,12 @@ error: calls to `std::mem::forget` with a reference instead of an owned value. F LL | forget(&SomeStruct); | ^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::forget-ref` implied by `-D warnings` note: argument has type `&SomeStruct` --> $DIR/forget_ref.rs:11:12 | LL | forget(&SomeStruct); | ^^^^^^^^^^^ + = note: `-D clippy::forget-ref` implied by `-D warnings` error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing --> $DIR/forget_ref.rs:14:5 diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.stderr b/src/tools/clippy/tests/ui/format_args_unfixable.stderr index 4476218ad58..37a6afb1ba7 100644 --- a/src/tools/clippy/tests/ui/format_args_unfixable.stderr +++ b/src/tools/clippy/tests/ui/format_args_unfixable.stderr @@ -4,9 +4,9 @@ error: `format!` in `println!` args LL | println!("error: {}", format!("something failed at {}", Location::caller())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::format-in-format-args` implied by `-D warnings` = help: combine the `format!(..)` arguments with the outer `println!(..)` call = help: or consider changing `format!` to `format_args!` + = note: `-D clippy::format-in-format-args` implied by `-D warnings` error: `format!` in `println!` args --> $DIR/format_args_unfixable.rs:28:5 diff --git a/src/tools/clippy/tests/ui/format_push_string.stderr b/src/tools/clippy/tests/ui/format_push_string.stderr index 953784bcc06..d7be9a5f206 100644 --- a/src/tools/clippy/tests/ui/format_push_string.stderr +++ b/src/tools/clippy/tests/ui/format_push_string.stderr @@ -4,8 +4,8 @@ error: `format!(..)` appended to existing `String` LL | string += &format!("{:?}", 1234); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::format-push-string` implied by `-D warnings` = help: consider using `write!` to avoid the extra allocation + = note: `-D clippy::format-push-string` implied by `-D warnings` error: `format!(..)` appended to existing `String` --> $DIR/format_push_string.rs:6:5 diff --git a/src/tools/clippy/tests/ui/formatting.stderr b/src/tools/clippy/tests/ui/formatting.stderr index 9272cd60484..caccd5cba17 100644 --- a/src/tools/clippy/tests/ui/formatting.stderr +++ b/src/tools/clippy/tests/ui/formatting.stderr @@ -4,8 +4,8 @@ error: this looks like you are trying to use `.. -= ..`, but you really are doin LL | a =- 35; | ^^^^ | - = note: `-D clippy::suspicious-assignment-formatting` implied by `-D warnings` = note: to remove this lint, use either `-=` or `= -` + = note: `-D clippy::suspicious-assignment-formatting` implied by `-D warnings` error: this looks like you are trying to use `.. *= ..`, but you really are doing `.. = (* ..)` --> $DIR/formatting.rs:17:6 @@ -29,8 +29,8 @@ error: possibly missing a comma here LL | -1, -2, -3 // <= no comma here | ^ | - = note: `-D clippy::possible-missing-comma` implied by `-D warnings` = note: to remove this lint, add a comma or write the expr in a single line + = note: `-D clippy::possible-missing-comma` implied by `-D warnings` error: possibly missing a comma here --> $DIR/formatting.rs:33:19 diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr index 2951e6bdac4..469adadd219 100644 --- a/src/tools/clippy/tests/ui/from_over_into.stderr +++ b/src/tools/clippy/tests/ui/from_over_into.stderr @@ -4,8 +4,8 @@ error: an implementation of `From` is preferred since it gives you `Into<_>` for LL | impl Into<StringWrapper> for String { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::from-over-into` implied by `-D warnings` = help: consider to implement `From<std::string::String>` instead + = note: `-D clippy::from-over-into` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr index a9f2ad36d0a..5b6858e4568 100644 --- a/src/tools/clippy/tests/ui/future_not_send.stderr +++ b/src/tools/clippy/tests/ui/future_not_send.stderr @@ -4,7 +4,6 @@ error: future cannot be sent between threads safely LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool { | ^^^^ future returned by `private_future` is not `Send` | - = note: `-D clippy::future-not-send` implied by `-D warnings` note: future is not `Send` as this value is used across an await --> $DIR/future_not_send.rs:8:19 | @@ -25,6 +24,7 @@ LL | async { true }.await LL | } | - `cell` is later dropped here = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync` + = note: `-D clippy::future-not-send` implied by `-D warnings` error: future cannot be sent between threads safely --> $DIR/future_not_send.rs:11:42 diff --git a/src/tools/clippy/tests/ui/get_unwrap.stderr b/src/tools/clippy/tests/ui/get_unwrap.stderr index ea8fec52735..937f8590408 100644 --- a/src/tools/clippy/tests/ui/get_unwrap.stderr +++ b/src/tools/clippy/tests/ui/get_unwrap.stderr @@ -16,8 +16,8 @@ error: used `unwrap()` on `an Option` value LL | let _ = boxed_slice.get(1).unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::unwrap-used` implied by `-D warnings` = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + = note: `-D clippy::unwrap-used` implied by `-D warnings` error: called `.get().unwrap()` on a slice. Using `[]` is more clear and more concise --> $DIR/get_unwrap.rs:36:17 diff --git a/src/tools/clippy/tests/ui/if_let_mutex.stderr b/src/tools/clippy/tests/ui/if_let_mutex.stderr index 8a4d5dbac59..da0cc25f0ab 100644 --- a/src/tools/clippy/tests/ui/if_let_mutex.stderr +++ b/src/tools/clippy/tests/ui/if_let_mutex.stderr @@ -13,8 +13,8 @@ LL | | do_stuff(lock); LL | | }; | |_____^ | - = note: `-D clippy::if-let-mutex` implied by `-D warnings` = help: move the lock call outside of the `if let ...` expression + = note: `-D clippy::if-let-mutex` implied by `-D warnings` error: calling `Mutex::lock` inside the scope of another `Mutex::lock` causes a deadlock --> $DIR/if_let_mutex.rs:22:5 diff --git a/src/tools/clippy/tests/ui/if_not_else.stderr b/src/tools/clippy/tests/ui/if_not_else.stderr index 8c8cc44bb03..46671c15274 100644 --- a/src/tools/clippy/tests/ui/if_not_else.stderr +++ b/src/tools/clippy/tests/ui/if_not_else.stderr @@ -8,8 +8,8 @@ LL | | println!("Bunny"); LL | | } | |_____^ | - = note: `-D clippy::if-not-else` implied by `-D warnings` = help: remove the `!` and swap the blocks of the `if`/`else` + = note: `-D clippy::if-not-else` implied by `-D warnings` error: unnecessary `!=` operation --> $DIR/if_not_else.rs:17:5 diff --git a/src/tools/clippy/tests/ui/if_same_then_else.stderr b/src/tools/clippy/tests/ui/if_same_then_else.stderr index 2cdf442486a..fb23b81d36d 100644 --- a/src/tools/clippy/tests/ui/if_same_then_else.stderr +++ b/src/tools/clippy/tests/ui/if_same_then_else.stderr @@ -11,7 +11,6 @@ LL | | foo(); LL | | } else { | |_____^ | - = note: `-D clippy::if-same-then-else` implied by `-D warnings` note: same as this --> $DIR/if_same_then_else.rs:31:12 | @@ -24,6 +23,7 @@ LL | | 0..10; LL | | foo(); LL | | } | |_____^ + = note: `-D clippy::if-same-then-else` implied by `-D warnings` error: this `if` has identical blocks --> $DIR/if_same_then_else.rs:67:21 diff --git a/src/tools/clippy/tests/ui/if_same_then_else2.stderr b/src/tools/clippy/tests/ui/if_same_then_else2.stderr index cac788f859d..704cfd9669a 100644 --- a/src/tools/clippy/tests/ui/if_same_then_else2.stderr +++ b/src/tools/clippy/tests/ui/if_same_then_else2.stderr @@ -11,7 +11,6 @@ LL | | } LL | | } else { | |_____^ | - = note: `-D clippy::if-same-then-else` implied by `-D warnings` note: same as this --> $DIR/if_same_then_else2.rs:23:12 | @@ -24,6 +23,7 @@ LL | | let bar: &Option<_> = &Some::<u8>(42); LL | | } LL | | } | |_____^ + = note: `-D clippy::if-same-then-else` implied by `-D warnings` error: this `if` has identical blocks --> $DIR/if_same_then_else2.rs:35:13 diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr index c22ace30d2d..24e0b5947f1 100644 --- a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr +++ b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr @@ -10,8 +10,8 @@ LL | | None LL | | }; | |_____^ | - = note: `-D clippy::if-then-some-else-none` implied by `-D warnings` = help: consider using `bool::then` like: `foo().then(|| { /* snippet */ "foo" })` + = note: `-D clippy::if-then-some-else-none` implied by `-D warnings` error: this could be simplified with `bool::then` --> $DIR/if_then_some_else_none.rs:14:13 diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.stderr b/src/tools/clippy/tests/ui/ifs_same_cond.stderr index 0c8f49b8687..4113087327a 100644 --- a/src/tools/clippy/tests/ui/ifs_same_cond.stderr +++ b/src/tools/clippy/tests/ui/ifs_same_cond.stderr @@ -4,12 +4,12 @@ error: this `if` has the same condition as a previous `if` LL | } else if b { | ^ | - = note: `-D clippy::ifs-same-cond` implied by `-D warnings` note: same as this --> $DIR/ifs_same_cond.rs:8:8 | LL | if b { | ^ + = note: `-D clippy::ifs-same-cond` implied by `-D warnings` error: this `if` has the same condition as a previous `if` --> $DIR/ifs_same_cond.rs:14:15 diff --git a/src/tools/clippy/tests/ui/impl.stderr b/src/tools/clippy/tests/ui/impl.stderr index 8703ecac93e..e28b1bf0cdd 100644 --- a/src/tools/clippy/tests/ui/impl.stderr +++ b/src/tools/clippy/tests/ui/impl.stderr @@ -6,7 +6,6 @@ LL | | fn second() {} LL | | } | |_^ | - = note: `-D clippy::multiple-inherent-impl` implied by `-D warnings` note: first implementation here --> $DIR/impl.rs:6:1 | @@ -14,6 +13,7 @@ LL | / impl MyStruct { LL | | fn first() {} LL | | } | |_^ + = note: `-D clippy::multiple-inherent-impl` implied by `-D warnings` error: multiple implementations of this structure --> $DIR/impl.rs:24:5 diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr index 6ae700753f0..a8d8b38163d 100644 --- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr +++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr @@ -16,8 +16,8 @@ error: indexing may panic LL | x[index]; | ^^^^^^^^ | - = note: `-D clippy::indexing-slicing` implied by `-D warnings` = help: consider using `.get(n)` or `.get_mut(n)` instead + = note: `-D clippy::indexing-slicing` implied by `-D warnings` error: indexing may panic --> $DIR/indexing_slicing_index.rs:38:5 diff --git a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr index f70722b92a5..dc54bd41365 100644 --- a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr +++ b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr @@ -4,8 +4,8 @@ error: slicing may panic LL | &x[index..]; | ^^^^^^^^^^ | - = note: `-D clippy::indexing-slicing` implied by `-D warnings` = help: consider using `.get(n..)` or .get_mut(n..)` instead + = note: `-D clippy::indexing-slicing` implied by `-D warnings` error: slicing may panic --> $DIR/indexing_slicing_slice.rs:13:6 diff --git a/src/tools/clippy/tests/ui/inefficient_to_string.stderr b/src/tools/clippy/tests/ui/inefficient_to_string.stderr index 1c0490ffa44..914dc92bfb6 100644 --- a/src/tools/clippy/tests/ui/inefficient_to_string.stderr +++ b/src/tools/clippy/tests/ui/inefficient_to_string.stderr @@ -4,12 +4,12 @@ error: calling `to_string` on `&&str` LL | let _: String = rrstr.to_string(); | ^^^^^^^^^^^^^^^^^ help: try dereferencing the receiver: `(*rrstr).to_string()` | + = help: `&str` implements `ToString` through a slower blanket impl, but `str` has a fast specialization of `ToString` note: the lint level is defined here --> $DIR/inefficient_to_string.rs:2:9 | LL | #![deny(clippy::inefficient_to_string)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: `&str` implements `ToString` through a slower blanket impl, but `str` has a fast specialization of `ToString` error: calling `to_string` on `&&&str` --> $DIR/inefficient_to_string.rs:12:21 diff --git a/src/tools/clippy/tests/ui/infinite_loop.stderr b/src/tools/clippy/tests/ui/infinite_loop.stderr index 4ec7d900ade..85258b9d64f 100644 --- a/src/tools/clippy/tests/ui/infinite_loop.stderr +++ b/src/tools/clippy/tests/ui/infinite_loop.stderr @@ -4,8 +4,8 @@ error: variables in the condition are not mutated in the loop body LL | while y < 10 { | ^^^^^^ | - = note: `#[deny(clippy::while_immutable_condition)]` on by default = note: this may lead to an infinite or to a never running loop + = note: `#[deny(clippy::while_immutable_condition)]` on by default error: variables in the condition are not mutated in the loop body --> $DIR/infinite_loop.rs:25:11 diff --git a/src/tools/clippy/tests/ui/inherent_to_string.stderr b/src/tools/clippy/tests/ui/inherent_to_string.stderr index 4f331f5bec9..443fecae1aa 100644 --- a/src/tools/clippy/tests/ui/inherent_to_string.stderr +++ b/src/tools/clippy/tests/ui/inherent_to_string.stderr @@ -6,8 +6,8 @@ LL | | "A.to_string()".to_string() LL | | } | |_____^ | - = note: `-D clippy::inherent-to-string` implied by `-D warnings` = help: implement trait `Display` for type `A` instead + = note: `-D clippy::inherent-to-string` implied by `-D warnings` error: type `C` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display` --> $DIR/inherent_to_string.rs:44:5 @@ -17,12 +17,12 @@ LL | | "C.to_string()".to_string() LL | | } | |_____^ | + = help: remove the inherent method from type `C` note: the lint level is defined here --> $DIR/inherent_to_string.rs:2:9 | LL | #![deny(clippy::inherent_to_string_shadow_display)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: remove the inherent method from type `C` error: aborting due to 2 previous errors diff --git a/src/tools/clippy/tests/ui/inspect_for_each.stderr b/src/tools/clippy/tests/ui/inspect_for_each.stderr index 9f976bb7458..67c2d5e53c7 100644 --- a/src/tools/clippy/tests/ui/inspect_for_each.stderr +++ b/src/tools/clippy/tests/ui/inspect_for_each.stderr @@ -9,8 +9,8 @@ LL | | b.push(z); LL | | }); | |______^ | - = note: `-D clippy::inspect-for-each` implied by `-D warnings` = help: move the code from `inspect(..)` to `for_each(..)` and remove the `inspect(..)` + = note: `-D clippy::inspect-for-each` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/integer_division.stderr b/src/tools/clippy/tests/ui/integer_division.stderr index cbb7f881424..ca800127920 100644 --- a/src/tools/clippy/tests/ui/integer_division.stderr +++ b/src/tools/clippy/tests/ui/integer_division.stderr @@ -4,8 +4,8 @@ error: integer division LL | let n = 1 / 2; | ^^^^^ | - = note: `-D clippy::integer-division` implied by `-D warnings` = help: division of integers may cause loss of precision. consider using floats + = note: `-D clippy::integer-division` implied by `-D warnings` error: integer division --> $DIR/integer_division.rs:6:13 diff --git a/src/tools/clippy/tests/ui/issue_4266.stderr b/src/tools/clippy/tests/ui/issue_4266.stderr index e5042aaa776..240f4bcc38f 100644 --- a/src/tools/clippy/tests/ui/issue_4266.stderr +++ b/src/tools/clippy/tests/ui/issue_4266.stderr @@ -18,8 +18,8 @@ error: methods called `new` usually take no `self` LL | pub async fn new(&mut self) -> Self { | ^^^^^^^^^ | - = note: `-D clippy::wrong-self-convention` implied by `-D warnings` = help: consider choosing a less ambiguous name + = note: `-D clippy::wrong-self-convention` implied by `-D warnings` error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/iter_nth.stderr b/src/tools/clippy/tests/ui/iter_nth.stderr index d00b2fb672b..a0fe353bcf7 100644 --- a/src/tools/clippy/tests/ui/iter_nth.stderr +++ b/src/tools/clippy/tests/ui/iter_nth.stderr @@ -4,8 +4,8 @@ error: called `.iter().nth()` on a Vec LL | let bad_vec = some_vec.iter().nth(3); | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::iter-nth` implied by `-D warnings` = help: calling `.get()` is both faster and more readable + = note: `-D clippy::iter-nth` implied by `-D warnings` error: called `.iter().nth()` on a slice --> $DIR/iter_nth.rs:34:26 diff --git a/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr b/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr index 74c327c7483..4062706f942 100644 --- a/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr +++ b/src/tools/clippy/tests/ui/iter_skip_next_unfixable.stderr @@ -4,12 +4,12 @@ error: called `skip(..).next()` on an iterator LL | let _: Vec<&str> = sp.skip(1).next().unwrap().split(' ').collect(); | ^^^^^^^^^^^^^^^ help: use `nth` instead: `.nth(1)` | - = note: `-D clippy::iter-skip-next` implied by `-D warnings` help: for this change `sp` has to be mutable --> $DIR/iter_skip_next_unfixable.rs:8:9 | LL | let sp = test_string.split('|').map(|s| s.trim()); | ^^ + = note: `-D clippy::iter-skip-next` implied by `-D warnings` error: called `skip(..).next()` on an iterator --> $DIR/iter_skip_next_unfixable.rs:11:29 diff --git a/src/tools/clippy/tests/ui/large_stack_arrays.stderr b/src/tools/clippy/tests/ui/large_stack_arrays.stderr index 0d91b65b428..c7bf941ad00 100644 --- a/src/tools/clippy/tests/ui/large_stack_arrays.stderr +++ b/src/tools/clippy/tests/ui/large_stack_arrays.stderr @@ -4,8 +4,8 @@ error: allocating a local array larger than 512000 bytes LL | [0u32; 20_000_000], | ^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::large-stack-arrays` implied by `-D warnings` = help: consider allocating on the heap with `vec![0u32; 20_000_000].into_boxed_slice()` + = note: `-D clippy::large-stack-arrays` implied by `-D warnings` error: allocating a local array larger than 512000 bytes --> $DIR/large_stack_arrays.rs:24:9 diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.stderr b/src/tools/clippy/tests/ui/len_without_is_empty.stderr index a1f48f7610b..8e890e2e259 100644 --- a/src/tools/clippy/tests/ui/len_without_is_empty.stderr +++ b/src/tools/clippy/tests/ui/len_without_is_empty.stderr @@ -92,8 +92,8 @@ error: this returns a `Result<_, ()>` LL | pub fn len(&self) -> Result<usize, ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::result-unit-err` implied by `-D warnings` = help: use a custom `Error` type instead + = note: `-D clippy::result-unit-err` implied by `-D warnings` error: this returns a `Result<_, ()>` --> $DIR/len_without_is_empty.rs:240:5 diff --git a/src/tools/clippy/tests/ui/let_if_seq.stderr b/src/tools/clippy/tests/ui/let_if_seq.stderr index 271ccce681c..f2e0edb6fbc 100644 --- a/src/tools/clippy/tests/ui/let_if_seq.stderr +++ b/src/tools/clippy/tests/ui/let_if_seq.stderr @@ -7,8 +7,8 @@ LL | | foo = 42; LL | | } | |_____^ help: it is more idiomatic to write: `let <mut> foo = if f() { 42 } else { 0 };` | - = note: `-D clippy::useless-let-if-seq` implied by `-D warnings` = note: you might not need `mut` at all + = note: `-D clippy::useless-let-if-seq` implied by `-D warnings` error: `if _ { .. } else { .. }` is an expression --> $DIR/let_if_seq.rs:71:5 diff --git a/src/tools/clippy/tests/ui/let_underscore_drop.stderr b/src/tools/clippy/tests/ui/let_underscore_drop.stderr index ee7bbe995f1..324b7cd431d 100644 --- a/src/tools/clippy/tests/ui/let_underscore_drop.stderr +++ b/src/tools/clippy/tests/ui/let_underscore_drop.stderr @@ -4,8 +4,8 @@ error: non-binding `let` on a type that implements `Drop` LL | let _ = Box::new(()); | ^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::let-underscore-drop` implied by `-D warnings` = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop` + = note: `-D clippy::let-underscore-drop` implied by `-D warnings` error: non-binding `let` on a type that implements `Drop` --> $DIR/let_underscore_drop.rs:18:5 diff --git a/src/tools/clippy/tests/ui/let_underscore_lock.stderr b/src/tools/clippy/tests/ui/let_underscore_lock.stderr index 4365b48fabb..d7779e7b6c4 100644 --- a/src/tools/clippy/tests/ui/let_underscore_lock.stderr +++ b/src/tools/clippy/tests/ui/let_underscore_lock.stderr @@ -4,8 +4,8 @@ error: non-binding let on a synchronization lock LL | let _ = m.lock(); | ^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::let-underscore-lock` implied by `-D warnings` = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop` + = note: `-D clippy::let-underscore-lock` implied by `-D warnings` error: non-binding let on a synchronization lock --> $DIR/let_underscore_lock.rs:10:5 diff --git a/src/tools/clippy/tests/ui/let_underscore_must_use.stderr b/src/tools/clippy/tests/ui/let_underscore_must_use.stderr index 5b751ea56de..bae60f2ff9b 100644 --- a/src/tools/clippy/tests/ui/let_underscore_must_use.stderr +++ b/src/tools/clippy/tests/ui/let_underscore_must_use.stderr @@ -4,8 +4,8 @@ error: non-binding let on a result of a `#[must_use]` function LL | let _ = f(); | ^^^^^^^^^^^^ | - = note: `-D clippy::let-underscore-must-use` implied by `-D warnings` = help: consider explicitly using function result + = note: `-D clippy::let-underscore-must-use` implied by `-D warnings` error: non-binding let on an expression with `#[must_use]` type --> $DIR/let_underscore_must_use.rs:68:5 diff --git a/src/tools/clippy/tests/ui/linkedlist.stderr b/src/tools/clippy/tests/ui/linkedlist.stderr index 51327df1321..c76c9496131 100644 --- a/src/tools/clippy/tests/ui/linkedlist.stderr +++ b/src/tools/clippy/tests/ui/linkedlist.stderr @@ -4,8 +4,8 @@ error: you seem to be using a `LinkedList`! Perhaps you meant some other data st LL | const C: LinkedList<i32> = LinkedList::new(); | ^^^^^^^^^^^^^^^ | - = note: `-D clippy::linkedlist` implied by `-D warnings` = help: a `VecDeque` might work + = note: `-D clippy::linkedlist` implied by `-D warnings` error: you seem to be using a `LinkedList`! Perhaps you meant some other data structure? --> $DIR/linkedlist.rs:9:11 diff --git a/src/tools/clippy/tests/ui/manual_find.stderr b/src/tools/clippy/tests/ui/manual_find.stderr index da0fd4aaef7..ea04bb066e6 100644 --- a/src/tools/clippy/tests/ui/manual_find.stderr +++ b/src/tools/clippy/tests/ui/manual_find.stderr @@ -9,8 +9,8 @@ LL | | } LL | | None | |________^ help: replace with an iterator: `strings.into_iter().find(|s| s == String::new())` | - = note: `-D clippy::manual-find` implied by `-D warnings` = note: you may need to dereference some variables + = note: `-D clippy::manual-find` implied by `-D warnings` error: manual implementation of `Iterator::find` --> $DIR/manual_find.rs:14:5 diff --git a/src/tools/clippy/tests/ui/manual_flatten.stderr b/src/tools/clippy/tests/ui/manual_flatten.stderr index da053c05668..180a6ff4e9a 100644 --- a/src/tools/clippy/tests/ui/manual_flatten.stderr +++ b/src/tools/clippy/tests/ui/manual_flatten.stderr @@ -11,7 +11,6 @@ LL | | } LL | | } | |_____^ | - = note: `-D clippy::manual-flatten` implied by `-D warnings` help: ...and remove the `if let` statement in the for loop --> $DIR/manual_flatten.rs:8:9 | @@ -19,6 +18,7 @@ LL | / if let Some(y) = n { LL | | println!("{}", y); LL | | } | |_________^ + = note: `-D clippy::manual-flatten` implied by `-D warnings` error: unnecessary `if let` since only the `Ok` variant of the iterator element is used --> $DIR/manual_flatten.rs:15:5 diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr index 144fe86df55..087f766be70 100644 --- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr +++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr @@ -13,12 +13,12 @@ LL | | _C, LL | | } | |_^ | - = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings` help: remove this variant --> $DIR/manual_non_exhaustive_enum.rs:9:5 | LL | _C, | ^^ + = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings` error: this seems like a manual implementation of the non-exhaustive pattern --> $DIR/manual_non_exhaustive_enum.rs:14:1 diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr index e0766c17b75..d0bed8e1121 100644 --- a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr +++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr @@ -12,12 +12,12 @@ LL | | _c: (), LL | | } | |_____^ | - = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings` help: remove this field --> $DIR/manual_non_exhaustive_struct.rs:8:9 | LL | _c: (), | ^^^^^^ + = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings` error: this seems like a manual implementation of the non-exhaustive pattern --> $DIR/manual_non_exhaustive_struct.rs:13:5 diff --git a/src/tools/clippy/tests/ui/manual_strip.stderr b/src/tools/clippy/tests/ui/manual_strip.stderr index 896edf2ae51..2191ccb85dd 100644 --- a/src/tools/clippy/tests/ui/manual_strip.stderr +++ b/src/tools/clippy/tests/ui/manual_strip.stderr @@ -4,12 +4,12 @@ error: stripping a prefix manually LL | str::to_string(&s["ab".len()..]); | ^^^^^^^^^^^^^^^^ | - = note: `-D clippy::manual-strip` implied by `-D warnings` note: the prefix was tested here --> $DIR/manual_strip.rs:6:5 | LL | if s.starts_with("ab") { | ^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::manual-strip` implied by `-D warnings` help: try using the `strip_prefix` method | LL ~ if let Some(<stripped>) = s.strip_prefix("ab") { diff --git a/src/tools/clippy/tests/ui/map_err.stderr b/src/tools/clippy/tests/ui/map_err.stderr index c035840521e..d44403a84a5 100644 --- a/src/tools/clippy/tests/ui/map_err.stderr +++ b/src/tools/clippy/tests/ui/map_err.stderr @@ -4,8 +4,8 @@ error: `map_err(|_|...` wildcard pattern discards the original error LL | println!("{:?}", x.map_err(|_| Errors::Ignored)); | ^^^ | - = note: `-D clippy::map-err-ignore` implied by `-D warnings` = help: consider storing the original error as a source in the new error, or silence this warning using an ignored identifier (`.map_err(|_foo| ...`) + = note: `-D clippy::map-err-ignore` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr index b81bb1ecfae..a72becbeb66 100644 --- a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr +++ b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr @@ -4,12 +4,12 @@ error: some ranges overlap LL | 0..=10 => println!("0..=10"), | ^^^^^^ | - = note: `-D clippy::match-overlapping-arm` implied by `-D warnings` note: overlaps with this --> $DIR/match_overlapping_arm.rs:14:9 | LL | 0..=11 => println!("0..=11"), | ^^^^^^ + = note: `-D clippy::match-overlapping-arm` implied by `-D warnings` error: some ranges overlap --> $DIR/match_overlapping_arm.rs:19:9 diff --git a/src/tools/clippy/tests/ui/match_same_arms.stderr b/src/tools/clippy/tests/ui/match_same_arms.stderr index b6d04263b37..db85b5964e8 100644 --- a/src/tools/clippy/tests/ui/match_same_arms.stderr +++ b/src/tools/clippy/tests/ui/match_same_arms.stderr @@ -4,13 +4,13 @@ error: this match arm has an identical body to the `_` wildcard arm LL | Abc::A => 0, | ^^^^^^^^^^^ help: try removing the arm | - = note: `-D clippy::match-same-arms` implied by `-D warnings` = help: or try changing either arm body note: `_` wildcard arm here --> $DIR/match_same_arms.rs:13:9 | LL | _ => 0, //~ ERROR match arms have same body | ^^^^^^ + = note: `-D clippy::match-same-arms` implied by `-D warnings` error: this match arm has an identical body to another arm --> $DIR/match_same_arms.rs:17:9 diff --git a/src/tools/clippy/tests/ui/match_same_arms2.stderr b/src/tools/clippy/tests/ui/match_same_arms2.stderr index 14a672ba2fe..b260155d218 100644 --- a/src/tools/clippy/tests/ui/match_same_arms2.stderr +++ b/src/tools/clippy/tests/ui/match_same_arms2.stderr @@ -10,7 +10,6 @@ LL | | a LL | | }, | |_________^ help: try removing the arm | - = note: `-D clippy::match-same-arms` implied by `-D warnings` = help: or try changing either arm body note: `_` wildcard arm here --> $DIR/match_same_arms2.rs:20:9 @@ -23,6 +22,7 @@ LL | | let mut a = 42 + [23].len() as i32; LL | | a LL | | }, | |_________^ + = note: `-D clippy::match-same-arms` implied by `-D warnings` error: this match arm has an identical body to another arm --> $DIR/match_same_arms2.rs:34:9 diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr index 2d66daea804..525533bf07b 100644 --- a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr +++ b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2018.stderr @@ -4,8 +4,8 @@ error: `Err(_)` matches all errors LL | Err(_) => panic!("err"), | ^^^^^^ | - = note: `-D clippy::match-wild-err-arm` implied by `-D warnings` = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable + = note: `-D clippy::match-wild-err-arm` implied by `-D warnings` error: `Err(_)` matches all errors --> $DIR/match_wild_err_arm.rs:20:9 diff --git a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr index 2d66daea804..525533bf07b 100644 --- a/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr +++ b/src/tools/clippy/tests/ui/match_wild_err_arm.edition2021.stderr @@ -4,8 +4,8 @@ error: `Err(_)` matches all errors LL | Err(_) => panic!("err"), | ^^^^^^ | - = note: `-D clippy::match-wild-err-arm` implied by `-D warnings` = note: match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable + = note: `-D clippy::match-wild-err-arm` implied by `-D warnings` error: `Err(_)` matches all errors --> $DIR/match_wild_err_arm.rs:20:9 diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr index b1c23b539ff..6e749d2741c 100644 --- a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr +++ b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr @@ -4,12 +4,12 @@ error: stripping a prefix manually LL | assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!"); | ^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::manual-strip` implied by `-D warnings` note: the prefix was tested here --> $DIR/min_rust_version_attr.rs:203:9 | LL | if s.starts_with("hello, ") { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::manual-strip` implied by `-D warnings` help: try using the `strip_prefix` method | LL ~ if let Some(<stripped>) = s.strip_prefix("hello, ") { diff --git a/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr b/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr index 3534b53282f..9822c77c9df 100644 --- a/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr +++ b/src/tools/clippy/tests/ui/mismatched_target_os_unix.stderr @@ -6,8 +6,8 @@ LL | #[cfg(linux)] | | | help: try: `target_os = "linux"` | - = note: `-D clippy::mismatched-target-os` implied by `-D warnings` = help: did you mean `unix`? + = note: `-D clippy::mismatched-target-os` implied by `-D warnings` error: operating system used in target family position --> $DIR/mismatched_target_os_unix.rs:9:1 diff --git a/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr b/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr index cb720256c50..204d4990557 100644 --- a/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr +++ b/src/tools/clippy/tests/ui/mismatching_type_param_order.stderr @@ -4,8 +4,8 @@ error: `Foo` has a similarly named generic type parameter `B` in its declaration LL | impl<B, A> Foo<B, A> {} | ^ | - = note: `-D clippy::mismatching-type-param-order` implied by `-D warnings` = help: try `A`, or a name that does not conflict with `Foo`'s generic params + = note: `-D clippy::mismatching-type-param-order` implied by `-D warnings` error: `Foo` has a similarly named generic type parameter `A` in its declaration, but in a different order --> $DIR/mismatching_type_param_order.rs:11:23 diff --git a/src/tools/clippy/tests/ui/missing_panics_doc.stderr b/src/tools/clippy/tests/ui/missing_panics_doc.stderr index 91ebd695238..c9ded7f1ad0 100644 --- a/src/tools/clippy/tests/ui/missing_panics_doc.stderr +++ b/src/tools/clippy/tests/ui/missing_panics_doc.stderr @@ -7,12 +7,12 @@ LL | | result.unwrap() LL | | } | |_^ | - = note: `-D clippy::missing-panics-doc` implied by `-D warnings` note: first possible panic found here --> $DIR/missing_panics_doc.rs:8:5 | LL | result.unwrap() | ^^^^^^^^^^^^^^^ + = note: `-D clippy::missing-panics-doc` implied by `-D warnings` error: docs for function which may panic missing `# Panics` section --> $DIR/missing_panics_doc.rs:12:1 diff --git a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr index 2e951cdbcbf..8cc68b0ac7b 100644 --- a/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr +++ b/src/tools/clippy/tests/ui/mixed_read_write_in_expression.stderr @@ -4,12 +4,12 @@ error: unsequenced read of `x` LL | } + x; | ^ | - = note: `-D clippy::mixed-read-write-in-expression` implied by `-D warnings` note: whether read occurs before this write depends on evaluation order --> $DIR/mixed_read_write_in_expression.rs:12:9 | LL | x = 1; | ^^^^^ + = note: `-D clippy::mixed-read-write-in-expression` implied by `-D warnings` error: unsequenced read of `x` --> $DIR/mixed_read_write_in_expression.rs:17:5 diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr index 97844aaaa75..36106de31f0 100644 --- a/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr +++ b/src/tools/clippy/tests/ui/modulo_arithmetic_float.stderr @@ -4,8 +4,8 @@ error: you are using modulo operator on constants with different signs: `-1.600 LL | -1.6 % 2.1; | ^^^^^^^^^^ | - = note: `-D clippy::modulo-arithmetic` implied by `-D warnings` = note: double check for expected result especially when interoperating with different languages + = note: `-D clippy::modulo-arithmetic` implied by `-D warnings` error: you are using modulo operator on constants with different signs: `1.600 % -2.100` --> $DIR/modulo_arithmetic_float.rs:7:5 diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr index f71adf5b0d0..9ff676ff6bc 100644 --- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr +++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.stderr @@ -4,9 +4,9 @@ error: you are using modulo operator on types that might have different signs LL | a % b; | ^^^^^ | - = note: `-D clippy::modulo-arithmetic` implied by `-D warnings` = note: double check for expected result especially when interoperating with different languages = note: or consider using `rem_euclid` or similar function + = note: `-D clippy::modulo-arithmetic` implied by `-D warnings` error: you are using modulo operator on types that might have different signs --> $DIR/modulo_arithmetic_integral.rs:9:5 diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr index 11b5f77461b..1453d44f488 100644 --- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr +++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr @@ -4,9 +4,9 @@ error: you are using modulo operator on constants with different signs: `-1 % 2` LL | -1 % 2; | ^^^^^^ | - = note: `-D clippy::modulo-arithmetic` implied by `-D warnings` = note: double check for expected result especially when interoperating with different languages = note: or consider using `rem_euclid` or similar function + = note: `-D clippy::modulo-arithmetic` implied by `-D warnings` error: you are using modulo operator on constants with different signs: `1 % -2` --> $DIR/modulo_arithmetic_integral_const.rs:12:5 diff --git a/src/tools/clippy/tests/ui/mut_from_ref.stderr b/src/tools/clippy/tests/ui/mut_from_ref.stderr index b76d6a13ffb..c20ff54bf94 100644 --- a/src/tools/clippy/tests/ui/mut_from_ref.stderr +++ b/src/tools/clippy/tests/ui/mut_from_ref.stderr @@ -4,12 +4,12 @@ error: mutable borrow from immutable input(s) LL | fn this_wont_hurt_a_bit(&self) -> &mut Foo { | ^^^^^^^^ | - = note: `-D clippy::mut-from-ref` implied by `-D warnings` note: immutable borrow here --> $DIR/mut_from_ref.rs:7:29 | LL | fn this_wont_hurt_a_bit(&self) -> &mut Foo { | ^^^^^ + = note: `-D clippy::mut-from-ref` implied by `-D warnings` error: mutable borrow from immutable input(s) --> $DIR/mut_from_ref.rs:13:25 diff --git a/src/tools/clippy/tests/ui/mut_range_bound.stderr b/src/tools/clippy/tests/ui/mut_range_bound.stderr index 4b5a3fc1e41..e0c8dced382 100644 --- a/src/tools/clippy/tests/ui/mut_range_bound.stderr +++ b/src/tools/clippy/tests/ui/mut_range_bound.stderr @@ -4,8 +4,8 @@ error: attempt to mutate range bound within loop LL | m = 5; | ^ | - = note: `-D clippy::mut-range-bound` implied by `-D warnings` = note: the range of the loop is unchanged + = note: `-D clippy::mut-range-bound` implied by `-D warnings` error: attempt to mutate range bound within loop --> $DIR/mut_range_bound.rs:15:9 diff --git a/src/tools/clippy/tests/ui/needless_continue.stderr b/src/tools/clippy/tests/ui/needless_continue.stderr index b8657c74caa..005ba010f34 100644 --- a/src/tools/clippy/tests/ui/needless_continue.stderr +++ b/src/tools/clippy/tests/ui/needless_continue.stderr @@ -7,7 +7,6 @@ LL | | continue; LL | | } | |_________^ | - = note: `-D clippy::needless-continue` implied by `-D warnings` = help: consider dropping the `else` clause and merging the code that follows (in the loop) with the `if` block if i % 2 == 0 && i % 3 == 0 { println!("{}", i); @@ -33,6 +32,7 @@ LL | | } } println!("bleh"); } + = note: `-D clippy::needless-continue` implied by `-D warnings` error: there is no need for an explicit `else` block for this `if` expression --> $DIR/needless_continue.rs:44:9 diff --git a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr index b6c904a147a..e912b59a6e7 100644 --- a/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr +++ b/src/tools/clippy/tests/ui/non_send_fields_in_send_ty.stderr @@ -4,13 +4,13 @@ error: some fields in `RingBuffer<T>` are not safe to be sent to another thread LL | unsafe impl<T> Send for RingBuffer<T> {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings` note: it is not safe to send field `data` to another thread --> $DIR/non_send_fields_in_send_ty.rs:12:5 | LL | data: Vec<UnsafeCell<T>>, | ^^^^^^^^^^^^^^^^^^^^^^^^ = help: add bounds on type parameter `T` that satisfy `Vec<UnsafeCell<T>>: Send` + = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings` error: some fields in `MvccRwLock<T>` are not safe to be sent to another thread --> $DIR/non_send_fields_in_send_ty.rs:25:1 diff --git a/src/tools/clippy/tests/ui/octal_escapes.stderr b/src/tools/clippy/tests/ui/octal_escapes.stderr index 54f5bbb0fc4..295dc1798e3 100644 --- a/src/tools/clippy/tests/ui/octal_escapes.stderr +++ b/src/tools/clippy/tests/ui/octal_escapes.stderr @@ -4,8 +4,8 @@ error: octal-looking escape in string literal LL | let _bad1 = "/033[0m"; | ^^^^^^^^^ | - = note: `-D clippy::octal-escapes` implied by `-D warnings` = help: octal escapes are not supported, `/0` is always a null character + = note: `-D clippy::octal-escapes` implied by `-D warnings` help: if an octal escape was intended, use the hexadecimal representation instead | LL | let _bad1 = "/x1b[0m"; diff --git a/src/tools/clippy/tests/ui/ok_expect.stderr b/src/tools/clippy/tests/ui/ok_expect.stderr index b02b28e7f68..6c40adbb53d 100644 --- a/src/tools/clippy/tests/ui/ok_expect.stderr +++ b/src/tools/clippy/tests/ui/ok_expect.stderr @@ -4,8 +4,8 @@ error: called `ok().expect()` on a `Result` value LL | res.ok().expect("disaster!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::ok-expect` implied by `-D warnings` = help: you can call `expect()` directly on the `Result` + = note: `-D clippy::ok-expect` implied by `-D warnings` error: called `ok().expect()` on a `Result` value --> $DIR/ok_expect.rs:20:5 diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr index 74057ddcfda..571e5c4b5fa 100644 --- a/src/tools/clippy/tests/ui/only_used_in_recursion.stderr +++ b/src/tools/clippy/tests/ui/only_used_in_recursion.stderr @@ -4,12 +4,12 @@ error: parameter is only used in recursion LL | fn _one_unused(flag: u32, a: usize) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_a` | - = note: `-D clippy::only-used-in-recursion` implied by `-D warnings` note: parameter used here --> $DIR/only_used_in_recursion.rs:12:53 | LL | if flag == 0 { 0 } else { _one_unused(flag - 1, a) } | ^ + = note: `-D clippy::only-used-in-recursion` implied by `-D warnings` error: parameter is only used in recursion --> $DIR/only_used_in_recursion.rs:15:27 diff --git a/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr index 23f6ffd30c9..8dcbfdd612e 100644 --- a/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr +++ b/src/tools/clippy/tests/ui/only_used_in_recursion2.stderr @@ -4,12 +4,12 @@ error: parameter is only used in recursion LL | fn _with_inner(flag: u32, a: u32, b: u32) -> usize { | ^ help: if this is intentional, prefix it with an underscore: `_b` | - = note: `-D clippy::only-used-in-recursion` implied by `-D warnings` note: parameter used here --> $DIR/only_used_in_recursion2.rs:9:52 | LL | if flag == 0 { 0 } else { _with_inner(flag, a, b + x) } | ^ + = note: `-D clippy::only-used-in-recursion` implied by `-D warnings` error: parameter is only used in recursion --> $DIR/only_used_in_recursion2.rs:4:25 diff --git a/src/tools/clippy/tests/ui/option_env_unwrap.stderr b/src/tools/clippy/tests/ui/option_env_unwrap.stderr index 885ac096cc8..bc188a07e9e 100644 --- a/src/tools/clippy/tests/ui/option_env_unwrap.stderr +++ b/src/tools/clippy/tests/ui/option_env_unwrap.stderr @@ -4,8 +4,8 @@ error: this will panic at run-time if the environment variable doesn't exist at LL | let _ = option_env!("PATH").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::option-env-unwrap` implied by `-D warnings` = help: consider using the `env!` macro instead + = note: `-D clippy::option-env-unwrap` implied by `-D warnings` error: this will panic at run-time if the environment variable doesn't exist at compile-time --> $DIR/option_env_unwrap.rs:19:13 diff --git a/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr index 158cae8b8f3..e989f2ece30 100644 --- a/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr +++ b/src/tools/clippy/tests/ui/overly_complex_bool_expr.stderr @@ -4,12 +4,12 @@ error: this boolean expression contains a logic bug LL | let _ = a && b || a; | ^^^^^^^^^^^ help: it would look like the following: `a` | - = note: `-D clippy::overly-complex-bool-expr` implied by `-D warnings` help: this expression can be optimized out by applying boolean operations to the outer expression --> $DIR/overly_complex_bool_expr.rs:11:18 | LL | let _ = a && b || a; | ^ + = note: `-D clippy::overly-complex-bool-expr` implied by `-D warnings` error: this boolean expression contains a logic bug --> $DIR/overly_complex_bool_expr.rs:13:13 diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr index 561503ae54f..97787bc84e2 100644 --- a/src/tools/clippy/tests/ui/panic_in_result_fn.stderr +++ b/src/tools/clippy/tests/ui/panic_in_result_fn.stderr @@ -7,13 +7,13 @@ LL | | panic!("error"); LL | | } | |_____^ | - = note: `-D clippy::panic-in-result-fn` implied by `-D warnings` = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking --> $DIR/panic_in_result_fn.rs:8:9 | LL | panic!("error"); | ^^^^^^^^^^^^^^^ + = note: `-D clippy::panic-in-result-fn` implied by `-D warnings` error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` --> $DIR/panic_in_result_fn.rs:11:5 diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr index b6aa005e7b5..eb0aacbb6a4 100644 --- a/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr +++ b/src/tools/clippy/tests/ui/panic_in_result_fn_assertions.stderr @@ -8,13 +8,13 @@ LL | | Ok(true) LL | | } | |_____^ | - = note: `-D clippy::panic-in-result-fn` implied by `-D warnings` = help: `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertions should not be used in a function that returns `Result` as `Result` is expected to return an error instead of crashing note: return Err() instead of panicking --> $DIR/panic_in_result_fn_assertions.rs:9:9 | LL | assert!(x == 5, "wrong argument"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::panic-in-result-fn` implied by `-D warnings` error: used `unimplemented!()`, `unreachable!()`, `todo!()`, `panic!()` or assertion in a function that returns `Result` --> $DIR/panic_in_result_fn_assertions.rs:13:5 diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr index 3421d568365..87fb243b65e 100644 --- a/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr +++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/mutability.stderr @@ -4,8 +4,8 @@ error: type of pattern does not match the expression type LL | Some(_) => (), | ^^^^^^^ | - = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` error: type of pattern does not match the expression type --> $DIR/mutability.rs:15:9 diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr index d285c93782c..a91b5ac6cf7 100644 --- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr +++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_alternatives.stderr @@ -4,8 +4,8 @@ error: type of pattern does not match the expression type LL | if let Value::B | Value::A(_) = ref_value {} | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` error: type of pattern does not match the expression type --> $DIR/pattern_alternatives.rs:16:34 diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr index d428e85b0c9..8bc5c63baab 100644 --- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr +++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_structs.stderr @@ -4,8 +4,8 @@ error: type of pattern does not match the expression type LL | let Struct { .. } = ref_value; | ^^^^^^^^^^^^^ | - = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` error: type of pattern does not match the expression type --> $DIR/pattern_structs.rs:14:33 diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr index edd0074d00d..a1ef540d283 100644 --- a/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr +++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/pattern_tuples.stderr @@ -4,8 +4,8 @@ error: type of pattern does not match the expression type LL | let TupleStruct(_) = ref_value; | ^^^^^^^^^^^^^^ | - = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` error: type of pattern does not match the expression type --> $DIR/pattern_tuples.rs:12:25 diff --git a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr index 12b3d3a8bd0..f56a3a89380 100644 --- a/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr +++ b/src/tools/clippy/tests/ui/pattern_type_mismatch/syntax.stderr @@ -4,8 +4,8 @@ error: type of pattern does not match the expression type LL | Some(_) => (), | ^^^^^^^ | - = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` = help: use `*` to dereference the match expression or explicitly match against a `&_` pattern and adjust the enclosed variable bindings + = note: `-D clippy::pattern-type-mismatch` implied by `-D warnings` error: type of pattern does not match the expression type --> $DIR/syntax.rs:30:12 diff --git a/src/tools/clippy/tests/ui/proc_macro.stderr b/src/tools/clippy/tests/ui/proc_macro.stderr index 48fd58c9a49..c795f6ad0d2 100644 --- a/src/tools/clippy/tests/ui/proc_macro.stderr +++ b/src/tools/clippy/tests/ui/proc_macro.stderr @@ -4,8 +4,8 @@ error: approximate value of `f{32, 64}::consts::PI` found LL | let _x = 3.14; | ^^^^ | - = note: `#[deny(clippy::approx_constant)]` on by default = help: consider using the constant directly + = note: `#[deny(clippy::approx_constant)]` on by default error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/pub_use.stderr b/src/tools/clippy/tests/ui/pub_use.stderr index 9ab710df818..ba4ee732c05 100644 --- a/src/tools/clippy/tests/ui/pub_use.stderr +++ b/src/tools/clippy/tests/ui/pub_use.stderr @@ -4,8 +4,8 @@ error: using `pub use` LL | pub use inner::Test; | ^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::pub-use` implied by `-D warnings` = help: move the exported item to a public module instead + = note: `-D clippy::pub-use` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr index cd7d91e1206..7814f5b5403 100644 --- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr +++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/arc.stderr @@ -4,8 +4,8 @@ error: initializing a reference-counted pointer in `vec![elem; len]` LL | let v = vec![Arc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings` = note: each element will point to the same `Arc` instance + = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings` help: consider initializing each `Arc` element individually | LL ~ let v = { diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr index fe861afe054..80deb7cb9f2 100644 --- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr +++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/rc.stderr @@ -4,8 +4,8 @@ error: initializing a reference-counted pointer in `vec![elem; len]` LL | let v = vec![Rc::new("x".to_string()); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings` = note: each element will point to the same `Rc` instance + = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings` help: consider initializing each `Rc` element individually | LL ~ let v = { diff --git a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr index 4a21946ccdf..789e14a302f 100644 --- a/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr +++ b/src/tools/clippy/tests/ui/rc_clone_in_vec_init/weak.stderr @@ -4,8 +4,8 @@ error: initializing a reference-counted pointer in `vec![elem; len]` LL | let v = vec![SyncWeak::<u32>::new(); 2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings` = note: each element will point to the same `Weak` instance + = note: `-D clippy::rc-clone-in-vec-init` implied by `-D warnings` help: consider initializing each `Weak` element individually | LL ~ let v = { diff --git a/src/tools/clippy/tests/ui/rc_mutex.stderr b/src/tools/clippy/tests/ui/rc_mutex.stderr index fe84361d781..cee3bd8b224 100644 --- a/src/tools/clippy/tests/ui/rc_mutex.stderr +++ b/src/tools/clippy/tests/ui/rc_mutex.stderr @@ -4,8 +4,8 @@ error: usage of `Rc<Mutex<_>>` LL | foo: Rc<Mutex<i32>>, | ^^^^^^^^^^^^^^ | - = note: `-D clippy::rc-mutex` implied by `-D warnings` = help: consider using `Rc<RefCell<_>>` or `Arc<Mutex<_>>` instead + = note: `-D clippy::rc-mutex` implied by `-D warnings` error: usage of `Rc<Mutex<_>>` --> $DIR/rc_mutex.rs:26:18 diff --git a/src/tools/clippy/tests/ui/redundant_allocation.stderr b/src/tools/clippy/tests/ui/redundant_allocation.stderr index 54d4d88dba8..e0826fefa6c 100644 --- a/src/tools/clippy/tests/ui/redundant_allocation.stderr +++ b/src/tools/clippy/tests/ui/redundant_allocation.stderr @@ -4,9 +4,9 @@ error: usage of `Box<Rc<T>>` LL | pub fn box_test6<T>(foo: Box<Rc<T>>) {} | ^^^^^^^^^^ | - = note: `-D clippy::redundant-allocation` implied by `-D warnings` = note: `Rc<T>` is already on the heap, `Box<Rc<T>>` makes an extra allocation = help: consider using just `Box<T>` or `Rc<T>` + = note: `-D clippy::redundant-allocation` implied by `-D warnings` error: usage of `Box<Arc<T>>` --> $DIR/redundant_allocation.rs:19:30 diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr b/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr index fdd76ef17a5..8dd4a6a2687 100644 --- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr +++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.stderr @@ -4,8 +4,8 @@ error: usage of `Box<&T>` LL | pub fn box_test1<T>(foo: Box<&T>) {} | ^^^^^^^ help: try: `&T` | - = note: `-D clippy::redundant-allocation` implied by `-D warnings` = note: `&T` is already a pointer, `Box<&T>` allocates a pointer on the heap + = note: `-D clippy::redundant-allocation` implied by `-D warnings` error: usage of `Box<&MyStruct>` --> $DIR/redundant_allocation_fixable.rs:28:27 diff --git a/src/tools/clippy/tests/ui/redundant_clone.stderr b/src/tools/clippy/tests/ui/redundant_clone.stderr index aa1dd7cbb45..782590034d0 100644 --- a/src/tools/clippy/tests/ui/redundant_clone.stderr +++ b/src/tools/clippy/tests/ui/redundant_clone.stderr @@ -4,12 +4,12 @@ error: redundant clone LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); | ^^^^^^^^^^^^ help: remove this | - = note: `-D clippy::redundant-clone` implied by `-D warnings` note: this value is dropped without further use --> $DIR/redundant_clone.rs:10:14 | LL | let _s = ["lorem", "ipsum"].join(" ").to_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::redundant-clone` implied by `-D warnings` error: redundant clone --> $DIR/redundant_clone.rs:13:15 diff --git a/src/tools/clippy/tests/ui/redundant_else.stderr b/src/tools/clippy/tests/ui/redundant_else.stderr index 9000cdc814b..de9d00a6024 100644 --- a/src/tools/clippy/tests/ui/redundant_else.stderr +++ b/src/tools/clippy/tests/ui/redundant_else.stderr @@ -7,8 +7,8 @@ LL | | println!("yet don't pull down your hedge."); LL | | } | |_________^ | - = note: `-D clippy::redundant-else` implied by `-D warnings` = help: remove the `else` block and move the contents out + = note: `-D clippy::redundant-else` implied by `-D warnings` error: redundant else block --> $DIR/redundant_else.rs:17:16 diff --git a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr index eb7aa70ee27..23f08103f35 100644 --- a/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr +++ b/src/tools/clippy/tests/ui/redundant_pattern_matching_drop_order.stderr @@ -4,9 +4,9 @@ error: redundant pattern matching, consider using `is_ok()` LL | if let Ok(_) = m.lock() {} | -------^^^^^----------- help: try this: `if m.lock().is_ok()` | - = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` = note: this will change drop order of the result, as well as all temporaries = note: add `#[allow(clippy::redundant_pattern_matching)]` if this is important + = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: redundant pattern matching, consider using `is_err()` --> $DIR/redundant_pattern_matching_drop_order.rs:13:12 diff --git a/src/tools/clippy/tests/ui/regex.stderr b/src/tools/clippy/tests/ui/regex.stderr index 1394a9b63bc..2424644c6f6 100644 --- a/src/tools/clippy/tests/ui/regex.stderr +++ b/src/tools/clippy/tests/ui/regex.stderr @@ -4,8 +4,8 @@ error: trivial regex LL | let pipe_in_wrong_position = Regex::new("|"); | ^^^ | - = note: `-D clippy::trivial-regex` implied by `-D warnings` = help: the regex is unlikely to be useful as it is + = note: `-D clippy::trivial-regex` implied by `-D warnings` error: trivial regex --> $DIR/regex.rs:14:60 diff --git a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr index 57ebd47f8c7..e15633fb1a1 100644 --- a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr +++ b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.stderr @@ -4,8 +4,8 @@ error: unnecessary use of `..` pattern in struct binding. All fields were alread LL | A { a: 5, b: 42, c: "", .. } => {}, // Lint | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::rest-pat-in-fully-bound-structs` implied by `-D warnings` = help: consider removing `..` from this binding + = note: `-D clippy::rest-pat-in-fully-bound-structs` implied by `-D warnings` error: unnecessary use of `..` pattern in struct binding. All fields were already bound --> $DIR/rest_pat_in_fully_bound_structs.rs:23:9 diff --git a/src/tools/clippy/tests/ui/result_large_err.stderr b/src/tools/clippy/tests/ui/result_large_err.stderr index ef19f2854ab..bea101fe20b 100644 --- a/src/tools/clippy/tests/ui/result_large_err.stderr +++ b/src/tools/clippy/tests/ui/result_large_err.stderr @@ -4,8 +4,8 @@ error: the `Err`-variant returned from this function is very large LL | pub fn large_err() -> Result<(), [u8; 512]> { | ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes | - = note: `-D clippy::result-large-err` implied by `-D warnings` = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>` + = note: `-D clippy::result-large-err` implied by `-D warnings` error: the `Err`-variant returned from this function is very large --> $DIR/result_large_err.rs:19:21 diff --git a/src/tools/clippy/tests/ui/result_unit_error.stderr b/src/tools/clippy/tests/ui/result_unit_error.stderr index 8c7573eabda..8393a4bf03b 100644 --- a/src/tools/clippy/tests/ui/result_unit_error.stderr +++ b/src/tools/clippy/tests/ui/result_unit_error.stderr @@ -4,8 +4,8 @@ error: this returns a `Result<_, ()>` LL | pub fn returns_unit_error() -> Result<u32, ()> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::result-unit-err` implied by `-D warnings` = help: use a custom `Error` type instead + = note: `-D clippy::result-unit-err` implied by `-D warnings` error: this returns a `Result<_, ()>` --> $DIR/result_unit_error.rs:12:5 diff --git a/src/tools/clippy/tests/ui/return_self_not_must_use.stderr b/src/tools/clippy/tests/ui/return_self_not_must_use.stderr index 94be87dfa31..34932fe1c2c 100644 --- a/src/tools/clippy/tests/ui/return_self_not_must_use.stderr +++ b/src/tools/clippy/tests/ui/return_self_not_must_use.stderr @@ -4,8 +4,8 @@ error: missing `#[must_use]` attribute on a method returning `Self` LL | fn what(&self) -> Self; | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::return-self-not-must-use` implied by `-D warnings` = help: consider adding the `#[must_use]` attribute to the method or directly to the `Self` type + = note: `-D clippy::return-self-not-must-use` implied by `-D warnings` error: missing `#[must_use]` attribute on a method returning `Self` --> $DIR/return_self_not_must_use.rs:18:5 diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr index cd438b83040..3901546cbd6 100644 --- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr +++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr @@ -4,12 +4,12 @@ error: this `if` has the same function call as a previous `if` LL | } else if function() { | ^^^^^^^^^^ | - = note: `-D clippy::same-functions-in-if-condition` implied by `-D warnings` note: same as this --> $DIR/same_functions_in_if_condition.rs:30:8 | LL | if function() { | ^^^^^^^^^^ + = note: `-D clippy::same-functions-in-if-condition` implied by `-D warnings` error: this `if` has the same function call as a previous `if` --> $DIR/same_functions_in_if_condition.rs:36:15 diff --git a/src/tools/clippy/tests/ui/same_item_push.stderr b/src/tools/clippy/tests/ui/same_item_push.stderr index d9ffa15780a..1d1254d9fcc 100644 --- a/src/tools/clippy/tests/ui/same_item_push.stderr +++ b/src/tools/clippy/tests/ui/same_item_push.stderr @@ -4,8 +4,8 @@ error: it looks like the same item is being pushed into this Vec LL | vec.push(item); | ^^^ | - = note: `-D clippy::same-item-push` implied by `-D warnings` = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item) + = note: `-D clippy::same-item-push` implied by `-D warnings` error: it looks like the same item is being pushed into this Vec --> $DIR/same_item_push.rs:29:9 diff --git a/src/tools/clippy/tests/ui/same_name_method.stderr b/src/tools/clippy/tests/ui/same_name_method.stderr index f55ec9f3cc6..0c6908c0959 100644 --- a/src/tools/clippy/tests/ui/same_name_method.stderr +++ b/src/tools/clippy/tests/ui/same_name_method.stderr @@ -4,12 +4,12 @@ error: method's name is the same as an existing method in a trait LL | fn foo() {} | ^^^^^^^^^^^ | - = note: `-D clippy::same-name-method` implied by `-D warnings` note: existing `foo` defined here --> $DIR/same_name_method.rs:25:13 | LL | fn foo() {} | ^^^^^^^^^^^ + = note: `-D clippy::same-name-method` implied by `-D warnings` error: method's name is the same as an existing method in a trait --> $DIR/same_name_method.rs:35:13 diff --git a/src/tools/clippy/tests/ui/search_is_some.stderr b/src/tools/clippy/tests/ui/search_is_some.stderr index 54760545bce..6bea8c67477 100644 --- a/src/tools/clippy/tests/ui/search_is_some.stderr +++ b/src/tools/clippy/tests/ui/search_is_some.stderr @@ -8,8 +8,8 @@ LL | | } LL | | ).is_some(); | |______________________________^ | - = note: `-D clippy::search-is-some` implied by `-D warnings` = help: this is more succinctly expressed by calling `any()` + = note: `-D clippy::search-is-some` implied by `-D warnings` error: called `is_some()` after searching an `Iterator` with `position` --> $DIR/search_is_some.rs:20:13 diff --git a/src/tools/clippy/tests/ui/shadow.stderr b/src/tools/clippy/tests/ui/shadow.stderr index 43d76094d0e..c3d7bc2a536 100644 --- a/src/tools/clippy/tests/ui/shadow.stderr +++ b/src/tools/clippy/tests/ui/shadow.stderr @@ -4,12 +4,12 @@ error: `x` is shadowed by itself in `x` LL | let x = x; | ^ | - = note: `-D clippy::shadow-same` implied by `-D warnings` note: previous binding is here --> $DIR/shadow.rs:5:9 | LL | let x = 1; | ^ + = note: `-D clippy::shadow-same` implied by `-D warnings` error: `mut x` is shadowed by itself in `&x` --> $DIR/shadow.rs:7:13 @@ -53,12 +53,12 @@ error: `x` is shadowed LL | let x = x.0; | ^ | - = note: `-D clippy::shadow-reuse` implied by `-D warnings` note: previous binding is here --> $DIR/shadow.rs:13:9 | LL | let x = ([[0]], ()); | ^ + = note: `-D clippy::shadow-reuse` implied by `-D warnings` error: `x` is shadowed --> $DIR/shadow.rs:15:9 @@ -150,12 +150,12 @@ error: `x` shadows a previous, unrelated binding LL | let x = 2; | ^ | - = note: `-D clippy::shadow-unrelated` implied by `-D warnings` note: previous binding is here --> $DIR/shadow.rs:30:9 | LL | let x = 1; | ^ + = note: `-D clippy::shadow-unrelated` implied by `-D warnings` error: `x` shadows a previous, unrelated binding --> $DIR/shadow.rs:36:13 diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr b/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr index 2b7d4628c3f..d2f41e3f934 100644 --- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr +++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_1.stderr @@ -6,8 +6,8 @@ LL | | unimplemented!() LL | | } | |_____^ | - = note: `-D clippy::should-implement-trait` implied by `-D warnings` = help: consider implementing the trait `std::ops::Add` or choosing a less ambiguous method name + = note: `-D clippy::should-implement-trait` implied by `-D warnings` error: method `as_mut` can be confused for the standard trait method `std::convert::AsMut::as_mut` --> $DIR/method_list_1.rs:29:5 diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr index b6fd4356956..10bfea68ff5 100644 --- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr +++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr @@ -6,8 +6,8 @@ LL | | unimplemented!() LL | | } | |_____^ | - = note: `-D clippy::should-implement-trait` implied by `-D warnings` = help: consider implementing the trait `std::cmp::PartialEq` or choosing a less ambiguous method name + = note: `-D clippy::should-implement-trait` implied by `-D warnings` error: method `from_iter` can be confused for the standard trait method `std::iter::FromIterator::from_iter` --> $DIR/method_list_2.rs:30:5 diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr index 88ea6bce25b..f1ed808ba08 100644 --- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr +++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr @@ -10,8 +10,8 @@ LL | mutex.lock().unwrap().bar(); LL | }; | - temporary lives until here | - = note: `-D clippy::significant-drop-in-scrutinee` implied by `-D warnings` = note: this might lead to deadlocks or other unexpected behavior + = note: `-D clippy::significant-drop-in-scrutinee` implied by `-D warnings` help: try moving the temporary above the match | LL ~ let value = mutex.lock().unwrap().foo(); diff --git a/src/tools/clippy/tests/ui/similar_names.stderr b/src/tools/clippy/tests/ui/similar_names.stderr index 6e772693897..43c5cee4b45 100644 --- a/src/tools/clippy/tests/ui/similar_names.stderr +++ b/src/tools/clippy/tests/ui/similar_names.stderr @@ -4,12 +4,12 @@ error: binding's name is too similar to existing binding LL | let bpple: i32; | ^^^^^ | - = note: `-D clippy::similar-names` implied by `-D warnings` note: existing binding defined here --> $DIR/similar_names.rs:19:9 | LL | let apple: i32; | ^^^^^ + = note: `-D clippy::similar-names` implied by `-D warnings` error: binding's name is too similar to existing binding --> $DIR/similar_names.rs:23:9 diff --git a/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr b/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr index 1438b3999db..bfe6d44b589 100644 --- a/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr +++ b/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr @@ -4,8 +4,8 @@ error: single-character lifetime names are likely uninformative LL | struct DiagnosticCtx<'a, 'b> | ^^ | - = note: `-D clippy::single-char-lifetime-names` implied by `-D warnings` = help: use a more informative name + = note: `-D clippy::single-char-lifetime-names` implied by `-D warnings` error: single-character lifetime names are likely uninformative --> $DIR/single_char_lifetime_names.rs:5:26 diff --git a/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr b/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr index cf990be1b9f..633546f6419 100644 --- a/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr +++ b/src/tools/clippy/tests/ui/single_component_path_imports_nested_first.stderr @@ -4,8 +4,8 @@ error: this import is redundant LL | use {regex, serde}; | ^^^^^ | - = note: `-D clippy::single-component-path-imports` implied by `-D warnings` = help: remove this import + = note: `-D clippy::single-component-path-imports` implied by `-D warnings` error: this import is redundant --> $DIR/single_component_path_imports_nested_first.rs:13:17 diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr index 0f0dff57f51..037f695f3ee 100644 --- a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr +++ b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr @@ -4,8 +4,8 @@ error: found a count of bytes instead of a count of elements of `T` LL | unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) }; | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::size-of-in-element-count` implied by `-D warnings` = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type + = note: `-D clippy::size-of-in-element-count` implied by `-D warnings` error: found a count of bytes instead of a count of elements of `T` --> $DIR/expressions.rs:18:62 diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr index c1e824167b7..4351e6a14fe 100644 --- a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr +++ b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr @@ -4,8 +4,8 @@ error: found a count of bytes instead of a count of elements of `T` LL | unsafe { copy_nonoverlapping::<u8>(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) }; | ^^^^^^^^^^^^^^^ | - = note: `-D clippy::size-of-in-element-count` implied by `-D warnings` = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type + = note: `-D clippy::size-of-in-element-count` implied by `-D warnings` error: found a count of bytes instead of a count of elements of `T` --> $DIR/functions.rs:19:62 diff --git a/src/tools/clippy/tests/ui/skip_while_next.stderr b/src/tools/clippy/tests/ui/skip_while_next.stderr index 269cc13468b..7308ab4e55c 100644 --- a/src/tools/clippy/tests/ui/skip_while_next.stderr +++ b/src/tools/clippy/tests/ui/skip_while_next.stderr @@ -4,8 +4,8 @@ error: called `skip_while(<p>).next()` on an `Iterator` LL | let _ = v.iter().skip_while(|&x| *x < 0).next(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::skip-while-next` implied by `-D warnings` = help: this is more succinctly expressed by calling `.find(!<p>)` instead + = note: `-D clippy::skip-while-next` implied by `-D warnings` error: called `skip_while(<p>).next()` on an `Iterator` --> $DIR/skip_while_next.rs:17:13 diff --git a/src/tools/clippy/tests/ui/stable_sort_primitive.stderr b/src/tools/clippy/tests/ui/stable_sort_primitive.stderr index c35e0c22ae8..1432fdcff77 100644 --- a/src/tools/clippy/tests/ui/stable_sort_primitive.stderr +++ b/src/tools/clippy/tests/ui/stable_sort_primitive.stderr @@ -4,8 +4,8 @@ error: used `sort` on primitive type `i32` LL | vec.sort(); | ^^^^^^^^^^ help: try: `vec.sort_unstable()` | - = note: `-D clippy::stable-sort-primitive` implied by `-D warnings` = note: an unstable sort typically performs faster without any observable difference for this data type + = note: `-D clippy::stable-sort-primitive` implied by `-D warnings` error: used `sort` on primitive type `bool` --> $DIR/stable_sort_primitive.rs:9:5 diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.stderr b/src/tools/clippy/tests/ui/std_instead_of_core.stderr index bc49dabf586..8138ccb82a0 100644 --- a/src/tools/clippy/tests/ui/std_instead_of_core.stderr +++ b/src/tools/clippy/tests/ui/std_instead_of_core.stderr @@ -4,8 +4,8 @@ error: used import from `std` instead of `core` LL | use std::hash::Hasher; | ^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::std-instead-of-core` implied by `-D warnings` = help: consider importing the item from `core` + = note: `-D clippy::std-instead-of-core` implied by `-D warnings` error: used import from `std` instead of `core` --> $DIR/std_instead_of_core.rs:11:9 @@ -69,8 +69,8 @@ error: used import from `std` instead of `alloc` LL | use std::vec; | ^^^^^^^^ | - = note: `-D clippy::std-instead-of-alloc` implied by `-D warnings` = help: consider importing the item from `alloc` + = note: `-D clippy::std-instead-of-alloc` implied by `-D warnings` error: used import from `std` instead of `alloc` --> $DIR/std_instead_of_core.rs:33:9 @@ -86,8 +86,8 @@ error: used import from `alloc` instead of `core` LL | use alloc::slice::from_ref; | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings` = help: consider importing the item from `core` + = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings` error: aborting due to 11 previous errors diff --git a/src/tools/clippy/tests/ui/str_to_string.stderr b/src/tools/clippy/tests/ui/str_to_string.stderr index b1f73eda5d2..1d47da571fa 100644 --- a/src/tools/clippy/tests/ui/str_to_string.stderr +++ b/src/tools/clippy/tests/ui/str_to_string.stderr @@ -4,8 +4,8 @@ error: `to_string()` called on a `&str` LL | let hello = "hello world".to_string(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::str-to-string` implied by `-D warnings` = help: consider using `.to_owned()` + = note: `-D clippy::str-to-string` implied by `-D warnings` error: `to_string()` called on a `&str` --> $DIR/str_to_string.rs:6:5 diff --git a/src/tools/clippy/tests/ui/string_to_string.stderr b/src/tools/clippy/tests/ui/string_to_string.stderr index 1ebd17999bd..e304c3e346d 100644 --- a/src/tools/clippy/tests/ui/string_to_string.stderr +++ b/src/tools/clippy/tests/ui/string_to_string.stderr @@ -4,8 +4,8 @@ error: `to_string()` called on a `String` LL | let mut v = message.to_string(); | ^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::string-to-string` implied by `-D warnings` = help: consider using `.clone()` + = note: `-D clippy::string-to-string` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/struct_excessive_bools.stderr b/src/tools/clippy/tests/ui/struct_excessive_bools.stderr index 2941bf2983a..e4d50043acb 100644 --- a/src/tools/clippy/tests/ui/struct_excessive_bools.stderr +++ b/src/tools/clippy/tests/ui/struct_excessive_bools.stderr @@ -9,8 +9,8 @@ LL | | d: bool, LL | | } | |_^ | - = note: `-D clippy::struct-excessive-bools` implied by `-D warnings` = help: consider using a state machine or refactoring bools into two-variant enums + = note: `-D clippy::struct-excessive-bools` implied by `-D warnings` error: more than 3 bools in a struct --> $DIR/struct_excessive_bools.rs:38:5 diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr index ee68eb5a791..2e512b47f12 100644 --- a/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr +++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr @@ -4,8 +4,8 @@ error: this looks like an `else {..}` but the `else` is missing LL | } { | ^ | - = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings` = note: to remove this lint, add the missing `else` or add a new line before the next block + = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings` error: this looks like an `else if` but the `else` is missing --> $DIR/suspicious_else_formatting.rs:21:6 diff --git a/src/tools/clippy/tests/ui/suspicious_map.stderr b/src/tools/clippy/tests/ui/suspicious_map.stderr index 3ffcd1a9031..e251674819e 100644 --- a/src/tools/clippy/tests/ui/suspicious_map.stderr +++ b/src/tools/clippy/tests/ui/suspicious_map.stderr @@ -4,8 +4,8 @@ error: this call to `map()` won't have an effect on the call to `count()` LL | let _ = (0..3).map(|x| x + 2).count(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::suspicious-map` implied by `-D warnings` = help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect` + = note: `-D clippy::suspicious-map` implied by `-D warnings` error: this call to `map()` won't have an effect on the call to `count()` --> $DIR/suspicious_map.rs:7:13 diff --git a/src/tools/clippy/tests/ui/suspicious_splitn.stderr b/src/tools/clippy/tests/ui/suspicious_splitn.stderr index 3bcd681fa49..55ce63d4faa 100644 --- a/src/tools/clippy/tests/ui/suspicious_splitn.stderr +++ b/src/tools/clippy/tests/ui/suspicious_splitn.stderr @@ -4,8 +4,8 @@ error: `splitn` called with `0` splits LL | let _ = "a,b".splitn(0, ','); | ^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::suspicious-splitn` implied by `-D warnings` = note: the resulting iterator will always return `None` + = note: `-D clippy::suspicious-splitn` implied by `-D warnings` error: `rsplitn` called with `0` splits --> $DIR/suspicious_splitn.rs:11:13 diff --git a/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr b/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr index 581527dcff8..9f1289ccba0 100644 --- a/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr +++ b/src/tools/clippy/tests/ui/suspicious_unary_op_formatting.stderr @@ -4,8 +4,8 @@ error: by not having a space between `>` and `-` it looks like `>-` is a single LL | if a >- 30 {} | ^^^^ | - = note: `-D clippy::suspicious-unary-op-formatting` implied by `-D warnings` = help: put a space between `>` and `-` and remove the space after `-` + = note: `-D clippy::suspicious-unary-op-formatting` implied by `-D warnings` error: by not having a space between `>=` and `-` it looks like `>=-` is a single operator --> $DIR/suspicious_unary_op_formatting.rs:9:9 diff --git a/src/tools/clippy/tests/ui/swap.stderr b/src/tools/clippy/tests/ui/swap.stderr index 2b556b475ce..ee4b7a508a5 100644 --- a/src/tools/clippy/tests/ui/swap.stderr +++ b/src/tools/clippy/tests/ui/swap.stderr @@ -6,8 +6,8 @@ LL | | bar.a = bar.b; LL | | bar.b = temp; | |________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b)` | - = note: `-D clippy::manual-swap` implied by `-D warnings` = note: or maybe you should use `std::mem::replace`? + = note: `-D clippy::manual-swap` implied by `-D warnings` error: this looks like you are swapping elements of `foo` manually --> $DIR/swap.rs:36:5 @@ -96,8 +96,8 @@ LL | / a = b; LL | | b = a; | |_________^ help: try: `std::mem::swap(&mut a, &mut b)` | - = note: `-D clippy::almost-swapped` implied by `-D warnings` = note: or maybe you should use `std::mem::replace`? + = note: `-D clippy::almost-swapped` implied by `-D warnings` error: this looks like you are trying to swap `c.0` and `a` --> $DIR/swap.rs:140:5 diff --git a/src/tools/clippy/tests/ui/trailing_empty_array.stderr b/src/tools/clippy/tests/ui/trailing_empty_array.stderr index 9e2bd31d9fa..2e148440035 100644 --- a/src/tools/clippy/tests/ui/trailing_empty_array.stderr +++ b/src/tools/clippy/tests/ui/trailing_empty_array.stderr @@ -7,8 +7,8 @@ LL | | last: [usize; 0], LL | | } | |_^ | - = note: `-D clippy::trailing-empty-array` implied by `-D warnings` = help: consider annotating `RarelyUseful` with `#[repr(C)]` or another `repr` attribute + = note: `-D clippy::trailing-empty-array` implied by `-D warnings` error: trailing zero-sized array in a struct which is not marked with a `repr` attribute --> $DIR/trailing_empty_array.rs:10:1 diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr index fbd9abb005f..4d56a94646c 100644 --- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr +++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds_unfixable.stderr @@ -4,12 +4,12 @@ error: this trait bound is already specified in the where clause LL | fn bad_foo<T: Clone + Default, Z: Copy>(arg0: T, arg1: Z) | ^^^^^ | + = help: consider removing this trait bound note: the lint level is defined here --> $DIR/trait_duplication_in_bounds_unfixable.rs:1:9 | LL | #![deny(clippy::trait_duplication_in_bounds)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: consider removing this trait bound error: this trait bound is already specified in the where clause --> $DIR/trait_duplication_in_bounds_unfixable.rs:6:23 diff --git a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr index 1d88714814d..70d700c1cc4 100644 --- a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr +++ b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr @@ -4,12 +4,12 @@ error: this type has already been used as a bound predicate LL | T: Clone, | ^^^^^^^^ | + = help: consider combining the bounds: `T: Copy + Clone` note: the lint level is defined here --> $DIR/type_repetition_in_bounds.rs:1:9 | LL | #![deny(clippy::type_repetition_in_bounds)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: consider combining the bounds: `T: Copy + Clone` error: this type has already been used as a bound predicate --> $DIR/type_repetition_in_bounds.rs:25:5 diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr index c6a2127443b..2c466ff5c73 100644 --- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr +++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr @@ -4,8 +4,8 @@ error: unsafe block missing a safety comment LL | /* Safety: */ unsafe {} | ^^^^^^^^^ | - = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` = help: consider adding a safety comment on the preceding line + = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` error: unsafe block missing a safety comment --> $DIR/undocumented_unsafe_blocks.rs:266:5 diff --git a/src/tools/clippy/tests/ui/undropped_manually_drops.stderr b/src/tools/clippy/tests/ui/undropped_manually_drops.stderr index 2ac0fe98697..92611a9b7df 100644 --- a/src/tools/clippy/tests/ui/undropped_manually_drops.stderr +++ b/src/tools/clippy/tests/ui/undropped_manually_drops.stderr @@ -4,8 +4,8 @@ error: the inner value of this ManuallyDrop will not be dropped LL | drop(std::mem::ManuallyDrop::new(S)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::undropped-manually-drops` implied by `-D warnings` = help: to drop a `ManuallyDrop<T>`, use std::mem::ManuallyDrop::drop + = note: `-D clippy::undropped-manually-drops` implied by `-D warnings` error: the inner value of this ManuallyDrop will not be dropped --> $DIR/undropped_manually_drops.rs:15:5 diff --git a/src/tools/clippy/tests/ui/uninit_vec.stderr b/src/tools/clippy/tests/ui/uninit_vec.stderr index 520bfb26b62..77fc689f076 100644 --- a/src/tools/clippy/tests/ui/uninit_vec.stderr +++ b/src/tools/clippy/tests/ui/uninit_vec.stderr @@ -7,8 +7,8 @@ LL | unsafe { LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ | - = note: `-D clippy::uninit-vec` implied by `-D warnings` = help: initialize the buffer or wrap the content in `MaybeUninit` + = note: `-D clippy::uninit-vec` implied by `-D warnings` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values --> $DIR/uninit_vec.rs:18:5 diff --git a/src/tools/clippy/tests/ui/unit_hash.stderr b/src/tools/clippy/tests/ui/unit_hash.stderr index 050fa55a12b..089d1212dd1 100644 --- a/src/tools/clippy/tests/ui/unit_hash.stderr +++ b/src/tools/clippy/tests/ui/unit_hash.stderr @@ -4,8 +4,8 @@ error: this call to `hash` on the unit type will do nothing LL | Foo::Empty => ().hash(&mut state), | ^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)` | - = note: `-D clippy::unit-hash` implied by `-D warnings` = note: the implementation of `Hash` for `()` is a no-op + = note: `-D clippy::unit-hash` implied by `-D warnings` error: this call to `hash` on the unit type will do nothing --> $DIR/unit_hash.rs:24:5 diff --git a/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr b/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr index e63d5874609..1d9564ce225 100644 --- a/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr +++ b/src/tools/clippy/tests/ui/unit_return_expecting_ord.stderr @@ -4,12 +4,12 @@ error: this closure returns the unit type which also implements Ord LL | structs.sort_by_key(|s| { | ^^^ | - = note: `-D clippy::unit-return-expecting-ord` implied by `-D warnings` help: probably caused by this trailing semicolon --> $DIR/unit_return_expecting_ord.rs:19:24 | LL | double(s.field); | ^ + = note: `-D clippy::unit-return-expecting-ord` implied by `-D warnings` error: this closure returns the unit type which also implements PartialOrd --> $DIR/unit_return_expecting_ord.rs:22:30 diff --git a/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr b/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr index 83a5618c983..db805eb3680 100644 --- a/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_self_imports.stderr @@ -6,8 +6,8 @@ LL | use std::fs::{self as alias}; | | | help: consider omitting `::{self}`: `fs as alias;` | - = note: `-D clippy::unnecessary-self-imports` implied by `-D warnings` = note: this will slightly change semantics; any non-module items at the same path will also be imported + = note: `-D clippy::unnecessary-self-imports` implied by `-D warnings` error: import ending with `::{self}` --> $DIR/unnecessary_self_imports.rs:8:1 diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr index 7deb90b06f3..02bf45a33fb 100644 --- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr +++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr @@ -4,12 +4,12 @@ error: redundant clone LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^ help: remove this | - = note: `-D clippy::redundant-clone` implied by `-D warnings` note: this value is dropped without further use --> $DIR/unnecessary_to_owned.rs:151:20 | LL | require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::redundant-clone` implied by `-D warnings` error: redundant clone --> $DIR/unnecessary_to_owned.rs:152:40 diff --git a/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr b/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr index b8d3c294532..6f7c3154569 100644 --- a/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr +++ b/src/tools/clippy/tests/ui/unneeded_field_pattern.stderr @@ -4,8 +4,8 @@ error: you matched a field with a wildcard pattern, consider using `..` instead LL | Foo { a: _, b: 0, .. } => {}, | ^^^^ | - = note: `-D clippy::unneeded-field-pattern` implied by `-D warnings` = help: try with `Foo { b: 0, .. }` + = note: `-D clippy::unneeded-field-pattern` implied by `-D warnings` error: all the struct fields are matched to a wildcard pattern, consider using `..` --> $DIR/unneeded_field_pattern.rs:16:9 diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr index 18c4276c6dd..8aaae2d7fff 100644 --- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr +++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.stderr @@ -4,8 +4,8 @@ error: you are deriving `serde::Deserialize` on a type that has methods using `u LL | #[derive(Deserialize)] | ^^^^^^^^^^^ | - = note: `-D clippy::unsafe-derive-deserialize` implied by `-D warnings` = help: consider implementing `serde::Deserialize` manually. See https://serde.rs/impl-deserialize.html + = note: `-D clippy::unsafe-derive-deserialize` implied by `-D warnings` = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info) error: you are deriving `serde::Deserialize` on a type that has methods using `unsafe` diff --git a/src/tools/clippy/tests/ui/unused_async.stderr b/src/tools/clippy/tests/ui/unused_async.stderr index 8b8ad065a4c..cff3eccbd32 100644 --- a/src/tools/clippy/tests/ui/unused_async.stderr +++ b/src/tools/clippy/tests/ui/unused_async.stderr @@ -6,8 +6,8 @@ LL | | 4 LL | | } | |_^ | - = note: `-D clippy::unused-async` implied by `-D warnings` = help: consider removing the `async` from this function + = note: `-D clippy::unused-async` implied by `-D warnings` error: unused `async` for function with no await statements --> $DIR/unused_async.rs:17:5 diff --git a/src/tools/clippy/tests/ui/unused_io_amount.stderr b/src/tools/clippy/tests/ui/unused_io_amount.stderr index e5bdd993aa1..7ba7e09c0f0 100644 --- a/src/tools/clippy/tests/ui/unused_io_amount.stderr +++ b/src/tools/clippy/tests/ui/unused_io_amount.stderr @@ -4,8 +4,8 @@ error: written amount is not handled LL | s.write(b"test")?; | ^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::unused-io-amount` implied by `-D warnings` = help: use `Write::write_all` instead, or handle partial writes + = note: `-D clippy::unused-io-amount` implied by `-D warnings` error: read amount is not handled --> $DIR/unused_io_amount.rs:11:5 diff --git a/src/tools/clippy/tests/ui/unused_peekable.stderr b/src/tools/clippy/tests/ui/unused_peekable.stderr index d557f54179d..54788f2fa2f 100644 --- a/src/tools/clippy/tests/ui/unused_peekable.stderr +++ b/src/tools/clippy/tests/ui/unused_peekable.stderr @@ -4,8 +4,8 @@ error: `peek` never called on `Peekable` iterator LL | let peekable = std::iter::empty::<u32>().peekable(); | ^^^^^^^^ | - = note: `-D clippy::unused-peekable` implied by `-D warnings` = help: consider removing the call to `peekable` + = note: `-D clippy::unused-peekable` implied by `-D warnings` error: `peek` never called on `Peekable` iterator --> $DIR/unused_peekable.rs:18:9 diff --git a/src/tools/clippy/tests/ui/unused_self.stderr b/src/tools/clippy/tests/ui/unused_self.stderr index 0534b40eabb..23186122a9a 100644 --- a/src/tools/clippy/tests/ui/unused_self.stderr +++ b/src/tools/clippy/tests/ui/unused_self.stderr @@ -4,8 +4,8 @@ error: unused `self` argument LL | fn unused_self_move(self) {} | ^^^^ | - = note: `-D clippy::unused-self` implied by `-D warnings` = help: consider refactoring to a associated function + = note: `-D clippy::unused-self` implied by `-D warnings` error: unused `self` argument --> $DIR/unused_self.rs:12:28 diff --git a/src/tools/clippy/tests/ui/unwrap.stderr b/src/tools/clippy/tests/ui/unwrap.stderr index 78422757819..e88d580f7bd 100644 --- a/src/tools/clippy/tests/ui/unwrap.stderr +++ b/src/tools/clippy/tests/ui/unwrap.stderr @@ -4,8 +4,8 @@ error: used `unwrap()` on `an Option` value LL | let _ = opt.unwrap(); | ^^^^^^^^^^^^ | - = note: `-D clippy::unwrap-used` implied by `-D warnings` = help: if you don't want to handle the `None` case gracefully, consider using `expect()` to provide a better panic message + = note: `-D clippy::unwrap-used` implied by `-D warnings` error: used `unwrap()` on `a Result` value --> $DIR/unwrap.rs:10:13 diff --git a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr index 1a19459b2c1..211d2be1834 100644 --- a/src/tools/clippy/tests/ui/unwrap_expect_used.stderr +++ b/src/tools/clippy/tests/ui/unwrap_expect_used.stderr @@ -4,8 +4,8 @@ error: used `unwrap()` on `an Option` value LL | Some(3).unwrap(); | ^^^^^^^^^^^^^^^^ | - = note: `-D clippy::unwrap-used` implied by `-D warnings` = help: if this value is `None`, it will panic + = note: `-D clippy::unwrap-used` implied by `-D warnings` error: used `expect()` on `an Option` value --> $DIR/unwrap_expect_used.rs:24:5 @@ -13,8 +13,8 @@ error: used `expect()` on `an Option` value LL | Some(3).expect("Hello world!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::expect-used` implied by `-D warnings` = help: if this value is `None`, it will panic + = note: `-D clippy::expect-used` implied by `-D warnings` error: used `unwrap()` on `a Result` value --> $DIR/unwrap_expect_used.rs:31:5 diff --git a/src/tools/clippy/tests/ui/unwrap_in_result.stderr b/src/tools/clippy/tests/ui/unwrap_in_result.stderr index 56bc2f2d1c0..40e6bfe087e 100644 --- a/src/tools/clippy/tests/ui/unwrap_in_result.stderr +++ b/src/tools/clippy/tests/ui/unwrap_in_result.stderr @@ -10,13 +10,13 @@ LL | | } LL | | } | |_____^ | - = note: `-D clippy::unwrap-in-result` implied by `-D warnings` = help: unwrap and expect should not be used in a function that returns result or option note: potential non-recoverable error(s) --> $DIR/unwrap_in_result.rs:24:17 | LL | let i = i_str.parse::<i32>().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: `-D clippy::unwrap-in-result` implied by `-D warnings` error: used unwrap or expect in a function that returns result or option --> $DIR/unwrap_in_result.rs:32:5 diff --git a/src/tools/clippy/tests/ui/useless_conversion_try.stderr b/src/tools/clippy/tests/ui/useless_conversion_try.stderr index 12e74d61471..9aef9dda6f6 100644 --- a/src/tools/clippy/tests/ui/useless_conversion_try.stderr +++ b/src/tools/clippy/tests/ui/useless_conversion_try.stderr @@ -4,12 +4,12 @@ error: useless conversion to the same type: `T` LL | let _ = T::try_from(val).unwrap(); | ^^^^^^^^^^^^^^^^ | + = help: consider removing `T::try_from()` note: the lint level is defined here --> $DIR/useless_conversion_try.rs:1:9 | LL | #![deny(clippy::useless_conversion)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - = help: consider removing `T::try_from()` error: useless conversion to the same type: `T` --> $DIR/useless_conversion_try.rs:5:5 diff --git a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr index 7428cf62d6c..8851e9f38be 100644 --- a/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr +++ b/src/tools/clippy/tests/ui/vec_resize_to_zero.stderr @@ -6,8 +6,8 @@ LL | v.resize(0, 5); | | | help: ...or you can empty the vector with: `clear()` | - = note: `-D clippy::vec-resize-to-zero` implied by `-D warnings` = help: the arguments may be inverted... + = note: `-D clippy::vec-resize-to-zero` implied by `-D warnings` error: aborting due to previous error diff --git a/src/tools/clippy/tests/ui/verbose_file_reads.stderr b/src/tools/clippy/tests/ui/verbose_file_reads.stderr index 550b6ab679f..44266c7c01f 100644 --- a/src/tools/clippy/tests/ui/verbose_file_reads.stderr +++ b/src/tools/clippy/tests/ui/verbose_file_reads.stderr @@ -4,8 +4,8 @@ error: use of `File::read_to_end` LL | f.read_to_end(&mut buffer)?; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::verbose-file-reads` implied by `-D warnings` = help: consider using `fs::read` instead + = note: `-D clippy::verbose-file-reads` implied by `-D warnings` error: use of `File::read_to_string` --> $DIR/verbose_file_reads.rs:26:5 diff --git a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr b/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr index 2f1be61e5df..14748f583f0 100644 --- a/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr +++ b/src/tools/clippy/tests/ui/vtable_address_comparisons.stderr @@ -4,8 +4,8 @@ error: comparing trait object pointers compares a non-unique vtable address LL | let _ = a == b; | ^^^^^^ | - = note: `-D clippy::vtable-address-comparisons` implied by `-D warnings` = help: consider extracting and comparing data pointers only + = note: `-D clippy::vtable-address-comparisons` implied by `-D warnings` error: comparing trait object pointers compares a non-unique vtable address --> $DIR/vtable_address_comparisons.rs:15:13 diff --git a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr index 45b87aa0f20..bd5860f45ca 100644 --- a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr +++ b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr @@ -4,8 +4,8 @@ error: wildcard pattern covers any other pattern as it will match anyway LL | "bar" | _ => { | ^^^^^^^^^ | - = note: `-D clippy::wildcard-in-or-patterns` implied by `-D warnings` = help: consider handling `_` separately + = note: `-D clippy::wildcard-in-or-patterns` implied by `-D warnings` error: wildcard pattern covers any other pattern as it will match anyway --> $DIR/wild_in_or_pats.rs:16:9 diff --git a/src/tools/clippy/tests/ui/wrong_self_convention.stderr b/src/tools/clippy/tests/ui/wrong_self_convention.stderr index 2e7ee51d7e1..d002e55c570 100644 --- a/src/tools/clippy/tests/ui/wrong_self_convention.stderr +++ b/src/tools/clippy/tests/ui/wrong_self_convention.stderr @@ -4,8 +4,8 @@ error: methods called `from_*` usually take no `self` LL | fn from_i32(self) {} | ^^^^ | - = note: `-D clippy::wrong-self-convention` implied by `-D warnings` = help: consider choosing a less ambiguous name + = note: `-D clippy::wrong-self-convention` implied by `-D warnings` error: methods called `from_*` usually take no `self` --> $DIR/wrong_self_convention.rs:22:21 diff --git a/src/tools/clippy/tests/ui/wrong_self_convention2.stderr b/src/tools/clippy/tests/ui/wrong_self_convention2.stderr index 5bdc47f91f6..8de10e7be69 100644 --- a/src/tools/clippy/tests/ui/wrong_self_convention2.stderr +++ b/src/tools/clippy/tests/ui/wrong_self_convention2.stderr @@ -4,8 +4,8 @@ error: methods called `from_*` usually take no `self` LL | pub fn from_be_self(self) -> Self { | ^^^^ | - = note: `-D clippy::wrong-self-convention` implied by `-D warnings` = help: consider choosing a less ambiguous name + = note: `-D clippy::wrong-self-convention` implied by `-D warnings` error: methods called `from_*` usually take no `self` --> $DIR/wrong_self_convention2.rs:63:25 diff --git a/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr b/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr index 8665d8dc9a9..3d009083cee 100644 --- a/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr +++ b/src/tools/clippy/tests/ui/wrong_self_conventions_mut.stderr @@ -4,8 +4,8 @@ error: methods with the following characteristics: (`to_*` and `self` type is no LL | pub fn to_many(&mut self) -> Option<&mut [T]> { | ^^^^^^^^^ | - = note: `-D clippy::wrong-self-convention` implied by `-D warnings` = help: consider choosing a less ambiguous name + = note: `-D clippy::wrong-self-convention` implied by `-D warnings` error: methods with the following characteristics: (`to_*` and `*_mut`) usually take `self` by mutable reference --> $DIR/wrong_self_conventions_mut.rs:22:28 diff --git a/src/tools/clippy/tests/ui/zero_div_zero.stderr b/src/tools/clippy/tests/ui/zero_div_zero.stderr index 86563542e06..2793d160644 100644 --- a/src/tools/clippy/tests/ui/zero_div_zero.stderr +++ b/src/tools/clippy/tests/ui/zero_div_zero.stderr @@ -4,8 +4,8 @@ error: constant division of `0.0` with `0.0` will always result in NaN LL | let nan = 0.0 / 0.0; | ^^^^^^^^^ | - = note: `-D clippy::zero-divided-by-zero` implied by `-D warnings` = help: consider using `f64::NAN` if you would like a constant representing NaN + = note: `-D clippy::zero-divided-by-zero` implied by `-D warnings` error: constant division of `0.0` with `0.0` will always result in NaN --> $DIR/zero_div_zero.rs:5:19 diff --git a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr index d924f33797d..c6ba6fa76f0 100644 --- a/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr +++ b/src/tools/clippy/tests/ui/zero_sized_btreemap_values.stderr @@ -4,8 +4,8 @@ error: map with zero-sized value type LL | const CONST_NOT_OK: Option<BTreeMap<String, ()>> = None; | ^^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::zero-sized-map-values` implied by `-D warnings` = help: consider using a set instead + = note: `-D clippy::zero-sized-map-values` implied by `-D warnings` error: map with zero-sized value type --> $DIR/zero_sized_btreemap_values.rs:8:30 diff --git a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr index 79770bf90d7..75bdeb42ec0 100644 --- a/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr +++ b/src/tools/clippy/tests/ui/zero_sized_hashmap_values.stderr @@ -4,8 +4,8 @@ error: map with zero-sized value type LL | const CONST_NOT_OK: Option<HashMap<String, ()>> = None; | ^^^^^^^^^^^^^^^^^^^ | - = note: `-D clippy::zero-sized-map-values` implied by `-D warnings` = help: consider using a set instead + = note: `-D clippy::zero-sized-map-values` implied by `-D warnings` error: map with zero-sized value type --> $DIR/zero_sized_hashmap_values.rs:8:30 diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index dccfd4e0d98..b48395035d4 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -797,7 +797,10 @@ fn make_test_closure( let config = config.clone(); let testpaths = testpaths.clone(); let revision = revision.cloned(); - test::DynTestFn(Box::new(move || runtest::run(config, &testpaths, revision.as_deref()))) + test::DynTestFn(Box::new(move || { + runtest::run(config, &testpaths, revision.as_deref()); + Ok(()) + })) } /// Returns `true` if the given target is an Android target for the diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index cda27beab30..d07610b19d7 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -7,7 +7,7 @@ #![feature(int_log)] #![feature(variant_count)] #![feature(yeet_expr)] -#![feature(is_some_with)] +#![feature(is_some_and)] #![feature(nonzero_ops)] #![feature(local_key_cell_methods)] #![cfg_attr(bootstrap, feature(let_else))] diff --git a/src/tools/miri/src/stacked_borrows/stack.rs b/src/tools/miri/src/stacked_borrows/stack.rs index 494ea08b56e..97632af785d 100644 --- a/src/tools/miri/src/stacked_borrows/stack.rs +++ b/src/tools/miri/src/stacked_borrows/stack.rs @@ -211,7 +211,7 @@ impl<'tcx> Stack { } // Couldn't find it in the stack; but if there is an unknown bottom it might be there. - let found = self.unknown_bottom.is_some_and(|&unknown_limit| { + let found = self.unknown_bottom.is_some_and(|unknown_limit| { tag.0 < unknown_limit.0 // unknown_limit is an upper bound for what can be in the unknown bottom. }); if found { Ok(None) } else { Err(()) } diff --git a/src/tools/miri/tests/fail/erroneous_const2.stderr b/src/tools/miri/tests/fail/erroneous_const2.stderr index 05ed8ea1c14..4d402257b8b 100644 --- a/src/tools/miri/tests/fail/erroneous_const2.stderr +++ b/src/tools/miri/tests/fail/erroneous_const2.stderr @@ -4,9 +4,9 @@ error: any use of this value will cause an error LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; | -------------- ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow | - = note: `#[deny(const_err)]` on by default = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800> + = note: `#[deny(const_err)]` on by default error[E0080]: evaluation of constant value failed --> $DIR/erroneous_const2.rs:LL:CC diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs index cd9d5300964..0c60d500a80 100644 --- a/src/tools/remote-test-server/src/main.rs +++ b/src/tools/remote-test-server/src/main.rs @@ -12,6 +12,7 @@ #[cfg(not(windows))] use std::fs::Permissions; +use std::net::SocketAddr; #[cfg(not(windows))] use std::os::unix::prelude::*; @@ -41,30 +42,44 @@ static TEST: AtomicUsize = AtomicUsize::new(0); #[derive(Copy, Clone)] struct Config { - pub remote: bool, - pub verbose: bool, + verbose: bool, + sequential: bool, + bind: SocketAddr, } impl Config { pub fn default() -> Config { - Config { remote: false, verbose: false } + Config { + verbose: false, + sequential: false, + bind: if cfg!(target_os = "android") || cfg!(windows) { + ([0, 0, 0, 0], 12345).into() + } else { + ([10, 0, 2, 15], 12345).into() + }, + } } pub fn parse_args() -> Config { let mut config = Config::default(); let args = env::args().skip(1); + let mut next_is_bind = false; for argument in args { match &argument[..] { - "remote" => { - config.remote = true; - } - "verbose" | "-v" => { - config.verbose = true; + bind if next_is_bind => { + config.bind = t!(bind.parse()); + next_is_bind = false; } + "--bind" => next_is_bind = true, + "--sequential" => config.sequential = true, + "--verbose" | "-v" => config.verbose = true, arg => panic!("unknown argument: {}", arg), } } + if next_is_bind { + panic!("missing value for --bind"); + } config } @@ -81,13 +96,7 @@ fn main() { let config = Config::parse_args(); - let bind_addr = if cfg!(target_os = "android") || cfg!(windows) || config.remote { - "0.0.0.0:12345" - } else { - "10.0.2.15:12345" - }; - - let listener = t!(TcpListener::bind(bind_addr)); + let listener = t!(TcpListener::bind(config.bind)); let (work, tmp): (PathBuf, PathBuf) = if cfg!(target_os = "android") { ("/data/tmp/work".into(), "/data/tmp/work/tmp".into()) } else { @@ -97,7 +106,7 @@ fn main() { tmp_dir.push("tmp"); (work_dir, tmp_dir) }; - println!("listening on {}!", bind_addr); + println!("listening on {}!", config.bind); t!(fs::create_dir_all(&work)); t!(fs::create_dir_all(&tmp)); @@ -119,7 +128,12 @@ fn main() { let lock = lock.clone(); let work = work.clone(); let tmp = tmp.clone(); - thread::spawn(move || handle_run(socket, &work, &tmp, &lock, config)); + let f = move || handle_run(socket, &work, &tmp, &lock, config); + if config.sequential { + f(); + } else { + thread::spawn(f); + } } else { panic!("unknown command {:?}", buf); } diff --git a/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs b/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs index 7fb4b90e6d9..371d642c15d 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/imports/merge_imports.rs @@ -225,7 +225,7 @@ fn path_cmp_short(a: &ast::Path, b: &ast::Path) -> Ordering { } /// Compares two paths, if one ends earlier than the other the has_tl parameters decide which is -/// greater as a a path that has a tree list should be greater, while one that just ends without +/// greater as a path that has a tree list should be greater, while one that just ends without /// a tree list should be considered less. pub(super) fn use_tree_path_cmp( a: &ast::Path, diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs index 298814af5a4..ac10721d955 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/bin/logger.rs @@ -132,7 +132,7 @@ where let ext = span.extensions(); - // `FormattedFields` is a a formatted representation of the span's + // `FormattedFields` is a formatted representation of the span's // fields, which is stored in its extensions by the `fmt` layer's // `new_span` method. The fields will have been formatted // by the same field formatter that's provided to the event diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 9aab66b1d21..d4733107e79 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -73,14 +73,11 @@ const EXCEPTIONS_BOOTSTRAP: &[(&str, &str)] = &[ /// these and all their dependencies *must not* be in the exception list. const RUNTIME_CRATES: &[&str] = &["std", "core", "alloc", "test", "panic_abort", "panic_unwind"]; -/// Crates whose dependencies must be explicitly permitted. -const RESTRICTED_DEPENDENCY_CRATES: &[&str] = &["rustc_driver", "rustc_codegen_llvm"]; - /// Crates rustc is allowed to depend on. Avoid adding to the list if possible. /// /// This list is here to provide a speed-bump to adding a new dependency to /// rustc. Please check with the compiler team before adding an entry. -const PERMITTED_DEPENDENCIES: &[&str] = &[ +const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "addr2line", "adler", "ahash", @@ -307,7 +304,7 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ ]; const FORBIDDEN_TO_HAVE_DUPLICATES: &[&str] = &[ - // These two crates take quite a long time to build, so don't allow two versions of them + // This crate takes quite a long time to build, so don't allow two versions of them // to accidentally sneak into our dependency graph, in order to ensure we keep our CI times // under control. "cargo", @@ -324,12 +321,12 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { .features(cargo_metadata::CargoOpt::AllFeatures); let metadata = t!(cmd.exec()); let runtime_ids = compute_runtime_crates(&metadata); - check_exceptions(&metadata, EXCEPTIONS, runtime_ids, bad); - check_dependencies( + check_license_exceptions(&metadata, EXCEPTIONS, runtime_ids, bad); + check_permitted_dependencies( &metadata, - "main workspace", - PERMITTED_DEPENDENCIES, - RESTRICTED_DEPENDENCY_CRATES, + "rustc", + PERMITTED_RUSTC_DEPENDENCIES, + &["rustc_driver", "rustc_codegen_llvm"], bad, ); check_crate_duplicate(&metadata, FORBIDDEN_TO_HAVE_DUPLICATES, bad); @@ -342,8 +339,8 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { .features(cargo_metadata::CargoOpt::AllFeatures); let metadata = t!(cmd.exec()); let runtime_ids = HashSet::new(); - check_exceptions(&metadata, EXCEPTIONS_CRANELIFT, runtime_ids, bad); - check_dependencies( + check_license_exceptions(&metadata, EXCEPTIONS_CRANELIFT, runtime_ids, bad); + check_permitted_dependencies( &metadata, "cranelift", PERMITTED_CRANELIFT_DEPENDENCIES, @@ -358,13 +355,13 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { .features(cargo_metadata::CargoOpt::AllFeatures); let metadata = t!(cmd.exec()); let runtime_ids = HashSet::new(); - check_exceptions(&metadata, EXCEPTIONS_BOOTSTRAP, runtime_ids, bad); + check_license_exceptions(&metadata, EXCEPTIONS_BOOTSTRAP, runtime_ids, bad); } /// Check that all licenses are in the valid list in `LICENSES`. /// -/// Packages listed in `EXCEPTIONS` are allowed for tools. -fn check_exceptions( +/// Packages listed in `exceptions` are allowed for tools. +fn check_license_exceptions( metadata: &Metadata, exceptions: &[(&str, &str)], runtime_ids: HashSet<&PackageId>, @@ -434,11 +431,11 @@ fn check_exceptions( } } -/// Checks the dependency of `RESTRICTED_DEPENDENCY_CRATES` at the given path. Changes `bad` to +/// Checks the dependency of `restricted_dependency_crates` at the given path. Changes `bad` to /// `true` if a check failed. /// -/// Specifically, this checks that the dependencies are on the `PERMITTED_DEPENDENCIES`. -fn check_dependencies( +/// Specifically, this checks that the dependencies are on the `permitted_dependencies`. +fn check_permitted_dependencies( metadata: &Metadata, descr: &str, permitted_dependencies: &[&'static str], diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 28a0700a64b..d8b3903b98e 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -538,7 +538,9 @@ fn map_lib_features( becoming_feature = None; if line.contains("rustc_const_unstable(") { // `const fn` features are handled specially. - let feature_name = match find_attr_val(line, "feature") { + let feature_name = match find_attr_val(line, "feature").or_else(|| { + iter_lines.peek().and_then(|next| find_attr_val(next.1, "feature")) + }) { Some(name) => name, None => err!("malformed stability attribute: missing `feature` key"), }; |
