From 420c58fb119325325ec2f58f1686d7bcb63b51ad Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 27 Feb 2024 15:05:02 +0000 Subject: [PATCH 001/114] sess: stabilize relro-level Signed-off-by: David Wood --- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/options.rs | 4 ++-- compiler/rustc_session/src/session.rs | 2 +- src/doc/rustc/src/codegen-options/index.md | 20 ++++++++++++++++++++ tests/run-make/relro-levels/Makefile | 8 ++++---- 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index e4a050dcfc9b..5cc286e86eb5 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2013,7 +2013,7 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: /// Add options making relocation sections in the produced ELF files read-only /// and suppressing lazy binding. fn add_relro_args(cmd: &mut dyn Linker, sess: &Session) { - match sess.opts.unstable_opts.relro_level.unwrap_or(sess.target.relro_level) { + match sess.opts.cg.relro_level.unwrap_or(sess.target.relro_level) { RelroLevel::Full => cmd.full_relro(), RelroLevel::Partial => cmd.partial_relro(), RelroLevel::Off => cmd.no_relro(), diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 112553b2f703..f22d727c391f 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -608,6 +608,7 @@ fn test_codegen_options_tracking_hash() { tracked!(profile_generate, SwitchWithOptPath::Enabled(None)); tracked!(profile_use, Some(PathBuf::from("abc"))); tracked!(relocation_model, Some(RelocModel::Pic)); + tracked!(relro_level, Some(RelroLevel::Full)); tracked!(soft_float, true); tracked!(split_debuginfo, Some(SplitDebuginfo::Packed)); tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); @@ -805,7 +806,6 @@ fn test_unstable_options_tracking_hash() { tracked!(profile_sample_use, Some(PathBuf::from("abc"))); tracked!(profiler_runtime, "abc".to_string()); tracked!(relax_elf_relocations, Some(true)); - tracked!(relro_level, Some(RelroLevel::Full)); tracked!(remap_cwd_prefix, Some(PathBuf::from("abc"))); tracked!(sanitizer, SanitizerSet::ADDRESS); tracked!(sanitizer_cfi_canonical_jump_tables, None); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 743f47603393..9bb252f89c83 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1494,6 +1494,8 @@ options! { relocation_model: Option = (None, parse_relocation_model, [TRACKED], "control generation of position-independent code (PIC) \ (`rustc --print relocation-models` for details)"), + relro_level: Option = (None, parse_relro_level, [TRACKED], + "choose which RELRO level to use"), remark: Passes = (Passes::Some(Vec::new()), parse_passes, [UNTRACKED], "output remarks for these optimization passes (space separated, or \"all\")"), rpath: bool = (false, parse_bool, [UNTRACKED], @@ -1829,8 +1831,6 @@ options! { "randomize the layout of types (default: no)"), relax_elf_relocations: Option = (None, parse_opt_bool, [TRACKED], "whether ELF relocations can be relaxed"), - relro_level: Option = (None, parse_relro_level, [TRACKED], - "choose which RELRO level to use"), remap_cwd_prefix: Option = (None, parse_opt_pathbuf, [TRACKED], "remap paths under the current working directory to this path prefix"), remap_path_scope: RemapPathScopeComponents = (RemapPathScopeComponents::all(), parse_remap_path_scope, [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index b6c194868989..b243fe8eb4d5 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -587,7 +587,7 @@ impl Session { let dbg_opts = &self.opts.unstable_opts; - let relro_level = dbg_opts.relro_level.unwrap_or(self.target.relro_level); + let relro_level = self.opts.cg.relro_level.unwrap_or(self.target.relro_level); // Only enable this optimization by default if full relro is also enabled. // In this case, lazy binding was already unavailable, so nothing is lost. diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 4a4f1ae98e40..0cba925bb4fc 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -479,6 +479,26 @@ then `-C target-feature=+crt-static` "wins" over `-C relocation-model=pic`, and the linker is instructed (`-static`) to produce a statically linked but not position-independent executable. +## relro-level + +This flag controls what level of RELRO (Relocation Read-Only) is enabled. RELRO is an exploit +mitigation which makes the Global Offset Table (GOT) read-only. + +Supported values for this option are: + +- `off`: Dynamically linked functions are resolved lazily and the GOT is writable. +- `partial`: Dynamically linked functions are resolved lazily and written into the Procedure + Linking Table (PLT) part of the GOT (`.got.plt`). The non-PLT part of the GOT (`.got`) is made + read-only and both are moved to prevent writing from buffer overflows. +- `full`: Dynamically linked functions are resolved at the start of program execution and the + Global Offset Table (`.got`/`.got.plt`) is populated eagerly and then made read-only. The GOT is + also moved to prevent writing from buffer overflows. Full RELRO uses more memory and increases + process startup time. + +This flag is ignored on platforms where RELRO is not supported (targets which do not use the ELF +binary format), such as Windows or macOS. Each rustc target has its own default for RELRO. rustc +enables Full RELRO by default on platforms where it is supported. + ## remark This flag lets you print remarks for optimization passes. diff --git a/tests/run-make/relro-levels/Makefile b/tests/run-make/relro-levels/Makefile index e0402f59f12d..94f08bcb4945 100644 --- a/tests/run-make/relro-levels/Makefile +++ b/tests/run-make/relro-levels/Makefile @@ -3,20 +3,20 @@ include ../tools.mk # only-linux # -# This tests the different -Zrelro-level values, and makes sure that they work properly. +# This tests the different -Crelro-level values, and makes sure that they work properly. all: # Ensure that binaries built with the full relro level links them with both # RELRO and BIND_NOW for doing eager symbol resolving. - $(RUSTC) -Zrelro-level=full hello.rs + $(RUSTC) -Crelro-level=full hello.rs readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO readelf -d $(TMPDIR)/hello | grep -q BIND_NOW - $(RUSTC) -Zrelro-level=partial hello.rs + $(RUSTC) -Crelro-level=partial hello.rs readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO # Ensure that we're *not* built with RELRO when setting it to off. We do # not want to check for BIND_NOW however, as the linker might have that # enabled by default. - $(RUSTC) -Zrelro-level=off hello.rs + $(RUSTC) -Crelro-level=off hello.rs ! readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO From a0bb25f11c99905b03785de0b5173f9b1bd7bded Mon Sep 17 00:00:00 2001 From: Bryant Le Date: Thu, 14 Mar 2024 18:31:09 -0500 Subject: [PATCH 002/114] doc(bootstrap): add top-level doc-comment to utils/tarball.rs --- src/bootstrap/src/utils/tarball.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 03f56cba29d8..47f135fae9ed 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -1,3 +1,10 @@ +//! Facilitates the management and generation of tarballs. +//! +//! Tarballs efficiently hold Rust compiler build artifacts and +//! capture a snapshot of each boostrap stage. +//! In uplifting, a tarball from Stage N captures essential components +//! to assemble Stage N + 1 compiler. + use std::{ path::{Path, PathBuf}, process::Command, From b75e6b4e7e7b12b461e70a5ffaf280b46c746575 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Sun, 17 Mar 2024 13:34:42 +0300 Subject: [PATCH 003/114] fetch submodule before checking llvm stamp Previously, we were checking the LLVM stamp before fetching the submodule which leads to not being able to compile llvm on submodule updates. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/llvm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 701bd585eee7..327dc04b4e51 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -94,6 +94,7 @@ pub fn prebuilt_llvm_config( } } + builder.update_submodule(&Path::new("src").join("llvm-project")); let root = "src/llvm-project/llvm"; let out_dir = builder.llvm_out(target); @@ -279,7 +280,6 @@ impl Step for Llvm { Err(m) => m, }; - builder.update_submodule(&Path::new("src").join("llvm-project")); if builder.llvm_link_shared() && target.is_windows() { panic!("shared linking to LLVM is not currently supported on {}", target.triple); } From 3683b11d212d938b5c314a0d0971b794d521046f Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 28 Mar 2024 17:27:17 +0300 Subject: [PATCH 004/114] create `Build::update_existing_submodule` and use for llvm Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/llvm.rs | 5 +++++ src/bootstrap/src/lib.rs | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs index 327dc04b4e51..59fdd2e3caf5 100644 --- a/src/bootstrap/src/core/build_steps/llvm.rs +++ b/src/bootstrap/src/core/build_steps/llvm.rs @@ -76,6 +76,9 @@ pub fn prebuilt_llvm_config( builder: &Builder<'_>, target: TargetSelection, ) -> Result { + // If we have llvm submodule initialized already, sync it. + builder.update_existing_submodule(&Path::new("src").join("llvm-project")); + builder.config.maybe_download_ci_llvm(); // If we're using a custom LLVM bail out here, but we can only use a @@ -94,7 +97,9 @@ pub fn prebuilt_llvm_config( } } + // Initialize the llvm submodule if not initialized already. builder.update_submodule(&Path::new("src").join("llvm-project")); + let root = "src/llvm-project/llvm"; let out_dir = builder.llvm_out(target); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index f0fe994d155d..9568514db510 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -625,6 +625,18 @@ impl Build { } } + /// Updates the given submodule only if it's initialized already; nothing happens otherwise. + pub fn update_existing_submodule(&self, submodule: &Path) { + // Avoid running git when there isn't a git checkout. + if !self.config.submodules(self.rust_info()) { + return; + } + + if GitInfo::new(false, submodule).is_managed_git_subrepository() { + self.update_submodule(submodule); + } + } + /// Executes the entire build, as configured by the flags and configuration. pub fn build(&mut self) { unsafe { From 1ca145778a4971d82c56025ece1824ec672428b9 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Tue, 2 Apr 2024 14:35:25 +0800 Subject: [PATCH 005/114] Support type '/' to search --- src/librustdoc/html/static/js/main.js | 3 ++- src/librustdoc/html/templates/page.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index b9a769a7c6da..0bd75d4a4fc3 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -438,6 +438,7 @@ function preLoadCss(cssUrl) { case "s": case "S": + case "/": ev.preventDefault(); searchState.focus(); break; @@ -1310,7 +1311,7 @@ function preLoadCss(cssUrl) { const shortcuts = [ ["?", "Show this help dialog"], - ["S", "Focus the search field"], + ["S / /", "Focus the search field"], ["↑", "Move up in search results"], ["↓", "Move down in search results"], ["← / →", "Switch result tab (when results focused)"], diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index 0f3debae66c7..27b0ed69a583 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -135,7 +135,7 @@ aria-label="Run search in the documentation" {#+ #} autocomplete="off" {#+ #} spellcheck="false" {#+ #} - placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {#+ #} + placeholder="Type ‘S’ or ‘/’ to search, ‘?’ for more options…" {#+ #} type="search"> {# #}
{# #} ? {# #} From 3cbc9e956095401af31a95f82f2d663dc0c8d343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 4 Apr 2024 19:03:32 +0200 Subject: [PATCH 006/114] Rename ModSep to PathSep --- compiler/rustc_ast/src/attr/mod.rs | 6 +++--- compiler/rustc_ast/src/token.rs | 20 ++++++++++--------- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- .../rustc_expand/src/proc_macro_server.rs | 2 +- .../rustc_parse/src/parser/diagnostics.rs | 12 +++++------ compiler/rustc_parse/src/parser/item.rs | 10 +++++----- compiler/rustc_parse/src/parser/mod.rs | 4 ++-- .../rustc_parse/src/parser/nonterminal.rs | 4 ++-- compiler/rustc_parse/src/parser/pat.rs | 2 +- compiler/rustc_parse/src/parser/path.rs | 18 ++++++++--------- compiler/rustc_parse/src/parser/ty.rs | 2 +- .../clippy_lints/src/crate_in_macro_def.rs | 2 +- src/tools/rustfmt/src/macros.rs | 2 +- 13 files changed, 44 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 98138cedb24d..5e3fc7e33577 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -308,11 +308,11 @@ impl MetaItem { // FIXME: Share code with `parse_path`. let path = match tokens.next().map(|tt| TokenTree::uninterpolate(tt)).as_deref() { Some(&TokenTree::Token( - Token { kind: ref kind @ (token::Ident(..) | token::ModSep), span }, + Token { kind: ref kind @ (token::Ident(..) | token::PathSep), span }, _, )) => 'arm: { let mut segments = if let &token::Ident(name, _) = kind { - if let Some(TokenTree::Token(Token { kind: token::ModSep, .. }, _)) = + if let Some(TokenTree::Token(Token { kind: token::PathSep, .. }, _)) = tokens.peek() { tokens.next(); @@ -331,7 +331,7 @@ impl MetaItem { } else { return None; } - if let Some(TokenTree::Token(Token { kind: token::ModSep, .. }, _)) = + if let Some(TokenTree::Token(Token { kind: token::PathSep, .. }, _)) = tokens.peek() { tokens.next(); diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index f49eb2f22c50..24a193561343 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -290,7 +290,7 @@ pub enum TokenKind { /// `:` Colon, /// `::` - ModSep, + PathSep, /// `->` RArrow, /// `<-` @@ -393,7 +393,7 @@ impl TokenKind { BinOpEq(Shr) => (Gt, Ge), DotDot => (Dot, Dot), DotDotDot => (Dot, DotDot), - ModSep => (Colon, Colon), + PathSep => (Colon, Colon), RArrow => (BinOp(Minus), Gt), LArrow => (Lt, BinOp(Minus)), FatArrow => (Eq, Gt), @@ -454,7 +454,9 @@ impl Token { 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, + | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => { + true + } OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..) | Lifetime(..) | Interpolated(..) | Eof => false, @@ -481,7 +483,7 @@ impl Token { // DotDotDot is no longer supported, but we need some way to display the error DotDot | DotDotDot | DotDotEq | // range notation Lt | BinOp(Shl) | // associated path - ModSep | // global path + PathSep | // global path Lifetime(..) | // labeled loop Pound => true, // expression attributes Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) | @@ -507,7 +509,7 @@ impl Token { // DotDotDot is no longer supported | DotDot | DotDotDot | DotDotEq // ranges | Lt | BinOp(Shl) // associated path - | ModSep => true, // global path + | PathSep => true, // global path Interpolated(ref nt) => matches!(&nt.0, NtLiteral(..) | NtPat(..) | NtBlock(..) | @@ -530,7 +532,7 @@ impl Token { Question | // maybe bound in trait object Lifetime(..) | // lifetime bound in trait object Lt | BinOp(Shl) | // associated path - ModSep => true, // global path + PathSep => true, // global path Interpolated(ref nt) => matches!(&nt.0, NtTy(..) | NtPath(..)), // For anonymous structs or unions, which only appear in specific positions // (type of struct fields or union fields), we don't consider them as regular types @@ -708,7 +710,7 @@ impl Token { } pub fn is_path_start(&self) -> bool { - self == &ModSep + self == &PathSep || self.is_qpath_start() || self.is_whole_path() || self.is_path_segment_keyword() @@ -821,7 +823,7 @@ impl Token { _ => return None, }, Colon => match joint.kind { - Colon => ModSep, + Colon => PathSep, _ => return None, }, SingleQuote => match joint.kind { @@ -830,7 +832,7 @@ impl Token { }, Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot - | DotDotEq | Comma | Semi | ModSep | RArrow | LArrow | FatArrow | Pound | Dollar + | DotDotEq | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | Lifetime(..) | Interpolated(..) | DocComment(..) | Eof => return None, }; diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 3ea182c58675..2f9367c2d24c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -893,7 +893,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere token::Comma => ",".into(), token::Semi => ";".into(), token::Colon => ":".into(), - token::ModSep => "::".into(), + token::PathSep => "::".into(), token::RArrow => "->".into(), token::LArrow => "<-".into(), token::FatArrow => "=>".into(), diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index ddc685c9d07d..5a66b0fbdef1 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -208,7 +208,7 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec op(","), Semi => op(";"), Colon => op(":"), - ModSep => op("::"), + PathSep => op("::"), RArrow => op("->"), LArrow => op("<-"), FatArrow => op("=>"), diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 7038b8bbe47a..64f766543a7c 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -279,7 +279,7 @@ impl<'a> Parser<'a> { TokenKind::Colon, TokenKind::Comma, TokenKind::Semi, - TokenKind::ModSep, + TokenKind::PathSep, TokenKind::OpenDelim(Delimiter::Brace), TokenKind::OpenDelim(Delimiter::Parenthesis), TokenKind::CloseDelim(Delimiter::Brace), @@ -1169,7 +1169,7 @@ impl<'a> Parser<'a> { return; } - if token::ModSep == self.token.kind && segment.args.is_none() { + if token::PathSep == self.token.kind && segment.args.is_none() { let snapshot = self.create_snapshot_for_diagnostic(); self.bump(); let lo = self.token.span; @@ -1420,7 +1420,7 @@ impl<'a> Parser<'a> { [(token::Lt, 1), (token::Gt, -1), (token::BinOp(token::Shr), -2)]; self.consume_tts(1, &modifiers); - if !&[token::OpenDelim(Delimiter::Parenthesis), token::ModSep] + if !&[token::OpenDelim(Delimiter::Parenthesis), token::PathSep] .contains(&self.token.kind) { // We don't have `foo< bar >(` or `foo< bar >::`, so we rewind the @@ -1428,7 +1428,7 @@ impl<'a> Parser<'a> { self.restore_snapshot(snapshot); } } - return if token::ModSep == self.token.kind { + return if token::PathSep == self.token.kind { // We have some certainty that this was a bad turbofish at this point. // `foo< bar >::` if let ExprKind::Binary(o, ..) = inner_op.kind @@ -1784,7 +1784,7 @@ impl<'a> Parser<'a> { } // Do not add `::` to expected tokens. - if self.token == token::ModSep { + if self.token == token::PathSep { if let Some(ty) = base.to_ty() { return self.maybe_recover_from_bad_qpath_stage_2(ty.span, ty); } @@ -1799,7 +1799,7 @@ impl<'a> Parser<'a> { ty_span: Span, ty: P, ) -> PResult<'a, P> { - self.expect(&token::ModSep)?; + self.expect(&token::PathSep)?; let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None }; self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?; diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index d54eb8dc4c9e..003479b9d8ec 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -358,12 +358,12 @@ impl<'a> Parser<'a> { fn is_reuse_path_item(&mut self) -> bool { // no: `reuse ::path` for compatibility reasons with macro invocations self.token.is_keyword(kw::Reuse) - && self.look_ahead(1, |t| t.is_path_start() && t.kind != token::ModSep) + && self.look_ahead(1, |t| t.is_path_start() && t.kind != token::PathSep) } /// Are we sure this could not possibly be a macro invocation? fn isnt_macro_invocation(&mut self) -> bool { - self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::ModSep) + self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::PathSep) } /// Recover on encountering a struct or method definition where the user @@ -1020,7 +1020,7 @@ impl<'a> Parser<'a> { { // `use *;` or `use ::*;` or `use {...};` or `use ::{...};` let mod_sep_ctxt = self.token.span.ctxt(); - if self.eat(&token::ModSep) { + if self.eat(&token::PathSep) { prefix .segments .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); @@ -1031,7 +1031,7 @@ impl<'a> Parser<'a> { // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;` prefix = self.parse_path(PathStyle::Mod)?; - if self.eat(&token::ModSep) { + if self.eat(&token::PathSep) { self.parse_use_tree_glob_or_nested()? } else { // Recover from using a colon as path separator. @@ -2752,7 +2752,7 @@ impl<'a> Parser<'a> { // Is `self` `n` tokens ahead? let is_isolated_self = |this: &Self, n| { this.is_keyword_ahead(n, &[kw::SelfLower]) - && this.look_ahead(n + 1, |t| t != &token::ModSep) + && this.look_ahead(n + 1, |t| t != &token::PathSep) }; // Is `mut self` `n` tokens ahead? let is_isolated_mut_self = diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 1971591364d3..ca7285c2126f 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -109,7 +109,7 @@ macro_rules! maybe_recover_from_interpolated_ty_qpath { ($self: expr, $allow_qpath_recovery: expr) => { if $allow_qpath_recovery && $self.may_recover() - && $self.look_ahead(1, |t| t == &token::ModSep) + && $self.look_ahead(1, |t| t == &token::PathSep) && let token::Interpolated(nt) = &$self.token.kind && let token::NtTy(ty) = &nt.0 { @@ -1532,7 +1532,7 @@ impl<'a> Parser<'a> { /// `::{` or `::*` fn is_import_coupler(&mut self) -> bool { - self.check(&token::ModSep) + self.check(&token::PathSep) && self.look_ahead(1, |t| { *t == token::OpenDelim(Delimiter::Brace) || *t == token::BinOp(token::Star) }) diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index 36a00df7b441..73b17353ac90 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -62,7 +62,7 @@ impl<'a> Parser<'a> { _ => false, }, NonterminalKind::Path | NonterminalKind::Meta => match &token.kind { - token::ModSep | token::Ident(..) => true, + token::PathSep | token::Ident(..) => true, token::Interpolated(nt) => may_be_ident(&nt.0), _ => false, }, @@ -76,7 +76,7 @@ impl<'a> Parser<'a> { token::Literal(_) | // literal token::DotDot | // range pattern (future compat) token::DotDotDot | // range pattern (future compat) - token::ModSep | // path + token::PathSep | // path token::Lt | // path (UFCS constant) token::BinOp(token::Shl) => true, // path (double UFCS) // leading vert `|` or-pattern diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 59e0cd92c4cb..dd1ecf9b7c16 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -1016,7 +1016,7 @@ impl<'a> Parser<'a> { && self.look_ahead(1, |t| !matches!(t.kind, token::OpenDelim(Delimiter::Parenthesis) // A tuple struct pattern. | token::OpenDelim(Delimiter::Brace) // A struct pattern. | token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern. - | token::ModSep // A tuple / struct variant pattern. + | token::PathSep // A tuple / struct variant pattern. | token::Not)) // A macro expanding to a pattern. } diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 608cdd945ff9..0f410772dd98 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -96,7 +96,7 @@ impl<'a> Parser<'a> { } if !self.recover_colon_before_qpath_proj() { - self.expect(&token::ModSep)?; + self.expect(&token::PathSep)?; } let qself = P(QSelf { ty, path_span, position: path.segments.len() }); @@ -200,7 +200,7 @@ impl<'a> Parser<'a> { let lo = self.token.span; let mut segments = ThinVec::new(); let mod_sep_ctxt = self.token.span.ctxt(); - if self.eat(&token::ModSep) { + if self.eat(&token::PathSep) { segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); } self.parse_path_segments(&mut segments, style, ty_generics)?; @@ -232,11 +232,11 @@ impl<'a> Parser<'a> { // `PathStyle::Expr` is only provided at the root invocation and never in // `parse_path_segment` to recurse and therefore can be checked to maintain // this invariant. - self.check_trailing_angle_brackets(&segment, &[&token::ModSep]); + self.check_trailing_angle_brackets(&segment, &[&token::PathSep]); } segments.push(segment); - if self.is_import_coupler() || !self.eat(&token::ModSep) { + if self.is_import_coupler() || !self.eat(&token::PathSep) { if style == PathStyle::Expr && self.may_recover() && self.token == token::Colon @@ -291,7 +291,7 @@ impl<'a> Parser<'a> { Ok( if style == PathStyle::Type && check_args_start(self) || style != PathStyle::Mod - && self.check(&token::ModSep) + && self.check(&token::PathSep) && self.look_ahead(1, |t| is_args_start(t)) { // We use `style == PathStyle::Expr` to check if this is in a recursion or not. If @@ -303,7 +303,7 @@ impl<'a> Parser<'a> { } // Generic arguments are found - `<`, `(`, `::<` or `::(`. - self.eat(&token::ModSep); + self.eat(&token::PathSep); let lo = self.token.span; let args = if self.eat_lt() { // `<'a, T, A = U>` @@ -379,7 +379,7 @@ impl<'a> Parser<'a> { let token_before_parsing = self.token.clone(); let mut snapshot = None; if self.may_recover() - && prev_token_before_parsing.kind == token::ModSep + && prev_token_before_parsing.kind == token::PathSep && (style == PathStyle::Expr && self.token.can_begin_expr() || style == PathStyle::Pat && self.token.can_begin_pattern()) { @@ -388,7 +388,7 @@ impl<'a> Parser<'a> { let (inputs, _) = match self.parse_paren_comma_seq(|p| p.parse_ty()) { Ok(output) => output, - Err(mut error) if prev_token_before_parsing.kind == token::ModSep => { + Err(mut error) if prev_token_before_parsing.kind == token::PathSep => { error.span_label( prev_token_before_parsing.span.to(token_before_parsing.span), "while parsing this parenthesized list of type arguments starting here", @@ -470,7 +470,7 @@ impl<'a> Parser<'a> { } } - if let token::ModSep | token::RArrow = self.token.kind { + if let token::PathSep | token::RArrow = self.token.kind { return; } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 1cea32cb90fe..1eeb11a09fed 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -82,7 +82,7 @@ enum AllowCVariadic { /// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes /// that `IDENT` is not the ident of a fn trait. fn can_continue_type_after_non_fn_ident(t: &Token) -> bool { - t == &token::ModSep || t == &token::Lt || t == &token::BinOp(token::Shl) + t == &token::PathSep || t == &token::Lt || t == &token::BinOp(token::Shl) } fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool { diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs index b1aa472aa03f..adf6f7c47375 100644 --- a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs +++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs @@ -88,7 +88,7 @@ fn contains_unhygienic_crate_reference(tts: &TokenStream) -> Option { if !prev_is_dollar && let Some(span) = is_crate_keyword(curr) && let Some(next) = cursor.look_ahead(0) - && is_token(next, &TokenKind::ModSep) + && is_token(next, &TokenKind::PathSep) { return Some(span); } diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index 8d77d2b32542..6b24b1aec5d6 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -1091,7 +1091,7 @@ fn next_space(tok: &TokenKind) -> SpaceState { | TokenKind::DotDotEq | TokenKind::Question => SpaceState::Punctuation, - TokenKind::ModSep + TokenKind::PathSep | TokenKind::Pound | TokenKind::Dollar | TokenKind::OpenDelim(_) From 651d02a2f06e61fb1a2d67c1f90651db1483a5ca Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 7 Apr 2024 13:17:21 -0400 Subject: [PATCH 007/114] Don't even parse an intrinsic unless the feature gate is enabled --- compiler/rustc_hir_typeck/src/expr.rs | 11 +-- compiler/rustc_middle/src/ty/util.rs | 11 ++- tests/ui/feature-gates/feature-gate-abi.rs | 2 - .../ui/feature-gates/feature-gate-abi.stderr | 71 +++++++------------ .../feature-gates/feature-gate-intrinsics.rs | 1 - .../feature-gate-intrinsics.stderr | 10 +-- .../incorrect-read_via_copy-defn.rs | 7 ++ .../incorrect-read_via_copy-defn.stderr | 18 +++++ tests/ui/intrinsics/incorrect-transmute.rs | 3 +- .../ui/intrinsics/incorrect-transmute.stderr | 11 +-- 10 files changed, 67 insertions(+), 78 deletions(-) create mode 100644 tests/ui/intrinsics/incorrect-read_via_copy-defn.rs create mode 100644 tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 4da45303d127..3b64517089b9 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -55,7 +55,6 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; -use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::ObligationCtxt; @@ -541,16 +540,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::FnDef(did, _) = *ty.kind() { let fn_sig = ty.fn_sig(tcx); - if tcx.fn_sig(did).skip_binder().abi() == RustIntrinsic - && tcx.item_name(did) == sym::transmute - { + if tcx.is_intrinsic(did, sym::transmute) { let Some(from) = fn_sig.inputs().skip_binder().get(0) else { - let e = self.dcx().span_delayed_bug( + span_bug!( tcx.def_span(did), - "intrinsic fn `transmute` defined with no parameters", + "intrinsic fn `transmute` defined with no parameters" ); - self.set_tainted_by_errors(e); - return Ty::new_error(tcx, e); }; let to = fn_sig.output().skip_binder(); // We defer the transmute to the end of typeck, once all inference vars have diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index cef15b29a851..a504212d5785 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -1679,10 +1679,15 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool { .any(|items| items.iter().any(|item| item.has_name(sym::notable_trait))) } -/// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute) +/// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute). +/// +/// We double check the feature gate here because whether a function may be defined as an intrinsic causes +/// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may +/// cause an ICE that we otherwise may want to prevent. pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option { - if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic) - || tcx.has_attr(def_id, sym::rustc_intrinsic) + if (matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic) + && tcx.features().intrinsics) + || (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs) { Some(ty::IntrinsicDef { name: tcx.item_name(def_id.into()), diff --git a/tests/ui/feature-gates/feature-gate-abi.rs b/tests/ui/feature-gates/feature-gate-abi.rs index 1c3a732a497f..3aa430e736f0 100644 --- a/tests/ui/feature-gates/feature-gate-abi.rs +++ b/tests/ui/feature-gates/feature-gate-abi.rs @@ -13,10 +13,8 @@ trait Tuple { } // Functions extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change //~^ ERROR intrinsic must be in - //~| ERROR unrecognized intrinsic function: `f1` extern "rust-intrinsic" fn f2() {} //~ ERROR intrinsics are subject to change //~^ ERROR intrinsic must be in - //~| ERROR unrecognized intrinsic function: `f2` extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change // Methods in trait definition diff --git a/tests/ui/feature-gates/feature-gate-abi.stderr b/tests/ui/feature-gates/feature-gate-abi.stderr index c28cd05a96ad..dbdfa7b275d4 100644 --- a/tests/ui/feature-gates/feature-gate-abi.stderr +++ b/tests/ui/feature-gates/feature-gate-abi.stderr @@ -8,7 +8,7 @@ LL | extern "rust-intrinsic" fn f1() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:17:8 + --> $DIR/feature-gate-abi.rs:16:8 | LL | extern "rust-intrinsic" fn f2() {} | ^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | extern "rust-intrinsic" fn f2() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:20:8 + --> $DIR/feature-gate-abi.rs:18:8 | LL | extern "rust-call" fn f4(_: ()) {} | ^^^^^^^^^^^ @@ -27,7 +27,7 @@ LL | extern "rust-call" fn f4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:24:12 + --> $DIR/feature-gate-abi.rs:22:12 | LL | extern "rust-intrinsic" fn m1(); | ^^^^^^^^^^^^^^^^ @@ -36,7 +36,7 @@ LL | extern "rust-intrinsic" fn m1(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:26:12 + --> $DIR/feature-gate-abi.rs:24:12 | LL | extern "rust-intrinsic" fn m2(); | ^^^^^^^^^^^^^^^^ @@ -45,7 +45,7 @@ LL | extern "rust-intrinsic" fn m2(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:28:12 + --> $DIR/feature-gate-abi.rs:26:12 | LL | extern "rust-call" fn m4(_: ()); | ^^^^^^^^^^^ @@ -55,7 +55,7 @@ LL | extern "rust-call" fn m4(_: ()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:30:12 + --> $DIR/feature-gate-abi.rs:28:12 | LL | extern "rust-call" fn dm4(_: ()) {} | ^^^^^^^^^^^ @@ -65,7 +65,7 @@ LL | extern "rust-call" fn dm4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:37:12 + --> $DIR/feature-gate-abi.rs:35:12 | LL | extern "rust-intrinsic" fn m1() {} | ^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | extern "rust-intrinsic" fn m1() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:39:12 + --> $DIR/feature-gate-abi.rs:37:12 | LL | extern "rust-intrinsic" fn m2() {} | ^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ LL | extern "rust-intrinsic" fn m2() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:41:12 + --> $DIR/feature-gate-abi.rs:39:12 | LL | extern "rust-call" fn m4(_: ()) {} | ^^^^^^^^^^^ @@ -93,7 +93,7 @@ LL | extern "rust-call" fn m4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:46:12 + --> $DIR/feature-gate-abi.rs:44:12 | LL | extern "rust-intrinsic" fn im1() {} | ^^^^^^^^^^^^^^^^ @@ -102,7 +102,7 @@ LL | extern "rust-intrinsic" fn im1() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:48:12 + --> $DIR/feature-gate-abi.rs:46:12 | LL | extern "rust-intrinsic" fn im2() {} | ^^^^^^^^^^^^^^^^ @@ -111,7 +111,7 @@ LL | extern "rust-intrinsic" fn im2() {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:50:12 + --> $DIR/feature-gate-abi.rs:48:12 | LL | extern "rust-call" fn im4(_: ()) {} | ^^^^^^^^^^^ @@ -121,7 +121,7 @@ LL | extern "rust-call" fn im4(_: ()) {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:54:18 + --> $DIR/feature-gate-abi.rs:52:18 | LL | type A1 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^ @@ -130,7 +130,7 @@ LL | type A1 = extern "rust-intrinsic" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:55:18 + --> $DIR/feature-gate-abi.rs:53:18 | LL | type A2 = extern "rust-intrinsic" fn(); | ^^^^^^^^^^^^^^^^ @@ -139,7 +139,7 @@ LL | type A2 = extern "rust-intrinsic" fn(); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:56:18 + --> $DIR/feature-gate-abi.rs:54:18 | LL | type A4 = extern "rust-call" fn(_: ()); | ^^^^^^^^^^^ @@ -149,7 +149,7 @@ LL | type A4 = extern "rust-call" fn(_: ()); = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:59:8 + --> $DIR/feature-gate-abi.rs:57:8 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^ @@ -158,7 +158,7 @@ LL | extern "rust-intrinsic" {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: intrinsics are subject to change - --> $DIR/feature-gate-abi.rs:60:8 + --> $DIR/feature-gate-abi.rs:58:8 | LL | extern "rust-intrinsic" {} | ^^^^^^^^^^^^^^^^ @@ -167,7 +167,7 @@ LL | extern "rust-intrinsic" {} = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error[E0658]: rust-call ABI is subject to change - --> $DIR/feature-gate-abi.rs:61:8 + --> $DIR/feature-gate-abi.rs:59:8 | LL | extern "rust-call" {} | ^^^^^^^^^^^ @@ -176,30 +176,14 @@ LL | extern "rust-call" {} = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0093]: unrecognized intrinsic function: `f1` - --> $DIR/feature-gate-abi.rs:14:28 - | -LL | extern "rust-intrinsic" fn f1() {} - | ^^ unrecognized intrinsic - | - = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type` - -error[E0093]: unrecognized intrinsic function: `f2` - --> $DIR/feature-gate-abi.rs:17:28 - | -LL | extern "rust-intrinsic" fn f2() {} - | ^^ unrecognized intrinsic - | - = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type` - error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:24:32 + --> $DIR/feature-gate-abi.rs:22:32 | LL | extern "rust-intrinsic" fn m1(); | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:26:32 + --> $DIR/feature-gate-abi.rs:24:32 | LL | extern "rust-intrinsic" fn m2(); | ^^ @@ -211,36 +195,35 @@ LL | extern "rust-intrinsic" fn f1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:17:33 + --> $DIR/feature-gate-abi.rs:16:33 | LL | extern "rust-intrinsic" fn f2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:37:37 + --> $DIR/feature-gate-abi.rs:35:37 | LL | extern "rust-intrinsic" fn m1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:39:37 + --> $DIR/feature-gate-abi.rs:37:37 | LL | extern "rust-intrinsic" fn m2() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:46:38 + --> $DIR/feature-gate-abi.rs:44:38 | LL | extern "rust-intrinsic" fn im1() {} | ^^ error: intrinsic must be in `extern "rust-intrinsic" { ... }` block - --> $DIR/feature-gate-abi.rs:48:38 + --> $DIR/feature-gate-abi.rs:46:38 | LL | extern "rust-intrinsic" fn im2() {} | ^^ -error: aborting due to 29 previous errors +error: aborting due to 27 previous errors -Some errors have detailed explanations: E0093, E0658. -For more information about an error, try `rustc --explain E0093`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.rs b/tests/ui/feature-gates/feature-gate-intrinsics.rs index 725d968d24c3..e0dc3cc579d7 100644 --- a/tests/ui/feature-gates/feature-gate-intrinsics.rs +++ b/tests/ui/feature-gates/feature-gate-intrinsics.rs @@ -4,6 +4,5 @@ extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change extern "rust-intrinsic" fn baz() {} //~ ERROR intrinsics are subject to change //~^ ERROR intrinsic must be in -//~| ERROR unrecognized intrinsic function: `baz` fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.stderr b/tests/ui/feature-gates/feature-gate-intrinsics.stderr index 583a4a1a84eb..577a620e2d2c 100644 --- a/tests/ui/feature-gates/feature-gate-intrinsics.stderr +++ b/tests/ui/feature-gates/feature-gate-intrinsics.stderr @@ -24,21 +24,13 @@ LL | fn bar(); | = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type` -error[E0093]: unrecognized intrinsic function: `baz` - --> $DIR/feature-gate-intrinsics.rs:5:28 - | -LL | extern "rust-intrinsic" fn baz() {} - | ^^^ unrecognized intrinsic - | - = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type` - error: intrinsic must be in `extern "rust-intrinsic" { ... }` block --> $DIR/feature-gate-intrinsics.rs:5:34 | LL | extern "rust-intrinsic" fn baz() {} | ^^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0093, E0658. For more information about an error, try `rustc --explain E0093`. diff --git a/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs b/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs new file mode 100644 index 000000000000..66de1f60ed9b --- /dev/null +++ b/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs @@ -0,0 +1,7 @@ +fn main() { + read_via_copy(); +} + +extern "rust-intrinsic" fn read_via_copy() {} +//~^ ERROR intrinsics are subject to change +//~| ERROR intrinsic must be in `extern "rust-intrinsic" { ... }` block diff --git a/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr b/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr new file mode 100644 index 000000000000..362ee185b7b1 --- /dev/null +++ b/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr @@ -0,0 +1,18 @@ +error[E0658]: intrinsics are subject to change + --> $DIR/incorrect-read_via_copy-defn.rs:5:8 + | +LL | extern "rust-intrinsic" fn read_via_copy() {} + | ^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(intrinsics)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: intrinsic must be in `extern "rust-intrinsic" { ... }` block + --> $DIR/incorrect-read_via_copy-defn.rs:5:44 + | +LL | extern "rust-intrinsic" fn read_via_copy() {} + | ^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/intrinsics/incorrect-transmute.rs b/tests/ui/intrinsics/incorrect-transmute.rs index 4f1d1491ec9c..eed524ae8a8a 100644 --- a/tests/ui/intrinsics/incorrect-transmute.rs +++ b/tests/ui/intrinsics/incorrect-transmute.rs @@ -3,6 +3,5 @@ fn main() { } extern "rust-intrinsic" fn transmute() {} -//~^ ERROR intrinsic has wrong number of type parameters: found 0, expected 2 -//~| ERROR intrinsics are subject to change +//~^ ERROR intrinsics are subject to change //~| ERROR intrinsic must be in `extern "rust-intrinsic" { ... }` block diff --git a/tests/ui/intrinsics/incorrect-transmute.stderr b/tests/ui/intrinsics/incorrect-transmute.stderr index 20b95925b76d..8123f3d71a29 100644 --- a/tests/ui/intrinsics/incorrect-transmute.stderr +++ b/tests/ui/intrinsics/incorrect-transmute.stderr @@ -7,19 +7,12 @@ LL | extern "rust-intrinsic" fn transmute() {} = help: add `#![feature(intrinsics)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0094]: intrinsic has wrong number of type parameters: found 0, expected 2 - --> $DIR/incorrect-transmute.rs:5:37 - | -LL | extern "rust-intrinsic" fn transmute() {} - | ^ expected 2 type parameters - error: intrinsic must be in `extern "rust-intrinsic" { ... }` block --> $DIR/incorrect-transmute.rs:5:40 | LL | extern "rust-intrinsic" fn transmute() {} | ^^ -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0094, E0658. -For more information about an error, try `rustc --explain E0094`. +For more information about this error, try `rustc --explain E0658`. From dacfbfccc5da7c88e466af06be9468f2d10da03e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 9 Apr 2024 17:44:20 +0000 Subject: [PATCH 008/114] Update ar_archive_writer to 0.2.0 This adds a whole bunch of tests checking for any difference with llvm's archive writer. It also fixes two mistakes in the porting from C++ to Rust. The first one causes a divergence for Mach-O archives which may or may not be harmless. The second will definitively cause issues, but only applies to thin archives, which rustc currently doesn't create. --- Cargo.lock | 4 ++-- compiler/rustc_codegen_ssa/Cargo.toml | 2 +- compiler/rustc_codegen_ssa/src/back/archive.rs | 9 +-------- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1bdaef81ff8..d8044c67a47b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -210,9 +210,9 @@ dependencies = [ [[package]] name = "ar_archive_writer" -version = "0.1.5" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9792d37ca5173d7e7f4fe453739a0671d0557915a030a383d6b866476bbc3e71" +checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a" dependencies = [ "object 0.32.2", ] diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index baf10622a6df..f347a7fb0bb1 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -ar_archive_writer = "0.1.5" +ar_archive_writer = "0.2.0" bitflags = "2.4.1" cc = "1.0.90" itertools = "0.12" diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs index ef55682d541e..d336973d2b9c 100644 --- a/compiler/rustc_codegen_ssa/src/back/archive.rs +++ b/compiler/rustc_codegen_ssa/src/back/archive.rs @@ -285,14 +285,7 @@ impl<'a> ArArchiveBuilder<'a> { .tempfile_in(output.parent().unwrap_or_else(|| Path::new(""))) .map_err(|err| io_error_context("couldn't create a temp file", err))?; - write_archive_to_stream( - archive_tmpfile.as_file_mut(), - &entries, - true, - archive_kind, - true, - false, - )?; + write_archive_to_stream(archive_tmpfile.as_file_mut(), &entries, archive_kind, false)?; let any_entries = !entries.is_empty(); drop(entries); From a57a99041616612c8cd7e0cdfe4eb117f9960644 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 10 Apr 2024 08:53:07 +0300 Subject: [PATCH 009/114] drop `changelog-seen` It's been 7 months since we deprecated this. It should be fine to remove it now. Signed-off-by: onur-ozkan --- src/bootstrap/src/bin/main.rs | 4 ---- src/bootstrap/src/core/config/config.rs | 16 +--------------- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs index 340a5c87f0bc..4cb67b7aa624 100644 --- a/src/bootstrap/src/bin/main.rs +++ b/src/bootstrap/src/bin/main.rs @@ -131,10 +131,6 @@ fn main() { fn check_version(config: &Config) -> Option { let mut msg = String::new(); - if config.changelog_seen.is_some() { - msg.push_str("WARNING: The use of `changelog-seen` is deprecated. Please refer to `change-id` option in `config.example.toml` instead.\n"); - } - let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap().change_id; let warned_id_path = config.out.join("bootstrap").join(".last-warned-change-id"); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 96dec9752504..334cff2fdc58 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -145,7 +145,6 @@ impl LldMode { /// `config.example.toml`. #[derive(Default, Clone)] pub struct Config { - pub changelog_seen: Option, // FIXME: Deprecated field. Remove it at 2024. pub change_id: Option, pub bypass_bootstrap_lock: bool, pub ccache: Option, @@ -605,7 +604,6 @@ impl Target { #[derive(Deserialize, Default)] #[serde(deny_unknown_fields, rename_all = "kebab-case")] pub(crate) struct TomlConfig { - changelog_seen: Option, // FIXME: Deprecated field. Remove it at 2024. #[serde(flatten)] change_id: ChangeIdWrapper, build: Option, @@ -645,17 +643,7 @@ trait Merge { impl Merge for TomlConfig { fn merge( &mut self, - TomlConfig { - build, - install, - llvm, - rust, - dist, - target, - profile: _, - changelog_seen, - change_id, - }: Self, + TomlConfig { build, install, llvm, rust, dist, target, profile: _, change_id }: Self, replace: ReplaceOpt, ) { fn do_merge(x: &mut Option, y: Option, replace: ReplaceOpt) { @@ -667,7 +655,6 @@ impl Merge for TomlConfig { } } } - self.changelog_seen.merge(changelog_seen, replace); self.change_id.inner.merge(change_id.inner, replace); do_merge(&mut self.build, build, replace); do_merge(&mut self.install, install, replace); @@ -1400,7 +1387,6 @@ impl Config { } toml.merge(override_toml, ReplaceOpt::Override); - config.changelog_seen = toml.changelog_seen; config.change_id = toml.change_id.inner; let Build { From cce21be686b5ad46705b0fa6472fcef90d87668f Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Wed, 10 Apr 2024 14:10:35 +0300 Subject: [PATCH 010/114] add change entry for the removal of `changelog-seen` Signed-off-by: onur-ozkan --- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 277ec00fa623..db3df598a0c6 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -170,4 +170,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Warning, summary: "`rust.split-debuginfo` has been moved to `target..split-debuginfo` and its default value is determined for each target individually.", }, + ChangeInfo { + change_id: 123711, + severity: ChangeSeverity::Warning, + summary: "The deprecated field `changelog-seen` has been removed. Using that field in `config.toml` from now on will result in breakage.", + }, ]; From efbbfa24a5b309c713079486908c1754721548f9 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 10 Apr 2024 15:02:04 +0200 Subject: [PATCH 011/114] visionOS: Fix logic for finding the SDK root The `sdk_name` is `xros`/`xrsimulator`, not `visionos`/`visionossimulator`. --- compiler/rustc_codegen_ssa/src/back/link.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index ac278de02af2..cc3f18294cac 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -3029,9 +3029,10 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result {} "watchsimulator" if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {} - "visionos" - if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {} - "visionossimulator" + "xros" + if sdkroot.contains("XRSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "xrsimulator" if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {} // Ignore `SDKROOT` if it's not a valid path. _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {} From 69a3b0e213a8b197c1099fb129dac6ce8185d39b Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 10 Apr 2024 14:59:11 +0200 Subject: [PATCH 012/114] visionOS: Fix unused import warning The import is used once in this file, inside `posix_spawn`, so let's move the import into that function instead, to reduce the number of `cfg`s that need to be kept in sync. --- .../std/src/sys/pal/unix/process/process_unix.rs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index e798510f9e64..d65657790c48 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -11,18 +11,6 @@ use crate::os::linux::process::PidFd; #[cfg(target_os = "linux")] use crate::os::unix::io::AsRawFd; -#[cfg(any( - target_os = "macos", - target_os = "watchos", - target_os = "visionos", - target_os = "tvos", - target_os = "freebsd", - all(target_os = "linux", target_env = "gnu"), - all(target_os = "linux", target_env = "musl"), - target_os = "nto", -))] -use crate::sys::weak::weak; - #[cfg(target_os = "vxworks")] use libc::RTP_ID as pid_t; @@ -466,6 +454,7 @@ impl Command { envp: Option<&CStringArray>, ) -> io::Result> { use crate::mem::MaybeUninit; + use crate::sys::weak::weak; use crate::sys::{self, cvt_nz, unix_sigpipe_attr_specified}; if self.get_gid().is_some() From 1a7238407c8964fb902f259d712eac9e87052680 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 10 Apr 2024 18:00:43 +0200 Subject: [PATCH 013/114] Allow specifying SDKROOT as containing XRSimulator.platform Checking this was missing from the `link_env_remove` function, so compilation might fail if set when compiling for macOS --- compiler/rustc_target/src/spec/base/apple/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 021457b145fa..d667bad44e3b 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -298,6 +298,7 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow]> { || sdkroot.contains("WatchOS.platform") || sdkroot.contains("WatchSimulator.platform") || sdkroot.contains("XROS.platform") + || sdkroot.contains("XRSimulator.platform") { env_remove.push("SDKROOT".into()) } From 800c50608ca992bce2b90bd7361ad908bb4045e2 Mon Sep 17 00:00:00 2001 From: Amanda Stjerna Date: Thu, 11 Apr 2024 16:56:45 +0200 Subject: [PATCH 014/114] Slightly more readable NLL/constraint graph dumps --- .../src/region_infer/graphviz.rs | 40 +++++++++++++++++-- .../rustc_borrowck/src/region_infer/mod.rs | 2 +- .../src/region_infer/opaque_types.rs | 2 +- compiler/rustc_type_ir/src/lib.rs | 5 +++ 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs index c103ba3c4070..f145d30fe38a 100644 --- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs +++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs @@ -6,7 +6,38 @@ use std::borrow::Cow; use std::io::{self, Write}; use super::*; +use itertools::Itertools; use rustc_graphviz as dot; +use rustc_middle::ty::UniverseIndex; + +fn render_outlives_constraint(constraint: &OutlivesConstraint<'_>) -> String { + match constraint.locations { + Locations::All(_) => "All(...)".to_string(), + Locations::Single(loc) => format!("{loc:?}"), + } +} + +fn render_universe(u: UniverseIndex) -> String { + if u.is_root() { + return "".to_string(); + } + + format!("/{:?}", u) +} + +fn render_region_vid(rvid: RegionVid, regioncx: &RegionInferenceContext<'_>) -> String { + let universe_str = render_universe(regioncx.region_definition(rvid).universe); + + let external_name_str = if let Some(external_name) = + regioncx.region_definition(rvid).external_name.and_then(|e| e.get_name()) + { + format!(" ({external_name})") + } else { + "".to_string() + }; + + format!("{:?}{universe_str}{external_name_str}", rvid) +} impl<'tcx> RegionInferenceContext<'tcx> { /// Write out the region constraint graph. @@ -46,10 +77,10 @@ impl<'a, 'this, 'tcx> dot::Labeller<'this> for RawConstraints<'a, 'tcx> { Some(dot::LabelText::LabelStr(Cow::Borrowed("box"))) } fn node_label(&'this self, n: &RegionVid) -> dot::LabelText<'this> { - dot::LabelText::LabelStr(format!("{n:?}").into()) + dot::LabelText::LabelStr(render_region_vid(*n, self.regioncx).into()) } fn edge_label(&'this self, e: &OutlivesConstraint<'tcx>) -> dot::LabelText<'this> { - dot::LabelText::LabelStr(format!("{:?}", e.locations).into()) + dot::LabelText::LabelStr(render_outlives_constraint(e).into()) } } @@ -96,8 +127,9 @@ impl<'a, 'this, 'tcx> dot::Labeller<'this> for SccConstraints<'a, 'tcx> { Some(dot::LabelText::LabelStr(Cow::Borrowed("box"))) } fn node_label(&'this self, n: &ConstraintSccIndex) -> dot::LabelText<'this> { - let nodes = &self.nodes_per_scc[*n]; - dot::LabelText::LabelStr(format!("{n:?} = {nodes:?}").into()) + let nodes_str = + self.nodes_per_scc[*n].iter().map(|n| render_region_vid(*n, self.regioncx)).join(", "); + dot::LabelText::LabelStr(format!("SCC({n}) = {{{nodes_str}}}", n = n.as_usize()).into()) } } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 599f7dd18c3e..dd75548a15df 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1562,7 +1562,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Because this free region must be in the ROOT universe, we // know it cannot contain any bound universes. - assert!(self.scc_universes[longer_fr_scc] == ty::UniverseIndex::ROOT); + assert!(self.scc_universes[longer_fr_scc].is_root()); debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none()); // Only check all of the relations for the main representative of each diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 9f0e54febe4c..73ba5bee13b7 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -213,7 +213,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let scc = self.constraint_sccs.scc(vid); // Special handling of higher-ranked regions. - if self.scc_universes[scc] != ty::UniverseIndex::ROOT { + if !self.scc_universes[scc].is_root() { match self.scc_values.placeholders_contained_in(scc).enumerate().last() { // If the region contains a single placeholder then they're equal. Some((0, placeholder)) => { diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 45e22b12a8b0..a5b33a8125d5 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -346,6 +346,11 @@ impl UniverseIndex { pub fn cannot_name(self, other: UniverseIndex) -> bool { self < other } + + /// Returns `true` if `self` is the root universe, otherwise false. + pub fn is_root(self) -> bool { + self == Self::ROOT + } } impl Default for UniverseIndex { From a30a79c5b4c3f470648adbfe3eb11575e72b2f97 Mon Sep 17 00:00:00 2001 From: joboet Date: Thu, 11 Apr 2024 19:36:30 +0200 Subject: [PATCH 015/114] std: use queue-based `RwLock` on SGX --- .../src/sys/pal/sgx/libunwind_integration.rs | 46 ++++ library/std/src/sys/pal/sgx/mod.rs | 1 + library/std/src/sys/pal/sgx/waitqueue/mod.rs | 21 -- library/std/src/sys/sync/rwlock/sgx.rs | 219 ------------------ library/std/src/sys/sync/rwlock/sgx/tests.rs | 21 -- 5 files changed, 47 insertions(+), 261 deletions(-) create mode 100644 library/std/src/sys/pal/sgx/libunwind_integration.rs delete mode 100644 library/std/src/sys/sync/rwlock/sgx.rs delete mode 100644 library/std/src/sys/sync/rwlock/sgx/tests.rs diff --git a/library/std/src/sys/pal/sgx/libunwind_integration.rs b/library/std/src/sys/pal/sgx/libunwind_integration.rs new file mode 100644 index 000000000000..debfd324c864 --- /dev/null +++ b/library/std/src/sys/pal/sgx/libunwind_integration.rs @@ -0,0 +1,46 @@ +//! The functions in this module are needed by libunwind. These symbols are named +//! in pre-link args for the target specification, so keep that in sync. + +#![cfg(not(test))] + +use crate::sys::sync::RwLock; + +// Verify that the byte pattern libunwind uses to initialize an RwLock is +// equivalent to the value of RwLock::new(). If the value changes, +// `src/UnwindRustSgx.h` in libunwind needs to be changed too. +const _: () = unsafe { + let bits_rust: usize = crate::mem::transmute(RwLock::new()); + assert!(bits_rust == 0); +}; + +const EINVAL: i32 = 22; + +#[no_mangle] +pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RwLock) -> i32 { + if p.is_null() { + return EINVAL; + } + + // We cannot differentiate between reads an writes in unlock and therefore + // always use a write-lock. Unwinding isn't really in the hot path anyway. + unsafe { (*p).write() }; + return 0; +} + +#[no_mangle] +pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 { + if p.is_null() { + return EINVAL; + } + unsafe { (*p).write() }; + return 0; +} + +#[no_mangle] +pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 { + if p.is_null() { + return EINVAL; + } + unsafe { (*p).write_unlock() }; + return 0; +} diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 76f930b86f2e..d30976ec1514 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -17,6 +17,7 @@ pub mod fd; pub mod fs; #[path = "../unsupported/io.rs"] pub mod io; +mod libunwind_integration; pub mod net; pub mod os; #[path = "../unsupported/pipe.rs"] diff --git a/library/std/src/sys/pal/sgx/waitqueue/mod.rs b/library/std/src/sys/pal/sgx/waitqueue/mod.rs index 2d952b7ebbca..ea49bb280346 100644 --- a/library/std/src/sys/pal/sgx/waitqueue/mod.rs +++ b/library/std/src/sys/pal/sgx/waitqueue/mod.rs @@ -52,10 +52,6 @@ impl WaitVariable { WaitVariable { queue: WaitQueue::new(), lock: var } } - pub fn queue_empty(&self) -> bool { - self.queue.is_empty() - } - pub fn lock_var(&self) -> &T { &self.lock } @@ -98,19 +94,6 @@ impl Default for WaitQueue { } } -impl<'a, T> WaitGuard<'a, T> { - /// Returns which TCSes will be notified when this guard drops. - pub fn notified_tcs(&self) -> NotifiedTcs { - self.notified_tcs - } - - /// Drop this `WaitGuard`, after dropping another `guard`. - pub fn drop_after(self, guard: U) { - drop(guard); - drop(self); - } -} - impl<'a, T> Deref for WaitGuard<'a, T> { type Target = SpinMutexGuard<'a, WaitVariable>; @@ -141,10 +124,6 @@ impl WaitQueue { WaitQueue { inner: UnsafeList::new() } } - pub fn is_empty(&self) -> bool { - self.inner.is_empty() - } - /// Adds the calling thread to the `WaitVariable`'s wait queue, then wait /// until a wakeup event. /// diff --git a/library/std/src/sys/sync/rwlock/sgx.rs b/library/std/src/sys/sync/rwlock/sgx.rs deleted file mode 100644 index 136dea597bb0..000000000000 --- a/library/std/src/sys/sync/rwlock/sgx.rs +++ /dev/null @@ -1,219 +0,0 @@ -#[cfg(test)] -mod tests; - -use crate::alloc::Layout; -use crate::num::NonZero; -use crate::sys::pal::waitqueue::{ - try_lock_or_false, NotifiedTcs, SpinMutex, SpinMutexGuard, WaitQueue, WaitVariable, -}; -use crate::sys_common::lazy_box::{LazyBox, LazyInit}; - -struct AllocatedRwLock { - readers: SpinMutex>>>, - writer: SpinMutex>, -} - -pub struct RwLock { - inner: LazyBox, -} - -impl LazyInit for AllocatedRwLock { - fn init() -> Box { - Box::new(AllocatedRwLock { - readers: SpinMutex::new(WaitVariable::new(None)), - writer: SpinMutex::new(WaitVariable::new(false)), - }) - } -} - -// Check at compile time that RwLock's size and alignment matches the C definition -// in libunwind (see also `test_c_rwlock_initializer` in `tests`). -const _: () = { - let rust = Layout::new::(); - let c = Layout::new::<*mut ()>(); - assert!(rust.size() == c.size()); - assert!(rust.align() == c.align()); -}; - -impl RwLock { - pub const fn new() -> RwLock { - RwLock { inner: LazyBox::new() } - } - - #[inline] - pub fn read(&self) { - let lock = &*self.inner; - let mut rguard = lock.readers.lock(); - let wguard = lock.writer.lock(); - if *wguard.lock_var() || !wguard.queue_empty() { - // Another thread has or is waiting for the write lock, wait - drop(wguard); - WaitQueue::wait(rguard, || {}); - // Another thread has passed the lock to us - } else { - // No waiting writers, acquire the read lock - *rguard.lock_var_mut() = NonZero::new(rguard.lock_var().map_or(0, |n| n.get()) + 1); - } - } - - #[inline] - pub unsafe fn try_read(&self) -> bool { - let lock = &*self.inner; - let mut rguard = try_lock_or_false!(lock.readers); - let wguard = try_lock_or_false!(lock.writer); - if *wguard.lock_var() || !wguard.queue_empty() { - // Another thread has or is waiting for the write lock - false - } else { - // No waiting writers, acquire the read lock - *rguard.lock_var_mut() = NonZero::new(rguard.lock_var().map_or(0, |n| n.get()) + 1); - true - } - } - - #[inline] - pub fn write(&self) { - let lock = &*self.inner; - let rguard = lock.readers.lock(); - let mut wguard = lock.writer.lock(); - if *wguard.lock_var() || rguard.lock_var().is_some() { - // Another thread has the lock, wait - drop(rguard); - WaitQueue::wait(wguard, || {}); - // Another thread has passed the lock to us - } else { - // We are just now obtaining the lock - *wguard.lock_var_mut() = true; - } - } - - #[inline] - pub fn try_write(&self) -> bool { - let lock = &*self.inner; - let rguard = try_lock_or_false!(lock.readers); - let mut wguard = try_lock_or_false!(lock.writer); - if *wguard.lock_var() || rguard.lock_var().is_some() { - // Another thread has the lock - false - } else { - // We are just now obtaining the lock - *wguard.lock_var_mut() = true; - true - } - } - - #[inline] - unsafe fn __read_unlock( - &self, - mut rguard: SpinMutexGuard<'_, WaitVariable>>>, - wguard: SpinMutexGuard<'_, WaitVariable>, - ) { - *rguard.lock_var_mut() = NonZero::new(rguard.lock_var().unwrap().get() - 1); - if rguard.lock_var().is_some() { - // There are other active readers - } else { - if let Ok(mut wguard) = WaitQueue::notify_one(wguard) { - // A writer was waiting, pass the lock - *wguard.lock_var_mut() = true; - wguard.drop_after(rguard); - } else { - // No writers were waiting, the lock is released - rtassert!(rguard.queue_empty()); - } - } - } - - #[inline] - pub unsafe fn read_unlock(&self) { - let lock = &*self.inner; - let rguard = lock.readers.lock(); - let wguard = lock.writer.lock(); - unsafe { self.__read_unlock(rguard, wguard) }; - } - - #[inline] - unsafe fn __write_unlock( - &self, - rguard: SpinMutexGuard<'_, WaitVariable>>>, - wguard: SpinMutexGuard<'_, WaitVariable>, - ) { - match WaitQueue::notify_one(wguard) { - Err(mut wguard) => { - // No writers waiting, release the write lock - *wguard.lock_var_mut() = false; - if let Ok(mut rguard) = WaitQueue::notify_all(rguard) { - // One or more readers were waiting, pass the lock to them - if let NotifiedTcs::All { count } = rguard.notified_tcs() { - *rguard.lock_var_mut() = Some(count) - } else { - unreachable!() // called notify_all - } - rguard.drop_after(wguard); - } else { - // No readers waiting, the lock is released - } - } - Ok(wguard) => { - // There was a thread waiting for write, just pass the lock - wguard.drop_after(rguard); - } - } - } - - #[inline] - pub unsafe fn write_unlock(&self) { - let lock = &*self.inner; - let rguard = lock.readers.lock(); - let wguard = lock.writer.lock(); - unsafe { self.__write_unlock(rguard, wguard) }; - } - - // only used by __rust_rwlock_unlock below - #[inline] - #[cfg_attr(test, allow(dead_code))] - unsafe fn unlock(&self) { - let lock = &*self.inner; - let rguard = lock.readers.lock(); - let wguard = lock.writer.lock(); - if *wguard.lock_var() == true { - unsafe { self.__write_unlock(rguard, wguard) }; - } else { - unsafe { self.__read_unlock(rguard, wguard) }; - } - } -} - -// The following functions are needed by libunwind. These symbols are named -// in pre-link args for the target specification, so keep that in sync. -#[cfg(not(test))] -const EINVAL: i32 = 22; - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RwLock) -> i32 { - if p.is_null() { - return EINVAL; - } - unsafe { (*p).read() }; - return 0; -} - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 { - if p.is_null() { - return EINVAL; - } - unsafe { (*p).write() }; - return 0; -} - -#[cfg(not(test))] -#[no_mangle] -pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 { - if p.is_null() { - return EINVAL; - } - unsafe { (*p).unlock() }; - return 0; -} diff --git a/library/std/src/sys/sync/rwlock/sgx/tests.rs b/library/std/src/sys/sync/rwlock/sgx/tests.rs deleted file mode 100644 index 5fd6670afd43..000000000000 --- a/library/std/src/sys/sync/rwlock/sgx/tests.rs +++ /dev/null @@ -1,21 +0,0 @@ -use super::*; -use crate::ptr; - -// Verify that the byte pattern libunwind uses to initialize an RwLock is -// equivalent to the value of RwLock::new(). If the value changes, -// `src/UnwindRustSgx.h` in libunwind needs to be changed too. -#[test] -fn test_c_rwlock_initializer() { - const C_RWLOCK_INIT: *mut () = ptr::null_mut(); - - // For the test to work, we need the padding/unused bytes in RwLock to be - // initialized as 0. In practice, this is the case with statics. - static RUST_RWLOCK_INIT: RwLock = RwLock::new(); - - unsafe { - // If the assertion fails, that not necessarily an issue with the value - // of C_RWLOCK_INIT. It might just be an issue with the way padding - // bytes are initialized in the test code. - assert_eq!(crate::mem::transmute_copy::<_, *mut ()>(&RUST_RWLOCK_INIT), C_RWLOCK_INIT); - }; -} From 8afee1420232e9698aef020b35aff048b9a302e9 Mon Sep 17 00:00:00 2001 From: joboet Date: Thu, 11 Apr 2024 19:36:50 +0200 Subject: [PATCH 016/114] std: use queue-based `RwLock` on Xous --- library/std/src/sys/sync/rwlock/xous.rs | 74 ------------------------- 1 file changed, 74 deletions(-) delete mode 100644 library/std/src/sys/sync/rwlock/xous.rs diff --git a/library/std/src/sys/sync/rwlock/xous.rs b/library/std/src/sys/sync/rwlock/xous.rs deleted file mode 100644 index ab45b33e1f69..000000000000 --- a/library/std/src/sys/sync/rwlock/xous.rs +++ /dev/null @@ -1,74 +0,0 @@ -use crate::sync::atomic::{AtomicIsize, Ordering::Acquire}; -use crate::thread::yield_now; - -pub struct RwLock { - /// The "mode" value indicates how many threads are waiting on this - /// Mutex. Possible values are: - /// -1: The lock is locked for writing - /// 0: The lock is unlocked - /// >=1: The lock is locked for reading - /// - /// This currently spins waiting for the lock to be freed. An - /// optimization would be to involve the ticktimer server to - /// coordinate unlocks. - mode: AtomicIsize, -} - -const RWLOCK_WRITING: isize = -1; -const RWLOCK_FREE: isize = 0; - -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -impl RwLock { - #[inline] - #[rustc_const_stable(feature = "const_locks", since = "1.63.0")] - pub const fn new() -> RwLock { - RwLock { mode: AtomicIsize::new(RWLOCK_FREE) } - } - - #[inline] - pub unsafe fn read(&self) { - while !unsafe { self.try_read() } { - yield_now(); - } - } - - #[inline] - pub unsafe fn try_read(&self) -> bool { - self.mode - .fetch_update( - Acquire, - Acquire, - |v| if v == RWLOCK_WRITING { None } else { Some(v + 1) }, - ) - .is_ok() - } - - #[inline] - pub unsafe fn write(&self) { - while !unsafe { self.try_write() } { - yield_now(); - } - } - - #[inline] - pub unsafe fn try_write(&self) -> bool { - self.mode.compare_exchange(RWLOCK_FREE, RWLOCK_WRITING, Acquire, Acquire).is_ok() - } - - #[inline] - pub unsafe fn read_unlock(&self) { - let previous = self.mode.fetch_sub(1, Acquire); - assert!(previous != RWLOCK_FREE); - assert!(previous != RWLOCK_WRITING); - } - - #[inline] - pub unsafe fn write_unlock(&self) { - assert_eq!( - self.mode.compare_exchange(RWLOCK_WRITING, RWLOCK_FREE, Acquire, Acquire), - Ok(RWLOCK_WRITING) - ); - } -} From dbda4f91aa0cac1ed3885f1c53c7b66a578d16a1 Mon Sep 17 00:00:00 2001 From: joboet Date: Thu, 11 Apr 2024 19:37:12 +0200 Subject: [PATCH 017/114] std: use queue-based `RwLock` on Windows 7 --- library/std/src/sys/sync/rwlock/mod.rs | 16 ++++----- library/std/src/sys/sync/rwlock/windows7.rs | 40 --------------------- 2 files changed, 6 insertions(+), 50 deletions(-) delete mode 100644 library/std/src/sys/sync/rwlock/windows7.rs diff --git a/library/std/src/sys/sync/rwlock/mod.rs b/library/std/src/sys/sync/rwlock/mod.rs index 675931c64bdd..70ba6bf38ef5 100644 --- a/library/std/src/sys/sync/rwlock/mod.rs +++ b/library/std/src/sys/sync/rwlock/mod.rs @@ -12,24 +12,20 @@ cfg_if::cfg_if! { ))] { mod futex; pub use futex::RwLock; - } else if #[cfg(target_family = "unix")] { + } else if #[cfg(any( + target_family = "unix", + all(target_os = "windows", target_vendor = "win7"), + all(target_vendor = "fortanix", target_env = "sgx"), + target_os = "xous", + ))] { mod queue; pub use queue::RwLock; - } else if #[cfg(all(target_os = "windows", target_vendor = "win7"))] { - mod windows7; - pub use windows7::RwLock; - } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] { - mod sgx; - pub use sgx::RwLock; } else if #[cfg(target_os = "solid_asp3")] { mod solid; pub use solid::RwLock; } else if #[cfg(target_os = "teeos")] { mod teeos; pub use teeos::RwLock; - } else if #[cfg(target_os = "xous")] { - mod xous; - pub use xous::RwLock; } else { mod no_threads; pub use no_threads::RwLock; diff --git a/library/std/src/sys/sync/rwlock/windows7.rs b/library/std/src/sys/sync/rwlock/windows7.rs deleted file mode 100644 index e69415baac42..000000000000 --- a/library/std/src/sys/sync/rwlock/windows7.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::cell::UnsafeCell; -use crate::sys::c; - -pub struct RwLock { - inner: UnsafeCell, -} - -unsafe impl Send for RwLock {} -unsafe impl Sync for RwLock {} - -impl RwLock { - #[inline] - pub const fn new() -> RwLock { - RwLock { inner: UnsafeCell::new(c::SRWLOCK_INIT) } - } - #[inline] - pub fn read(&self) { - unsafe { c::AcquireSRWLockShared(self.inner.get()) } - } - #[inline] - pub fn try_read(&self) -> bool { - unsafe { c::TryAcquireSRWLockShared(self.inner.get()) != 0 } - } - #[inline] - pub fn write(&self) { - unsafe { c::AcquireSRWLockExclusive(self.inner.get()) } - } - #[inline] - pub fn try_write(&self) -> bool { - unsafe { c::TryAcquireSRWLockExclusive(self.inner.get()) != 0 } - } - #[inline] - pub unsafe fn read_unlock(&self) { - c::ReleaseSRWLockShared(self.inner.get()) - } - #[inline] - pub unsafe fn write_unlock(&self) { - c::ReleaseSRWLockExclusive(self.inner.get()) - } -} From 6e19f82160c216fcb5f8eaff915b7fe274a5568e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 15 Apr 2024 11:44:14 +0000 Subject: [PATCH 018/114] disable two debuginfo tests under gdb 15 it seems gdb 15 regresses some of our debuginfo tests. disable them temporarily so that CI doesn't randomly start failing soon. --- tests/debuginfo/include_string.rs | 2 ++ tests/debuginfo/vec-slices.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/debuginfo/include_string.rs b/tests/debuginfo/include_string.rs index 75013ab5274e..628ac92fe341 100644 --- a/tests/debuginfo/include_string.rs +++ b/tests/debuginfo/include_string.rs @@ -1,4 +1,6 @@ //@ min-lldb-version: 310 +//@ ignore-gdb-version: 15.0 - 99.0 +// ^ test temporarily disabled as it fails under gdb 15 //@ compile-flags:-g // gdb-command:run diff --git a/tests/debuginfo/vec-slices.rs b/tests/debuginfo/vec-slices.rs index 5a8481699b2e..a8235dba40c0 100644 --- a/tests/debuginfo/vec-slices.rs +++ b/tests/debuginfo/vec-slices.rs @@ -1,4 +1,6 @@ //@ min-lldb-version: 310 +//@ ignore-gdb-version: 15.0 - 99.0 +// ^ test temporarily disabled as it fails under gdb 15 //@ compile-flags:-g From 67334df1eaceede825f81d19c557b73969528d65 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Apr 2024 16:18:32 +0000 Subject: [PATCH 019/114] The new solver ignores `DefineOpaqueTypes`, so switch it to `Yes` We assert that we are in the new solver in the line above --- compiler/rustc_infer/src/infer/at.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index f2222eec76af..1d0afe1709c3 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -282,7 +282,7 @@ impl<'a, 'tcx> Trace<'a, 'tcx> { { let Trace { at, trace } = self; debug_assert!(at.infcx.next_trait_solver()); - let mut fields = at.infcx.combine_fields(trace, at.param_env, DefineOpaqueTypes::No); + let mut fields = at.infcx.combine_fields(trace, at.param_env, DefineOpaqueTypes::Yes); fields .equate(StructurallyRelateAliases::Yes) .relate(a, b) From 96e7d25891fbac3fb693a6c041b93a98712aba15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 14 Apr 2024 16:35:14 +0000 Subject: [PATCH 020/114] add missing lld directive to compiletest --- src/tools/compiletest/src/header.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index f78e0363f55b..99597875d0f9 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -839,6 +839,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-profiler-support", "needs-relocation-model-pic", "needs-run-enabled", + "needs-rust-lld", "needs-rust-lldb", "needs-sanitizer-address", "needs-sanitizer-cfi", From 682535e7775efb2f2e4934b2cf5bc5edc3253968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 14 Apr 2024 16:36:09 +0000 Subject: [PATCH 021/114] add regex to run_make_support note: version more recent than 1.8 depend on memchr 2.6, which creates conflicts as memchr 2.5.0 is pinned elsewhere in the workspace --- Cargo.lock | 1 + src/tools/run-make-support/Cargo.toml | 1 + src/tools/run-make-support/src/lib.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 1f26dd7c43cf..faf2c473ee18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3342,6 +3342,7 @@ name = "run_make_support" version = "0.0.0" dependencies = [ "object 0.34.0", + "regex", "wasmparser", ] diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index d8bb8c643d1d..3ea35c7940c2 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" [dependencies] object = "0.34.0" wasmparser = "0.118.2" +regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 47b46a0a699c..9a4fdff5d152 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -13,6 +13,7 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Output}; pub use object; +pub use regex; pub use wasmparser; pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc}; From 97795923fc06fa3a944337cd5c4461b2c4833cb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 14 Apr 2024 17:00:32 +0000 Subject: [PATCH 022/114] port `rust-lld` test to rmake also check that turning off the linker feature does not use lld --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/rust-lld/Makefile | 12 ---- tests/run-make/rust-lld/rmake.rs | 64 +++++++++++++++++++ 3 files changed, 64 insertions(+), 13 deletions(-) delete mode 100644 tests/run-make/rust-lld/Makefile create mode 100644 tests/run-make/rust-lld/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 3914feb3499d..45d3acd8fd4e 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -250,7 +250,6 @@ run-make/rlib-format-packed-bundled-libs-3/Makefile run-make/rlib-format-packed-bundled-libs/Makefile run-make/rmeta-preferred/Makefile run-make/rust-lld-custom-target/Makefile -run-make/rust-lld/Makefile run-make/rustc-macro-dep-files/Makefile run-make/rustdoc-determinism/Makefile run-make/rustdoc-error-lines/Makefile diff --git a/tests/run-make/rust-lld/Makefile b/tests/run-make/rust-lld/Makefile deleted file mode 100644 index 1ecac479f414..000000000000 --- a/tests/run-make/rust-lld/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# ignore-msvc -# needs-rust-lld -# ignore-s390x lld does not yet support s390x as target -all: - RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Clink-self-contained=+linker -Zlinker-features=+lld -Zunstable-options -Clink-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt - $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt - - # while we're here, also check that the last linker feature flag "wins" - RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Clink-self-contained=+linker -Zlinker-features=-lld -Zlinker-features=+lld -Zunstable-options -Clink-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt - $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs new file mode 100644 index 000000000000..053b580ebd1e --- /dev/null +++ b/tests/run-make/rust-lld/rmake.rs @@ -0,0 +1,64 @@ +// Test linking using `cc` with `rust-lld`, using the unstable CLI described in MCP 510 +// see https://github.com/rust-lang/compiler-team/issues/510 for more info + +//@ needs-rust-lld +//@ ignore-msvc +//@ ignore-s390x lld does not yet support s390x as target + +extern crate run_make_support; + +use run_make_support::regex::Regex; +use run_make_support::rustc; +use std::process::Output; + +fn main() { + // Opt-in to lld and the self-contained linker, to link with rust-lld. We'll check that by + // asking the linker to display its version number with a link-arg. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .arg("-Zlinker-features=+lld") + .arg("-Clink-self-contained=+linker") + .arg("-Zunstable-options") + .arg("-Clink-args=-Wl,-v") + .input("main.rs") + .run(); + assert!( + find_lld_version_in_logs(output), + "the LLD version string should be present in the output logs" + ); + + // It should not be used when we explictly opt-out of lld. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .arg("-Clink-args=-Wl,-v") + .arg("-Zlinker-features=-lld") + .input("main.rs") + .run(); + assert!( + !find_lld_version_in_logs(output), + "the LLD version string should not be present in the output logs" + ); + + // While we're here, also check that the last linker feature flag "wins" when passed multiple + // times to rustc. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .arg("-Clink-args=-Wl,-v") + .arg("-Clink-self-contained=+linker") + .arg("-Zunstable-options") + .arg("-Zlinker-features=-lld") + .arg("-Zlinker-features=+lld") + .arg("-Zlinker-features=-lld,+lld") + .input("main.rs") + .run(); + assert!( + find_lld_version_in_logs(output), + "the LLD version string should be present in the output logs" + ); +} + +fn find_lld_version_in_logs(output: Output) -> bool { + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + let stderr = std::str::from_utf8(&output.stderr).unwrap(); + stderr.lines().any(|line| lld_version_re.is_match(line)) +} From 8fa6984e8edda921d34620f4eca657dc164c0f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 14 Apr 2024 17:15:48 +0000 Subject: [PATCH 023/114] port `rust-lld-custom-target` test to rmake also make sure that rust-lld can be disabled via linker features, even when enabled by default by the target spec --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/rust-lld-custom-target/Makefile | 7 --- .../run-make/rust-lld-custom-target/rmake.rs | 51 +++++++++++++++++++ 3 files changed, 51 insertions(+), 8 deletions(-) delete mode 100644 tests/run-make/rust-lld-custom-target/Makefile create mode 100644 tests/run-make/rust-lld-custom-target/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 45d3acd8fd4e..f0ed0ae806fd 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -249,7 +249,6 @@ run-make/rlib-format-packed-bundled-libs-2/Makefile run-make/rlib-format-packed-bundled-libs-3/Makefile run-make/rlib-format-packed-bundled-libs/Makefile run-make/rmeta-preferred/Makefile -run-make/rust-lld-custom-target/Makefile run-make/rustc-macro-dep-files/Makefile run-make/rustdoc-determinism/Makefile run-make/rustdoc-error-lines/Makefile diff --git a/tests/run-make/rust-lld-custom-target/Makefile b/tests/run-make/rust-lld-custom-target/Makefile deleted file mode 100644 index 007493ab0b99..000000000000 --- a/tests/run-make/rust-lld-custom-target/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -# needs-rust-lld -# only-x86_64-unknown-linux-gnu -all: - RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) --crate-type cdylib --target custom-target.json -Clink-args=-Wl,-v lib.rs 2> $(TMPDIR)/output.txt - $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs new file mode 100644 index 000000000000..1b6e7c65b47e --- /dev/null +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -0,0 +1,51 @@ +// Test linking using `cc` with `rust-lld`, using a custom target with features described in MCP 510 +// see https://github.com/rust-lang/compiler-team/issues/510 for more info: +// +// Starting from the `x86_64-unknown-linux-gnu` target spec, we add the following options: +// - a linker-flavor using lld via a C compiler +// - the self-contained linker component is enabled + +//@ needs-rust-lld +//@ only-x86_64-unknown-linux-gnu + +extern crate run_make_support; + +use run_make_support::regex::Regex; +use run_make_support::rustc; +use std::process::Output; + +fn main() { + // Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking + // the linker to display its version number with a link-arg. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .crate_type("cdylib") + .target("custom-target.json") + .arg("-Clink-args=-Wl,-v") + .input("lib.rs") + .run(); + assert!( + find_lld_version_in_logs(output), + "the LLD version string should be present in the output logs" + ); + + // But it can also be disabled via linker features. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .crate_type("cdylib") + .target("custom-target.json") + .arg("-Zlinker-features=-lld") + .arg("-Clink-args=-Wl,-v") + .input("lib.rs") + .run(); + assert!( + !find_lld_version_in_logs(output), + "the LLD version string should not be present in the output logs" + ); +} + +fn find_lld_version_in_logs(output: Output) -> bool { + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + let stderr = std::str::from_utf8(&output.stderr).unwrap(); + stderr.lines().any(|line| lld_version_re.is_match(line)) +} From 8acfe9a1380f73fade8dfe35aa054b3b6870faee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 15 Apr 2024 18:08:55 +0000 Subject: [PATCH 024/114] add `link_arg` helper to `run_make_support` and use it in the `rust-lld` tests --- src/tools/run-make-support/src/rustc.rs | 6 ++++++ tests/run-make/rust-lld-custom-target/rmake.rs | 4 ++-- tests/run-make/rust-lld/rmake.rs | 6 +++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index ebda151b908b..88e409a588a1 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -149,6 +149,12 @@ impl Rustc { self } + /// Add an extra argument to the linker invocation, via `-Clink-arg`. + pub fn link_arg(&mut self, link_arg: &str) -> &mut Self { + self.cmd.arg(format!("-Clink-arg={link_arg}")); + self + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index 1b6e7c65b47e..b5341725e36e 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -21,7 +21,7 @@ fn main() { .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") .crate_type("cdylib") .target("custom-target.json") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .input("lib.rs") .run(); assert!( @@ -35,7 +35,7 @@ fn main() { .crate_type("cdylib") .target("custom-target.json") .arg("-Zlinker-features=-lld") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .input("lib.rs") .run(); assert!( diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index 053b580ebd1e..acb6d74aaa8b 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -19,7 +19,7 @@ fn main() { .arg("-Zlinker-features=+lld") .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .input("main.rs") .run(); assert!( @@ -30,7 +30,7 @@ fn main() { // It should not be used when we explictly opt-out of lld. let output = rustc() .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .arg("-Zlinker-features=-lld") .input("main.rs") .run(); @@ -43,7 +43,7 @@ fn main() { // times to rustc. let output = rustc() .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") .arg("-Zlinker-features=-lld") From 99e88e59c8b82996133cdcbdd3e2a4a284d97963 Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Mon, 15 Apr 2024 12:41:32 -0700 Subject: [PATCH 025/114] sanitizers: Add rustc_sanitizers to triagebot.toml --- triagebot.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index b96225c45205..e2ee4b12638e 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -384,7 +384,7 @@ trigger_files = [ [autolabel."PG-exploit-mitigations"] trigger_files = [ - "compiler/rustc_symbol_mangling/src/typeid", + "compiler/rustc_sanitizers", "src/doc/rustc/src/exploit-mitigations.md", "src/doc/unstable-book/src/compiler-flags/branch-protection.md", "src/doc/unstable-book/src/compiler-flags/cf-protection.md", @@ -701,7 +701,7 @@ cc = ["@nnethercote"] message = "Changes to the size of AST and/or HIR nodes." cc = ["@nnethercote"] -[mentions."compiler/rustc_symbol_mangling/src/typeid"] +[mentions."compiler/rustc_sanitizers"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] [mentions."src/doc/rustc/src/exploit-mitigations.md"] From 83d73e4929c3ad0c5c170da012c7c487a1b89398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Mon, 15 Apr 2024 19:14:21 +0200 Subject: [PATCH 026/114] crashes: readme: add reminder to add Fixes #abcde to prs to automatically close issues. --- tests/crashes/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/crashes/README.md b/tests/crashes/README.md index dee11e2a3dd0..71ce9b2eca6f 100644 --- a/tests/crashes/README.md +++ b/tests/crashes/README.md @@ -14,3 +14,10 @@ If you happen to fix one of the crashes, please move it to a fitting subdirectory in `tests/ui` and give it a meaningful name. Also please add a doc comment at the top of the file explaining why this test exists. :) +Adding +Fixes #NNNNN +Fixes #MMMMM +to the description of your pull request will ensure the +corresponding tickets will be closed automatically upon merge. +The ticket ids can be found in the file name or the `known-bug` annotation +inside the testfile. From af887d3c42e6d2a2885f846ba0a67c052743fa7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 15 Apr 2024 19:45:01 +0000 Subject: [PATCH 027/114] mention json target specs in `run_make_support` --- src/tools/run-make-support/src/rustc.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 88e409a588a1..9bf41c6e2e9a 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -128,9 +128,8 @@ impl Rustc { self } - /// Specify target triple. + /// Specify the target triple, or a path to a custom target json spec file. pub fn target(&mut self, target: &str) -> &mut Self { - assert!(!target.contains(char::is_whitespace), "target triple cannot contain spaces"); self.cmd.arg(format!("--target={target}")); self } From 909fcfcb6a01b9a811835ba001954e6c62b2a2bc Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 25 Feb 2024 14:56:14 +0100 Subject: [PATCH 028/114] Stabilize checking of cfgs at compile-time: --check-cfg option --- compiler/rustc_session/src/config.rs | 2 +- src/librustdoc/doctest.rs | 7 ++----- src/librustdoc/lib.rs | 2 +- tests/rustdoc-ui/{check-cfg => }/check-cfg.rs | 2 +- tests/rustdoc-ui/{check-cfg => }/check-cfg.stderr | 0 tests/rustdoc-ui/check-cfg/check-cfg-test.stderr | 11 ----------- tests/rustdoc-ui/check-cfg/check-cfg-unstable.rs | 2 -- tests/rustdoc-ui/check-cfg/check-cfg-unstable.stderr | 2 -- tests/ui/check-cfg/allow-at-crate-level.rs | 2 +- tests/ui/check-cfg/allow-macro-cfg.rs | 2 +- tests/ui/check-cfg/allow-same-level.rs | 2 +- tests/ui/check-cfg/allow-top-level.rs | 2 +- tests/ui/check-cfg/allow-upper-level.rs | 2 +- tests/ui/check-cfg/cargo-feature.none.stderr | 8 ++++---- tests/ui/check-cfg/cargo-feature.rs | 1 - tests/ui/check-cfg/cargo-feature.some.stderr | 8 ++++---- .../ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs | 1 - .../check-cfg/cfg-value-for-cfg-name-duplicate.stderr | 2 +- tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs | 1 - .../check-cfg/cfg-value-for-cfg-name-multiple.stderr | 2 +- tests/ui/check-cfg/cfg-value-for-cfg-name.rs | 1 - tests/ui/check-cfg/cfg-value-for-cfg-name.stderr | 4 ++-- tests/ui/check-cfg/compact-names.rs | 2 +- tests/ui/check-cfg/compact-values.rs | 2 +- tests/ui/check-cfg/concat-values.rs | 1 - tests/ui/check-cfg/concat-values.stderr | 4 ++-- tests/ui/check-cfg/diagnotics.rs | 2 +- tests/ui/check-cfg/empty-values.rs | 2 +- .../exhaustive-names-values.empty_cfg.stderr | 8 ++++---- .../check-cfg/exhaustive-names-values.feature.stderr | 6 +++--- .../ui/check-cfg/exhaustive-names-values.full.stderr | 6 +++--- tests/ui/check-cfg/exhaustive-names-values.rs | 1 - tests/ui/check-cfg/exhaustive-names.rs | 2 +- tests/ui/check-cfg/exhaustive-values.rs | 4 ++-- tests/ui/check-cfg/invalid-arguments.rs | 1 - tests/ui/check-cfg/mix.rs | 2 +- tests/ui/check-cfg/no-expected-values.empty.stderr | 4 ++-- tests/ui/check-cfg/no-expected-values.mixed.stderr | 4 ++-- tests/ui/check-cfg/no-expected-values.rs | 1 - tests/ui/check-cfg/no-expected-values.simple.stderr | 4 ++-- tests/ui/check-cfg/order-independant.rs | 2 -- .../check-cfg/order-independant.values_after.stderr | 2 +- .../check-cfg/order-independant.values_before.stderr | 2 +- tests/ui/check-cfg/stmt-no-ice.rs | 2 +- tests/ui/check-cfg/unexpected-cfg-name.rs | 2 +- tests/ui/check-cfg/unexpected-cfg-value.rs | 2 +- tests/ui/check-cfg/unknown-values.rs | 1 - tests/ui/check-cfg/values-none.explicit.stderr | 4 ++-- tests/ui/check-cfg/values-none.implicit.stderr | 4 ++-- tests/ui/check-cfg/values-none.rs | 1 - tests/ui/check-cfg/values-target-json.rs | 2 +- tests/ui/check-cfg/well-known-names.rs | 2 +- tests/ui/check-cfg/well-known-values.rs | 2 +- tests/ui/feature-gates/feature-gate-check-cfg.rs | 3 --- tests/ui/feature-gates/feature-gate-check-cfg.stderr | 2 -- 55 files changed, 60 insertions(+), 95 deletions(-) rename tests/rustdoc-ui/{check-cfg => }/check-cfg.rs (73%) rename tests/rustdoc-ui/{check-cfg => }/check-cfg.stderr (100%) delete mode 100644 tests/rustdoc-ui/check-cfg/check-cfg-test.stderr delete mode 100644 tests/rustdoc-ui/check-cfg/check-cfg-unstable.rs delete mode 100644 tests/rustdoc-ui/check-cfg/check-cfg-unstable.stderr delete mode 100644 tests/ui/feature-gates/feature-gate-check-cfg.rs delete mode 100644 tests/ui/feature-gates/feature-gate-check-cfg.stderr diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7aca86f7169d..d9fc43625ef5 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1373,7 +1373,7 @@ pub fn rustc_short_optgroups() -> Vec { opt::flag_s("h", "help", "Display this message"), opt::multi_s("", "cfg", "Configure the compilation environment. SPEC supports the syntax `NAME[=\"VALUE\"]`.", "SPEC"), - opt::multi("", "check-cfg", "Provide list of valid cfg options for checking", "SPEC"), + opt::multi_s("", "check-cfg", "Provide list of expected cfgs for checking", "SPEC"), opt::multi_s( "L", "", diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 22a3cf4d44db..0ad4c9c23464 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -60,11 +60,8 @@ pub(crate) fn generate_args_file(file_path: &Path, options: &RustdocOptions) -> for cfg in &options.cfgs { content.push(format!("--cfg={cfg}")); } - if !options.check_cfgs.is_empty() { - content.push("-Zunstable-options".to_string()); - for check_cfg in &options.check_cfgs { - content.push(format!("--check-cfg={check_cfg}")); - } + for check_cfg in &options.check_cfgs { + content.push(format!("--check-cfg={check_cfg}")); } for lib_str in &options.lib_strs { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index b78fb4c4eee2..f2a7518b4ce2 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -242,7 +242,7 @@ fn opts() -> Vec { o.optmulti("L", "library-path", "directory to add to crate search path", "DIR") }), stable("cfg", |o| o.optmulti("", "cfg", "pass a --cfg to rustc", "")), - unstable("check-cfg", |o| o.optmulti("", "check-cfg", "pass a --check-cfg to rustc", "")), + stable("check-cfg", |o| o.optmulti("", "check-cfg", "pass a --check-cfg to rustc", "")), stable("extern", |o| o.optmulti("", "extern", "pass an --extern to rustc", "NAME[=PATH]")), unstable("extern-html-root-url", |o| { o.optmulti( diff --git a/tests/rustdoc-ui/check-cfg/check-cfg.rs b/tests/rustdoc-ui/check-cfg.rs similarity index 73% rename from tests/rustdoc-ui/check-cfg/check-cfg.rs rename to tests/rustdoc-ui/check-cfg.rs index 27b09985728d..6ca37db75af0 100644 --- a/tests/rustdoc-ui/check-cfg/check-cfg.rs +++ b/tests/rustdoc-ui/check-cfg.rs @@ -1,5 +1,5 @@ //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() /// uniz is nor a builtin nor pass as arguments so is unexpected #[cfg(uniz)] diff --git a/tests/rustdoc-ui/check-cfg/check-cfg.stderr b/tests/rustdoc-ui/check-cfg.stderr similarity index 100% rename from tests/rustdoc-ui/check-cfg/check-cfg.stderr rename to tests/rustdoc-ui/check-cfg.stderr diff --git a/tests/rustdoc-ui/check-cfg/check-cfg-test.stderr b/tests/rustdoc-ui/check-cfg/check-cfg-test.stderr deleted file mode 100644 index 9770be2f191f..000000000000 --- a/tests/rustdoc-ui/check-cfg/check-cfg-test.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: unexpected `cfg` condition value - --> $DIR/check-cfg-test.rs:9:7 - | -LL | #[cfg(feature = "invalid")] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: expected values for `feature` are: test - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: 1 warning emitted - diff --git a/tests/rustdoc-ui/check-cfg/check-cfg-unstable.rs b/tests/rustdoc-ui/check-cfg/check-cfg-unstable.rs deleted file mode 100644 index b24b198e807a..000000000000 --- a/tests/rustdoc-ui/check-cfg/check-cfg-unstable.rs +++ /dev/null @@ -1,2 +0,0 @@ -//@ check-fail -//@ compile-flags: --check-cfg=cfg() diff --git a/tests/rustdoc-ui/check-cfg/check-cfg-unstable.stderr b/tests/rustdoc-ui/check-cfg/check-cfg-unstable.stderr deleted file mode 100644 index 9b27c2bc058a..000000000000 --- a/tests/rustdoc-ui/check-cfg/check-cfg-unstable.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: the `-Z unstable-options` flag must also be passed to enable the flag `check-cfg` - diff --git a/tests/ui/check-cfg/allow-at-crate-level.rs b/tests/ui/check-cfg/allow-at-crate-level.rs index 48258b97ccc4..03b4676ad5f1 100644 --- a/tests/ui/check-cfg/allow-at-crate-level.rs +++ b/tests/ui/check-cfg/allow-at-crate-level.rs @@ -1,7 +1,7 @@ // This test check that #![allow(unexpected_cfgs)] works with --cfg // //@ check-pass -//@ compile-flags: --cfg=unexpected --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --cfg=unexpected --check-cfg=cfg() #![allow(unexpected_cfgs)] diff --git a/tests/ui/check-cfg/allow-macro-cfg.rs b/tests/ui/check-cfg/allow-macro-cfg.rs index d3999af77663..3db6e18d77a8 100644 --- a/tests/ui/check-cfg/allow-macro-cfg.rs +++ b/tests/ui/check-cfg/allow-macro-cfg.rs @@ -1,7 +1,7 @@ // This test check that local #[allow(unexpected_cfgs)] works // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[allow(unexpected_cfgs)] fn foo() { diff --git a/tests/ui/check-cfg/allow-same-level.rs b/tests/ui/check-cfg/allow-same-level.rs index 231ad522c8d0..e932ece6ee77 100644 --- a/tests/ui/check-cfg/allow-same-level.rs +++ b/tests/ui/check-cfg/allow-same-level.rs @@ -1,7 +1,7 @@ // This test check that #[allow(unexpected_cfgs)] doesn't work if put on the same level // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[allow(unexpected_cfgs)] #[cfg(FALSE)] diff --git a/tests/ui/check-cfg/allow-top-level.rs b/tests/ui/check-cfg/allow-top-level.rs index c77a0c7c97ba..0f88543d8478 100644 --- a/tests/ui/check-cfg/allow-top-level.rs +++ b/tests/ui/check-cfg/allow-top-level.rs @@ -1,7 +1,7 @@ // This test check that a top-level #![allow(unexpected_cfgs)] works // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #![allow(unexpected_cfgs)] diff --git a/tests/ui/check-cfg/allow-upper-level.rs b/tests/ui/check-cfg/allow-upper-level.rs index 97339a887bf5..d03d0cab37b7 100644 --- a/tests/ui/check-cfg/allow-upper-level.rs +++ b/tests/ui/check-cfg/allow-upper-level.rs @@ -1,7 +1,7 @@ // This test check that #[allow(unexpected_cfgs)] work if put on an upper level // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[allow(unexpected_cfgs)] mod aa { diff --git a/tests/ui/check-cfg/cargo-feature.none.stderr b/tests/ui/check-cfg/cargo-feature.none.stderr index 09a1c9502672..0b914c2bc355 100644 --- a/tests/ui/check-cfg/cargo-feature.none.stderr +++ b/tests/ui/check-cfg/cargo-feature.none.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `serde` - --> $DIR/cargo-feature.rs:14:7 + --> $DIR/cargo-feature.rs:13:7 | LL | #[cfg(feature = "serde")] | ^^^^^^^^^^^^^^^^^ help: remove the condition @@ -10,7 +10,7 @@ LL | #[cfg(feature = "serde")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) - --> $DIR/cargo-feature.rs:18:7 + --> $DIR/cargo-feature.rs:17:7 | LL | #[cfg(feature)] | ^^^^^^^ help: remove the condition @@ -20,7 +20,7 @@ LL | #[cfg(feature)] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `tokio_unstable` - --> $DIR/cargo-feature.rs:22:7 + --> $DIR/cargo-feature.rs:21:7 | LL | #[cfg(tokio_unstable)] | ^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | #[cfg(tokio_unstable)] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `CONFIG_NVME` - --> $DIR/cargo-feature.rs:26:7 + --> $DIR/cargo-feature.rs:25:7 | LL | #[cfg(CONFIG_NVME = "m")] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/cargo-feature.rs b/tests/ui/check-cfg/cargo-feature.rs index ba451921d794..ced0d381d2df 100644 --- a/tests/ui/check-cfg/cargo-feature.rs +++ b/tests/ui/check-cfg/cargo-feature.rs @@ -5,7 +5,6 @@ //@ check-pass //@ revisions: some none //@ rustc-env:CARGO_CRATE_NAME=foo -//@ compile-flags: -Z unstable-options //@ [none]compile-flags: --check-cfg=cfg(feature,values()) //@ [some]compile-flags: --check-cfg=cfg(feature,values("bitcode")) //@ [some]compile-flags: --check-cfg=cfg(CONFIG_NVME,values("y")) diff --git a/tests/ui/check-cfg/cargo-feature.some.stderr b/tests/ui/check-cfg/cargo-feature.some.stderr index 4db9c66fc869..1a4ef89efc1a 100644 --- a/tests/ui/check-cfg/cargo-feature.some.stderr +++ b/tests/ui/check-cfg/cargo-feature.some.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `serde` - --> $DIR/cargo-feature.rs:14:7 + --> $DIR/cargo-feature.rs:13:7 | LL | #[cfg(feature = "serde")] | ^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | #[cfg(feature = "serde")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) - --> $DIR/cargo-feature.rs:18:7 + --> $DIR/cargo-feature.rs:17:7 | LL | #[cfg(feature)] | ^^^^^^^- help: specify a config value: `= "bitcode"` @@ -20,7 +20,7 @@ LL | #[cfg(feature)] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `tokio_unstable` - --> $DIR/cargo-feature.rs:22:7 + --> $DIR/cargo-feature.rs:21:7 | LL | #[cfg(tokio_unstable)] | ^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | #[cfg(tokio_unstable)] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `m` - --> $DIR/cargo-feature.rs:26:7 + --> $DIR/cargo-feature.rs:25:7 | LL | #[cfg(CONFIG_NVME = "m")] | ^^^^^^^^^^^^^^--- diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs index 35c5f2ae31cc..79d4e45c13b4 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs @@ -2,7 +2,6 @@ // This test checks we won't suggest more than 3 span suggestions for cfg names // //@ check-pass -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(foo,values("value")) --check-cfg=cfg(bar,values("value")) --check-cfg=cfg(bee,values("value")) --check-cfg=cfg(cow,values("value")) #[cfg(value)] diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr index 9c190117e745..46d6d29b15eb 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `value` - --> $DIR/cfg-value-for-cfg-name-duplicate.rs:8:7 + --> $DIR/cfg-value-for-cfg-name-duplicate.rs:7:7 | LL | #[cfg(value)] | ^^^^^ diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs index 6caedbe719e5..f2fd050bb75a 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs @@ -2,7 +2,6 @@ // This test checks that when a single cfg has a value for user's specified name // //@ check-pass -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(foo,values("my_value")) --check-cfg=cfg(bar,values("my_value")) #[cfg(my_value)] diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr index 7113790b83ae..a70a8b2d3e4a 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `my_value` - --> $DIR/cfg-value-for-cfg-name-multiple.rs:8:7 + --> $DIR/cfg-value-for-cfg-name-multiple.rs:7:7 | LL | #[cfg(my_value)] | ^^^^^^^^ diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name.rs b/tests/ui/check-cfg/cfg-value-for-cfg-name.rs index eade190a75cc..e8f9095655b5 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name.rs +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name.rs @@ -3,7 +3,6 @@ // suggest to use `#[cfg(target_os = "linux")]` instead of `#[cfg(linux)]` // //@ check-pass -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg() #[cfg(linux)] diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr index ba9f5f4acbd5..fab7f595c250 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `linux` - --> $DIR/cfg-value-for-cfg-name.rs:9:7 + --> $DIR/cfg-value-for-cfg-name.rs:8:7 | LL | #[cfg(linux)] | ^^^^^ help: found config with similar value: `target_os = "linux"` @@ -10,7 +10,7 @@ LL | #[cfg(linux)] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `linux` - --> $DIR/cfg-value-for-cfg-name.rs:14:7 + --> $DIR/cfg-value-for-cfg-name.rs:13:7 | LL | #[cfg(linux = "os-name")] | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/compact-names.rs b/tests/ui/check-cfg/compact-names.rs index 6592d2acb82d..ddbd20b99b28 100644 --- a/tests/ui/check-cfg/compact-names.rs +++ b/tests/ui/check-cfg/compact-names.rs @@ -1,7 +1,7 @@ // This test check that we correctly emit an warning for compact cfg // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #![feature(cfg_target_compact)] diff --git a/tests/ui/check-cfg/compact-values.rs b/tests/ui/check-cfg/compact-values.rs index 8df2bf55264f..bda4686ebd74 100644 --- a/tests/ui/check-cfg/compact-values.rs +++ b/tests/ui/check-cfg/compact-values.rs @@ -1,7 +1,7 @@ // This test check that we correctly emit an warning for compact cfg // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #![feature(cfg_target_compact)] diff --git a/tests/ui/check-cfg/concat-values.rs b/tests/ui/check-cfg/concat-values.rs index 0b2c1949ca39..c546590a2c1f 100644 --- a/tests/ui/check-cfg/concat-values.rs +++ b/tests/ui/check-cfg/concat-values.rs @@ -1,5 +1,4 @@ //@ check-pass -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(my_cfg,values("foo")) --check-cfg=cfg(my_cfg,values("bar")) //@ compile-flags: --check-cfg=cfg(my_cfg,values()) diff --git a/tests/ui/check-cfg/concat-values.stderr b/tests/ui/check-cfg/concat-values.stderr index 6fe9f2baa09f..dec43f5bda3b 100644 --- a/tests/ui/check-cfg/concat-values.stderr +++ b/tests/ui/check-cfg/concat-values.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: (none) - --> $DIR/concat-values.rs:6:7 + --> $DIR/concat-values.rs:5:7 | LL | #[cfg(my_cfg)] | ^^^^^^ @@ -10,7 +10,7 @@ LL | #[cfg(my_cfg)] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `unk` - --> $DIR/concat-values.rs:10:7 + --> $DIR/concat-values.rs:9:7 | LL | #[cfg(my_cfg = "unk")] | ^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/diagnotics.rs b/tests/ui/check-cfg/diagnotics.rs index 134bfcf8ef49..cccd6f9bbc3e 100644 --- a/tests/ui/check-cfg/diagnotics.rs +++ b/tests/ui/check-cfg/diagnotics.rs @@ -2,7 +2,7 @@ //@ revisions: cargo rustc //@ [rustc]unset-rustc-env:CARGO_CRATE_NAME //@ [cargo]rustc-env:CARGO_CRATE_NAME=foo -//@ compile-flags: --check-cfg=cfg(feature,values("foo")) --check-cfg=cfg(no_values) -Z unstable-options +//@ compile-flags: --check-cfg=cfg(feature,values("foo")) --check-cfg=cfg(no_values) #[cfg(featur)] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/empty-values.rs b/tests/ui/check-cfg/empty-values.rs index 07462951e1bf..cad2d351b962 100644 --- a/tests/ui/check-cfg/empty-values.rs +++ b/tests/ui/check-cfg/empty-values.rs @@ -1,7 +1,7 @@ // Check that we detect unexpected value when none are allowed // //@ check-pass -//@ compile-flags: --check-cfg=cfg(foo,values()) -Zunstable-options +//@ compile-flags: --check-cfg=cfg(foo,values()) #[cfg(foo = "foo")] //~^ WARNING unexpected `cfg` condition value diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr index d28702633427..5d1fc74137b3 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:10:7 + --> $DIR/exhaustive-names-values.rs:9:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | #[cfg(unknown_key = "value")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:14:7 + --> $DIR/exhaustive-names-values.rs:13:7 | LL | #[cfg(test = "value")] | ^^^^---------- @@ -21,7 +21,7 @@ LL | #[cfg(test = "value")] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` - --> $DIR/exhaustive-names-values.rs:18:7 + --> $DIR/exhaustive-names-values.rs:17:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ @@ -30,7 +30,7 @@ LL | #[cfg(feature = "unk")] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` - --> $DIR/exhaustive-names-values.rs:25:7 + --> $DIR/exhaustive-names-values.rs:24:7 | LL | #[cfg(feature = "std")] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr index b24b10bb6150..9be2ec71b44d 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:10:7 + --> $DIR/exhaustive-names-values.rs:9:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | #[cfg(unknown_key = "value")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:14:7 + --> $DIR/exhaustive-names-values.rs:13:7 | LL | #[cfg(test = "value")] | ^^^^---------- @@ -21,7 +21,7 @@ LL | #[cfg(test = "value")] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` - --> $DIR/exhaustive-names-values.rs:18:7 + --> $DIR/exhaustive-names-values.rs:17:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr index b24b10bb6150..9be2ec71b44d 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:10:7 + --> $DIR/exhaustive-names-values.rs:9:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ @@ -10,7 +10,7 @@ LL | #[cfg(unknown_key = "value")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:14:7 + --> $DIR/exhaustive-names-values.rs:13:7 | LL | #[cfg(test = "value")] | ^^^^---------- @@ -21,7 +21,7 @@ LL | #[cfg(test = "value")] = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` - --> $DIR/exhaustive-names-values.rs:18:7 + --> $DIR/exhaustive-names-values.rs:17:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/exhaustive-names-values.rs b/tests/ui/check-cfg/exhaustive-names-values.rs index d554c19ef25a..f6c3e1f575ad 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.rs +++ b/tests/ui/check-cfg/exhaustive-names-values.rs @@ -2,7 +2,6 @@ // //@ check-pass //@ revisions: empty_cfg feature full -//@ compile-flags: -Z unstable-options //@ [empty_cfg]compile-flags: --check-cfg=cfg() //@ [feature]compile-flags: --check-cfg=cfg(feature,values("std")) //@ [full]compile-flags: --check-cfg=cfg(feature,values("std")) --check-cfg=cfg() diff --git a/tests/ui/check-cfg/exhaustive-names.rs b/tests/ui/check-cfg/exhaustive-names.rs index edfb3705a7dc..23bde4dff550 100644 --- a/tests/ui/check-cfg/exhaustive-names.rs +++ b/tests/ui/check-cfg/exhaustive-names.rs @@ -1,7 +1,7 @@ // Check warning for unexpected cfg // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[cfg(unknown_key = "value")] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/exhaustive-values.rs b/tests/ui/check-cfg/exhaustive-values.rs index 5e65caa6aea7..029b2ff2c691 100644 --- a/tests/ui/check-cfg/exhaustive-values.rs +++ b/tests/ui/check-cfg/exhaustive-values.rs @@ -2,8 +2,8 @@ // //@ check-pass //@ revisions: empty_cfg without_names -//@ [empty_cfg]compile-flags: --check-cfg=cfg() -Z unstable-options -//@ [without_names]compile-flags: --check-cfg=cfg(any()) -Z unstable-options +//@ [empty_cfg]compile-flags: --check-cfg=cfg() +//@ [without_names]compile-flags: --check-cfg=cfg(any()) #[cfg(test = "value")] //~^ WARNING unexpected `cfg` condition value diff --git a/tests/ui/check-cfg/invalid-arguments.rs b/tests/ui/check-cfg/invalid-arguments.rs index bdcc202443ba..84087a16e80e 100644 --- a/tests/ui/check-cfg/invalid-arguments.rs +++ b/tests/ui/check-cfg/invalid-arguments.rs @@ -9,7 +9,6 @@ //@ revisions: mixed_values_any mixed_any any_values giberich unterminated //@ revisions: none_not_empty cfg_none // -//@ compile-flags: -Z unstable-options //@ [anything_else]compile-flags: --check-cfg=anything_else(...) //@ [string_for_name_1]compile-flags: --check-cfg=cfg("NOT_IDENT") //@ [string_for_name_2]compile-flags: --check-cfg=cfg(foo,"NOT_IDENT",bar) diff --git a/tests/ui/check-cfg/mix.rs b/tests/ui/check-cfg/mix.rs index 69156ab67635..ab8a180bc6f4 100644 --- a/tests/ui/check-cfg/mix.rs +++ b/tests/ui/check-cfg/mix.rs @@ -3,7 +3,7 @@ // we correctly lint on the `cfg!` macro and `cfg_attr` attribute. // //@ check-pass -//@ compile-flags: --cfg feature="bar" --cfg unknown_name -Z unstable-options +//@ compile-flags: --cfg feature="bar" --cfg unknown_name //@ compile-flags: --check-cfg=cfg(feature,values("foo")) #[cfg(windows)] diff --git a/tests/ui/check-cfg/no-expected-values.empty.stderr b/tests/ui/check-cfg/no-expected-values.empty.stderr index 0c0dbe9bac60..65827efdd39a 100644 --- a/tests/ui/check-cfg/no-expected-values.empty.stderr +++ b/tests/ui/check-cfg/no-expected-values.empty.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:11:7 + --> $DIR/no-expected-values.rs:10:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^-------- @@ -12,7 +12,7 @@ LL | #[cfg(feature = "foo")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:15:7 + --> $DIR/no-expected-values.rs:14:7 | LL | #[cfg(test = "foo")] | ^^^^-------- diff --git a/tests/ui/check-cfg/no-expected-values.mixed.stderr b/tests/ui/check-cfg/no-expected-values.mixed.stderr index 0c0dbe9bac60..65827efdd39a 100644 --- a/tests/ui/check-cfg/no-expected-values.mixed.stderr +++ b/tests/ui/check-cfg/no-expected-values.mixed.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:11:7 + --> $DIR/no-expected-values.rs:10:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^-------- @@ -12,7 +12,7 @@ LL | #[cfg(feature = "foo")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:15:7 + --> $DIR/no-expected-values.rs:14:7 | LL | #[cfg(test = "foo")] | ^^^^-------- diff --git a/tests/ui/check-cfg/no-expected-values.rs b/tests/ui/check-cfg/no-expected-values.rs index a80f9ec97764..42e7f45fa7a9 100644 --- a/tests/ui/check-cfg/no-expected-values.rs +++ b/tests/ui/check-cfg/no-expected-values.rs @@ -2,7 +2,6 @@ // //@ check-pass //@ revisions: simple mixed empty -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(values,simple,mixed,empty) //@ [simple]compile-flags: --check-cfg=cfg(test) --check-cfg=cfg(feature) //@ [mixed]compile-flags: --check-cfg=cfg(test,feature) diff --git a/tests/ui/check-cfg/no-expected-values.simple.stderr b/tests/ui/check-cfg/no-expected-values.simple.stderr index 0c0dbe9bac60..65827efdd39a 100644 --- a/tests/ui/check-cfg/no-expected-values.simple.stderr +++ b/tests/ui/check-cfg/no-expected-values.simple.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:11:7 + --> $DIR/no-expected-values.rs:10:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^-------- @@ -12,7 +12,7 @@ LL | #[cfg(feature = "foo")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:15:7 + --> $DIR/no-expected-values.rs:14:7 | LL | #[cfg(test = "foo")] | ^^^^-------- diff --git a/tests/ui/check-cfg/order-independant.rs b/tests/ui/check-cfg/order-independant.rs index 9ac96d0b15bf..671d2e764d30 100644 --- a/tests/ui/check-cfg/order-independant.rs +++ b/tests/ui/check-cfg/order-independant.rs @@ -1,9 +1,7 @@ //@ check-pass // //@ revisions: values_before values_after -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(values_before,values_after) -// //@ [values_before]compile-flags: --check-cfg=cfg(a,values("b")) --check-cfg=cfg(a) //@ [values_after]compile-flags: --check-cfg=cfg(a) --check-cfg=cfg(a,values("b")) diff --git a/tests/ui/check-cfg/order-independant.values_after.stderr b/tests/ui/check-cfg/order-independant.values_after.stderr index d1de26ba3039..2be28be39a7a 100644 --- a/tests/ui/check-cfg/order-independant.values_after.stderr +++ b/tests/ui/check-cfg/order-independant.values_after.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `unk` - --> $DIR/order-independant.rs:13:7 + --> $DIR/order-independant.rs:11:7 | LL | #[cfg(a = "unk")] | ^^^^^^^^^ diff --git a/tests/ui/check-cfg/order-independant.values_before.stderr b/tests/ui/check-cfg/order-independant.values_before.stderr index d1de26ba3039..2be28be39a7a 100644 --- a/tests/ui/check-cfg/order-independant.values_before.stderr +++ b/tests/ui/check-cfg/order-independant.values_before.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `unk` - --> $DIR/order-independant.rs:13:7 + --> $DIR/order-independant.rs:11:7 | LL | #[cfg(a = "unk")] | ^^^^^^^^^ diff --git a/tests/ui/check-cfg/stmt-no-ice.rs b/tests/ui/check-cfg/stmt-no-ice.rs index 8a447ade068d..866a5836db0d 100644 --- a/tests/ui/check-cfg/stmt-no-ice.rs +++ b/tests/ui/check-cfg/stmt-no-ice.rs @@ -1,7 +1,7 @@ // This test checks that there is no ICE with this code // //@ check-pass -//@ compile-flags:--check-cfg=cfg() -Z unstable-options +//@ compile-flags:--check-cfg=cfg() fn main() { #[cfg(crossbeam_loom)] diff --git a/tests/ui/check-cfg/unexpected-cfg-name.rs b/tests/ui/check-cfg/unexpected-cfg-name.rs index 5ea9f560ee42..365c29d10fbb 100644 --- a/tests/ui/check-cfg/unexpected-cfg-name.rs +++ b/tests/ui/check-cfg/unexpected-cfg-name.rs @@ -1,7 +1,7 @@ // Check warning for unexpected configuration name // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[cfg(widnows)] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/unexpected-cfg-value.rs b/tests/ui/check-cfg/unexpected-cfg-value.rs index a4a10e503be5..583cf40c4851 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.rs +++ b/tests/ui/check-cfg/unexpected-cfg-value.rs @@ -1,7 +1,7 @@ // Check for unexpected configuration value in the code. // //@ check-pass -//@ compile-flags: --cfg=feature="rand" -Z unstable-options +//@ compile-flags: --cfg=feature="rand" //@ compile-flags: --check-cfg=cfg(feature,values("serde","full")) #[cfg(feature = "sedre")] diff --git a/tests/ui/check-cfg/unknown-values.rs b/tests/ui/check-cfg/unknown-values.rs index 61ea82871b23..7b2b00fe9d4c 100644 --- a/tests/ui/check-cfg/unknown-values.rs +++ b/tests/ui/check-cfg/unknown-values.rs @@ -2,7 +2,6 @@ // //@ check-pass //@ revisions: simple mixed with_values -//@ compile-flags: -Z unstable-options //@ compile-flags: --check-cfg=cfg(simple,mixed,with_values) //@ [simple]compile-flags: --check-cfg=cfg(foo,values(any())) //@ [mixed]compile-flags: --check-cfg=cfg(foo) --check-cfg=cfg(foo,values(any())) diff --git a/tests/ui/check-cfg/values-none.explicit.stderr b/tests/ui/check-cfg/values-none.explicit.stderr index a025ff441b70..c14cde940052 100644 --- a/tests/ui/check-cfg/values-none.explicit.stderr +++ b/tests/ui/check-cfg/values-none.explicit.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `too` - --> $DIR/values-none.rs:11:7 + --> $DIR/values-none.rs:10:7 | LL | #[cfg(foo = "too")] | ^^^-------- @@ -12,7 +12,7 @@ LL | #[cfg(foo = "too")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `bar` - --> $DIR/values-none.rs:16:7 + --> $DIR/values-none.rs:15:7 | LL | #[cfg(foo = "bar")] | ^^^-------- diff --git a/tests/ui/check-cfg/values-none.implicit.stderr b/tests/ui/check-cfg/values-none.implicit.stderr index a025ff441b70..c14cde940052 100644 --- a/tests/ui/check-cfg/values-none.implicit.stderr +++ b/tests/ui/check-cfg/values-none.implicit.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `too` - --> $DIR/values-none.rs:11:7 + --> $DIR/values-none.rs:10:7 | LL | #[cfg(foo = "too")] | ^^^-------- @@ -12,7 +12,7 @@ LL | #[cfg(foo = "too")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `bar` - --> $DIR/values-none.rs:16:7 + --> $DIR/values-none.rs:15:7 | LL | #[cfg(foo = "bar")] | ^^^-------- diff --git a/tests/ui/check-cfg/values-none.rs b/tests/ui/check-cfg/values-none.rs index 6a68020e4182..bd9c0255b7db 100644 --- a/tests/ui/check-cfg/values-none.rs +++ b/tests/ui/check-cfg/values-none.rs @@ -1,7 +1,6 @@ //@ check-pass // //@ revisions: explicit implicit -//@ compile-flags: -Zunstable-options //@ [explicit]compile-flags: --check-cfg=cfg(foo,values(none())) //@ [implicit]compile-flags: --check-cfg=cfg(foo) //@ [simple] compile-flags: --check-cfg=cfg(foo,values(none(),"too")) diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index afe6e0aaffd3..f3a27043e671 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs @@ -2,7 +2,7 @@ // //@ check-pass //@ needs-llvm-components: x86 -//@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json -Z unstable-options +//@ compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json #![feature(lang_items, no_core, auto_traits)] #![no_core] diff --git a/tests/ui/check-cfg/well-known-names.rs b/tests/ui/check-cfg/well-known-names.rs index a0feee4225a3..c277b84d9bd6 100644 --- a/tests/ui/check-cfg/well-known-names.rs +++ b/tests/ui/check-cfg/well-known-names.rs @@ -1,7 +1,7 @@ // This test checks that we lint on non well known names and that we don't lint on well known names // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() #[cfg(target_oz = "linux")] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/well-known-values.rs b/tests/ui/check-cfg/well-known-values.rs index 2758a793538e..4c010a62d210 100644 --- a/tests/ui/check-cfg/well-known-values.rs +++ b/tests/ui/check-cfg/well-known-values.rs @@ -5,7 +5,7 @@ // values since the suggestion shows them. // //@ check-pass -//@ compile-flags: --check-cfg=cfg() -Z unstable-options +//@ compile-flags: --check-cfg=cfg() //@ compile-flags: -Zcheck-cfg-all-expected #![feature(cfg_overflow_checks)] diff --git a/tests/ui/feature-gates/feature-gate-check-cfg.rs b/tests/ui/feature-gates/feature-gate-check-cfg.rs deleted file mode 100644 index 1e0106aa7485..000000000000 --- a/tests/ui/feature-gates/feature-gate-check-cfg.rs +++ /dev/null @@ -1,3 +0,0 @@ -//@ compile-flags: --check-cfg "cfg()" - -fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-check-cfg.stderr b/tests/ui/feature-gates/feature-gate-check-cfg.stderr deleted file mode 100644 index 9b27c2bc058a..000000000000 --- a/tests/ui/feature-gates/feature-gate-check-cfg.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: the `-Z unstable-options` flag must also be passed to enable the flag `check-cfg` - From a20de73ccfdf24a59f43da9cf9e0d95ca40d6aab Mon Sep 17 00:00:00 2001 From: Urgau Date: Sun, 25 Feb 2024 15:45:43 +0100 Subject: [PATCH 029/114] Move --check-cfg documentation to stable books --- .../src/context/diagnostics/check_cfg.rs | 4 +- compiler/rustc_session/src/config/cfg.rs | 2 +- src/doc/rustc/src/SUMMARY.md | 1 + .../compiler-flags => rustc/src}/check-cfg.md | 8 +-- src/doc/rustc/src/command-line-arguments.md | 10 ++++ src/doc/rustdoc/src/command-line-arguments.md | 14 +++++ src/doc/rustdoc/src/unstable-features.md | 16 ------ tests/rustdoc-ui/check-cfg.stderr | 2 +- .../rustdoc-ui/doctest/check-cfg-test.stderr | 2 +- tests/ui/check-cfg/allow-same-level.stderr | 2 +- .../cfg-value-for-cfg-name-duplicate.stderr | 2 +- .../cfg-value-for-cfg-name-multiple.stderr | 2 +- .../check-cfg/cfg-value-for-cfg-name.stderr | 4 +- tests/ui/check-cfg/compact-names.stderr | 2 +- tests/ui/check-cfg/compact-values.stderr | 2 +- tests/ui/check-cfg/concat-values.stderr | 4 +- tests/ui/check-cfg/diagnotics.rustc.stderr | 12 ++-- tests/ui/check-cfg/empty-values.stderr | 4 +- .../exhaustive-names-values.empty_cfg.stderr | 8 +-- .../exhaustive-names-values.feature.stderr | 6 +- .../exhaustive-names-values.full.stderr | 6 +- tests/ui/check-cfg/exhaustive-names.stderr | 2 +- .../exhaustive-values.empty_cfg.stderr | 2 +- .../exhaustive-values.without_names.stderr | 2 +- tests/ui/check-cfg/mix.stderr | 54 +++++++++--------- .../check-cfg/no-expected-values.empty.stderr | 4 +- .../check-cfg/no-expected-values.mixed.stderr | 4 +- .../no-expected-values.simple.stderr | 4 +- .../order-independant.values_after.stderr | 2 +- .../order-independant.values_before.stderr | 2 +- tests/ui/check-cfg/stmt-no-ice.stderr | 2 +- tests/ui/check-cfg/unexpected-cfg-name.stderr | 2 +- .../ui/check-cfg/unexpected-cfg-value.stderr | 4 +- .../ui/check-cfg/values-none.explicit.stderr | 4 +- .../ui/check-cfg/values-none.implicit.stderr | 4 +- tests/ui/check-cfg/well-known-names.stderr | 8 +-- tests/ui/check-cfg/well-known-values.stderr | 56 +++++++++---------- triagebot.toml | 2 +- 38 files changed, 137 insertions(+), 134 deletions(-) rename src/doc/{unstable-book/src/compiler-flags => rustc/src}/check-cfg.md (97%) diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs index 2c9a3a6d1b25..0472525d49a4 100644 --- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs +++ b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs @@ -168,7 +168,7 @@ pub(super) fn unexpected_cfg_name( diag.note("see for more information about checking conditional configuration"); } else { diag.help(format!("to expect this configuration use `--check-cfg={inst}`")); - diag.note("see for more information about checking conditional configuration"); + diag.note("see for more information about checking conditional configuration"); } } @@ -272,6 +272,6 @@ pub(super) fn unexpected_cfg_value( if !is_cfg_a_well_know_name { diag.help(format!("to expect this configuration use `--check-cfg={inst}`")); } - diag.note("see for more information about checking conditional configuration"); + diag.note("see for more information about checking conditional configuration"); } } diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs index 34dcd0cf598f..31badbd86927 100644 --- a/compiler/rustc_session/src/config/cfg.rs +++ b/compiler/rustc_session/src/config/cfg.rs @@ -257,7 +257,7 @@ impl CheckCfg { // `tests/ui/check-cfg/well-known-values.rs` (in order to test the // expected values of the new config) and bless the all directory. // - // Don't forget to update `src/doc/unstable-book/src/compiler-flags/check-cfg.md` + // Don't forget to update `src/doc/rustc/src/check-cfg.md` // in the unstable book as well! ins!(sym::debug_assertions, no_values); diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index db85753145d4..31096b6df92b 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -77,6 +77,7 @@ - [Profile-guided Optimization](profile-guided-optimization.md) - [Instrumentation-based Code Coverage](instrument-coverage.md) - [Linker-plugin-based LTO](linker-plugin-lto.md) +- [Checking conditional configurations](check-cfg.md) - [Exploit Mitigations](exploit-mitigations.md) - [Symbol Mangling](symbol-mangling/index.md) - [v0 Symbol Format](symbol-mangling/v0.md) diff --git a/src/doc/unstable-book/src/compiler-flags/check-cfg.md b/src/doc/rustc/src/check-cfg.md similarity index 97% rename from src/doc/unstable-book/src/compiler-flags/check-cfg.md rename to src/doc/rustc/src/check-cfg.md index 836929aba0bf..37708bda1f3d 100644 --- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md +++ b/src/doc/rustc/src/check-cfg.md @@ -1,10 +1,4 @@ -# `check-cfg` - -The tracking issue for this feature is: [#82450](https://github.com/rust-lang/rust/issues/82450). - ------------------------- - -This feature enables checking of conditional configuration. +# Checking conditional configurations `rustc` accepts the `--check-cfg` option, which specifies whether to check conditions and how to check them. The `--check-cfg` option takes a value, called the _check cfg specification_. diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index 5e02453e2366..7c605333c25d 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -18,6 +18,16 @@ The value can either be a single identifier or two identifiers separated by `=`. For examples, `--cfg 'verbose'` or `--cfg 'feature="serde"'`. These correspond to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively. + +## `--check-cfg`: enables checking conditional configurations + +This flag will enable checking conditional configurations. +Refer to the [Checking conditional configurations](check-cfg.md) of this book +for further details and explanation. + +For examples, `--check-cfg 'cfg(verbose)'` or `--check-cfg 'cfg(feature, values("serde"))'`. +These correspond to `#[cfg(verbose)]` and `#[cfg(feature = "serde")]` respectively. + ## `-L`: add a directory to the library search path diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md index fe5cb529c263..822f341b370a 100644 --- a/src/doc/rustdoc/src/command-line-arguments.md +++ b/src/doc/rustdoc/src/command-line-arguments.md @@ -131,6 +131,20 @@ This flag accepts the same values as `rustc --cfg`, and uses it to configure compilation. The example above uses `feature`, but any of the `cfg` values are acceptable. +## `--check-cfg`: check configuration flags + +This flag accepts the same values as `rustc --check-cfg`, and uses it to +check configuration flags. + +Using this flag looks like this: + +```bash +$ rustdoc src/lib.rs --check-cfg='cfg(my_cfg, values("foo", "bar"))' +``` + +The example above check every well known names and values (`target_os`, `doc`, `test`, ...) +and check the values of `my_cfg`: `foo` and `bar`. + ## `--extern`: specify a dependency's location Using this flag looks like this: diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index 41602dec44c4..bdb55de8d634 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -618,22 +618,6 @@ crate being documented (`foobar`) and a path to output the calls To scrape examples from test code, e.g. functions marked `#[test]`, then add the `--scrape-tests` flag. -### `--check-cfg`: check configuration flags - - * Tracking issue: [#82450](https://github.com/rust-lang/rust/issues/82450) - -This flag accepts the same values as `rustc --check-cfg`, and uses it to check configuration flags. - -Using this flag looks like this: - -```bash -$ rustdoc src/lib.rs -Z unstable-options \ - --check-cfg='cfg(feature, values("foo", "bar"))' -``` - -The example above check every well known names and values (`target_os`, `doc`, `test`, ...) -and check the values of `feature`: `foo` and `bar`. - ### `--generate-link-to-definition`: Generate links on types in source code * Tracking issue: [#89095](https://github.com/rust-lang/rust/issues/89095) diff --git a/tests/rustdoc-ui/check-cfg.stderr b/tests/rustdoc-ui/check-cfg.stderr index 3bca5dd08346..6f026cee41e9 100644 --- a/tests/rustdoc-ui/check-cfg.stderr +++ b/tests/rustdoc-ui/check-cfg.stderr @@ -5,7 +5,7 @@ LL | #[cfg(uniz)] | ^^^^ help: there is a config with a similar name: `unix` | = help: to expect this configuration use `--check-cfg=cfg(uniz)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/rustdoc-ui/doctest/check-cfg-test.stderr b/tests/rustdoc-ui/doctest/check-cfg-test.stderr index 5524f582d560..a2f173a2cb91 100644 --- a/tests/rustdoc-ui/doctest/check-cfg-test.stderr +++ b/tests/rustdoc-ui/doctest/check-cfg-test.stderr @@ -6,7 +6,7 @@ LL | #[cfg(feature = "invalid")] | = note: expected values for `feature` are: `test` = help: to expect this configuration use `--check-cfg=cfg(feature, values("invalid"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/allow-same-level.stderr b/tests/ui/check-cfg/allow-same-level.stderr index 493132d462ac..349f41cb142c 100644 --- a/tests/ui/check-cfg/allow-same-level.stderr +++ b/tests/ui/check-cfg/allow-same-level.stderr @@ -6,7 +6,7 @@ LL | #[cfg(FALSE)] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(FALSE)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr index 46d6d29b15eb..23ae4c55e42b 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr @@ -6,7 +6,7 @@ LL | #[cfg(value)] | = help: expected names are: `bar`, `bee`, `clippy`, `cow`, `debug_assertions`, `doc`, `doctest`, `foo`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(value)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr index a70a8b2d3e4a..b5faaf6029c4 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr @@ -6,7 +6,7 @@ LL | #[cfg(my_value)] | = help: expected names are: `bar`, `clippy`, `debug_assertions`, `doc`, `doctest`, `foo`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(my_value)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default help: found config with similar value | diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr index fab7f595c250..01586a6c71d2 100644 --- a/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr +++ b/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr @@ -6,7 +6,7 @@ LL | #[cfg(linux)] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(linux)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `linux` @@ -16,7 +16,7 @@ LL | #[cfg(linux = "os-name")] | ^^^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(linux, values("os-name"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/compact-names.stderr b/tests/ui/check-cfg/compact-names.stderr index 446b8f408e33..929501b420a7 100644 --- a/tests/ui/check-cfg/compact-names.stderr +++ b/tests/ui/check-cfg/compact-names.stderr @@ -6,7 +6,7 @@ LL | #[cfg(target(os = "linux", architecture = "arm"))] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(target_architecture, values("arm"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/compact-values.stderr b/tests/ui/check-cfg/compact-values.stderr index 661ee7bff52a..45d084c46bfa 100644 --- a/tests/ui/check-cfg/compact-values.stderr +++ b/tests/ui/check-cfg/compact-values.stderr @@ -5,7 +5,7 @@ LL | #[cfg(target(os = "linux", pointer_width = "X"))] | ^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_pointer_width` are: `16`, `32`, `64` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/concat-values.stderr b/tests/ui/check-cfg/concat-values.stderr index dec43f5bda3b..ca8b58f73e5f 100644 --- a/tests/ui/check-cfg/concat-values.stderr +++ b/tests/ui/check-cfg/concat-values.stderr @@ -6,7 +6,7 @@ LL | #[cfg(my_cfg)] | = note: expected values for `my_cfg` are: `bar`, `foo` = help: to expect this configuration use `--check-cfg=cfg(my_cfg)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `unk` @@ -17,7 +17,7 @@ LL | #[cfg(my_cfg = "unk")] | = note: expected values for `my_cfg` are: `bar`, `foo` = help: to expect this configuration use `--check-cfg=cfg(my_cfg, values("unk"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/diagnotics.rustc.stderr b/tests/ui/check-cfg/diagnotics.rustc.stderr index 2b1129a39200..0a938d2143e9 100644 --- a/tests/ui/check-cfg/diagnotics.rustc.stderr +++ b/tests/ui/check-cfg/diagnotics.rustc.stderr @@ -6,7 +6,7 @@ LL | #[cfg(featur)] | = help: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(featur)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition name: `featur` @@ -16,7 +16,7 @@ LL | #[cfg(featur = "foo")] | ^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(featur, values("foo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration help: there is a config with a similar name and value | LL | #[cfg(feature = "foo")] @@ -30,7 +30,7 @@ LL | #[cfg(featur = "fo")] | = help: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(featur, values("fo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration help: there is a config with a similar name and different values | LL | #[cfg(feature = "foo")] @@ -43,7 +43,7 @@ LL | #[cfg(no_value)] | ^^^^^^^^ help: there is a config with a similar name: `no_values` | = help: to expect this configuration use `--check-cfg=cfg(no_value)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `no_value` --> $DIR/diagnotics.rs:26:7 @@ -52,7 +52,7 @@ LL | #[cfg(no_value = "foo")] | ^^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(no_value, values("foo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration help: there is a config with a similar name and no value | LL | #[cfg(no_values)] @@ -68,7 +68,7 @@ LL | #[cfg(no_values = "bar")] | = note: no expected value for `no_values` = help: to expect this configuration use `--check-cfg=cfg(no_values, values("bar"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 6 warnings emitted diff --git a/tests/ui/check-cfg/empty-values.stderr b/tests/ui/check-cfg/empty-values.stderr index e7b0b05d5616..1f773b10316e 100644 --- a/tests/ui/check-cfg/empty-values.stderr +++ b/tests/ui/check-cfg/empty-values.stderr @@ -6,7 +6,7 @@ LL | #[cfg(foo = "foo")] | = note: no expected values for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("foo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) @@ -17,7 +17,7 @@ LL | #[cfg(foo)] | = note: no expected values for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr index 5d1fc74137b3..9537d4f51729 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr @@ -6,7 +6,7 @@ LL | #[cfg(unknown_key = "value")] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` @@ -18,7 +18,7 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` --> $DIR/exhaustive-names-values.rs:17:7 @@ -27,7 +27,7 @@ LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` --> $DIR/exhaustive-names-values.rs:24:7 @@ -36,7 +36,7 @@ LL | #[cfg(feature = "std")] | ^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(feature, values("std"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 4 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr index 9be2ec71b44d..d63d86279534 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr @@ -6,7 +6,7 @@ LL | #[cfg(unknown_key = "value")] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` @@ -18,7 +18,7 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` --> $DIR/exhaustive-names-values.rs:17:7 @@ -28,7 +28,7 @@ LL | #[cfg(feature = "unk")] | = note: expected values for `feature` are: `std` = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 3 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr index 9be2ec71b44d..d63d86279534 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr @@ -6,7 +6,7 @@ LL | #[cfg(unknown_key = "value")] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` @@ -18,7 +18,7 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `unk` --> $DIR/exhaustive-names-values.rs:17:7 @@ -28,7 +28,7 @@ LL | #[cfg(feature = "unk")] | = note: expected values for `feature` are: `std` = help: to expect this configuration use `--check-cfg=cfg(feature, values("unk"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 3 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names.stderr b/tests/ui/check-cfg/exhaustive-names.stderr index 6ca7ed93625d..c42adec94b2b 100644 --- a/tests/ui/check-cfg/exhaustive-names.stderr +++ b/tests/ui/check-cfg/exhaustive-names.stderr @@ -6,7 +6,7 @@ LL | #[cfg(unknown_key = "value")] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(unknown_key, values("value"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr index e8cf29ae982a..63ba2c686254 100644 --- a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr @@ -7,7 +7,7 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/exhaustive-values.without_names.stderr b/tests/ui/check-cfg/exhaustive-values.without_names.stderr index e8cf29ae982a..63ba2c686254 100644 --- a/tests/ui/check-cfg/exhaustive-values.without_names.stderr +++ b/tests/ui/check-cfg/exhaustive-values.without_names.stderr @@ -7,7 +7,7 @@ LL | #[cfg(test = "value")] | help: remove the value | = note: no expected value for `test` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr index 87fabf8245f7..feb4f21b0ca4 100644 --- a/tests/ui/check-cfg/mix.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -5,7 +5,7 @@ LL | #[cfg(widnows)] | ^^^^^^^ help: there is a config with a similar name: `windows` | = help: to expect this configuration use `--check-cfg=cfg(widnows)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) @@ -16,7 +16,7 @@ LL | #[cfg(feature)] | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `bar` --> $DIR/mix.rs:23:7 @@ -26,7 +26,7 @@ LL | #[cfg(feature = "bar")] | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("bar"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:27:7 @@ -36,7 +36,7 @@ LL | #[cfg(feature = "zebra")] | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `uu` --> $DIR/mix.rs:31:12 @@ -46,7 +46,7 @@ LL | #[cfg_attr(uu, test)] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(uu)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `widnows` --> $DIR/mix.rs:40:10 @@ -55,7 +55,7 @@ LL | cfg!(widnows); | ^^^^^^^ help: there is a config with a similar name: `windows` | = help: to expect this configuration use `--check-cfg=cfg(widnows)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `bar` --> $DIR/mix.rs:43:10 @@ -65,7 +65,7 @@ LL | cfg!(feature = "bar"); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("bar"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:45:10 @@ -75,7 +75,7 @@ LL | cfg!(feature = "zebra"); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:47:10 @@ -84,7 +84,7 @@ LL | cfg!(xxx = "foo"); | ^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx, values("foo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:49:10 @@ -93,7 +93,7 @@ LL | cfg!(xxx); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:51:14 @@ -102,7 +102,7 @@ LL | cfg!(any(xxx, windows)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `bad` --> $DIR/mix.rs:53:14 @@ -112,7 +112,7 @@ LL | cfg!(any(feature = "bad", windows)); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("bad"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:55:23 @@ -121,7 +121,7 @@ LL | cfg!(any(windows, xxx)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:57:20 @@ -130,7 +130,7 @@ LL | cfg!(all(unix, xxx)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `aa` --> $DIR/mix.rs:59:14 @@ -139,7 +139,7 @@ LL | cfg!(all(aa, bb)); | ^^ | = help: to expect this configuration use `--check-cfg=cfg(aa)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `bb` --> $DIR/mix.rs:59:18 @@ -148,7 +148,7 @@ LL | cfg!(all(aa, bb)); | ^^ | = help: to expect this configuration use `--check-cfg=cfg(bb)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `aa` --> $DIR/mix.rs:62:14 @@ -157,7 +157,7 @@ LL | cfg!(any(aa, bb)); | ^^ | = help: to expect this configuration use `--check-cfg=cfg(aa)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `bb` --> $DIR/mix.rs:62:18 @@ -166,7 +166,7 @@ LL | cfg!(any(aa, bb)); | ^^ | = help: to expect this configuration use `--check-cfg=cfg(bb)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:65:20 @@ -176,7 +176,7 @@ LL | cfg!(any(unix, feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:67:14 @@ -185,7 +185,7 @@ LL | cfg!(any(xxx, feature = "zebra")); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:67:19 @@ -195,7 +195,7 @@ LL | cfg!(any(xxx, feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:70:14 @@ -204,7 +204,7 @@ LL | cfg!(any(xxx, unix, xxx)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `xxx` --> $DIR/mix.rs:70:25 @@ -213,7 +213,7 @@ LL | cfg!(any(xxx, unix, xxx)); | ^^^ | = help: to expect this configuration use `--check-cfg=cfg(xxx)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:73:14 @@ -223,7 +223,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:73:33 @@ -233,7 +233,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:73:52 @@ -243,7 +243,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | = note: expected values for `feature` are: `foo` = help: to expect this configuration use `--check-cfg=cfg(feature, values("zebra"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `zebra` --> $DIR/mix.rs:77:10 @@ -252,7 +252,7 @@ LL | cfg!(target_feature = "zebra"); | ^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2` and 187 more - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 27 warnings emitted diff --git a/tests/ui/check-cfg/no-expected-values.empty.stderr b/tests/ui/check-cfg/no-expected-values.empty.stderr index 65827efdd39a..0f181cc2ab12 100644 --- a/tests/ui/check-cfg/no-expected-values.empty.stderr +++ b/tests/ui/check-cfg/no-expected-values.empty.stderr @@ -8,7 +8,7 @@ LL | #[cfg(feature = "foo")] | = note: no expected value for `feature` = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` @@ -20,7 +20,7 @@ LL | #[cfg(test = "foo")] | help: remove the value | = note: no expected value for `test` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/no-expected-values.mixed.stderr b/tests/ui/check-cfg/no-expected-values.mixed.stderr index 65827efdd39a..0f181cc2ab12 100644 --- a/tests/ui/check-cfg/no-expected-values.mixed.stderr +++ b/tests/ui/check-cfg/no-expected-values.mixed.stderr @@ -8,7 +8,7 @@ LL | #[cfg(feature = "foo")] | = note: no expected value for `feature` = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` @@ -20,7 +20,7 @@ LL | #[cfg(test = "foo")] | help: remove the value | = note: no expected value for `test` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/no-expected-values.simple.stderr b/tests/ui/check-cfg/no-expected-values.simple.stderr index 65827efdd39a..0f181cc2ab12 100644 --- a/tests/ui/check-cfg/no-expected-values.simple.stderr +++ b/tests/ui/check-cfg/no-expected-values.simple.stderr @@ -8,7 +8,7 @@ LL | #[cfg(feature = "foo")] | = note: no expected value for `feature` = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` @@ -20,7 +20,7 @@ LL | #[cfg(test = "foo")] | help: remove the value | = note: no expected value for `test` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/order-independant.values_after.stderr b/tests/ui/check-cfg/order-independant.values_after.stderr index 2be28be39a7a..7e18df8e1c29 100644 --- a/tests/ui/check-cfg/order-independant.values_after.stderr +++ b/tests/ui/check-cfg/order-independant.values_after.stderr @@ -6,7 +6,7 @@ LL | #[cfg(a = "unk")] | = note: expected values for `a` are: (none), `b` = help: to expect this configuration use `--check-cfg=cfg(a, values("unk"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/order-independant.values_before.stderr b/tests/ui/check-cfg/order-independant.values_before.stderr index 2be28be39a7a..7e18df8e1c29 100644 --- a/tests/ui/check-cfg/order-independant.values_before.stderr +++ b/tests/ui/check-cfg/order-independant.values_before.stderr @@ -6,7 +6,7 @@ LL | #[cfg(a = "unk")] | = note: expected values for `a` are: (none), `b` = help: to expect this configuration use `--check-cfg=cfg(a, values("unk"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/stmt-no-ice.stderr b/tests/ui/check-cfg/stmt-no-ice.stderr index 1afdbe84d348..e686cdddc1c2 100644 --- a/tests/ui/check-cfg/stmt-no-ice.stderr +++ b/tests/ui/check-cfg/stmt-no-ice.stderr @@ -6,7 +6,7 @@ LL | #[cfg(crossbeam_loom)] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(crossbeam_loom)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/unexpected-cfg-name.stderr b/tests/ui/check-cfg/unexpected-cfg-name.stderr index 8748b324fb66..0b265078aa50 100644 --- a/tests/ui/check-cfg/unexpected-cfg-name.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-name.stderr @@ -5,7 +5,7 @@ LL | #[cfg(widnows)] | ^^^^^^^ help: there is a config with a similar name: `windows` | = help: to expect this configuration use `--check-cfg=cfg(widnows)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/unexpected-cfg-value.stderr b/tests/ui/check-cfg/unexpected-cfg-value.stderr index e5435d376709..c30012084920 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-value.stderr @@ -8,7 +8,7 @@ LL | #[cfg(feature = "sedre")] | = note: expected values for `feature` are: `full`, `serde` = help: to expect this configuration use `--check-cfg=cfg(feature, values("sedre"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `rand` @@ -19,7 +19,7 @@ LL | #[cfg(feature = "rand")] | = note: expected values for `feature` are: `full`, `serde` = help: to expect this configuration use `--check-cfg=cfg(feature, values("rand"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/values-none.explicit.stderr b/tests/ui/check-cfg/values-none.explicit.stderr index c14cde940052..f75cc08f551e 100644 --- a/tests/ui/check-cfg/values-none.explicit.stderr +++ b/tests/ui/check-cfg/values-none.explicit.stderr @@ -8,7 +8,7 @@ LL | #[cfg(foo = "too")] | = note: no expected value for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("too"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `bar` @@ -21,7 +21,7 @@ LL | #[cfg(foo = "bar")] | = note: no expected value for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("bar"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/values-none.implicit.stderr b/tests/ui/check-cfg/values-none.implicit.stderr index c14cde940052..f75cc08f551e 100644 --- a/tests/ui/check-cfg/values-none.implicit.stderr +++ b/tests/ui/check-cfg/values-none.implicit.stderr @@ -8,7 +8,7 @@ LL | #[cfg(foo = "too")] | = note: no expected value for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("too"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `bar` @@ -21,7 +21,7 @@ LL | #[cfg(foo = "bar")] | = note: no expected value for `foo` = help: to expect this configuration use `--check-cfg=cfg(foo, values("bar"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 2 warnings emitted diff --git a/tests/ui/check-cfg/well-known-names.stderr b/tests/ui/check-cfg/well-known-names.stderr index 467f9675f7f8..b2db777e8a84 100644 --- a/tests/ui/check-cfg/well-known-names.stderr +++ b/tests/ui/check-cfg/well-known-names.stderr @@ -5,7 +5,7 @@ LL | #[cfg(target_oz = "linux")] | ^^^^^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(target_oz, values("linux"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default help: there is a config with a similar name and value | @@ -20,7 +20,7 @@ LL | #[cfg(features = "foo")] | = help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, `windows` = help: to expect this configuration use `--check-cfg=cfg(features, values("foo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `feature` --> $DIR/well-known-names.rs:17:7 @@ -29,7 +29,7 @@ LL | #[cfg(feature = "foo")] | ^^^^^^^^^^^^^^^ | = help: to expect this configuration use `--check-cfg=cfg(feature, values("foo"))` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition name: `uniw` --> $DIR/well-known-names.rs:21:7 @@ -38,7 +38,7 @@ LL | #[cfg(uniw)] | ^^^^ help: there is a config with a similar name: `unix` | = help: to expect this configuration use `--check-cfg=cfg(uniw)` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 4 warnings emitted diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 729794150f62..af3ef92fdd57 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -7,7 +7,7 @@ LL | clippy = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `clippy` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -19,7 +19,7 @@ LL | debug_assertions = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `debug_assertions` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:31:5 @@ -30,7 +30,7 @@ LL | doc = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `doc` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:33:5 @@ -41,7 +41,7 @@ LL | doctest = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `doctest` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:35:5 @@ -52,7 +52,7 @@ LL | miri = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `miri` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:37:5 @@ -63,7 +63,7 @@ LL | overflow_checks = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `overflow_checks` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:39:5 @@ -72,7 +72,7 @@ LL | panic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `panic` are: `abort`, `unwind` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:41:5 @@ -83,7 +83,7 @@ LL | proc_macro = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `proc_macro` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:43:5 @@ -92,7 +92,7 @@ LL | relocation_model = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `relocation_model` are: `dynamic-no-pic`, `pic`, `pie`, `ropi`, `ropi-rwpi`, `rwpi`, `static` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:45:5 @@ -101,7 +101,7 @@ LL | sanitize = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `sanitize` are: `address`, `cfi`, `dataflow`, `hwaddress`, `kcfi`, `kernel-address`, `leak`, `memory`, `memtag`, `safestack`, `shadow-call-stack`, `thread` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:47:5 @@ -110,7 +110,7 @@ LL | target_abi = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_abi` are: ``, `abi64`, `abiv2`, `abiv2hf`, `eabi`, `eabihf`, `elf`, `fortanix`, `ilp32`, `llvm`, `macabi`, `sim`, `softfloat`, `spe`, `uwp`, `vec-extabi`, `x32` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:49:5 @@ -119,7 +119,7 @@ LL | target_arch = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_arch` are: `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:51:5 @@ -128,7 +128,7 @@ LL | target_endian = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_endian` are: `big`, `little` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:53:5 @@ -137,7 +137,7 @@ LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p2`, `psx`, `relibc`, `sgx`, `uclibc` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:55:5 @@ -146,7 +146,7 @@ LL | target_family = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_family` are: `unix`, `wasm`, `windows` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:57:5 @@ -155,7 +155,7 @@ LL | target_feature = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:59:5 @@ -164,7 +164,7 @@ LL | target_has_atomic = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_has_atomic` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:61:5 @@ -173,7 +173,7 @@ LL | target_has_atomic_equal_alignment = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_has_atomic_equal_alignment` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:63:5 @@ -182,7 +182,7 @@ LL | target_has_atomic_load_store = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_has_atomic_load_store` are: (none), `128`, `16`, `32`, `64`, `8`, `ptr` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:65:5 @@ -191,7 +191,7 @@ LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, `zkvm` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:67:5 @@ -200,7 +200,7 @@ LL | target_pointer_width = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_pointer_width` are: `16`, `32`, `64` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:69:5 @@ -211,7 +211,7 @@ LL | target_thread_local = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `target_thread_local` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:71:5 @@ -220,7 +220,7 @@ LL | target_vendor = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expected values for `target_vendor` are: `apple`, `espressif`, `fortanix`, `ibm`, `kmc`, `nintendo`, `nvidia`, `pc`, `risc0`, `sony`, `sun`, `unikraft`, `unknown`, `uwp`, `win7`, `wrs` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:73:5 @@ -231,7 +231,7 @@ LL | test = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `test` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:75:5 @@ -242,7 +242,7 @@ LL | ub_checks = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `ub_checks` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:77:5 @@ -253,7 +253,7 @@ LL | unix = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `unix` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` --> $DIR/well-known-values.rs:79:5 @@ -264,7 +264,7 @@ LL | windows = "_UNEXPECTED_VALUE", | help: remove the value | = note: no expected value for `windows` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `linuz` --> $DIR/well-known-values.rs:85:7 @@ -275,7 +275,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | help: there is a expected value with a similar name: `"linux"` | = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, `zkvm` - = note: see for more information about checking conditional configuration + = note: see for more information about checking conditional configuration warning: 28 warnings emitted diff --git a/triagebot.toml b/triagebot.toml index b96225c45205..1fdcffebf83a 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -728,7 +728,7 @@ cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] [mentions."src/doc/unstable-book/src/language-features/no-sanitize.md"] cc = ["@rust-lang/project-exploit-mitigations", "@rcvalle"] -[mentions."src/doc/unstable-book/src/compiler-flags/check-cfg.md"] +[mentions."src/doc/rustc/src/check-cfg.md"] cc = ["@Urgau"] [mentions."src/doc/rustc/src/platform-support"] From a076eae0d27915f352d92db1b63661e62750d7ae Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 3 Apr 2024 19:58:50 -0400 Subject: [PATCH 030/114] Parsing , pre-lowering support for precise captures --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast/src/mut_visit.rs | 5 +++- compiler/rustc_ast/src/visit.rs | 3 ++- compiler/rustc_ast_lowering/src/lib.rs | 3 ++- .../rustc_ast_passes/src/ast_validation.rs | 2 +- compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_ast_pretty/src/pprust/state.rs | 3 ++- compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_lint/src/unused.rs | 2 +- compiler/rustc_parse/src/parser/generics.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 2 +- compiler/rustc_parse/src/parser/ty.rs | 24 +++++++++++++++---- compiler/rustc_resolve/src/late.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_span/src/symbol.rs | 1 + 15 files changed, 41 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5b708cf4e1a5..55a934c48a80 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2132,7 +2132,7 @@ pub enum TyKind { /// The `NodeId` exists to prevent lowering from having to /// generate `NodeId`s on the fly, which would complicate /// the generation of opaque `type Foo = impl Trait` items significantly. - ImplTrait(NodeId, GenericBounds), + ImplTrait(NodeId, GenericBounds, Option>), /// No-op; kept solely so that we can pretty-print faithfully. Paren(P), /// Unused for now. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index da57def263df..b8a5eeebf3a0 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -518,9 +518,12 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { TyKind::TraitObject(bounds, _syntax) => { visit_vec(bounds, |bound| vis.visit_param_bound(bound)) } - TyKind::ImplTrait(id, bounds) => { + TyKind::ImplTrait(id, bounds, precise_capturing) => { vis.visit_id(id); visit_vec(bounds, |bound| vis.visit_param_bound(bound)); + visit_opt(precise_capturing, |precise_capturing| { + vis.visit_generic_args(precise_capturing); + }); } TyKind::MacCall(mac) => vis.visit_mac_call(mac), TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 9e9ae52962d8..917400217270 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -457,8 +457,9 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result { TyKind::TraitObject(bounds, ..) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject); } - TyKind::ImplTrait(_, bounds) => { + TyKind::ImplTrait(_, bounds, precise_capturing) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl); + visit_opt!(visitor, visit_generic_args, precise_capturing); } TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)), TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5005c22d4cc3..a4470622972e 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1398,7 +1398,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }); hir::TyKind::TraitObject(bounds, lifetime_bound, *kind) } - TyKind::ImplTrait(def_node_id, bounds) => { + TyKind::ImplTrait(def_node_id, bounds, precise_capturing) => { + assert!(precise_capturing.is_none(), "precise captures not supported yet!"); let span = t.span; match itctx { ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait( diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index cb4dcf3ae75f..495e90e967b9 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -737,7 +737,7 @@ impl<'a> AstValidator<'a> { } } } - TyKind::ImplTrait(_, bounds) => { + TyKind::ImplTrait(_, bounds, _) => { if self.is_impl_trait_banned { self.dcx().emit_err(errors::ImplTraitPath { span: ty.span }); } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index d7cd3efe408b..70a3ccb0f440 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -569,6 +569,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) { gate_all!(fn_delegation, "functions delegation is not yet fully implemented"); gate_all!(postfix_match, "postfix match is experimental"); gate_all!(mut_ref, "mutable by-reference bindings are experimental"); + gate_all!(precise_capturing, "precise captures on `impl Trait` are experimental"); if !visitor.features.never_patterns { if let Some(spans) = spans.get(&sym::never_patterns) { diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 51ccfe89fbdb..6553ed72532c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1150,7 +1150,8 @@ impl<'a> State<'a> { } self.print_type_bounds(bounds); } - ast::TyKind::ImplTrait(_, bounds) => { + ast::TyKind::ImplTrait(_, bounds, _precise_capturing) => { + // TODO(precise_capturing): self.word_nbsp("impl"); self.print_type_bounds(bounds); } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e6b19817de38..792cc1066f5a 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -535,6 +535,8 @@ declare_features! ( (unstable, must_not_suspend, "1.57.0", Some(83310)), /// Allows `mut ref` and `mut ref mut` identifier patterns. (incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)), + /// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args. + (incomplete, precise_capturing, "CURRENT_RUSTC_VERSION", Some(123432)), /// Allows using `#[naked]` on functions. (unstable, naked_functions, "1.9.0", Some(90957)), /// Allows specifying the as-needed link modifier diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 503caa35358a..3fe1f21d56a2 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -1235,7 +1235,7 @@ impl EarlyLintPass for UnusedParens { ast::TyKind::TraitObject(..) => {} ast::TyKind::BareFn(b) if self.with_self_ty_parens && b.generic_params.len() > 0 => {} - ast::TyKind::ImplTrait(_, bounds) if bounds.len() > 1 => {} + ast::TyKind::ImplTrait(_, bounds, _) if bounds.len() > 1 => {} _ => { let spans = if !ty.span.from_expansion() { r.span diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index fde16ac957df..93a15c938ecf 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -62,7 +62,7 @@ impl<'a> Parser<'a> { let snapshot = self.create_snapshot_for_diagnostic(); match self.parse_ty() { Ok(p) => { - if let TyKind::ImplTrait(_, bounds) = &p.kind { + if let TyKind::ImplTrait(_, bounds, None) = &p.kind { let span = impl_span.to(self.token.span.shrink_to_lo()); let mut err = self.dcx().struct_span_err( span, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index d54eb8dc4c9e..fd72dca6e21e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -625,7 +625,7 @@ impl<'a> Parser<'a> { // This notably includes paths passed through `ty` macro fragments (#46438). TyKind::Path(None, path) => path, other => { - if let TyKind::ImplTrait(_, bounds) = other + if let TyKind::ImplTrait(_, bounds, None) = other && let [bound] = bounds.as_slice() { // Suggest removing extra `impl` keyword: diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 1cea32cb90fe..5d6c4f39ae11 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -316,7 +316,7 @@ impl<'a> Parser<'a> { TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn) } (TyKind::TraitObject(bounds, _), kw::Impl) => { - TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds) + TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, None) } _ => return Err(err), }; @@ -655,7 +655,6 @@ impl<'a> Parser<'a> { /// Parses an `impl B0 + ... + Bn` type. fn parse_impl_ty(&mut self, impl_dyn_multi: &mut bool) -> PResult<'a, TyKind> { - // Always parse bounds greedily for better error recovery. if self.token.is_lifetime() { self.look_ahead(1, |t| { if let token::Ident(sym, _) = t.kind { @@ -669,9 +668,26 @@ impl<'a> Parser<'a> { } }) } + + // parse precise captures, if any. + let precise_capturing = if self.eat_keyword(kw::Use) { + self.expect_lt()?; + let use_span = self.prev_token.span; + self.psess.gated_spans.gate(sym::precise_capturing, use_span); + let lo = self.token.span; + let args = self.parse_angle_args(None)?; + self.expect_gt()?; + Some(ast::AngleBracketedArgs { args, span: lo.to(self.prev_token.span) }.into()) + } else { + None + }; + + // Always parse bounds greedily for better error recovery. let bounds = self.parse_generic_bounds()?; + *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus); - Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)) + + Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, precise_capturing)) } /// Is a `dyn B0 + ... + Bn` type allowed here? @@ -957,7 +973,7 @@ impl<'a> Parser<'a> { Applicability::MaybeIncorrect, ) } - TyKind::ImplTrait(_, bounds) + TyKind::ImplTrait(_, bounds, None) if let [GenericBound::Trait(tr, ..), ..] = bounds.as_slice() => { ( diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 33c9c7fcc620..9e881532311a 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -793,7 +793,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, self.r.record_partial_res(ty.id, PartialRes::new(res)); visit::walk_ty(self, ty) } - TyKind::ImplTrait(node_id, _) => { + TyKind::ImplTrait(node_id, _, _) => { let candidates = self.lifetime_elision_candidates.take(); visit::walk_ty(self, ty); self.record_lifetime_params_for_impl_trait(*node_id); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index bb4294fbcfb2..d79c638fa078 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -3121,7 +3121,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { .inputs .iter() .filter_map(|param| match ¶m.ty.kind { - TyKind::ImplTrait(_, bounds) => Some(bounds), + TyKind::ImplTrait(_, bounds, _) => Some(bounds), _ => None, }) .flat_map(|bounds| bounds.into_iter()) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index bfd0f77c237b..19c3fc589430 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1375,6 +1375,7 @@ symbols! { powif32, powif64, pre_dash_lto: "pre-lto", + precise_capturing, precise_pointer_size_matching, pref_align_of, prefetch_read_data, From 647b672f16f6db2f156b69668ca963ec28016464 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 3 Apr 2024 20:54:23 -0400 Subject: [PATCH 031/114] Begin AST lowering for precise captures --- compiler/rustc_ast_lowering/src/lib.rs | 79 ++++++++++++------- .../precise-capturing/higher-ranked.rs | 18 +++++ .../precise-capturing/higher-ranked.stderr | 11 +++ .../impl-trait/precise-capturing/outlives.rs | 16 ++++ .../precise-capturing/outlives.stderr | 11 +++ 5 files changed, 106 insertions(+), 29 deletions(-) create mode 100644 tests/ui/impl-trait/precise-capturing/higher-ranked.rs create mode 100644 tests/ui/impl-trait/precise-capturing/higher-ranked.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/outlives.rs create mode 100644 tests/ui/impl-trait/precise-capturing/outlives.stderr diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index a4470622972e..32b2f7c86cad 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1399,7 +1399,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TyKind::TraitObject(bounds, lifetime_bound, *kind) } TyKind::ImplTrait(def_node_id, bounds, precise_capturing) => { - assert!(precise_capturing.is_none(), "precise captures not supported yet!"); let span = t.span; match itctx { ImplTraitContext::OpaqueTy { origin, fn_kind } => self.lower_opaque_impl_trait( @@ -1409,8 +1408,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds, fn_kind, itctx, + precise_capturing.as_deref(), ), ImplTraitContext::Universal => { + assert!( + precise_capturing.is_none(), + "TODO: precise captures not supported on universals!" + ); let span = t.span; // HACK: pprust breaks strings with newlines when the type @@ -1521,6 +1525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds: &GenericBounds, fn_kind: Option, itctx: ImplTraitContext, + precise_capturing: Option<&ast::GenericArgs>, ) -> hir::TyKind<'hir> { // Make sure we know that some funky desugaring has been going on here. // This is a first: there is code in other places like for loop @@ -1529,40 +1534,56 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let captured_lifetimes_to_duplicate = match origin { - hir::OpaqueTyOrigin::TyAlias { .. } => { - // type alias impl trait and associated type position impl trait were - // decided to capture all in-scope lifetimes, which we collect for - // all opaques during resolution. - self.resolver - .take_extra_lifetime_params(opaque_ty_node_id) - .into_iter() - .map(|(ident, id, _)| Lifetime { id, ident }) - .collect() - } - hir::OpaqueTyOrigin::FnReturn(..) => { - if matches!( - fn_kind.expect("expected RPITs to be lowered with a FnKind"), - FnDeclKind::Impl | FnDeclKind::Trait - ) || self.tcx.features().lifetime_capture_rules_2024 - || span.at_least_rust_2024() - { - // return-position impl trait in trait was decided to capture all - // in-scope lifetimes, which we collect for all opaques during resolution. + let captured_lifetimes_to_duplicate = if let Some(precise_capturing) = precise_capturing { + let ast::GenericArgs::AngleBracketed(precise_capturing) = precise_capturing else { + panic!("we only parse angle-bracketed args") + }; + // We'll actually validate these later on; all we need is the list of + // lifetimes to duplicate during this portion of lowering. + precise_capturing + .args + .iter() + .filter_map(|arg| match arg { + ast::AngleBracketedArg::Arg(ast::GenericArg::Lifetime(lt)) => Some(*lt), + _ => None, + }) + .collect() + } else { + match origin { + hir::OpaqueTyOrigin::TyAlias { .. } => { + // type alias impl trait and associated type position impl trait were + // decided to capture all in-scope lifetimes, which we collect for + // all opaques during resolution. self.resolver .take_extra_lifetime_params(opaque_ty_node_id) .into_iter() .map(|(ident, id, _)| Lifetime { id, ident }) .collect() - } else { - // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` - // example, we only need to duplicate lifetimes that appear in the - // bounds, since those are the only ones that are captured by the opaque. - lifetime_collector::lifetimes_in_bounds(self.resolver, bounds) } - } - hir::OpaqueTyOrigin::AsyncFn(..) => { - unreachable!("should be using `lower_async_fn_ret_ty`") + hir::OpaqueTyOrigin::FnReturn(..) => { + if matches!( + fn_kind.expect("expected RPITs to be lowered with a FnKind"), + FnDeclKind::Impl | FnDeclKind::Trait + ) || self.tcx.features().lifetime_capture_rules_2024 + || span.at_least_rust_2024() + { + // return-position impl trait in trait was decided to capture all + // in-scope lifetimes, which we collect for all opaques during resolution. + self.resolver + .take_extra_lifetime_params(opaque_ty_node_id) + .into_iter() + .map(|(ident, id, _)| Lifetime { id, ident }) + .collect() + } else { + // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` + // example, we only need to duplicate lifetimes that appear in the + // bounds, since those are the only ones that are captured by the opaque. + lifetime_collector::lifetimes_in_bounds(self.resolver, bounds) + } + } + hir::OpaqueTyOrigin::AsyncFn(..) => { + unreachable!("should be using `lower_async_fn_ret_ty`") + } } }; debug!(?captured_lifetimes_to_duplicate); diff --git a/tests/ui/impl-trait/precise-capturing/higher-ranked.rs b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs new file mode 100644 index 000000000000..c9faaaed9689 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs @@ -0,0 +1,18 @@ +//@ check-pass + +// Show how precise captures allow us to skip capturing a higher-ranked lifetime + +#![feature(lifetime_capture_rules_2024, precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +trait Trait<'a> { + type Item; +} + +impl Trait<'_> for () { + type Item = Vec<()>; +} + +fn hello() -> impl for<'a> Trait<'a, Item = impl use<> IntoIterator> {} + +fn main() {} \ No newline at end of file diff --git a/tests/ui/impl-trait/precise-capturing/higher-ranked.stderr b/tests/ui/impl-trait/precise-capturing/higher-ranked.stderr new file mode 100644 index 000000000000..e48d6d42af07 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/higher-ranked.stderr @@ -0,0 +1,11 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/higher-ranked.rs:5:41 + | +LL | #![feature(lifetime_capture_rules_2024, precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/outlives.rs b/tests/ui/impl-trait/precise-capturing/outlives.rs new file mode 100644 index 000000000000..71e6333934e7 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/outlives.rs @@ -0,0 +1,16 @@ +//@ check-pass + +// Show that precise captures allow us to skip a lifetime param for outlives + +#![feature(lifetime_capture_rules_2024, precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn hello<'a: 'a, 'b: 'b>() -> impl use<'a> Sized { } + +fn outlives<'a, T: 'a>(_: T) {} + +fn test<'a, 'b>() { + outlives::<'a, _>(hello::<'a, 'b>()); +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/outlives.stderr b/tests/ui/impl-trait/precise-capturing/outlives.stderr new file mode 100644 index 000000000000..405c09cccd94 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/outlives.stderr @@ -0,0 +1,11 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/outlives.rs:5:41 + | +LL | #![feature(lifetime_capture_rules_2024, precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + From fc9e344874ce718c951016ba29f7fcabb36f26c3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 3 Apr 2024 21:47:02 -0400 Subject: [PATCH 032/114] Use dedicated PreciseCapturingArg for representing what goes in use<> --- compiler/rustc_ast/src/ast.rs | 10 ++- compiler/rustc_ast/src/mut_visit.rs | 31 ++++++++- compiler/rustc_ast/src/visit.rs | 32 ++++++++- compiler/rustc_ast_lowering/src/lib.rs | 89 +++++++++++++------------- compiler/rustc_parse/src/parser/ty.rs | 30 +++++++-- compiler/rustc_resolve/src/late.rs | 10 +++ 6 files changed, 146 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 55a934c48a80..623a6437c532 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2132,7 +2132,7 @@ pub enum TyKind { /// The `NodeId` exists to prevent lowering from having to /// generate `NodeId`s on the fly, which would complicate /// the generation of opaque `type Foo = impl Trait` items significantly. - ImplTrait(NodeId, GenericBounds, Option>), + ImplTrait(NodeId, GenericBounds, Option>), /// No-op; kept solely so that we can pretty-print faithfully. Paren(P), /// Unused for now. @@ -2188,6 +2188,14 @@ pub enum TraitObjectSyntax { None, } +#[derive(Clone, PartialEq, Encodable, Decodable, Debug)] +pub enum PreciseCapturingArg { + /// Lifetime parameter + Lifetime(Lifetime), + /// Type or const parameter + Arg(Ident, NodeId), +} + /// Inline assembly operand explicit register or register class. /// /// E.g., `"eax"` as in `asm!("mov eax, 2", out("eax") result)`. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index b8a5eeebf3a0..cb6258739374 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -259,6 +259,14 @@ pub trait MutVisitor: Sized { noop_visit_param_bound(tpb, self); } + fn visit_precise_capturing_args(&mut self, args: &mut ThinVec) { + noop_visit_precise_capturing_args(args, self); + } + + fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) { + noop_visit_precise_capturing_arg(arg, self); + } + fn visit_mt(&mut self, mt: &mut MutTy) { noop_visit_mt(mt, self); } @@ -522,7 +530,7 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { vis.visit_id(id); visit_vec(bounds, |bound| vis.visit_param_bound(bound)); visit_opt(precise_capturing, |precise_capturing| { - vis.visit_generic_args(precise_capturing); + vis.visit_precise_capturing_args(precise_capturing); }); } TyKind::MacCall(mac) => vis.visit_mac_call(mac), @@ -917,6 +925,27 @@ pub fn noop_visit_param_bound(pb: &mut GenericBound, vis: &mut T) } } +pub fn noop_visit_precise_capturing_args( + args: &mut ThinVec, + vis: &mut T, +) { + for arg in args { + vis.visit_precise_capturing_arg(arg); + } +} + +pub fn noop_visit_precise_capturing_arg(arg: &mut PreciseCapturingArg, vis: &mut T) { + match arg { + PreciseCapturingArg::Lifetime(lt) => { + vis.visit_lifetime(lt); + } + PreciseCapturingArg::Arg(ident, id) => { + vis.visit_ident(ident); + vis.visit_id(id); + } + } +} + pub fn noop_flat_map_generic_param( mut param: GenericParam, vis: &mut T, diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 917400217270..b7e4d31edd70 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -20,6 +20,7 @@ use rustc_span::Span; pub use rustc_ast_ir::visit::VisitorResult; pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list}; +use thin_vec::ThinVec; #[derive(Copy, Clone, Debug, PartialEq)] pub enum AssocCtxt { @@ -184,6 +185,12 @@ pub trait Visitor<'ast>: Sized { fn visit_param_bound(&mut self, bounds: &'ast GenericBound, _ctxt: BoundKind) -> Self::Result { walk_param_bound(self, bounds) } + fn visit_precise_capturing_args(&mut self, args: &'ast ThinVec) { + walk_precise_capturing_args(self, args); + } + fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { + walk_precise_capturing_arg(self, arg); + } fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef) -> Self::Result { walk_poly_trait_ref(self, t) } @@ -459,7 +466,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result { } TyKind::ImplTrait(_, bounds, precise_capturing) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl); - visit_opt!(visitor, visit_generic_args, precise_capturing); + visit_opt!(visitor, visit_precise_capturing_args, precise_capturing); } TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)), TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {} @@ -638,6 +645,29 @@ pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericB } } +pub fn walk_precise_capturing_args<'a, V: Visitor<'a>>( + visitor: &mut V, + args: &'a ThinVec, +) { + for arg in args { + visitor.visit_precise_capturing_arg(arg); + } +} + +pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( + visitor: &mut V, + arg: &'a PreciseCapturingArg, +) { + match arg { + PreciseCapturingArg::Lifetime(lt) => { + visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg); + } + PreciseCapturingArg::Arg(ident, _) => { + visitor.visit_ident(*ident); + } + } +} + pub fn walk_generic_param<'a, V: Visitor<'a>>( visitor: &mut V, param: &'a GenericParam, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 32b2f7c86cad..731dda39e9a8 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1525,7 +1525,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds: &GenericBounds, fn_kind: Option, itctx: ImplTraitContext, - precise_capturing: Option<&ast::GenericArgs>, + precise_capturing: Option<&[ast::PreciseCapturingArg]>, ) -> hir::TyKind<'hir> { // Make sure we know that some funky desugaring has been going on here. // This is a first: there is code in other places like for loop @@ -1534,58 +1534,55 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let captured_lifetimes_to_duplicate = if let Some(precise_capturing) = precise_capturing { - let ast::GenericArgs::AngleBracketed(precise_capturing) = precise_capturing else { - panic!("we only parse angle-bracketed args") - }; - // We'll actually validate these later on; all we need is the list of - // lifetimes to duplicate during this portion of lowering. - precise_capturing - .args - .iter() - .filter_map(|arg| match arg { - ast::AngleBracketedArg::Arg(ast::GenericArg::Lifetime(lt)) => Some(*lt), - _ => None, - }) - .collect() - } else { - match origin { - hir::OpaqueTyOrigin::TyAlias { .. } => { - // type alias impl trait and associated type position impl trait were - // decided to capture all in-scope lifetimes, which we collect for - // all opaques during resolution. - self.resolver - .take_extra_lifetime_params(opaque_ty_node_id) - .into_iter() - .map(|(ident, id, _)| Lifetime { id, ident }) - .collect() - } - hir::OpaqueTyOrigin::FnReturn(..) => { - if matches!( - fn_kind.expect("expected RPITs to be lowered with a FnKind"), - FnDeclKind::Impl | FnDeclKind::Trait - ) || self.tcx.features().lifetime_capture_rules_2024 - || span.at_least_rust_2024() - { - // return-position impl trait in trait was decided to capture all - // in-scope lifetimes, which we collect for all opaques during resolution. + let captured_lifetimes_to_duplicate = + if let Some(precise_capturing) = precise_capturing_args { + // We'll actually validate these later on; all we need is the list of + // lifetimes to duplicate during this portion of lowering. + precise_capturing + .iter() + .filter_map(|arg| match arg { + ast::PreciseCapturingArg::Lifetime(lt) => Some(*lt), + ast::PreciseCapturingArg::Arg(..) => None, + }) + .collect() + } else { + match origin { + hir::OpaqueTyOrigin::TyAlias { .. } => { + // type alias impl trait and associated type position impl trait were + // decided to capture all in-scope lifetimes, which we collect for + // all opaques during resolution. self.resolver .take_extra_lifetime_params(opaque_ty_node_id) .into_iter() .map(|(ident, id, _)| Lifetime { id, ident }) .collect() - } else { - // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` - // example, we only need to duplicate lifetimes that appear in the - // bounds, since those are the only ones that are captured by the opaque. - lifetime_collector::lifetimes_in_bounds(self.resolver, bounds) + } + hir::OpaqueTyOrigin::FnReturn(..) => { + if matches!( + fn_kind.expect("expected RPITs to be lowered with a FnKind"), + FnDeclKind::Impl | FnDeclKind::Trait + ) || self.tcx.features().lifetime_capture_rules_2024 + || span.at_least_rust_2024() + { + // return-position impl trait in trait was decided to capture all + // in-scope lifetimes, which we collect for all opaques during resolution. + self.resolver + .take_extra_lifetime_params(opaque_ty_node_id) + .into_iter() + .map(|(ident, id, _)| Lifetime { id, ident }) + .collect() + } else { + // in fn return position, like the `fn test<'a>() -> impl Debug + 'a` + // example, we only need to duplicate lifetimes that appear in the + // bounds, since those are the only ones that are captured by the opaque. + lifetime_collector::lifetimes_in_bounds(self.resolver, bounds) + } + } + hir::OpaqueTyOrigin::AsyncFn(..) => { + unreachable!("should be using `lower_async_fn_ret_ty`") } } - hir::OpaqueTyOrigin::AsyncFn(..) => { - unreachable!("should be using `lower_async_fn_ret_ty`") - } - } - }; + }; debug!(?captured_lifetimes_to_duplicate); self.lower_opaque_inner( diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 5d6c4f39ae11..62f0602e1fa2 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -1,4 +1,4 @@ -use super::{Parser, PathStyle, TokenType, Trailing}; +use super::{Parser, PathStyle, SeqSep, TokenType, Trailing}; use crate::errors::{ self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType, @@ -14,7 +14,7 @@ use rustc_ast::util::case::Case; use rustc_ast::{ self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, MacCall, MutTy, Mutability, PolyTraitRef, - TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, DUMMY_NODE_ID, + PreciseCapturingArg, TraitBoundModifiers, TraitObjectSyntax, Ty, TyKind, DUMMY_NODE_ID, }; use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{kw, sym, Ident}; @@ -671,13 +671,10 @@ impl<'a> Parser<'a> { // parse precise captures, if any. let precise_capturing = if self.eat_keyword(kw::Use) { - self.expect_lt()?; let use_span = self.prev_token.span; self.psess.gated_spans.gate(sym::precise_capturing, use_span); - let lo = self.token.span; - let args = self.parse_angle_args(None)?; - self.expect_gt()?; - Some(ast::AngleBracketedArgs { args, span: lo.to(self.prev_token.span) }.into()) + let args = self.parse_precise_capturing_args()?; + Some(args) } else { None }; @@ -690,6 +687,25 @@ impl<'a> Parser<'a> { Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds, precise_capturing)) } + fn parse_precise_capturing_args(&mut self) -> PResult<'a, ThinVec> { + Ok(self + .parse_unspanned_seq( + &TokenKind::Lt, + &TokenKind::Gt, + SeqSep::trailing_allowed(token::Comma), + |self_| { + if self_.check_ident() { + Ok(PreciseCapturingArg::Arg(self_.parse_ident().unwrap(), DUMMY_NODE_ID)) + } else if self_.check_lifetime() { + Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime())) + } else { + self_.unexpected_any() + } + }, + )? + .0) + } + /// Is a `dyn B0 + ... + Bn` type allowed here? fn is_explicit_dyn_type(&mut self) -> bool { self.check_keyword(kw::Dyn) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 9e881532311a..e4bcdc96f44c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1047,10 +1047,20 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, }); self.diag_metadata.current_function = previous_value; } + fn visit_lifetime(&mut self, lifetime: &'ast Lifetime, use_ctxt: visit::LifetimeCtxt) { self.resolve_lifetime(lifetime, use_ctxt) } + fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { + match arg { + PreciseCapturingArg::Lifetime(_) => visit::walk_precise_capturing_arg(self, arg), + PreciseCapturingArg::Arg(ident, _) => { + todo!("cannot resolve args yet: {ident}"); + } + } + } + fn visit_generics(&mut self, generics: &'ast Generics) { self.visit_generic_params(&generics.params, self.diag_metadata.current_self_item.is_some()); for p in &generics.where_clause.predicates { From c897092654bae65d5695ef3b1a5850c15513ed5d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 3 Apr 2024 22:34:53 -0400 Subject: [PATCH 033/114] Implement resolution, parse use --- compiler/rustc_parse/src/parser/ty.rs | 8 +++++++- compiler/rustc_resolve/src/late.rs | 24 ++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 62f0602e1fa2..a24ecf938ba4 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -694,7 +694,13 @@ impl<'a> Parser<'a> { &TokenKind::Gt, SeqSep::trailing_allowed(token::Comma), |self_| { - if self_.check_ident() { + if self_.check_keyword(kw::SelfUpper) { + self_.bump(); + Ok(PreciseCapturingArg::Arg( + self_.prev_token.ident().unwrap().0, + DUMMY_NODE_ID, + )) + } else if self_.check_ident() { Ok(PreciseCapturingArg::Arg(self_.parse_ident().unwrap(), DUMMY_NODE_ID)) } else if self_.check_lifetime() { Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime())) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index e4bcdc96f44c..c7e12284b50f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1055,8 +1055,28 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { match arg { PreciseCapturingArg::Lifetime(_) => visit::walk_precise_capturing_arg(self, arg), - PreciseCapturingArg::Arg(ident, _) => { - todo!("cannot resolve args yet: {ident}"); + PreciseCapturingArg::Arg(ident, node_id) => { + let ident = ident.normalize_to_macros_2_0(); + 'found: { + for (rib_t, rib_v) in + std::iter::zip(&self.ribs.type_ns, &self.ribs.value_ns).rev() + { + if let Some(res) = rib_t.bindings.get(&ident).or(rib_v.bindings.get(&ident)) + { + self.r.record_partial_res(*node_id, PartialRes::new(*res)); + break 'found; + } + } + self.report_error( + ident.span, + ResolutionError::FailedToResolve { + segment: Some(ident.name), + label: "could not find type or const parameter".to_string(), + suggestion: None, + module: None, + }, + ); + } } } } From 41cf87b71b792b40155cd79f96234a89ae7dc27f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 4 Apr 2024 10:48:47 -0400 Subject: [PATCH 034/114] Lower and resolve precise captures in HIR --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast/src/mut_visit.rs | 17 ++----- compiler/rustc_ast/src/visit.rs | 19 ++------ compiler/rustc_ast_lowering/src/lib.rs | 47 ++++++++++++++++--- .../src/lifetime_collector.rs | 15 +++--- compiler/rustc_hir/src/hir.rs | 9 ++++ compiler/rustc_hir/src/intravisit.rs | 20 +++++++- .../src/collect/resolve_bound_vars.rs | 25 ++++++++++ 8 files changed, 108 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 623a6437c532..ec445bc5ed30 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -63,7 +63,7 @@ impl fmt::Debug for Label { /// A "Lifetime" is an annotation of the scope in which variable /// can be used, e.g. `'a` in `&'a i32`. -#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq)] +#[derive(Clone, Encodable, Decodable, Copy, PartialEq, Eq, Hash)] pub struct Lifetime { pub id: NodeId, pub ident: Ident, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index cb6258739374..5c9e1313b5b8 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -259,10 +259,6 @@ pub trait MutVisitor: Sized { noop_visit_param_bound(tpb, self); } - fn visit_precise_capturing_args(&mut self, args: &mut ThinVec) { - noop_visit_precise_capturing_args(args, self); - } - fn visit_precise_capturing_arg(&mut self, arg: &mut PreciseCapturingArg) { noop_visit_precise_capturing_arg(arg, self); } @@ -530,7 +526,9 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { vis.visit_id(id); visit_vec(bounds, |bound| vis.visit_param_bound(bound)); visit_opt(precise_capturing, |precise_capturing| { - vis.visit_precise_capturing_args(precise_capturing); + for arg in precise_capturing { + vis.visit_precise_capturing_arg(arg); + } }); } TyKind::MacCall(mac) => vis.visit_mac_call(mac), @@ -925,15 +923,6 @@ pub fn noop_visit_param_bound(pb: &mut GenericBound, vis: &mut T) } } -pub fn noop_visit_precise_capturing_args( - args: &mut ThinVec, - vis: &mut T, -) { - for arg in args { - vis.visit_precise_capturing_arg(arg); - } -} - pub fn noop_visit_precise_capturing_arg(arg: &mut PreciseCapturingArg, vis: &mut T) { match arg { PreciseCapturingArg::Lifetime(lt) => { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index b7e4d31edd70..055afc422edb 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -20,7 +20,6 @@ use rustc_span::Span; pub use rustc_ast_ir::visit::VisitorResult; pub use rustc_ast_ir::{try_visit, visit_opt, walk_list, walk_visitable_list}; -use thin_vec::ThinVec; #[derive(Copy, Clone, Debug, PartialEq)] pub enum AssocCtxt { @@ -185,9 +184,6 @@ pub trait Visitor<'ast>: Sized { fn visit_param_bound(&mut self, bounds: &'ast GenericBound, _ctxt: BoundKind) -> Self::Result { walk_param_bound(self, bounds) } - fn visit_precise_capturing_args(&mut self, args: &'ast ThinVec) { - walk_precise_capturing_args(self, args); - } fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { walk_precise_capturing_arg(self, arg); } @@ -466,7 +462,11 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result { } TyKind::ImplTrait(_, bounds, precise_capturing) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl); - visit_opt!(visitor, visit_precise_capturing_args, precise_capturing); + if let Some(precise_capturing) = precise_capturing { + for arg in precise_capturing { + try_visit!(visitor.visit_precise_capturing_arg(arg)); + } + } } TyKind::Typeof(expression) => try_visit!(visitor.visit_anon_const(expression)), TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {} @@ -645,15 +645,6 @@ pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericB } } -pub fn walk_precise_capturing_args<'a, V: Visitor<'a>>( - visitor: &mut V, - args: &'a ThinVec, -) { - for arg in args { - visitor.visit_precise_capturing_arg(arg); - } -} - pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( visitor: &mut V, arg: &'a PreciseCapturingArg, diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 731dda39e9a8..2a220dd4df63 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -48,6 +48,7 @@ use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust; use rustc_data_structures::captures::Captures; use rustc_data_structures::fingerprint::Fingerprint; +use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; @@ -1525,7 +1526,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds: &GenericBounds, fn_kind: Option, itctx: ImplTraitContext, - precise_capturing: Option<&[ast::PreciseCapturingArg]>, + precise_capturing_args: Option<&[PreciseCapturingArg]>, ) -> hir::TyKind<'hir> { // Make sure we know that some funky desugaring has been going on here. // This is a first: there is code in other places like for loop @@ -1541,9 +1542,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { precise_capturing .iter() .filter_map(|arg| match arg { - ast::PreciseCapturingArg::Lifetime(lt) => Some(*lt), - ast::PreciseCapturingArg::Arg(..) => None, + PreciseCapturingArg::Lifetime(lt) => Some(*lt), + PreciseCapturingArg::Arg(..) => None, }) + // Add in all the lifetimes mentioned in the bounds. We will error + // them out later, but capturing them here is important to make sure + // they actually get resolved in resolve_bound_vars. + .chain(lifetime_collector::lifetimes_in_bounds(self.resolver, bounds)) .collect() } else { match origin { @@ -1592,6 +1597,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { captured_lifetimes_to_duplicate, span, opaque_ty_span, + precise_capturing_args, |this| this.lower_param_bounds(bounds, itctx), ) } @@ -1601,9 +1607,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { opaque_ty_node_id: NodeId, origin: hir::OpaqueTyOrigin, in_trait: bool, - captured_lifetimes_to_duplicate: Vec, + captured_lifetimes_to_duplicate: FxIndexSet, span: Span, opaque_ty_span: Span, + precise_capturing_args: Option<&[PreciseCapturingArg]>, lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>], ) -> hir::TyKind<'hir> { let opaque_ty_def_id = self.create_def( @@ -1690,8 +1697,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Install the remapping from old to new (if any). This makes sure that // any lifetimes that would have resolved to the def-id of captured // lifetimes are remapped to the new *synthetic* lifetimes of the opaque. - let bounds = this - .with_remapping(captured_to_synthesized_mapping, |this| lower_item_bounds(this)); + let (bounds, precise_capturing_args) = + this.with_remapping(captured_to_synthesized_mapping, |this| { + ( + lower_item_bounds(this), + precise_capturing_args.map(|precise_capturing| { + this.lower_precise_capturing_args(precise_capturing) + }), + ) + }); let generic_params = this.arena.alloc_from_iter(synthesized_lifetime_definitions.iter().map( @@ -1736,6 +1750,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { origin, lifetime_mapping, in_trait, + precise_capturing_args, }; // Generate an `type Foo = impl Trait;` declaration. @@ -1768,6 +1783,23 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } + fn lower_precise_capturing_args( + &mut self, + precise_capturing_args: &[PreciseCapturingArg], + ) -> &'hir [hir::PreciseCapturingArg<'hir>] { + self.arena.alloc_from_iter(precise_capturing_args.iter().map(|arg| match arg { + PreciseCapturingArg::Lifetime(lt) => { + hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt)) + } + PreciseCapturingArg::Arg(_, node_id) => { + let res = self.resolver.get_partial_res(*node_id).map_or(Res::Err, |partial_res| { + partial_res.full_res().expect("no partial res expected for precise capture arg") + }); + hir::PreciseCapturingArg::Param(self.lower_res(res), self.lower_node_id(*node_id)) + } + })) + } + fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] { self.arena.alloc_from_iter(decl.inputs.iter().map(|param| match param.pat.kind { PatKind::Ident(_, ident, _) => self.lower_ident(ident), @@ -1908,7 +1940,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, allowed_features); - let captured_lifetimes: Vec<_> = self + let captured_lifetimes = self .resolver .take_extra_lifetime_params(opaque_ty_node_id) .into_iter() @@ -1922,6 +1954,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { captured_lifetimes, span, opaque_ty_span, + None, |this| { let bound = this.lower_coroutine_fn_output_type_to_bound( output, diff --git a/compiler/rustc_ast_lowering/src/lifetime_collector.rs b/compiler/rustc_ast_lowering/src/lifetime_collector.rs index 4b1c057cdbf1..5456abd489be 100644 --- a/compiler/rustc_ast_lowering/src/lifetime_collector.rs +++ b/compiler/rustc_ast_lowering/src/lifetime_collector.rs @@ -1,6 +1,7 @@ use super::ResolverAstLoweringExt; use rustc_ast::visit::{self, BoundKind, LifetimeCtxt, Visitor}; use rustc_ast::{GenericBounds, Lifetime, NodeId, PathSegment, PolyTraitRef, Ty, TyKind}; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def::{DefKind, LifetimeRes, Res}; use rustc_middle::span_bug; use rustc_middle::ty::ResolverAstLowering; @@ -10,27 +11,23 @@ use rustc_span::Span; struct LifetimeCollectVisitor<'ast> { resolver: &'ast ResolverAstLowering, current_binders: Vec, - collected_lifetimes: Vec, + collected_lifetimes: FxIndexSet, } impl<'ast> LifetimeCollectVisitor<'ast> { fn new(resolver: &'ast ResolverAstLowering) -> Self { - Self { resolver, current_binders: Vec::new(), collected_lifetimes: Vec::new() } + Self { resolver, current_binders: Vec::new(), collected_lifetimes: FxIndexSet::default() } } fn record_lifetime_use(&mut self, lifetime: Lifetime) { match self.resolver.get_lifetime_res(lifetime.id).unwrap_or(LifetimeRes::Error) { LifetimeRes::Param { binder, .. } | LifetimeRes::Fresh { binder, .. } => { if !self.current_binders.contains(&binder) { - if !self.collected_lifetimes.contains(&lifetime) { - self.collected_lifetimes.push(lifetime); - } + self.collected_lifetimes.insert(lifetime); } } LifetimeRes::Static | LifetimeRes::Error => { - if !self.collected_lifetimes.contains(&lifetime) { - self.collected_lifetimes.push(lifetime); - } + self.collected_lifetimes.insert(lifetime); } LifetimeRes::Infer => {} res => { @@ -111,7 +108,7 @@ impl<'ast> Visitor<'ast> for LifetimeCollectVisitor<'ast> { pub(crate) fn lifetimes_in_bounds( resolver: &ResolverAstLowering, bounds: &GenericBounds, -) -> Vec { +) -> FxIndexSet { let mut visitor = LifetimeCollectVisitor::new(resolver); for bound in bounds { visitor.visit_param_bound(bound, BoundKind::Bound); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index c6e3ad31f013..dc76deb18152 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2557,6 +2557,15 @@ pub struct OpaqueTy<'hir> { /// originating from a trait method. This makes it so that the opaque is /// lowered as an associated type. pub in_trait: bool, + /// List of arguments captured via `impl use<'a, P, ...> Trait` syntax. + pub precise_capturing_args: Option<&'hir [PreciseCapturingArg<'hir>]>, +} + +#[derive(Debug, Clone, Copy, HashStable_Generic)] +pub enum PreciseCapturingArg<'hir> { + Lifetime(&'hir Lifetime), + /// Non-lifetime argument (type or const) + Param(Res, HirId), } /// From whence the opaque type came. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 5da9d4444da3..d3ede3a904f9 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -413,6 +413,9 @@ pub trait Visitor<'v>: Sized { fn visit_param_bound(&mut self, bounds: &'v GenericBound<'v>) -> Self::Result { walk_param_bound(self, bounds) } + fn visit_precise_capturing_arg(&mut self, arg: &'v PreciseCapturingArg<'v>) -> Self::Result { + walk_precise_capturing_arg(self, arg) + } fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef<'v>) -> Self::Result { walk_poly_trait_ref(self, t) } @@ -526,10 +529,15 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_ty(ty)); try_visit!(visitor.visit_generics(generics)); } - ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, .. }) => { + ItemKind::OpaqueTy(&OpaqueTy { generics, bounds, precise_capturing_args, .. }) => { try_visit!(visitor.visit_id(item.hir_id())); try_visit!(walk_generics(visitor, generics)); walk_list!(visitor, visit_param_bound, bounds); + if let Some(precise_capturing_args) = precise_capturing_args { + for arg in precise_capturing_args { + try_visit!(visitor.visit_precise_capturing_arg(arg)); + } + } } ItemKind::Enum(ref enum_definition, ref generics) => { try_visit!(visitor.visit_generics(generics)); @@ -1137,6 +1145,16 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>( } } +pub fn walk_precise_capturing_arg<'v, V: Visitor<'v>>( + visitor: &mut V, + arg: &'v PreciseCapturingArg<'v>, +) -> V::Result { + match *arg { + PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt), + PreciseCapturingArg::Param(_, hir_id) => visitor.visit_id(hir_id), + } +} + pub fn walk_poly_trait_ref<'v, V: Visitor<'v>>( visitor: &mut V, trait_ref: &'v PolyTraitRef<'v>, diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 3d16f1420d99..8e29269e8fd1 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -557,6 +557,31 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } } + fn visit_precise_capturing_arg( + &mut self, + arg: &'tcx hir::PreciseCapturingArg<'tcx>, + ) -> Self::Result { + match *arg { + hir::PreciseCapturingArg::Lifetime(lt) => match lt.res { + LifetimeName::Param(def_id) => { + self.resolve_lifetime_ref(def_id, lt); + } + LifetimeName::Error => {} + LifetimeName::ImplicitObjectLifetimeDefault + | LifetimeName::Infer + | LifetimeName::Static => todo!("TODO: Error on invalid lifetime"), + }, + hir::PreciseCapturingArg::Param(res, hir_id) => match res { + Res::Def(DefKind::TyParam | DefKind::ConstParam, def_id) + | Res::SelfTyParam { trait_: def_id } => { + self.resolve_type_ref(def_id.expect_local(), hir_id); + } + Res::Err => {} + _ => todo!("TODO: Error on invalid param res"), + }, + } + } + fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { match item.kind { hir::ForeignItemKind::Fn(_, _, generics) => { From 42ba57c0133306ff510bf641e9d90b33419d7ac7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 4 Apr 2024 12:54:56 -0400 Subject: [PATCH 035/114] Validation and other things --- compiler/rustc_ast/src/ast.rs | 2 +- compiler/rustc_ast/src/mut_visit.rs | 4 +- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/messages.ftl | 2 + compiler/rustc_ast_lowering/src/errors.rs | 7 ++ compiler/rustc_ast_lowering/src/lib.rs | 9 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 12 ++- compiler/rustc_feature/src/unstable.rs | 4 +- compiler/rustc_hir_analysis/messages.ftl | 10 ++ .../rustc_hir_analysis/src/check/check.rs | 95 ++++++++++++++++++- .../src/collect/resolve_bound_vars.rs | 13 ++- compiler/rustc_hir_analysis/src/errors.rs | 3 + .../src/errors/precise_captures.rs | 33 +++++++ compiler/rustc_parse/src/parser/ty.rs | 2 +- compiler/rustc_resolve/src/late.rs | 35 +++++++ .../precise-capturing/bad-lifetimes.rs | 14 +++ .../precise-capturing/bad-lifetimes.stderr | 45 +++++++++ .../precise-capturing/bad-params.rs | 16 ++++ .../precise-capturing/bad-params.stderr | 30 ++++++ .../forgot-to-capture-const.rs | 7 ++ .../forgot-to-capture-const.stderr | 19 ++++ .../forgot-to-capture-lifetime.rs | 7 ++ .../forgot-to-capture-lifetime.stderr | 19 ++++ .../forgot-to-capture-type.rs | 10 ++ .../forgot-to-capture-type.stderr | 35 +++++++ .../precise-capturing/higher-ranked.rs | 2 +- 26 files changed, 418 insertions(+), 19 deletions(-) create mode 100644 compiler/rustc_hir_analysis/src/errors/precise_captures.rs create mode 100644 tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs create mode 100644 tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/bad-params.rs create mode 100644 tests/ui/impl-trait/precise-capturing/bad-params.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.rs create mode 100644 tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs create mode 100644 tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs create mode 100644 tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ec445bc5ed30..ace20a005ee4 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2132,7 +2132,7 @@ pub enum TyKind { /// The `NodeId` exists to prevent lowering from having to /// generate `NodeId`s on the fly, which would complicate /// the generation of opaque `type Foo = impl Trait` items significantly. - ImplTrait(NodeId, GenericBounds, Option>), + ImplTrait(NodeId, GenericBounds, Option, Span)>>), /// No-op; kept solely so that we can pretty-print faithfully. Paren(P), /// Unused for now. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 5c9e1313b5b8..204f33cab345 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -525,11 +525,11 @@ pub fn noop_visit_ty(ty: &mut P, vis: &mut T) { TyKind::ImplTrait(id, bounds, precise_capturing) => { vis.visit_id(id); visit_vec(bounds, |bound| vis.visit_param_bound(bound)); - visit_opt(precise_capturing, |precise_capturing| { + if let Some((precise_capturing, _span)) = precise_capturing.as_deref_mut() { for arg in precise_capturing { vis.visit_precise_capturing_arg(arg); } - }); + } } TyKind::MacCall(mac) => vis.visit_mac_call(mac), TyKind::AnonStruct(id, fields) | TyKind::AnonUnion(id, fields) => { diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 055afc422edb..a9c29e077d13 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -462,7 +462,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) -> V::Result { } TyKind::ImplTrait(_, bounds, precise_capturing) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl); - if let Some(precise_capturing) = precise_capturing { + if let Some((precise_capturing, _span)) = precise_capturing.as_deref() { for arg in precise_capturing { try_visit!(visitor.visit_precise_capturing_arg(arg)); } diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index d91d65497e1c..a23e714ef017 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -127,6 +127,8 @@ ast_lowering_never_pattern_with_guard = a guard on a never pattern will never be run .suggestion = remove this guard +ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed on argument-position `impl Trait` + ast_lowering_previously_used_here = previously used here ast_lowering_register1 = register `{$reg1_name}` diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 6fd980ed3ca9..ca0821e2c9ed 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -414,3 +414,10 @@ pub(crate) struct AsyncBoundOnlyForFnTraits { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(ast_lowering_no_precise_captures_on_apit)] +pub(crate) struct NoPreciseCapturesOnApit { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 2a220dd4df63..b586d2a1bf56 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1409,13 +1409,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { bounds, fn_kind, itctx, - precise_capturing.as_deref(), + precise_capturing.as_deref().map(|(args, _)| args.as_slice()), ), ImplTraitContext::Universal => { - assert!( - precise_capturing.is_none(), - "TODO: precise captures not supported on universals!" - ); + if let Some(&(_, span)) = precise_capturing.as_deref() { + self.tcx.dcx().emit_err(errors::NoPreciseCapturesOnApit { span }); + }; let span = t.span; // HACK: pprust breaks strings with newlines when the type diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 6553ed72532c..db9633bb1cbb 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1150,9 +1150,17 @@ impl<'a> State<'a> { } self.print_type_bounds(bounds); } - ast::TyKind::ImplTrait(_, bounds, _precise_capturing) => { - // TODO(precise_capturing): + ast::TyKind::ImplTrait(_, bounds, precise_capturing_args) => { self.word_nbsp("impl"); + if let Some((precise_capturing_args, ..)) = precise_capturing_args.as_deref() { + self.word("use"); + self.word("<"); + self.commasep(Inconsistent, precise_capturing_args, |s, arg| match arg { + ast::PreciseCapturingArg::Arg(a, _) => s.print_ident(*a), + ast::PreciseCapturingArg::Lifetime(lt) => s.print_lifetime(*lt), + }); + self.word(">") + } self.print_type_bounds(bounds); } ast::TyKind::Array(ty, length) => { diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 792cc1066f5a..7986add68b7f 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -535,8 +535,6 @@ declare_features! ( (unstable, must_not_suspend, "1.57.0", Some(83310)), /// Allows `mut ref` and `mut ref mut` identifier patterns. (incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)), - /// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args. - (incomplete, precise_capturing, "CURRENT_RUSTC_VERSION", Some(123432)), /// Allows using `#[naked]` on functions. (unstable, naked_functions, "1.9.0", Some(90957)), /// Allows specifying the as-needed link modifier @@ -569,6 +567,8 @@ declare_features! ( (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows postfix match `expr.match { ... }` (unstable, postfix_match, "CURRENT_RUSTC_VERSION", Some(121618)), + /// Allows `use<'a, 'b, A, B>` in `impl use<...> Trait` for precise capture of generic args. + (incomplete, precise_capturing, "CURRENT_RUSTC_VERSION", Some(123432)), /// Allows macro attributes on expressions, statements and non-inline modules. (unstable, proc_macro_hygiene, "1.30.0", Some(54727)), /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 86b8b6d6b2b6..81cf3067a1ed 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -37,6 +37,8 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh .label = deref recursion limit reached .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) +hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found} + hir_analysis_cannot_capture_late_bound_const = cannot capture late-bound const parameter in {$what} .label = parameter defined here @@ -214,6 +216,10 @@ hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetim hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl .label = type parameter declared here +hir_analysis_lifetime_not_captured = `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + .label = lifetime captured due to being mentioned in the bounds of the `impl Trait` + .param_label = this lifetime parameter is captured + 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 @@ -339,6 +345,10 @@ hir_analysis_param_in_ty_of_assoc_const_binding = *[normal] the {$param_def_kind} `{$param_name}` is defined here } +hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope + .label = {$kind} parameter is implicitly captured by this `impl Trait` + .note = currently, all {$kind} parameters are required to be mentioned in the precise captures list + hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation .help = add `#![feature(unboxed_closures)]` to the crate attributes to use it diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 216b89fd4f15..f4d443c324a0 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1,10 +1,10 @@ use crate::check::intrinsicck::InlineAsmCtxt; -use crate::errors::LinkageType; use super::compare_impl_item::check_type_bounds; use super::compare_impl_item::{compare_impl_method, compare_impl_ty}; use super::*; use rustc_attr as attr; +use rustc_data_structures::unord::UnordSet; use rustc_errors::{codes::*, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; @@ -12,6 +12,7 @@ use rustc_hir::Node; use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::{Obligation, TraitEngineExt as _}; use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS; +use rustc_middle::middle::resolve_bound_vars::ResolvedArg; use rustc_middle::middle::stability::EvalResult; use rustc_middle::traits::ObligationCauseCode; use rustc_middle::ty::fold::BottomUpFolder; @@ -474,6 +475,94 @@ fn sanity_check_found_hidden_type<'tcx>( } } +fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) { + let hir::OpaqueTy { precise_capturing_args, .. } = + *tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); + let Some(precise_capturing_args) = precise_capturing_args else { + // No precise capturing args; nothing to validate + return; + }; + + let mut expected_captures = UnordSet::default(); + for arg in precise_capturing_args { + match *arg { + hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, .. }) + | hir::PreciseCapturingArg::Param(_, hir_id) => match tcx.named_bound_var(hir_id) { + Some(ResolvedArg::EarlyBound(def_id)) => { + expected_captures.insert(def_id); + } + _ => { + tcx.dcx().span_delayed_bug( + tcx.hir().span(hir_id), + "parameter should have been resolved", + ); + } + }, + } + } + + let variances = tcx.variances_of(opaque_def_id); + let mut def_id = Some(opaque_def_id.to_def_id()); + while let Some(generics) = def_id { + let generics = tcx.generics_of(generics); + def_id = generics.parent; + + for param in &generics.params { + if expected_captures.contains(¶m.def_id) { + assert_eq!( + variances[param.index as usize], + ty::Invariant, + "precise captured param should be invariant" + ); + continue; + } + + match param.kind { + ty::GenericParamDefKind::Lifetime => { + // Check if the lifetime param was captured but isn't named in the precise captures list. + if variances[param.index as usize] == ty::Invariant { + let param_span = + if let ty::ReEarlyParam(ty::EarlyParamRegion { def_id, .. }) + | ty::ReLateParam(ty::LateParamRegion { + bound_region: ty::BoundRegionKind::BrNamed(def_id, _), + .. + }) = *tcx + .map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local()) + { + Some(tcx.def_span(def_id)) + } else { + None + }; + // FIXME(precise_capturing): Structured suggestion for this would be useful + tcx.dcx().emit_err(errors::LifetimeNotCaptured { + use_span: tcx.def_span(param.def_id), + param_span, + opaque_span: tcx.def_span(opaque_def_id), + }); + continue; + } + } + ty::GenericParamDefKind::Type { .. } => { + // FIXME(precise_capturing): Structured suggestion for this would be useful + tcx.dcx().emit_err(errors::ParamNotCaptured { + param_span: tcx.def_span(param.def_id), + opaque_span: tcx.def_span(opaque_def_id), + kind: "type", + }); + } + ty::GenericParamDefKind::Const { .. } => { + // FIXME(precise_capturing): Structured suggestion for this would be useful + tcx.dcx().emit_err(errors::ParamNotCaptured { + param_span: tcx.def_span(param.def_id), + opaque_span: tcx.def_span(opaque_def_id), + kind: "const", + }); + } + } + } + } +} + fn is_enum_of_nonnullable_ptr<'tcx>( tcx: TyCtxt<'tcx>, adt_def: AdtDef<'tcx>, @@ -499,7 +588,7 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) { ty::Adt(adt_def, args) => !is_enum_of_nonnullable_ptr(tcx, *adt_def, *args), _ => true, } { - tcx.dcx().emit_err(LinkageType { span: tcx.def_span(def_id) }); + tcx.dcx().emit_err(errors::LinkageType { span: tcx.def_span(def_id) }); } } } @@ -566,6 +655,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) { check_union(tcx, def_id); } DefKind::OpaqueTy => { + check_opaque_precise_captures(tcx, def_id); + let origin = tcx.opaque_type_origin(def_id); if let hir::OpaqueTyOrigin::FnReturn(fn_def_id) | hir::OpaqueTyOrigin::AsyncFn(fn_def_id) = origin diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 8e29269e8fd1..8d5f4c13721f 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -569,7 +569,13 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { LifetimeName::Error => {} LifetimeName::ImplicitObjectLifetimeDefault | LifetimeName::Infer - | LifetimeName::Static => todo!("TODO: Error on invalid lifetime"), + | LifetimeName::Static => { + self.tcx.dcx().emit_err(errors::BadPreciseCapture { + span: lt.ident.span, + kind: "lifetime", + found: format!("`{}`", lt.ident.name), + }); + } }, hir::PreciseCapturingArg::Param(res, hir_id) => match res { Res::Def(DefKind::TyParam | DefKind::ConstParam, def_id) @@ -577,7 +583,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { self.resolve_type_ref(def_id.expect_local(), hir_id); } Res::Err => {} - _ => todo!("TODO: Error on invalid param res"), + _ => { + // This is handled in resolve + self.tcx.dcx().delayed_bug(format!("parameter should have been resolved")); + } }, } } diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index d129614e0e1a..867ee772a30a 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -10,6 +10,9 @@ use rustc_span::{symbol::Ident, Span, Symbol}; mod pattern_types; pub use pattern_types::*; +mod precise_captures; +pub(crate) use precise_captures::*; + #[derive(Diagnostic)] #[diag(hir_analysis_ambiguous_assoc_item)] pub struct AmbiguousAssocItem<'a> { diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs new file mode 100644 index 000000000000..3b22437abb24 --- /dev/null +++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs @@ -0,0 +1,33 @@ +use rustc_macros::Diagnostic; +use rustc_span::Span; + +#[derive(Diagnostic)] +#[diag(hir_analysis_param_not_captured)] +#[note] +pub struct ParamNotCaptured { + #[primary_span] + pub param_span: Span, + #[label] + pub opaque_span: Span, + pub kind: &'static str, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_lifetime_not_captured)] +pub struct LifetimeNotCaptured { + #[primary_span] + pub use_span: Span, + #[label(hir_analysis_param_label)] + pub param_span: Option, + #[label] + pub opaque_span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_bad_precise_capture)] +pub struct BadPreciseCapture { + #[primary_span] + pub span: Span, + pub kind: &'static str, + pub found: String, +} diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index a24ecf938ba4..91f4823f65d4 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -674,7 +674,7 @@ impl<'a> Parser<'a> { let use_span = self.prev_token.span; self.psess.gated_spans.gate(sym::precise_capturing, use_span); let args = self.parse_precise_capturing_args()?; - Some(args) + Some(P((args, use_span))) } else { None }; diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c7e12284b50f..7203adab135a 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1054,7 +1054,10 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, fn visit_precise_capturing_arg(&mut self, arg: &'ast PreciseCapturingArg) { match arg { + // Lower the lifetime regularly; we'll resolve the lifetime and check + // it's a parameter later on in HIR lowering. PreciseCapturingArg::Lifetime(_) => visit::walk_precise_capturing_arg(self, arg), + PreciseCapturingArg::Arg(ident, node_id) => { let ident = ident.normalize_to_macros_2_0(); 'found: { @@ -1064,6 +1067,38 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, if let Some(res) = rib_t.bindings.get(&ident).or(rib_v.bindings.get(&ident)) { self.r.record_partial_res(*node_id, PartialRes::new(*res)); + + // Validate that this is a parameter + match res { + Res::Def(DefKind::TyParam | DefKind::ConstParam, _) + | Res::SelfTyParam { .. } => {} + Res::SelfTyAlias { .. } => { + self.report_error( + ident.span, + ResolutionError::FailedToResolve { + segment: Some(ident.name), + label: "`Self` cannot be captured because it is not a type parameter".to_string(), + suggestion: None, + module: None, + }, + ); + } + _ => { + self.report_error( + ident.span, + ResolutionError::FailedToResolve { + segment: Some(ident.name), + label: format!( + "expected type or const parameter, found {}", + res.descr() + ), + suggestion: None, + module: None, + }, + ); + } + } + break 'found; } } diff --git a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs new file mode 100644 index 000000000000..623063a8f502 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs @@ -0,0 +1,14 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn no_elided_lt() -> impl use<'_> Sized {} +//~^ ERROR missing lifetime specifier +//~| ERROR expected lifetime parameter in `use<...>` precise captures list, found `'_` + +fn static_lt() -> impl use<'static> Sized {} +//~^ ERROR expected lifetime parameter in `use<...>` precise captures list, found `'static` + +fn missing_lt() -> impl use<'missing> Sized {} +//~^ ERROR use of undeclared lifetime name `'missing` + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr new file mode 100644 index 000000000000..a926362c50c8 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr @@ -0,0 +1,45 @@ +error[E0106]: missing lifetime specifier + --> $DIR/bad-lifetimes.rs:4:31 + | +LL | fn no_elided_lt() -> impl use<'_> Sized {} + | ^^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime, but this is uncommon unless you're returning a borrowed value from a `const` or a `static`, or if you will only have owned values + | +LL | fn no_elided_lt() -> impl use<'static> Sized {} + | ~~~~~~~ + +error[E0261]: use of undeclared lifetime name `'missing` + --> $DIR/bad-lifetimes.rs:11:29 + | +LL | fn missing_lt() -> impl use<'missing> Sized {} + | - ^^^^^^^^ undeclared lifetime + | | + | help: consider introducing lifetime `'missing` here: `<'missing>` + +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-lifetimes.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: expected lifetime parameter in `use<...>` precise captures list, found `'_` + --> $DIR/bad-lifetimes.rs:4:31 + | +LL | fn no_elided_lt() -> impl use<'_> Sized {} + | ^^ + +error: expected lifetime parameter in `use<...>` precise captures list, found `'static` + --> $DIR/bad-lifetimes.rs:8:28 + | +LL | fn static_lt() -> impl use<'static> Sized {} + | ^^^^^^^ + +error: aborting due to 4 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0106, E0261. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.rs b/tests/ui/impl-trait/precise-capturing/bad-params.rs new file mode 100644 index 000000000000..c600fa96f794 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bad-params.rs @@ -0,0 +1,16 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn missing() -> impl use Sized {} +//~^ ERROR could not find type or const parameter + +fn missing_self() -> impl use Sized {} +//~^ ERROR could not find type or const parameter + +struct MyType; +impl MyType { + fn self_is_not_param() -> impl use Sized {} + //~^ ERROR `Self` cannot be captured because it is not a type parameter +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.stderr b/tests/ui/impl-trait/precise-capturing/bad-params.stderr new file mode 100644 index 000000000000..bb5fe76ae3e3 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/bad-params.stderr @@ -0,0 +1,30 @@ +error[E0433]: failed to resolve: could not find type or const parameter + --> $DIR/bad-params.rs:4:26 + | +LL | fn missing() -> impl use Sized {} + | ^ could not find type or const parameter + +error[E0433]: failed to resolve: could not find type or const parameter + --> $DIR/bad-params.rs:7:31 + | +LL | fn missing_self() -> impl use Sized {} + | ^^^^ could not find type or const parameter + +error[E0433]: failed to resolve: `Self` cannot be captured because it is not a type parameter + --> $DIR/bad-params.rs:12:40 + | +LL | fn self_is_not_param() -> impl use Sized {} + | ^^^^ `Self` cannot be captured because it is not a type parameter + +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-params.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.rs new file mode 100644 index 000000000000..1b604e6c358b --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.rs @@ -0,0 +1,7 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn constant() -> impl use<> Sized {} +//~^ ERROR `impl Trait` must mention all const parameters in scope + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr new file mode 100644 index 000000000000..9c99f2b711ea --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-const.stderr @@ -0,0 +1,19 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/forgot-to-capture-const.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `impl Trait` must mention all const parameters in scope + --> $DIR/forgot-to-capture-const.rs:4:13 + | +LL | fn constant() -> impl use<> Sized {} + | ^^^^^^^^^^^^^^ ---------------- const parameter is implicitly captured by this `impl Trait` + | + = note: currently, all const parameters are required to be mentioned in the precise captures list + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs new file mode 100644 index 000000000000..7e856ba95172 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs @@ -0,0 +1,7 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn type_param() -> impl use<> Sized {} +//~^ ERROR `impl Trait` must mention all type parameters in scope + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr new file mode 100644 index 000000000000..1ef46a36e461 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr @@ -0,0 +1,19 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/forgot-to-capture-lifetime.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `impl Trait` must mention all type parameters in scope + --> $DIR/forgot-to-capture-lifetime.rs:4:15 + | +LL | fn type_param() -> impl use<> Sized {} + | ^ ---------------- type parameter is implicitly captured by this `impl Trait` + | + = note: currently, all type parameters are required to be mentioned in the precise captures list + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs new file mode 100644 index 000000000000..cc86bf83107e --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs @@ -0,0 +1,10 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x } +//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + +fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x } +//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr new file mode 100644 index 000000000000..58f284ec6bc1 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr @@ -0,0 +1,35 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/forgot-to-capture-type.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + --> $DIR/forgot-to-capture-type.rs:4:58 + | +LL | fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x } + | -- -----------------^^---- + | | | + | | lifetime captured due to being mentioned in the bounds of the `impl Trait` + | this lifetime parameter is captured + +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/forgot-to-capture-type.rs:7:60 + | +LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x } + | -- ---------------- ^ + | | | + | | opaque type defined here + | hidden type `&'a ()` captures the lifetime `'a` as defined here + | +help: to declare that `impl Sized` captures `'a`, you can add an explicit `'a` lifetime bound + | +LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized + 'a { x } + | ++++ + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/impl-trait/precise-capturing/higher-ranked.rs b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs index c9faaaed9689..28fb1fa4b9ec 100644 --- a/tests/ui/impl-trait/precise-capturing/higher-ranked.rs +++ b/tests/ui/impl-trait/precise-capturing/higher-ranked.rs @@ -15,4 +15,4 @@ impl Trait<'_> for () { fn hello() -> impl for<'a> Trait<'a, Item = impl use<> IntoIterator> {} -fn main() {} \ No newline at end of file +fn main() {} From 02d7317af218343818dcb107cda80750e9604a3a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 4 Apr 2024 14:46:26 -0400 Subject: [PATCH 036/114] Add hir::Node::PreciseCapturingNonLifetimeArg --- compiler/rustc_ast_lowering/src/index.rs | 17 ++++++++++ compiler/rustc_ast_lowering/src/lib.rs | 8 +++-- compiler/rustc_hir/src/hir.rs | 11 ++++++- compiler/rustc_hir/src/intravisit.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 4 ++- .../src/collect/resolve_bound_vars.rs | 4 +-- compiler/rustc_hir_pretty/src/lib.rs | 1 + compiler/rustc_middle/src/hir/map/mod.rs | 2 ++ .../forgot-to-capture-lifetime.rs | 7 ++-- .../forgot-to-capture-lifetime.stderr | 28 ++++++++++++---- .../forgot-to-capture-type.rs | 10 +++--- .../forgot-to-capture-type.stderr | 33 ++++++++----------- .../precise-capturing/self-capture.rs | 10 ++++++ .../precise-capturing/self-capture.stderr | 11 +++++++ 14 files changed, 110 insertions(+), 38 deletions(-) create mode 100644 tests/ui/impl-trait/precise-capturing/self-capture.rs create mode 100644 tests/ui/impl-trait/precise-capturing/self-capture.stderr diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index 4c552289a816..93be9b9b8cf5 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -385,4 +385,21 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_pattern_type_pattern(&mut self, p: &'hir hir::Pat<'hir>) { self.visit_pat(p) } + + fn visit_precise_capturing_arg( + &mut self, + arg: &'hir PreciseCapturingArg<'hir>, + ) -> Self::Result { + match arg { + PreciseCapturingArg::Lifetime(_) => { + // This is represented as a `Node::Lifetime`, intravisit will get to it below. + } + PreciseCapturingArg::Param(param) => self.insert( + param.ident.span, + param.hir_id, + Node::PreciseCapturingNonLifetimeArg(param), + ), + } + intravisit::walk_precise_capturing_arg(self, arg); + } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b586d2a1bf56..84776f920c46 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1790,11 +1790,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { PreciseCapturingArg::Lifetime(lt) => { hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt)) } - PreciseCapturingArg::Arg(_, node_id) => { + PreciseCapturingArg::Arg(ident, node_id) => { let res = self.resolver.get_partial_res(*node_id).map_or(Res::Err, |partial_res| { partial_res.full_res().expect("no partial res expected for precise capture arg") }); - hir::PreciseCapturingArg::Param(self.lower_res(res), self.lower_node_id(*node_id)) + hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { + hir_id: self.lower_node_id(*node_id), + ident: self.lower_ident(*ident), + res: self.lower_res(res), + }) } })) } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index dc76deb18152..00b1ea061cc7 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2565,7 +2565,14 @@ pub struct OpaqueTy<'hir> { pub enum PreciseCapturingArg<'hir> { Lifetime(&'hir Lifetime), /// Non-lifetime argument (type or const) - Param(Res, HirId), + Param(PreciseCapturingNonLifetimeArg), +} + +#[derive(Debug, Clone, Copy, HashStable_Generic)] +pub struct PreciseCapturingNonLifetimeArg { + pub hir_id: HirId, + pub ident: Ident, + pub res: Res, } /// From whence the opaque type came. @@ -3544,6 +3551,7 @@ pub enum Node<'hir> { WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>), // FIXME: Merge into `Node::Infer`. ArrayLenInfer(&'hir InferArg), + PreciseCapturingNonLifetimeArg(&'hir PreciseCapturingNonLifetimeArg), // Created by query feeding Synthetic, // Span by reference to minimize `Node`'s size @@ -3580,6 +3588,7 @@ impl<'hir> Node<'hir> { Node::TypeBinding(b) => Some(b.ident), Node::PatField(f) => Some(f.ident), Node::ExprField(f) => Some(f.ident), + Node::PreciseCapturingNonLifetimeArg(a) => Some(a.ident), Node::Param(..) | Node::AnonConst(..) | Node::ConstBlock(..) diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index d3ede3a904f9..cd9f9ff9109c 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1151,7 +1151,7 @@ pub fn walk_precise_capturing_arg<'v, V: Visitor<'v>>( ) -> V::Result { match *arg { PreciseCapturingArg::Lifetime(lt) => visitor.visit_lifetime(lt), - PreciseCapturingArg::Param(_, hir_id) => visitor.visit_id(hir_id), + PreciseCapturingArg::Param(param) => visitor.visit_id(param.hir_id), } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f4d443c324a0..592a8648f144 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -487,7 +487,9 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe for arg in precise_capturing_args { match *arg { hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, .. }) - | hir::PreciseCapturingArg::Param(_, hir_id) => match tcx.named_bound_var(hir_id) { + | hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { + hir_id, .. + }) => match tcx.named_bound_var(hir_id) { Some(ResolvedArg::EarlyBound(def_id)) => { expected_captures.insert(def_id); } diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 8d5f4c13721f..fb3713140ffe 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -577,10 +577,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { }); } }, - hir::PreciseCapturingArg::Param(res, hir_id) => match res { + hir::PreciseCapturingArg::Param(param) => match param.res { Res::Def(DefKind::TyParam | DefKind::ConstParam, def_id) | Res::SelfTyParam { trait_: def_id } => { - self.resolve_type_ref(def_id.expect_local(), hir_id); + self.resolve_type_ref(def_id.expect_local(), param.hir_id); } Res::Err => {} _ => { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 39312614c1b1..3d3b16baf697 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -99,6 +99,7 @@ impl<'a> State<'a> { Node::PatField(a) => self.print_patfield(a), Node::Arm(a) => self.print_arm(a), Node::Infer(_) => self.word("_"), + Node::PreciseCapturingNonLifetimeArg(param) => self.print_ident(param.ident), Node::Block(a) => { // Containing cbox, will be closed by print-block at `}`. self.cbox(INDENT_UNIT); diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 72f849b534a8..88de834c4362 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -909,6 +909,7 @@ impl<'hir> Map<'hir> { Node::Crate(item) => item.spans.inner_span, Node::WhereBoundPredicate(pred) => pred.span, Node::ArrayLenInfer(inf) => inf.span, + Node::PreciseCapturingNonLifetimeArg(param) => param.ident.span, Node::Synthetic => unreachable!(), Node::Err(span) => *span, } @@ -1176,6 +1177,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { Node::ArrayLenInfer(_) => node_str("array len infer"), Node::Synthetic => unreachable!(), Node::Err(_) => node_str("error"), + Node::PreciseCapturingNonLifetimeArg(_param) => node_str("parameter"), } } diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs index 7e856ba95172..cc86bf83107e 100644 --- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.rs @@ -1,7 +1,10 @@ #![feature(precise_capturing)] //~^ WARN the feature `precise_capturing` is incomplete -fn type_param() -> impl use<> Sized {} -//~^ ERROR `impl Trait` must mention all type parameters in scope +fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x } +//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + +fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x } +//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr index 1ef46a36e461..e472c898050a 100644 --- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-lifetime.stderr @@ -7,13 +7,29 @@ LL | #![feature(precise_capturing)] = note: see issue #123432 for more information = note: `#[warn(incomplete_features)]` on by default -error: `impl Trait` must mention all type parameters in scope - --> $DIR/forgot-to-capture-lifetime.rs:4:15 +error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list + --> $DIR/forgot-to-capture-lifetime.rs:4:58 | -LL | fn type_param() -> impl use<> Sized {} - | ^ ---------------- type parameter is implicitly captured by this `impl Trait` +LL | fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x } + | -- -----------------^^---- + | | | + | | lifetime captured due to being mentioned in the bounds of the `impl Trait` + | this lifetime parameter is captured + +error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds + --> $DIR/forgot-to-capture-lifetime.rs:7:60 | - = note: currently, all type parameters are required to be mentioned in the precise captures list +LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x } + | -- ---------------- ^ + | | | + | | opaque type defined here + | hidden type `&'a ()` captures the lifetime `'a` as defined here + | +help: to declare that `impl Sized` captures `'a`, you can add an explicit `'a` lifetime bound + | +LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized + 'a { x } + | ++++ -error: aborting due to 1 previous error; 1 warning emitted +error: aborting due to 2 previous errors; 1 warning emitted +For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs index cc86bf83107e..6eaff01183d4 100644 --- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.rs @@ -1,10 +1,12 @@ #![feature(precise_capturing)] //~^ WARN the feature `precise_capturing` is incomplete -fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x } -//~^ ERROR `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list +fn type_param() -> impl use<> Sized {} +//~^ ERROR `impl Trait` must mention all type parameters in scope -fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x } -//~^ ERROR hidden type for `impl Sized` captures lifetime that does not appear in bounds +trait Foo { +//~^ ERROR `impl Trait` must mention all type parameters in scope + fn bar() -> impl use<> Sized; +} fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr index 58f284ec6bc1..a8eb4547dcdd 100644 --- a/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr +++ b/tests/ui/impl-trait/precise-capturing/forgot-to-capture-type.stderr @@ -7,29 +7,24 @@ LL | #![feature(precise_capturing)] = note: see issue #123432 for more information = note: `#[warn(incomplete_features)]` on by default -error: `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list - --> $DIR/forgot-to-capture-type.rs:4:58 +error: `impl Trait` must mention all type parameters in scope + --> $DIR/forgot-to-capture-type.rs:4:15 | -LL | fn lifetime_in_bounds<'a>(x: &'a ()) -> impl use<> Into<&'a ()> { x } - | -- -----------------^^---- - | | | - | | lifetime captured due to being mentioned in the bounds of the `impl Trait` - | this lifetime parameter is captured +LL | fn type_param() -> impl use<> Sized {} + | ^ ---------------- type parameter is implicitly captured by this `impl Trait` + | + = note: currently, all type parameters are required to be mentioned in the precise captures list -error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds - --> $DIR/forgot-to-capture-type.rs:7:60 +error: `impl Trait` must mention all type parameters in scope + --> $DIR/forgot-to-capture-type.rs:7:1 | -LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized { x } - | -- ---------------- ^ - | | | - | | opaque type defined here - | hidden type `&'a ()` captures the lifetime `'a` as defined here +LL | trait Foo { + | ^^^^^^^^^ +LL | +LL | fn bar() -> impl use<> Sized; + | ---------------- type parameter is implicitly captured by this `impl Trait` | -help: to declare that `impl Sized` captures `'a`, you can add an explicit `'a` lifetime bound - | -LL | fn lifetime_in_hidden<'a>(x: &'a ()) -> impl use<> Sized + 'a { x } - | ++++ + = note: currently, all type parameters are required to be mentioned in the precise captures list error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0700`. diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.rs b/tests/ui/impl-trait/precise-capturing/self-capture.rs new file mode 100644 index 000000000000..ecbc388e27be --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/self-capture.rs @@ -0,0 +1,10 @@ +//@ check-pass + +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +trait Foo { + fn bar<'a>() -> impl use Sized; +} + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/self-capture.stderr b/tests/ui/impl-trait/precise-capturing/self-capture.stderr new file mode 100644 index 000000000000..5a058c6826d2 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/self-capture.stderr @@ -0,0 +1,11 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/self-capture.rs:3:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + From ce8961039e244b1e4e0fa02fc10d59a22abc9ea3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 4 Apr 2024 15:06:30 -0400 Subject: [PATCH 037/114] Some ordering and duplication checks --- compiler/rustc_hir_analysis/messages.ftl | 6 ++ .../rustc_hir_analysis/src/check/check.rs | 57 ++++++++++++++----- .../src/errors/precise_captures.rs | 22 ++++++- .../feature-gate-precise-capturing.rs | 4 ++ .../feature-gate-precise-capturing.stderr | 13 +++++ .../impl-trait/precise-capturing/ordering.rs | 16 ++++++ .../precise-capturing/ordering.stderr | 37 ++++++++++++ 7 files changed, 140 insertions(+), 15 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-precise-capturing.rs create mode 100644 tests/ui/feature-gates/feature-gate-precise-capturing.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/ordering.rs create mode 100644 tests/ui/impl-trait/precise-capturing/ordering.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 81cf3067a1ed..4ac2965bd5f0 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -113,6 +113,9 @@ hir_analysis_drop_impl_on_wrong_item = hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported +hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice + .label = parameter captured again here + hir_analysis_empty_specialization = specialization impl does not specialize any associated items .note = impl is a specialization of this impl @@ -216,6 +219,9 @@ hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetim hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl .label = type parameter declared here +hir_analysis_lifetime_must_be_first = lifetime parameter `{$name}` must be listed before non-lifetime parameters + .label = move the lifetime before this parameter + hir_analysis_lifetime_not_captured = `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list .label = lifetime captured due to being mentioned in the bounds of the `impl Trait` .param_label = this lifetime parameter is captured diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 592a8648f144..1e8cd50ca0de 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -4,7 +4,7 @@ use super::compare_impl_item::check_type_bounds; use super::compare_impl_item::{compare_impl_method, compare_impl_ty}; use super::*; use rustc_attr as attr; -use rustc_data_structures::unord::UnordSet; +use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{codes::*, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind}; @@ -484,22 +484,51 @@ fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDe }; let mut expected_captures = UnordSet::default(); + let mut seen_params = UnordMap::default(); + let mut prev_non_lifetime_param = None; for arg in precise_capturing_args { - match *arg { - hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, .. }) - | hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { - hir_id, .. - }) => match tcx.named_bound_var(hir_id) { - Some(ResolvedArg::EarlyBound(def_id)) => { - expected_captures.insert(def_id); + let (hir_id, ident) = match *arg { + hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { + hir_id, + ident, + .. + }) => { + if prev_non_lifetime_param.is_none() { + prev_non_lifetime_param = Some(ident); } - _ => { - tcx.dcx().span_delayed_bug( - tcx.hir().span(hir_id), - "parameter should have been resolved", - ); + (hir_id, ident) + } + hir::PreciseCapturingArg::Lifetime(&hir::Lifetime { hir_id, ident, .. }) => { + if let Some(prev_non_lifetime_param) = prev_non_lifetime_param { + tcx.dcx().emit_err(errors::LifetimesMustBeFirst { + lifetime_span: ident.span, + name: ident.name, + other_span: prev_non_lifetime_param.span, + }); } - }, + (hir_id, ident) + } + }; + + let ident = ident.normalize_to_macros_2_0(); + if let Some(span) = seen_params.insert(ident, ident.span) { + tcx.dcx().emit_err(errors::DuplicatePreciseCapture { + name: ident.name, + first_span: span, + second_span: ident.span, + }); + } + + match tcx.named_bound_var(hir_id) { + Some(ResolvedArg::EarlyBound(def_id)) => { + expected_captures.insert(def_id); + } + _ => { + tcx.dcx().span_delayed_bug( + tcx.hir().span(hir_id), + "parameter should have been resolved", + ); + } } } diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs index 3b22437abb24..e2eb9c72bf23 100644 --- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs +++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs @@ -1,5 +1,5 @@ use rustc_macros::Diagnostic; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; #[derive(Diagnostic)] #[diag(hir_analysis_param_not_captured)] @@ -31,3 +31,23 @@ pub struct BadPreciseCapture { pub kind: &'static str, pub found: String, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_duplicate_precise_capture)] +pub struct DuplicatePreciseCapture { + #[primary_span] + pub first_span: Span, + pub name: Symbol, + #[label] + pub second_span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_lifetime_must_be_first)] +pub struct LifetimesMustBeFirst { + #[primary_span] + pub lifetime_span: Span, + pub name: Symbol, + #[label] + pub other_span: Span, +} diff --git a/tests/ui/feature-gates/feature-gate-precise-capturing.rs b/tests/ui/feature-gates/feature-gate-precise-capturing.rs new file mode 100644 index 000000000000..0c3b49776230 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-precise-capturing.rs @@ -0,0 +1,4 @@ +fn hello() -> impl use<> Sized {} +//~^ ERROR precise captures on `impl Trait` are experimental + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-precise-capturing.stderr b/tests/ui/feature-gates/feature-gate-precise-capturing.stderr new file mode 100644 index 000000000000..102b39148f9f --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-precise-capturing.stderr @@ -0,0 +1,13 @@ +error[E0658]: precise captures on `impl Trait` are experimental + --> $DIR/feature-gate-precise-capturing.rs:1:20 + | +LL | fn hello() -> impl use<> Sized {} + | ^^^ + | + = note: see issue #123432 for more information + = help: add `#![feature(precise_capturing)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/impl-trait/precise-capturing/ordering.rs b/tests/ui/impl-trait/precise-capturing/ordering.rs new file mode 100644 index 000000000000..2bace798c570 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/ordering.rs @@ -0,0 +1,16 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn lt<'a>() -> impl use<'a, 'a> Sized {} +//~^ ERROR cannot capture parameter `'a` twice + +fn ty() -> impl use Sized {} +//~^ ERROR cannot capture parameter `T` twice + +fn ct() -> impl use Sized {} +//~^ ERROR cannot capture parameter `N` twice + +fn ordering<'a, T>() -> impl use Sized {} +//~^ ERROR lifetime parameter `'a` must be listed before non-lifetime parameters + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/ordering.stderr b/tests/ui/impl-trait/precise-capturing/ordering.stderr new file mode 100644 index 000000000000..3f545108df56 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/ordering.stderr @@ -0,0 +1,37 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/ordering.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: cannot capture parameter `'a` twice + --> $DIR/ordering.rs:4:25 + | +LL | fn lt<'a>() -> impl use<'a, 'a> Sized {} + | ^^ -- parameter captured again here + +error: cannot capture parameter `T` twice + --> $DIR/ordering.rs:7:24 + | +LL | fn ty() -> impl use Sized {} + | ^ - parameter captured again here + +error: cannot capture parameter `N` twice + --> $DIR/ordering.rs:10:37 + | +LL | fn ct() -> impl use Sized {} + | ^ - parameter captured again here + +error: lifetime parameter `'a` must be listed before non-lifetime parameters + --> $DIR/ordering.rs:13:37 + | +LL | fn ordering<'a, T>() -> impl use Sized {} + | - ^^ + | | + | move the lifetime before this parameter + +error: aborting due to 4 previous errors; 1 warning emitted + From 52c6b101ea18ed6f09367bf459ac55ffe473cd9c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 4 Apr 2024 20:23:52 -0400 Subject: [PATCH 038/114] Use a path instead of an ident (and stop manually resolving) --- compiler/rustc_ast/src/ast.rs | 4 +- compiler/rustc_ast/src/mut_visit.rs | 4 +- compiler/rustc_ast/src/visit.rs | 4 +- compiler/rustc_ast_lowering/src/lib.rs | 11 ++-- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- compiler/rustc_hir_analysis/messages.ftl | 3 + .../src/collect/resolve_bound_vars.rs | 16 ++++- .../src/errors/precise_captures.rs | 10 +++ compiler/rustc_parse/src/parser/ty.rs | 7 +- compiler/rustc_resolve/src/late.rs | 66 ++++--------------- .../precise-capturing/bad-params.rs | 6 +- .../precise-capturing/bad-params.stderr | 32 +++++---- 12 files changed, 81 insertions(+), 84 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ace20a005ee4..0cf96797028d 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2188,12 +2188,12 @@ pub enum TraitObjectSyntax { None, } -#[derive(Clone, PartialEq, Encodable, Decodable, Debug)] +#[derive(Clone, Encodable, Decodable, Debug)] pub enum PreciseCapturingArg { /// Lifetime parameter Lifetime(Lifetime), /// Type or const parameter - Arg(Ident, NodeId), + Arg(Path, NodeId), } /// Inline assembly operand explicit register or register class. diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 204f33cab345..c4e49d7dbea4 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -928,8 +928,8 @@ pub fn noop_visit_precise_capturing_arg(arg: &mut PreciseCapturin PreciseCapturingArg::Lifetime(lt) => { vis.visit_lifetime(lt); } - PreciseCapturingArg::Arg(ident, id) => { - vis.visit_ident(ident); + PreciseCapturingArg::Arg(path, id) => { + vis.visit_path(path); vis.visit_id(id); } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index a9c29e077d13..968d10ad4872 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -653,8 +653,8 @@ pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>( PreciseCapturingArg::Lifetime(lt) => { visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg); } - PreciseCapturingArg::Arg(ident, _) => { - visitor.visit_ident(*ident); + PreciseCapturingArg::Arg(path, id) => { + visitor.visit_path(path, *id); } } } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 84776f920c46..a21d6019cf16 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1790,13 +1790,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { PreciseCapturingArg::Lifetime(lt) => { hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt)) } - PreciseCapturingArg::Arg(ident, node_id) => { - let res = self.resolver.get_partial_res(*node_id).map_or(Res::Err, |partial_res| { + PreciseCapturingArg::Arg(path, id) => { + let [segment] = path.segments.as_slice() else { + panic!(); + }; + let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| { partial_res.full_res().expect("no partial res expected for precise capture arg") }); hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg { - hir_id: self.lower_node_id(*node_id), - ident: self.lower_ident(*ident), + hir_id: self.lower_node_id(*id), + ident: self.lower_ident(segment.ident), res: self.lower_res(res), }) } diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index db9633bb1cbb..969099409723 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1156,7 +1156,7 @@ impl<'a> State<'a> { self.word("use"); self.word("<"); self.commasep(Inconsistent, precise_capturing_args, |s, arg| match arg { - ast::PreciseCapturingArg::Arg(a, _) => s.print_ident(*a), + ast::PreciseCapturingArg::Arg(p, _) => s.print_path(p, false, 0), ast::PreciseCapturingArg::Lifetime(lt) => s.print_lifetime(*lt), }); self.word(">") diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 4ac2965bd5f0..bc6583444c33 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -39,6 +39,9 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found} +hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias + .label = `Self` is not a generic argument, but an alias to the type of the {$what} + hir_analysis_cannot_capture_late_bound_const = cannot capture late-bound const parameter in {$what} .label = parameter defined here diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index fb3713140ffe..78c2665fd1f3 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -583,9 +583,19 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { self.resolve_type_ref(def_id.expect_local(), param.hir_id); } Res::Err => {} - _ => { - // This is handled in resolve - self.tcx.dcx().delayed_bug(format!("parameter should have been resolved")); + Res::SelfTyAlias { alias_to, .. } => { + self.tcx.dcx().emit_err(errors::PreciseCaptureSelfAlias { + span: param.ident.span, + self_span: self.tcx.def_span(alias_to), + what: self.tcx.def_descr(alias_to), + }); + } + res => { + self.tcx.dcx().emit_err(errors::BadPreciseCapture { + span: param.ident.span, + kind: "type or const", + found: res.descr().to_string(), + }); } }, } diff --git a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs index e2eb9c72bf23..520bf1d9f404 100644 --- a/compiler/rustc_hir_analysis/src/errors/precise_captures.rs +++ b/compiler/rustc_hir_analysis/src/errors/precise_captures.rs @@ -32,6 +32,16 @@ pub struct BadPreciseCapture { pub found: String, } +#[derive(Diagnostic)] +#[diag(hir_analysis_precise_capture_self_alias)] +pub struct PreciseCaptureSelfAlias { + #[primary_span] + pub span: Span, + #[label] + pub self_span: Span, + pub what: &'static str, +} + #[derive(Diagnostic)] #[diag(hir_analysis_duplicate_precise_capture)] pub struct DuplicatePreciseCapture { diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 91f4823f65d4..f78a039394b8 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -697,11 +697,14 @@ impl<'a> Parser<'a> { if self_.check_keyword(kw::SelfUpper) { self_.bump(); Ok(PreciseCapturingArg::Arg( - self_.prev_token.ident().unwrap().0, + ast::Path::from_ident(self_.prev_token.ident().unwrap().0), DUMMY_NODE_ID, )) } else if self_.check_ident() { - Ok(PreciseCapturingArg::Arg(self_.parse_ident().unwrap(), DUMMY_NODE_ID)) + Ok(PreciseCapturingArg::Arg( + ast::Path::from_ident(self_.parse_ident()?), + DUMMY_NODE_ID, + )) } else if self_.check_lifetime() { Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime())) } else { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 7203adab135a..64434412886b 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1056,64 +1056,22 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, match arg { // Lower the lifetime regularly; we'll resolve the lifetime and check // it's a parameter later on in HIR lowering. - PreciseCapturingArg::Lifetime(_) => visit::walk_precise_capturing_arg(self, arg), + PreciseCapturingArg::Lifetime(_) => {} - PreciseCapturingArg::Arg(ident, node_id) => { - let ident = ident.normalize_to_macros_2_0(); - 'found: { - for (rib_t, rib_v) in - std::iter::zip(&self.ribs.type_ns, &self.ribs.value_ns).rev() - { - if let Some(res) = rib_t.bindings.get(&ident).or(rib_v.bindings.get(&ident)) - { - self.r.record_partial_res(*node_id, PartialRes::new(*res)); - - // Validate that this is a parameter - match res { - Res::Def(DefKind::TyParam | DefKind::ConstParam, _) - | Res::SelfTyParam { .. } => {} - Res::SelfTyAlias { .. } => { - self.report_error( - ident.span, - ResolutionError::FailedToResolve { - segment: Some(ident.name), - label: "`Self` cannot be captured because it is not a type parameter".to_string(), - suggestion: None, - module: None, - }, - ); - } - _ => { - self.report_error( - ident.span, - ResolutionError::FailedToResolve { - segment: Some(ident.name), - label: format!( - "expected type or const parameter, found {}", - res.descr() - ), - suggestion: None, - module: None, - }, - ); - } - } - - break 'found; - } - } - self.report_error( - ident.span, - ResolutionError::FailedToResolve { - segment: Some(ident.name), - label: "could not find type or const parameter".to_string(), - suggestion: None, - module: None, - }, - ); + PreciseCapturingArg::Arg(path, id) => { + let mut check_ns = |ns| { + self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns).is_some() + }; + // Like `Ty::Param`, we try resolving this as both a const and a type. + if !check_ns(TypeNS) && check_ns(ValueNS) { + self.smart_resolve_path(*id, &None, path, PathSource::Expr(None)); + } else { + self.smart_resolve_path(*id, &None, path, PathSource::Type); } } } + + visit::walk_precise_capturing_arg(self, arg) } fn visit_generics(&mut self, generics: &'ast Generics) { diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.rs b/tests/ui/impl-trait/precise-capturing/bad-params.rs index c600fa96f794..195bd1b67aeb 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-params.rs +++ b/tests/ui/impl-trait/precise-capturing/bad-params.rs @@ -2,15 +2,15 @@ //~^ WARN the feature `precise_capturing` is incomplete fn missing() -> impl use Sized {} -//~^ ERROR could not find type or const parameter +//~^ ERROR cannot find type `T` in this scope fn missing_self() -> impl use Sized {} -//~^ ERROR could not find type or const parameter +//~^ ERROR cannot find type `Self` in this scope struct MyType; impl MyType { fn self_is_not_param() -> impl use Sized {} - //~^ ERROR `Self` cannot be captured because it is not a type parameter + //~^ ERROR `Self` can't be captured in `use<...>` precise captures list, since it is an alias } fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.stderr b/tests/ui/impl-trait/precise-capturing/bad-params.stderr index bb5fe76ae3e3..09694a800c41 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-params.stderr +++ b/tests/ui/impl-trait/precise-capturing/bad-params.stderr @@ -1,20 +1,21 @@ -error[E0433]: failed to resolve: could not find type or const parameter +error[E0412]: cannot find type `T` in this scope --> $DIR/bad-params.rs:4:26 | LL | fn missing() -> impl use Sized {} - | ^ could not find type or const parameter + | ^ not found in this scope + | +help: you might be missing a type parameter + | +LL | fn missing() -> impl use Sized {} + | +++ -error[E0433]: failed to resolve: could not find type or const parameter +error[E0411]: cannot find type `Self` in this scope --> $DIR/bad-params.rs:7:31 | LL | fn missing_self() -> impl use Sized {} - | ^^^^ could not find type or const parameter - -error[E0433]: failed to resolve: `Self` cannot be captured because it is not a type parameter - --> $DIR/bad-params.rs:12:40 - | -LL | fn self_is_not_param() -> impl use Sized {} - | ^^^^ `Self` cannot be captured because it is not a type parameter + | ------------ ^^^^ `Self` is only available in impls, traits, and type definitions + | | + | `Self` not allowed in a function warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bad-params.rs:1:12 @@ -25,6 +26,15 @@ LL | #![feature(precise_capturing)] = note: see issue #123432 for more information = note: `#[warn(incomplete_features)]` on by default +error: `Self` can't be captured in `use<...>` precise captures list, since it is an alias + --> $DIR/bad-params.rs:12:40 + | +LL | impl MyType { + | ----------- `Self` is not a generic argument, but an alias to the type of the implementation +LL | fn self_is_not_param() -> impl use Sized {} + | ^^^^ + error: aborting due to 3 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0433`. +Some errors have detailed explanations: E0411, E0412. +For more information about an error, try `rustc --explain E0411`. From ac7651ccaf7447e695bf505916463927b78e433f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 4 Apr 2024 20:36:18 -0400 Subject: [PATCH 039/114] More polishing --- compiler/rustc_hir/src/hir.rs | 5 +++++ compiler/rustc_hir_analysis/messages.ftl | 6 +++--- compiler/rustc_hir_analysis/src/check/check.rs | 8 ++++++++ .../nice_region_error/static_impl_trait.rs | 1 + compiler/rustc_parse/src/parser/ty.rs | 4 +++- compiler/rustc_resolve/src/late.rs | 6 ++++++ tests/ui/impl-trait/precise-capturing/apit.rs | 7 +++++++ .../ui/impl-trait/precise-capturing/apit.stderr | 17 +++++++++++++++++ .../impl-trait/precise-capturing/bad-params.rs | 3 +++ .../precise-capturing/bad-params.stderr | 8 +++++++- tests/ui/impl-trait/precise-capturing/elided.rs | 8 ++++++++ .../impl-trait/precise-capturing/elided.stderr | 11 +++++++++++ 12 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 tests/ui/impl-trait/precise-capturing/apit.rs create mode 100644 tests/ui/impl-trait/precise-capturing/apit.stderr create mode 100644 tests/ui/impl-trait/precise-capturing/elided.rs create mode 100644 tests/ui/impl-trait/precise-capturing/elided.stderr diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 00b1ea061cc7..b39056d8690c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2568,6 +2568,11 @@ pub enum PreciseCapturingArg<'hir> { Param(PreciseCapturingNonLifetimeArg), } +/// We need to have a [`Node`] for the [`HirId`] that we attach the type/const param +/// resolution to. Lifetimes don't have this problem, and for them, it's actually +/// kind of detrimental to use a custom node type versus just using [`Lifetime`], +/// since resolve_bound_vars operates on `Lifetime`s. +// FIXME(precise_capturing): Investigate storing this as a path instead? #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct PreciseCapturingNonLifetimeArg { pub hir_id: HirId, diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index bc6583444c33..0ff78ebff995 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -39,9 +39,6 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found} -hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias - .label = `Self` is not a generic argument, but an alias to the type of the {$what} - hir_analysis_cannot_capture_late_bound_const = cannot capture late-bound const parameter in {$what} .label = parameter defined here @@ -374,6 +371,9 @@ hir_analysis_pattern_type_wild_pat = "wildcard patterns are not permitted for pa hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind} .label = not allowed in type signatures +hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias + .label = `Self` is not a generic argument, but an alias to the type of the {$what} + hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}` .note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}` diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 1e8cd50ca0de..8c85d13650b4 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -475,6 +475,14 @@ fn sanity_check_found_hidden_type<'tcx>( } } +/// Check that the opaque's precise captures list is valid (if present). +/// We check this for regular `impl Trait`s and also RPITITs, even though the latter +/// are technically GATs. +/// +/// This function is responsible for: +/// 1. Checking that all type/const params are mention in the captures list. +/// 2. Checking that all lifetimes that are implicitly captured are mentioned. +/// 3. Asserting that all parameters mentioned in the captures list are invariant. fn check_opaque_precise_captures<'tcx>(tcx: TyCtxt<'tcx>, opaque_def_id: LocalDefId) { let hir::OpaqueTy { precise_capturing_args, .. } = *tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty(); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index fe70b631cdb8..0bbabefaf954 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -283,6 +283,7 @@ pub fn suggest_new_region_bound( continue; } match fn_return.kind { + // FIXME(precise_captures): Suggest adding to `use<...>` list instead. TyKind::OpaqueDef(item_id, _, _) => { let item = tcx.hir().item(item_id); let ItemKind::OpaqueTy(opaque) = &item.kind else { diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index f78a039394b8..a6195fa76938 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -669,7 +669,9 @@ impl<'a> Parser<'a> { }) } - // parse precise captures, if any. + // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of + // lifetimes and ident params (including SelfUpper). These are validated later + // for order, duplication, and whether they actually reference params. let precise_capturing = if self.eat_keyword(kw::Use) { let use_span = self.prev_token.span; self.psess.gated_spans.gate(sym::precise_capturing, use_span); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 64434412886b..ba1391bc378a 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1059,6 +1059,12 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, PreciseCapturingArg::Lifetime(_) => {} PreciseCapturingArg::Arg(path, id) => { + // we want `impl use` to try to resolve `C` as both a type parameter or + // a const parameter. Since the resolver specifically doesn't allow having + // two generic params with the same name, even if they're a different namespace, + // it doesn't really matter which we try resolving first, but just like + // `Ty::Param` we just fall back to the value namespace only if it's missing + // from the type namespace. let mut check_ns = |ns| { self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns).is_some() }; diff --git a/tests/ui/impl-trait/precise-capturing/apit.rs b/tests/ui/impl-trait/precise-capturing/apit.rs new file mode 100644 index 000000000000..efcac9ebb0b8 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/apit.rs @@ -0,0 +1,7 @@ +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn hello(_: impl use<> Sized) {} +//~^ ERROR `use<...>` precise capturing syntax not allowed on argument-position `impl Trait` + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/apit.stderr b/tests/ui/impl-trait/precise-capturing/apit.stderr new file mode 100644 index 000000000000..36bf80d9e2f9 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/apit.stderr @@ -0,0 +1,17 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/apit.rs:1:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: `use<...>` precise capturing syntax not allowed on argument-position `impl Trait` + --> $DIR/apit.rs:4:18 + | +LL | fn hello(_: impl use<> Sized) {} + | ^^^ + +error: aborting due to 1 previous error; 1 warning emitted + diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.rs b/tests/ui/impl-trait/precise-capturing/bad-params.rs index 195bd1b67aeb..7970d49bf7c0 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-params.rs +++ b/tests/ui/impl-trait/precise-capturing/bad-params.rs @@ -13,4 +13,7 @@ impl MyType { //~^ ERROR `Self` can't be captured in `use<...>` precise captures list, since it is an alias } +fn hello() -> impl use Sized {} +//~^ ERROR expected type or const parameter in `use<...>` precise captures list, found function + fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/bad-params.stderr b/tests/ui/impl-trait/precise-capturing/bad-params.stderr index 09694a800c41..27bf05302f9b 100644 --- a/tests/ui/impl-trait/precise-capturing/bad-params.stderr +++ b/tests/ui/impl-trait/precise-capturing/bad-params.stderr @@ -34,7 +34,13 @@ LL | impl MyType { LL | fn self_is_not_param() -> impl use Sized {} | ^^^^ -error: aborting due to 3 previous errors; 1 warning emitted +error: expected type or const parameter in `use<...>` precise captures list, found function + --> $DIR/bad-params.rs:16:24 + | +LL | fn hello() -> impl use Sized {} + | ^^^^^ + +error: aborting due to 4 previous errors; 1 warning emitted Some errors have detailed explanations: E0411, E0412. For more information about an error, try `rustc --explain E0411`. diff --git a/tests/ui/impl-trait/precise-capturing/elided.rs b/tests/ui/impl-trait/precise-capturing/elided.rs new file mode 100644 index 000000000000..de80e8a5d581 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/elided.rs @@ -0,0 +1,8 @@ +//@ check-pass + +#![feature(precise_capturing)] +//~^ WARN the feature `precise_capturing` is incomplete + +fn elided(x: &()) -> impl use<'_> Sized { x } + +fn main() {} diff --git a/tests/ui/impl-trait/precise-capturing/elided.stderr b/tests/ui/impl-trait/precise-capturing/elided.stderr new file mode 100644 index 000000000000..38da0828de97 --- /dev/null +++ b/tests/ui/impl-trait/precise-capturing/elided.stderr @@ -0,0 +1,11 @@ +warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/elided.rs:3:12 + | +LL | #![feature(precise_capturing)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #123432 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + From 8ddd2805de6ad8200868befc6ae703243fac3a46 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 4 Apr 2024 20:52:56 -0400 Subject: [PATCH 040/114] Rustfmt, clippy --- src/tools/clippy/clippy_utils/src/ast_utils.rs | 11 ++++++++++- src/tools/rustfmt/src/types.rs | 9 +++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index f594a40ff59a..9f0bd4ea7e2e 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -709,7 +709,8 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool { (Tup(l), Tup(r)) => over(l, r, |l, r| eq_ty(l, r)), (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp), (TraitObject(lg, ls), TraitObject(rg, rs)) => ls == rs && over(lg, rg, eq_generic_bound), - (ImplTrait(_, lg), ImplTrait(_, rg)) => over(lg, rg, eq_generic_bound), + (ImplTrait(_, lg, lc), ImplTrait(_, rg, rc)) => + over(lg, rg, eq_generic_bound) && both(lc, rc, |lc, rc| over(lc.0.as_slice(), rc.0.as_slice(), eq_precise_capture)), (Typeof(l), Typeof(r)) => eq_expr(&l.value, &r.value), (MacCall(l), MacCall(r)) => eq_mac_call(l, r), _ => false, @@ -770,6 +771,14 @@ pub fn eq_generic_bound(l: &GenericBound, r: &GenericBound) -> bool { } } +pub fn eq_precise_capture(l: &PreciseCapturingArg, r: &PreciseCapturingArg) -> bool { + match (l, r) { + (PreciseCapturingArg::Lifetime(l), PreciseCapturingArg::Lifetime(r)) => l.ident == r.ident, + (PreciseCapturingArg::Arg(l, _), PreciseCapturingArg::Arg(r, _)) => l.segments[0].ident == r.segments[0].ident, + _ => false, + } +} + fn eq_term(l: &Term, r: &Term) -> bool { match (l, r) { (Term::Ty(l), Term::Ty(r)) => eq_ty(l, r), diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs index 10a87f6e6985..fe2d28ae1b9d 100644 --- a/src/tools/rustfmt/src/types.rs +++ b/src/tools/rustfmt/src/types.rs @@ -843,7 +843,11 @@ impl Rewrite for ast::Ty { rewrite_macro(mac, None, context, shape, MacroPosition::Expression) } ast::TyKind::ImplicitSelf => Some(String::from("")), - ast::TyKind::ImplTrait(_, ref it) => { + ast::TyKind::ImplTrait(_, ref it, ref captures) => { + // FIXME(precise_capturing): Implement formatting. + if captures.is_some() { + return None; + } // Empty trait is not a parser error. if it.is_empty() { return Some("impl".to_owned()); @@ -1106,7 +1110,8 @@ fn join_bounds_inner( pub(crate) fn opaque_ty(ty: &Option>) -> Option<&ast::GenericBounds> { ty.as_ref().and_then(|t| match &t.kind { - ast::TyKind::ImplTrait(_, bounds) => Some(bounds), + // FIXME(precise_capturing): Implement support here + ast::TyKind::ImplTrait(_, bounds, _) => Some(bounds), _ => None, }) } From 34bce07e8e8009b921a45e0c01890013c70cf097 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 12:47:01 -0400 Subject: [PATCH 041/114] Remove TypeVariableOriginKind --- .../src/type_check/input_output.rs | 7 +- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +- .../src/type_check/relate_tys.rs | 7 +- .../src/check/compare_impl_item.rs | 10 +-- compiler/rustc_hir_typeck/src/_match.rs | 13 ++-- compiler/rustc_hir_typeck/src/callee.rs | 22 ++----- compiler/rustc_hir_typeck/src/check.rs | 5 +- compiler/rustc_hir_typeck/src/closure.rs | 66 +++++++------------ compiler/rustc_hir_typeck/src/coercion.rs | 12 +--- compiler/rustc_hir_typeck/src/demand.rs | 6 +- compiler/rustc_hir_typeck/src/expectation.rs | 7 +- compiler/rustc_hir_typeck/src/expr.rs | 24 ++----- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 4 +- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 4 +- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 7 +- .../rustc_hir_typeck/src/gather_locals.rs | 7 +- compiler/rustc_hir_typeck/src/lib.rs | 17 ++--- .../src/method/prelude2021.rs | 8 +-- .../rustc_hir_typeck/src/method/suggest.rs | 18 ++--- compiler/rustc_hir_typeck/src/op.rs | 14 ++-- compiler/rustc_hir_typeck/src/pat.rs | 15 ++--- compiler/rustc_hir_typeck/src/place_op.rs | 8 +-- .../rustc_infer/src/infer/canonical/mod.rs | 4 +- .../infer/error_reporting/need_type_info.rs | 26 ++++---- compiler/rustc_infer/src/infer/mod.rs | 15 +---- .../rustc_infer/src/infer/opaque_types/mod.rs | 7 +- compiler/rustc_infer/src/infer/projection.rs | 4 +- .../src/infer/relate/generalize.rs | 9 +-- .../rustc_infer/src/infer/relate/lattice.rs | 14 ++-- .../rustc_infer/src/infer/type_variable.rs | 26 +------- .../rustc_mir_build/src/build/matches/util.rs | 9 ++- .../src/solve/eval_ctxt/mod.rs | 7 +- .../src/solve/normalize.rs | 8 +-- .../traits/error_reporting/infer_ctxt_ext.rs | 8 +-- .../src/traits/error_reporting/suggestions.rs | 15 ++--- .../error_reporting/type_err_ctxt_ext.rs | 7 +- .../src/traits/project.rs | 4 +- .../src/traits/structural_normalize.rs | 9 ++- src/tools/clippy/clippy_utils/src/ty.rs | 4 +- 39 files changed, 154 insertions(+), 307 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index a4c1066ee8e9..2511a1535af1 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -11,7 +11,7 @@ use std::assert_matches::assert_matches; use itertools::Itertools; use rustc_hir as hir; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{BoundRegionConversionTime, RegionVariableOrigin}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty}; @@ -75,10 +75,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); let next_ty_var = || { - self.infcx.next_ty_var(TypeVariableOrigin { - span: body.span, - kind: TypeVariableOriginKind::MiscVariable, - }) + self.infcx.next_ty_var(TypeVariableOrigin { span: body.span, param_def_id: None }) }; let output_ty = Ty::new_coroutine( self.tcx(), diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 71b54a761a2b..0600a105459b 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -16,7 +16,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{ BoundRegion, BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, }; @@ -2425,7 +2425,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ty::RawPtr(_, _) | ty::FnPtr(_) => { let ty_right = right.ty(body, tcx); let common_ty = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, + param_def_id: None, span: body.source_info(location).span, }); self.sub_types( diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 78609a482ed2..567bc6987384 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,6 +1,6 @@ use rustc_data_structures::fx::FxHashMap; use rustc_errors::ErrorGuaranteed; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::infer::{ObligationEmittingRelation, StructurallyRelateAliases}; use rustc_infer::traits::{Obligation, PredicateObligations}; @@ -129,10 +129,7 @@ impl<'me, 'bccx, 'tcx> NllTypeRelating<'me, 'bccx, 'tcx> { // the opaque. let mut enable_subtyping = |ty, opaque_is_expected| { let ty_vid = infcx.next_ty_var_id_in_universe( - TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.span(), - }, + TypeVariableOrigin { param_def_id: None, span: self.span() }, ty::UniverseIndex::ROOT, ); diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index a668a1045757..d2759087cb47 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -9,7 +9,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit; use rustc_hir::{GenericParamKind, ImplItemKind}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{util, FulfillmentError}; use rustc_middle::ty::error::{ExpectedFound, TypeError}; @@ -800,10 +800,10 @@ impl<'tcx> TypeFolder> for ImplTraitInTraitCollector<'_, 'tcx> { bug!("FIXME(RPITIT): error here"); } // Replace with infer var - let infer_ty = self.ocx.infcx.next_ty_var(TypeVariableOrigin { - span: self.span, - kind: TypeVariableOriginKind::MiscVariable, - }); + let infer_ty = self + .ocx + .infcx + .next_ty_var(TypeVariableOrigin { span: self.span, param_def_id: None }); self.types.insert(proj.def_id, (infer_ty, proj.args)); // Recurse into bounds for (pred, pred_span) in self diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 2a2fd0a41a62..dd6691293411 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -5,7 +5,7 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::{self as hir, ExprKind, PatKind}; use rustc_hir_pretty::ty_to_string; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; use rustc_trait_selection::traits::{ @@ -67,10 +67,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // arm for inconsistent arms or to the whole match when a `()` type // is required). Expectation::ExpectHasType(ety) if ety != Ty::new_unit(self.tcx) => ety, - _ => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: expr.span, - }), + _ => self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }), }; CoerceMany::with_coercion_sites(coerce_first, arms) }; @@ -578,10 +575,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ...but otherwise we want to use any supertype of the // scrutinee. This is sort of a workaround, see note (*) in // `check_pat` for some details. - let scrut_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: scrut.span, - }); + let scrut_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: scrut.span }); self.check_expr_has_type_or_error(scrut, scrut_ty, |_| {}); scrut_ty } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index aa94632b2b07..f6303fe9dd1c 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -13,10 +13,7 @@ use rustc_infer::{ infer, traits::{self, Obligation}, }; -use rustc_infer::{ - infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, - traits::ObligationCause, -}; +use rustc_infer::{infer::type_variable::TypeVariableOrigin, traits::ObligationCause}; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, }; @@ -180,18 +177,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { infer::FnCall, closure_args.coroutine_closure_sig(), ); - let tupled_upvars_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: callee_expr.span, - }); + let tupled_upvars_ty = self + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: callee_expr.span }); // We may actually receive a coroutine back whose kind is different // from the closure that this dispatched from. This is because when // we have no captures, we automatically implement `FnOnce`. This // impl forces the closure kind to `FnOnce` i.e. `u8`. - let kind_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: callee_expr.span, - }); + let kind_ty = self + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: callee_expr.span }); let call_sig = self.tcx.mk_fn_sig( [coroutine_closure_sig.tupled_inputs_ty], coroutine_closure_sig.to_coroutine( @@ -305,10 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_tup_from_iter( self.tcx, arg_exprs.iter().map(|e| { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: e.span, - }) + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: e.span }) }), ) }); diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 59a043d1d699..b0d1b6655dbf 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -8,7 +8,7 @@ use rustc_hir::def::DefKind; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::check::{check_function_signature, forbid_intrinsic_abi}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::RegionVariableOrigin; use rustc_middle::ty::{self, Binder, Ty, TyCtxt}; use rustc_span::def_id::LocalDefId; @@ -123,8 +123,7 @@ pub(super) fn check_fn<'a, 'tcx>( // We have special-cased the case where the function is declared // `-> dyn Foo` and we don't actually relate it to the // `fcx.ret_coercion`, so just instantiate a type variable. - actual_return_ty = - fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span }); + actual_return_ty = fcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span }); debug!("actual_return_ty replaced with {:?}", actual_return_ty); } diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index dbae8bfb5424..a6d548f19096 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -6,7 +6,7 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes}; use rustc_infer::infer::{InferOk, InferResult}; use rustc_macros::{TypeFoldable, TypeVisitable}; @@ -72,10 +72,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let parent_args = GenericArgs::identity_for_item(tcx, tcx.typeck_root_def_id(expr_def_id.to_def_id())); - let tupled_upvars_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let tupled_upvars_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); // FIXME: We could probably actually just unify this further -- // instead of having a `FnSig` and a `Option`, @@ -104,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // It will be unified during the upvar inference phase (`upvar.rs`) None => self.next_ty_var(TypeVariableOrigin { // FIXME(eddyb) distinguish closure kind inference variables from the rest. - kind: TypeVariableOriginKind::ClosureSynthetic, + param_def_id: None, span: expr_span, }), }; @@ -126,7 +124,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _) | hir::CoroutineKind::Coroutine(_) => { let yield_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, + param_def_id: None, span: expr_span, }); self.require_type_is_sized(yield_ty, expr_span, traits::SizedYieldType); @@ -138,7 +136,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // not a problem. hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _) => { let yield_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, + param_def_id: None, span: expr_span, }); self.require_type_is_sized(yield_ty, expr_span, traits::SizedYieldType); @@ -166,10 +164,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Resume type defaults to `()` if the coroutine has no argument. let resume_ty = liberated_sig.inputs().get(0).copied().unwrap_or(tcx.types.unit); - let interior = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let interior = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); self.deferred_coroutine_interiors.borrow_mut().push(( expr_def_id, body.id(), @@ -181,11 +177,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // later during upvar analysis. Regular coroutines always have the kind // ty of `().` let kind_ty = match kind { - hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) => self - .next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }), + hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) => { + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }) + } _ => tcx.types.unit, }; @@ -219,30 +213,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; // Compute all of the variables that will be used to populate the coroutine. - let resume_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); - let interior = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let resume_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); + let interior = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); let closure_kind_ty = match expected_kind { Some(kind) => Ty::from_closure_kind(tcx, kind), // Create a type variable (for now) to represent the closure kind. // It will be unified during the upvar inference phase (`upvar.rs`) - None => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }), + None => { + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }) + } }; - let coroutine_captures_by_ref_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let coroutine_captures_by_ref_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); let closure_args = ty::CoroutineClosureArgs::new( tcx, ty::CoroutineClosureArgsParts { @@ -274,16 +261,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Create a type variable (for now) to represent the closure kind. // It will be unified during the upvar inference phase (`upvar.rs`) - None => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }), + None => { + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }) + } }; - let coroutine_upvars_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: expr_span, - }); + let coroutine_upvars_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }); // We need to turn the liberated signature that we got from HIR, which // looks something like `|Args...| -> T`, into a signature that is suitable diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 720f4927ea89..3672bd2e8826 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -43,7 +43,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Expr; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult}; use rustc_infer::traits::TraitEngineExt as _; use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause, TraitEngine}; @@ -279,10 +279,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { if b.is_ty_var() { // Two unresolved type variables: create a `Coerce` predicate. let target_ty = if self.use_lub { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::LatticeVariable, - span: self.cause.span, - }) + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.cause.span }) } else { b }; @@ -581,10 +578,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // the `CoerceUnsized` target type and the expected type. // We only have the latter, so we use an inference variable // for the former and let type inference do the rest. - let origin = TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.cause.span, - }; + let origin = TypeVariableOrigin { param_def_id: None, span: self.cause.span }; let coerce_target = self.next_ty_var(origin); let mut coercion = self.unify_and(coerce_target, target, |target| { let unsize = Adjustment { kind: Adjust::Pointer(PointerCoercion::Unsize), target }; diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 75a68f16cf18..e3279bc4afea 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -337,10 +337,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty_op: |ty| { if let ty::Infer(infer) = ty.kind() { match infer { - ty::TyVar(_) => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }), + ty::TyVar(_) => self + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP }), ty::IntVar(_) => self.next_int_var(), ty::FloatVar(_) => self.next_float_var(), ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => { diff --git a/compiler/rustc_hir_typeck/src/expectation.rs b/compiler/rustc_hir_typeck/src/expectation.rs index ff84e753d70d..5106d29091a1 100644 --- a/compiler/rustc_hir_typeck/src/expectation.rs +++ b/compiler/rustc_hir_typeck/src/expectation.rs @@ -1,4 +1,4 @@ -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; @@ -110,8 +110,7 @@ impl<'a, 'tcx> Expectation<'tcx> { /// Like `only_has_type`, but instead of returning `None` if no /// hard constraint exists, creates a fresh type variable. pub(super) fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> { - self.only_has_type(fcx).unwrap_or_else(|| { - fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span }) - }) + self.only_has_type(fcx) + .unwrap_or_else(|| fcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span })) } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 8f30c3fd3774..45b001e2682f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -38,7 +38,7 @@ use rustc_hir::{ExprKind, HirId, QPath}; use rustc_hir_analysis::check::ty_kind_suggestion; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer as _; use rustc_infer::infer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::DefineOpaqueTypes; use rustc_infer::infer::InferOk; use rustc_infer::traits::query::NoSolution; @@ -81,10 +81,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return Ty::new_error(self.tcx(), reported); } - let adj_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::AdjustmentType, - span: expr.span, - }); + let adj_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }); self.apply_adjustments( expr, vec![Adjustment { kind: Adjust::NeverToAny, target: adj_ty }], @@ -1418,10 +1416,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }) .unwrap_or_else(|| { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: expr.span, - }) + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }) }); let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args); assert_eq!(self.diverges.get(), Diverges::Maybe); @@ -1432,10 +1427,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } coerce.complete(self) } else { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: expr.span, - }) + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr.span }) }; let array_len = args.len() as u64; self.suggest_array_len(expr, array_len); @@ -1518,10 +1510,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (uty, uty) } None => { - let ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: element.span, - }); + let ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: element.span }); let element_ty = self.check_expr_has_type_or_error(element, ty, |_| {}); (element_ty, ty) } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index a9a5a89a4136..5930fc406a4e 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -2,7 +2,7 @@ use crate::FnCtxt; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_infer::{infer::type_variable::TypeVariableOriginKind, traits::ObligationCauseCode}; +use rustc_infer::traits::ObligationCauseCode; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_span::{symbol::kw, Span}; use rustc_trait_selection::traits; @@ -340,7 +340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { type Result = ControlFlow>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { if let Some(origin) = self.0.type_var_origin(ty) - && let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind + && let Some(def_id) = origin.param_def_id && let generics = self.0.tcx.generics_of(self.1) && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) && let Some(arg) = diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 13226d304c8f..f346c6446e00 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -31,7 +31,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_hir_analysis::structured_errors::StructuredDiag; use rustc_index::IndexVec; use rustc_infer::infer::error_reporting::{FailureCode, ObligationCauseExt}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::TypeTrace; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::traits::ObligationCauseCode::ExprBindingObligation; @@ -2184,7 +2184,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { [ callee_ty, self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, + param_def_id: None, span: rustc_span::DUMMY_SP, }), ], diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 0b69c7a24317..338fd6d07285 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -16,7 +16,7 @@ use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::infer; use rustc_infer::infer::error_reporting::sub_relations::SubRelations; use rustc_infer::infer::error_reporting::TypeErrCtxt; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Session; @@ -236,10 +236,7 @@ impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> { fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx> { match param { Some(param) => self.var_for_def(span, param).as_type().unwrap(), - None => self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - }), + None => self.next_ty_var(TypeVariableOrigin { param_def_id: None, span }), } } diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index be5cd6e9d487..0b985e40c4e0 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -2,7 +2,7 @@ use crate::FnCtxt; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::PatKind; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::ty::Ty; use rustc_middle::ty::UserType; use rustc_span::def_id::LocalDefId; @@ -72,10 +72,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { match ty_opt { None => { // Infer the variable's type. - let var_ty = self.fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - }); + let var_ty = self.fcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span }); self.fcx.locals.borrow_mut().insert(nid, var_ty); var_ty } diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 476df9ae793f..5b2461f737e6 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -60,7 +60,7 @@ use rustc_hir::intravisit::{Map, Visitor}; use rustc_hir::{HirIdMap, Node}; use rustc_hir_analysis::check::check_abi; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc}; use rustc_middle::query::Providers; use rustc_middle::traits; @@ -261,10 +261,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti tcx.impl_trait_ref(item.container_id(tcx)).unwrap().instantiate_identity().args; Some(tcx.type_of(trait_item).instantiate(tcx, args)) } else { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - })) + Some(fcx.next_ty_var(TypeVariableOrigin { span, param_def_id: None })) } } else if let Node::AnonConst(_) = node { let id = tcx.local_def_id_to_hir_id(def_id); @@ -272,10 +269,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), span, .. }) if anon_const.hir_id == id => { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span, - })) + Some(fcx.next_ty_var(TypeVariableOrigin { span, param_def_id: None })) } Node::Expr(&hir::Expr { kind: hir::ExprKind::InlineAsm(asm), span, .. }) | Node::Item(&hir::Item { kind: hir::ItemKind::GlobalAsm(asm), span, .. }) => { @@ -285,10 +279,7 @@ fn infer_type_if_missing<'tcx>(fcx: &FnCtxt<'_, 'tcx>, node: Node<'tcx>) -> Opti Some(fcx.next_int_var()) } hir::InlineAsmOperand::SymFn { anon_const } if anon_const.hir_id == id => { - Some(fcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - })) + Some(fcx.next_ty_var(TypeVariableOrigin { span, param_def_id: None })) } _ => None, }) diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 0e43cb40485a..819641283451 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -7,7 +7,7 @@ use hir::HirId; use hir::ItemKind; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::ty::{Adt, Array, Ref, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::{Empty, Underscore}; @@ -218,10 +218,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If we know it does not, we don't need to warn. if method_name.name == sym::from_iter { if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) { - let any_type = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }); + let any_type = + self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span }); if !self .infcx .type_implements_trait(trait_def_id, [self_ty, any_type], self.param_env) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 754866c85c4a..a400e06e3b1c 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -22,11 +22,7 @@ use rustc_hir::lang_items::LangItem; use rustc_hir::PatKind::Binding; use rustc_hir::PathSegment; use rustc_hir::{ExprKind, Node, QPath}; -use rustc_infer::infer::{ - self, - type_variable::{TypeVariableOrigin, TypeVariableOriginKind}, - RegionVariableOrigin, -}; +use rustc_infer::infer::{self, type_variable::TypeVariableOrigin, RegionVariableOrigin}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; @@ -82,13 +78,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_ref = ty::TraitRef::new( tcx, fn_once, - [ - ty, - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }), - ], + [ty, self.next_ty_var(TypeVariableOrigin { param_def_id: None, span })], ); let poly_trait_ref = ty::Binder::dummy(trait_ref); let obligation = Obligation::misc( @@ -1271,7 +1261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|expr| { self.node_ty_opt(expr.hir_id).unwrap_or_else(|| { self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, + param_def_id: None, span: expr.span, }) }) @@ -1861,7 +1851,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { GenericArgKind::Type(_) => self .next_ty_var(TypeVariableOrigin { span: rustc_span::DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, + param_def_id: None, }) .into(), GenericArgKind::Const(arg) => self diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 94b723f694e9..49d0c8bfcd1b 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -7,7 +7,7 @@ use rustc_ast as ast; use rustc_data_structures::packed::Pu128; use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diag}; use rustc_hir as hir; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, @@ -219,10 +219,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // e.g., adding `&'a T` and `&'b T`, given `&'x T: Add<&'x T>`, will result // in `&'a T <: &'x T` and `&'b T <: &'x T`, instead of `'a = 'b = 'x`. let lhs_ty = self.check_expr(lhs_expr); - let fresh_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: lhs_expr.span, - }); + let fresh_var = self + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: lhs_expr.span }); self.demand_coerce(lhs_expr, lhs_ty, fresh_var, Some(rhs_expr), AllowTwoPhase::No) } IsAssign::Yes => { @@ -241,10 +239,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // using this variable as the expected type, which sometimes lets // us do better coercions than we would be able to do otherwise, // particularly for things like `String + &String`. - let rhs_ty_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: rhs_expr.span, - }); + let rhs_ty_var = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: rhs_expr.span }); let result = self.lookup_op_method( (lhs_expr, lhs_ty), diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index bb47f8dfba46..6bc81fd6e6f2 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -9,7 +9,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Mutability, Pat, PatKind}; use rustc_infer::infer; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::{self, Adt, Ty, TypeVisitableExt}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; @@ -1369,7 +1369,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.next_ty_var( // FIXME: `MiscVariable` for now -- obtaining the span and name information // from all tuple elements isn't trivial. - TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }, + TypeVariableOrigin { param_def_id: None, span }, ) }); let element_tys = tcx.mk_type_list_from_iter(element_tys_iter); @@ -1997,10 +1997,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(()) => { // Here, `demand::subtype` is good enough, but I don't // think any errors can be introduced by using `demand::eqtype`. - let inner_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: inner.span, - }); + let inner_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: inner.span }); let box_ty = Ty::new_box(tcx, inner_ty); self.demand_eqtype_pat(span, expected, box_ty, pat_info.top_info); (box_ty, inner_ty) @@ -2088,7 +2086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (expected, expected) } else { let inner_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, + param_def_id: None, span: inner.span, }); let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); @@ -2138,8 +2136,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; let len = before.len(); - let ty_var_origin = - TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }; + let ty_var_origin = TypeVariableOrigin { param_def_id: None, span }; let inner_ty = self.next_ty_var(ty_var_origin); Some(Ty::new_array(tcx, inner_ty, len.try_into().unwrap())) diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index f29dc39b7beb..bce43b3be343 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -4,7 +4,7 @@ use rustc_ast as ast; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir_analysis::autoderef::Autoderef; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::InferOk; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref, PointerCoercion}; use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; @@ -147,10 +147,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If some lookup succeeds, write callee into table and extract index/element // type from the method signature. // If some lookup succeeded, install method in table - let input_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::AutoDeref, - span: base_expr.span, - }); + let input_ty = + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: base_expr.span }); let method = self.try_overloaded_place_op(expr.span, self_ty, &[input_ty], PlaceOp::Index); diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index bcc476393ea7..bb8ade01515a 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -22,7 +22,7 @@ //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; -use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin}; use rustc_index::IndexVec; use rustc_middle::infer::unify_key::EffectVarValue; use rustc_middle::ty::fold::TypeFoldable; @@ -115,7 +115,7 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::Ty(ty_kind) => { let ty = match ty_kind { CanonicalTyVarKind::General(ui) => self.next_ty_var_in_universe( - TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span }, + TypeVariableOrigin { param_def_id: None, span }, universe_map(ui), ), 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 3b5658ed0ee6..744a594cfb2f 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 @@ -3,7 +3,7 @@ use crate::errors::{ SourceKindMultiSuggestion, SourceKindSubdiag, }; use crate::infer::error_reporting::TypeErrCtxt; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::InferCtxt; use rustc_errors::{codes::*, Diag, IntoDiagArg}; use rustc_hir as hir; @@ -188,7 +188,8 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte let mut infcx_inner = infcx.inner.borrow_mut(); let ty_vars = infcx_inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); - if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind + if let Some(def_id) = var_origin.param_def_id + && let name = infcx.tcx.item_name(def_id) && name != kw::SelfUpper && !var_origin.span.from_expansion() { @@ -302,9 +303,8 @@ impl<'tcx> InferCtxt<'tcx> { let mut inner = self.inner.borrow_mut(); let ty_vars = &inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); - if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = - var_origin.kind - { + if let Some(def_id) = var_origin.param_def_id { + let name = self.tcx.item_name(def_id); if name != kw::SelfUpper && !var_origin.span.from_expansion() { return InferenceDiagnosticsData { name: name.to_string(), @@ -549,7 +549,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { GenericArgKind::Type(_) => self .next_ty_var(TypeVariableOrigin { span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, + param_def_id: None, }) .into(), GenericArgKind::Const(arg) => self @@ -576,10 +576,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } InferSourceKind::FullyQualifiedMethodCall { receiver, successor, args, def_id } => { - let placeholder = Some(self.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - })); + let placeholder = Some( + self.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }), + ); if let Some(args) = args.make_suggestable(self.infcx.tcx, true, placeholder) { let mut printer = fmt_printer(self, Namespace::ValueNS); printer.print_def_path(def_id, args).unwrap(); @@ -613,10 +612,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } InferSourceKind::ClosureReturn { ty, data, should_wrap_expr } => { - let placeholder = Some(self.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - })); + let placeholder = Some( + self.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }), + ); if let Some(ty) = ty.make_suggestable(self.infcx.tcx, true, placeholder) { let ty_info = ty_to_string(self, ty, None); multi_suggestions.push(SourceKindMultiSuggestion::new_closure_return( diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 0b8061104ab4..a285be385023 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -48,7 +48,7 @@ use rustc_span::Span; use snapshot::undo_log::InferCtxtUndoLogs; use std::cell::{Cell, RefCell}; use std::fmt; -use type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use type_variable::TypeVariableOrigin; pub mod at; pub mod canonical; @@ -1111,13 +1111,7 @@ impl<'tcx> InferCtxt<'tcx> { // as the generic parameters for the default, `(T, U)`. let ty_var_id = self.inner.borrow_mut().type_variables().new_var( self.universe(), - TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeParameterDefinition( - param.name, - param.def_id, - ), - span, - }, + TypeVariableOrigin { param_def_id: Some(param.def_id), span }, ); Ty::new_var(self.tcx, ty_var_id).into() @@ -1411,10 +1405,7 @@ impl<'tcx> InferCtxt<'tcx> { .entry(bt.var) .or_insert_with(|| { self.infcx - .next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.span, - }) + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.span }) .into() }) .expect_ty() diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index d32515425c4b..cf850353c48d 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -1,4 +1,4 @@ -use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use super::type_variable::TypeVariableOrigin; use super::{DefineOpaqueTypes, InferResult}; use crate::errors::OpaqueHiddenTypeDiag; use crate::infer::{InferCtxt, InferOk}; @@ -68,10 +68,7 @@ impl<'tcx> InferCtxt<'tcx> { // FIXME(compiler-errors): We probably should add a new TypeVariableOriginKind // for opaque types, and then use that kind to fix the spans for type errors // that we see later on. - let ty_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }); + let ty_var = self.next_ty_var(TypeVariableOrigin { param_def_id: None, span }); obligations.extend( self.handle_opaque_type(ty, ty_var, &cause, param_env).unwrap().obligations, ); diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index 38e74e538687..e60efe37fd9b 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -3,7 +3,7 @@ use rustc_middle::ty::{self, Ty}; use crate::traits::{Obligation, PredicateObligation}; -use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use super::type_variable::TypeVariableOrigin; use super::InferCtxt; impl<'tcx> InferCtxt<'tcx> { @@ -24,7 +24,7 @@ impl<'tcx> InferCtxt<'tcx> { debug_assert!(!self.next_trait_solver()); let def_id = projection_ty.def_id; let ty_var = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, + param_def_id: None, span: self.tcx.def_span(def_id), }); let projection = ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Projection( diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs index 5fb9d9341e03..74929daffe24 100644 --- a/compiler/rustc_infer/src/infer/relate/generalize.rs +++ b/compiler/rustc_infer/src/infer/relate/generalize.rs @@ -1,7 +1,7 @@ use std::mem; use super::StructurallyRelateAliases; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind, TypeVariableValue}; +use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableValue}; use crate::infer::{InferCtxt, ObligationEmittingRelation, RegionVariableOrigin}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -352,7 +352,7 @@ impl<'tcx> Generalizer<'_, 'tcx> { ) -> Result, TypeError<'tcx>> { if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() { return Ok(self.infcx.next_ty_var_in_universe( - TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span: self.span }, + TypeVariableOrigin { param_def_id: None, span: self.span }, self.for_universe, )); } @@ -375,10 +375,7 @@ impl<'tcx> Generalizer<'_, 'tcx> { debug!("generalization failure in alias"); Ok(self.infcx.next_ty_var_in_universe( - TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: self.span, - }, + TypeVariableOrigin { param_def_id: None, span: self.span }, self.for_universe, )) } diff --git a/compiler/rustc_infer/src/infer/relate/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs index 747158585db7..f9470c9b8f67 100644 --- a/compiler/rustc_infer/src/infer/relate/lattice.rs +++ b/compiler/rustc_infer/src/infer/relate/lattice.rs @@ -18,7 +18,7 @@ //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order) use super::combine::ObligationEmittingRelation; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::{DefineOpaqueTypes, InferCtxt}; use crate::traits::ObligationCause; @@ -88,18 +88,14 @@ where // iterate on the subtype obligations that are returned, but I // think this suffices. -nmatsakis (&ty::Infer(TyVar(..)), _) => { - let v = infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::LatticeVariable, - span: this.cause().span, - }); + let v = infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: this.cause().span }); this.relate_bound(v, b, a)?; Ok(v) } (_, &ty::Infer(TyVar(..))) => { - let v = infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::LatticeVariable, - span: this.cause().span, - }); + let v = infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: this.cause().span }); this.relate_bound(v, a, b)?; Ok(v) } diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index 55c6c92a5848..e6cc950ab25b 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -2,7 +2,6 @@ use rustc_data_structures::undo_log::Rollback; use rustc_hir::def_id::DefId; use rustc_index::IndexVec; use rustc_middle::ty::{self, Ty, TyVid}; -use rustc_span::symbol::Symbol; use rustc_span::Span; use crate::infer::InferCtxtUndoLogs; @@ -37,30 +36,9 @@ pub struct TypeVariableTable<'a, 'tcx> { #[derive(Copy, Clone, Debug)] pub struct TypeVariableOrigin { - pub kind: TypeVariableOriginKind, pub span: Span, -} - -/// Reasons to create a type inference variable -#[derive(Copy, Clone, Debug)] -pub enum TypeVariableOriginKind { - MiscVariable, - NormalizeProjectionType, - TypeInference, - TypeParameterDefinition(Symbol, DefId), - - /// One of the upvars or closure kind parameters in a `ClosureArgs` - /// (before it has been determined). - // FIXME(eddyb) distinguish upvar inference variables from the rest. - ClosureSynthetic, - AutoDeref, - AdjustmentType, - - /// In type check, when we are type checking a function that - /// returns `-> dyn Foo`, we instantiate a type variable with the - /// return type for diagnostic purposes. - DynReturnFn, - LatticeVariable, + // `DefId` of the type parameter this was instantiated for, if any. + pub param_def_id: Option, } #[derive(Clone)] diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 440be873d4ee..d6376b7b0dca 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -2,7 +2,7 @@ use crate::build::expr::as_place::{PlaceBase, PlaceBuilder}; use crate::build::matches::{Binding, Candidate, FlatPat, MatchPair, TestCase}; use crate::build::Builder; use rustc_data_structures::fx::FxIndexSet; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::mir::*; use rustc_middle::thir::{self, *}; use rustc_middle::ty; @@ -178,10 +178,9 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { cx.tcx, ty::InlineConstArgsParts { parent_args: ty::GenericArgs::identity_for_item(cx.tcx, parent_id), - ty: cx.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span, - }), + ty: cx + .infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span }), }, ) .args; diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 0154aff12b6e..46311e2c88b8 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -2,7 +2,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::DefId; use rustc_infer::infer::at::ToTrace; use rustc_infer::infer::canonical::CanonicalVarValues; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{ BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk, TyCtxtInferExt, }; @@ -587,10 +587,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } pub(super) fn next_ty_infer(&self) -> Ty<'tcx> { - self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }) + self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP }) } pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> { diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 5b45e1a34e48..a9f82e36f266 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -3,7 +3,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{BoundVarReplacer, PlaceholderReplacer}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::infer::at::At; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::TraitEngineExt; use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine}; @@ -74,10 +74,8 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { self.depth += 1; - let new_infer_ty = infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, - span: self.at.cause.span, - }); + let new_infer_ty = + infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.at.cause.span }); let obligation = Obligation::new( tcx, self.at.cause.clone(), diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs index 6c6c8ca1d9fe..d41d43bad718 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/infer_ctxt_ext.rs @@ -1,4 +1,4 @@ -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::InferCtxt; use crate::traits::{Obligation, ObligationCause, ObligationCtxt}; use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, Diag}; @@ -217,10 +217,8 @@ impl<'tcx> InferCtxt<'tcx> { let Some(trait_def_id) = trait_def_id else { continue }; // Make a fresh inference variable so we can determine what the generic parameters // of the trait are. - let var = self.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - }); + let var = + self.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }); // FIXME(effects) let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, [ty.skip_binder(), var]); let obligation = Obligation::new( 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 2067956d0f5f..061320b9070e 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -24,7 +24,7 @@ use rustc_hir::is_range_literal; use rustc_hir::lang_items::LangItem; use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node}; use rustc_infer::infer::error_reporting::TypeErrCtxt; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk}; use rustc_middle::hir::map; use rustc_middle::traits::IsConstable; @@ -1894,10 +1894,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty::Tuple(inputs) if infcx.tcx.is_fn_trait(trait_ref.def_id()) => { infcx.tcx.mk_fn_sig( *inputs, - infcx.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - }), + infcx + .next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }), false, hir::Unsafety::Normal, abi::Abi::Rust, @@ -1905,10 +1903,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } _ => infcx.tcx.mk_fn_sig( [inputs], - infcx.next_ty_var(TypeVariableOrigin { - span: DUMMY_SP, - kind: TypeVariableOriginKind::MiscVariable, - }), + infcx.next_ty_var(TypeVariableOrigin { span: DUMMY_SP, param_def_id: None }), false, hir::Unsafety::Normal, abi::Abi::Rust, @@ -4269,7 +4264,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { continue; }; - let origin = TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }; + let origin = TypeVariableOrigin { param_def_id: None, span }; // Make `Self` be equivalent to the type of the call chain // expression we're looking at now, so that we can tell what // for example `Iterator::Item` is at this point in the chain. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 3819ea68e962..25002bb1facc 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -6,7 +6,7 @@ use crate::errors::{ AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch, }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::InferCtxtExt as _; use crate::infer::{self, InferCtxt}; use crate::traits::error_reporting::infer_ctxt_ext::InferCtxtExt; @@ -2820,10 +2820,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let ty::Param(_) = *ty.kind() { let infcx = self.infcx; *self.var_map.entry(ty).or_insert_with(|| { - infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }) + infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: DUMMY_SP }) }) } else { ty.super_fold_with(self) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a5483c5bbc02..4a8df6c6a5ba 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -18,7 +18,7 @@ use rustc_middle::traits::ImplSource; use rustc_middle::traits::ImplSourceUserDefinedData; use crate::errors::InherentProjectionNormalizationOverflow; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::type_variable::TypeVariableOrigin; use crate::infer::{BoundRegionConversionTime, InferOk}; use crate::traits::normalize::normalize_with_depth; use crate::traits::normalize::normalize_with_depth_to; @@ -522,7 +522,7 @@ fn normalize_to_error<'a, 'tcx>( }; let tcx = selcx.infcx.tcx; let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, + param_def_id: None, span: tcx.def_span(projection_ty.def_id), }); Normalized { value: new_value, obligations: vec![trait_obligation] } diff --git a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs index 2f428564ae73..5746e20490d0 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_normalize.rs @@ -1,5 +1,5 @@ use rustc_infer::infer::at::At; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::traits::{FulfillmentError, TraitEngine}; use rustc_middle::ty::{self, Ty}; @@ -19,10 +19,9 @@ impl<'tcx> At<'_, 'tcx> { return Ok(ty); }; - let new_infer_ty = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::NormalizeProjectionType, - span: self.cause.span, - }); + let new_infer_ty = self + .infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.cause.span }); // We simply emit an `alias-eq` goal here, since that will take care of // normalizing the LHS of the projection until it is a rigid projection diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index ab1be66dc787..1afc5ed0157a 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::{TypeVariableOrigin}; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::interpret::Scalar; @@ -276,8 +276,8 @@ pub fn implements_trait_with_env_from_iter<'tcx>( .map(|arg| { arg.into().unwrap_or_else(|| { let orig = TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, span: DUMMY_SP, + param_def_id: None, }; infcx.next_ty_var(orig).into() }) From eb6f856169d74246c89b5e7d9b56da49e3af5bc0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 18:52:03 -0400 Subject: [PATCH 042/114] Remove ConstVariableOriginKind --- compiler/rustc_hir_typeck/src/demand.rs | 5 +---- compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 7 ++----- .../rustc_hir_typeck/src/method/suggest.rs | 4 ++-- .../rustc_infer/src/infer/canonical/mod.rs | 4 ++-- .../infer/error_reporting/need_type_info.rs | 19 ++++++------------- compiler/rustc_infer/src/infer/mod.rs | 15 +++------------ .../rustc_infer/src/infer/snapshot/fudge.rs | 9 ++++----- compiler/rustc_middle/src/infer/unify_key.rs | 12 ++---------- .../src/solve/eval_ctxt/mod.rs | 7 ++----- .../src/solve/normalize.rs | 7 ++----- 10 files changed, 26 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index e3279bc4afea..d6d22a43fe0b 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -354,10 +354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::ConstKind::Infer(_) = ct.kind() { self.next_const_var( ct.ty(), - ConstVariableOrigin { - kind: ConstVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }, + ConstVariableOrigin { param_def_id: None, span: DUMMY_SP }, ) } else { ct diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 338fd6d07285..080571e1a708 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -17,7 +17,7 @@ use rustc_infer::infer; use rustc_infer::infer::error_reporting::sub_relations::SubRelations; use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::type_variable::TypeVariableOrigin; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Session; use rustc_span::symbol::Ident; @@ -255,10 +255,7 @@ impl<'a, 'tcx> HirTyLowerer<'tcx> for FnCtxt<'a, 'tcx> { }, ) => self.var_for_effect(param).as_const().unwrap(), Some(param) => self.var_for_def(span, param).as_const().unwrap(), - None => self.next_const_var( - ty, - ConstVariableOrigin { kind: ConstVariableOriginKind::ConstInference, span }, - ), + None => self.next_const_var(ty, ConstVariableOrigin { span, param_def_id: None }), } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index a400e06e3b1c..8a16e726451a 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -23,7 +23,7 @@ use rustc_hir::PatKind::Binding; use rustc_hir::PathSegment; use rustc_hir::{ExprKind, Node, QPath}; use rustc_infer::infer::{self, type_variable::TypeVariableOrigin, RegionVariableOrigin}; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths}; @@ -1859,7 +1859,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { arg.ty(), ConstVariableOrigin { span: rustc_span::DUMMY_SP, - kind: ConstVariableOriginKind::MiscVariable, + param_def_id: None, }, ) .into(), diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index bb8ade01515a..734fa919eb5c 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -21,7 +21,7 @@ //! //! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html -use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind}; +use crate::infer::ConstVariableOrigin; use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin}; use rustc_index::IndexVec; use rustc_middle::infer::unify_key::EffectVarValue; @@ -148,7 +148,7 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::Const(ui, ty) => self .next_const_var_in_universe( ty, - ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span }, + ConstVariableOrigin { param_def_id: None, span }, universe_map(ui), ) .into(), 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 744a594cfb2f..f9f7f09203ae 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 @@ -13,9 +13,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, LetStmt, LocalSource}; use rustc_middle::hir::nested_filter; -use rustc_middle::infer::unify_key::{ - ConstVariableOrigin, ConstVariableOriginKind, ConstVariableValue, -}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableValue}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::{ @@ -217,8 +215,8 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte None } ConstVariableValue::Unknown { origin, universe: _ } => { - if let ConstVariableOriginKind::ConstParameterDefinition(name, _) = origin.kind { - return Some(name); + if let Some(def_id) = origin.param_def_id { + Some(infcx.tcx.item_name(def_id)) } else { None } @@ -341,11 +339,9 @@ impl<'tcx> InferCtxt<'tcx> { } ConstVariableValue::Unknown { origin, universe: _ } => origin, }; - if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) = - origin.kind - { + if let Some(def_id) = origin.param_def_id { return InferenceDiagnosticsData { - name: name.to_string(), + name: self.tcx.item_name(def_id).to_string(), span: Some(origin.span), kind: UnderspecifiedArgKind::Const { is_parameter: true }, parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id), @@ -555,10 +551,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { GenericArgKind::Const(arg) => self .next_const_var( arg.ty(), - ConstVariableOrigin { - span: DUMMY_SP, - kind: ConstVariableOriginKind::MiscVariable, - }, + ConstVariableOrigin { span: DUMMY_SP, param_def_id: None }, ) .into(), } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index a285be385023..0d50891c002b 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -30,7 +30,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_middle::infer::unify_key::ConstVariableValue; use rustc_middle::infer::unify_key::EffectVarValue; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType}; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ToType}; use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey}; use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult}; use rustc_middle::mir::ConstraintCategory; @@ -1120,13 +1120,7 @@ impl<'tcx> InferCtxt<'tcx> { if is_host_effect { return self.var_for_effect(param); } - let origin = ConstVariableOrigin { - kind: ConstVariableOriginKind::ConstParameterDefinition( - param.name, - param.def_id, - ), - span, - }; + let origin = ConstVariableOrigin { param_def_id: Some(param.def_id), span }; let const_var_id = self .inner .borrow_mut() @@ -1417,10 +1411,7 @@ impl<'tcx> InferCtxt<'tcx> { self.infcx .next_const_var( ty, - ConstVariableOrigin { - kind: ConstVariableOriginKind::MiscVariable, - span: self.span, - }, + ConstVariableOrigin { param_def_id: None, span: self.span }, ) .into() }) diff --git a/compiler/rustc_infer/src/infer/snapshot/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs index f8f1c1b4c45c..83667f7276d4 100644 --- a/compiler/rustc_infer/src/infer/snapshot/fudge.rs +++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs @@ -1,4 +1,4 @@ -use rustc_middle::infer::unify_key::{ConstVariableOriginKind, ConstVariableValue, ConstVidKey}; +use rustc_middle::infer::unify_key::{ConstVariableValue, ConstVidKey}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid}; @@ -33,10 +33,9 @@ fn const_vars_since_snapshot<'tcx>( range.start.vid..range.end.vid, (range.start.index()..range.end.index()) .map(|index| match table.probe_value(ConstVid::from_u32(index)) { - ConstVariableValue::Known { value: _ } => ConstVariableOrigin { - kind: ConstVariableOriginKind::MiscVariable, - span: rustc_span::DUMMY_SP, - }, + ConstVariableValue::Known { value: _ } => { + ConstVariableOrigin { param_def_id: None, span: rustc_span::DUMMY_SP } + } ConstVariableValue::Unknown { origin, universe: _ } => origin, }) .collect(), diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 84b428297dbb..5280acd72ce7 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -1,7 +1,6 @@ use crate::ty::{self, Ty, TyCtxt}; use rustc_data_structures::unify::{NoError, UnifyKey, UnifyValue}; use rustc_span::def_id::DefId; -use rustc_span::symbol::Symbol; use rustc_span::Span; use std::cmp; use std::marker::PhantomData; @@ -106,16 +105,9 @@ impl ToType for ty::FloatVarValue { #[derive(Copy, Clone, Debug)] pub struct ConstVariableOrigin { - pub kind: ConstVariableOriginKind, pub span: Span, -} - -/// Reasons to create a const inference variable -#[derive(Copy, Clone, Debug)] -pub enum ConstVariableOriginKind { - MiscVariable, - ConstInference, - ConstParameterDefinition(Symbol, DefId), + // `DefId` of the const parameter this was instantiated for, if any. + pub param_def_id: Option, } #[derive(Copy, Clone, Debug)] diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs index 46311e2c88b8..f914e6b3f2e8 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs @@ -10,7 +10,7 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::{MaybeCause, NestedNormalizationGoals}; use rustc_infer::traits::ObligationCause; use rustc_middle::infer::canonical::CanonicalVarInfos; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::solve::inspect; use rustc_middle::traits::solve::{ CanonicalInput, CanonicalResponse, Certainty, PredefinedOpaques, PredefinedOpaquesData, @@ -591,10 +591,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> { - self.infcx.next_const_var( - ty, - ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP }, - ) + self.infcx.next_const_var(ty, ConstVariableOrigin { param_def_id: None, span: DUMMY_SP }) } /// Returns a ty infer or a const infer depending on whether `kind` is a `Ty` or `Const`. diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index a9f82e36f266..94b44571d3b1 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -7,7 +7,7 @@ use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::TraitEngineExt; use rustc_infer::traits::{FulfillmentError, Obligation, TraitEngine}; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::infer::unify_key::ConstVariableOrigin; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{self, AliasTy, Ty, TyCtxt, UniverseIndex}; use rustc_middle::ty::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; @@ -122,10 +122,7 @@ impl<'tcx> NormalizationFolder<'_, 'tcx> { let new_infer_ct = infcx.next_const_var( ty, - ConstVariableOrigin { - kind: ConstVariableOriginKind::MiscVariable, - span: self.at.cause.span, - }, + ConstVariableOrigin { param_def_id: None, span: self.at.cause.span }, ); let obligation = Obligation::new( tcx, From ba6c166ee47356c7d7ad58586193e32b4fc8391d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 24 Mar 2024 19:34:14 -0400 Subject: [PATCH 043/114] Account for Self params properly --- .../infer/error_reporting/need_type_info.rs | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) 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 f9f7f09203ae..6b90d6612f04 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 @@ -16,11 +16,10 @@ use rustc_middle::hir::nested_filter; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableValue}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; -use rustc_middle::ty::{ - self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Ty, TyCtxt, - TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults, -}; -use rustc_span::symbol::{kw, sym, Ident}; +use rustc_middle::ty::{self, InferConst}; +use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef}; +use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults}; +use rustc_span::symbol::{sym, Ident}; use rustc_span::{BytePos, Span, DUMMY_SP}; use std::borrow::Cow; use std::iter; @@ -187,8 +186,10 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte let ty_vars = infcx_inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); if let Some(def_id) = var_origin.param_def_id + // The `Self` param of a trait has the def-id of the trait, + // since it's a synthetic parameter. + && infcx.tcx.def_kind(def_id) == DefKind::TyParam && let name = infcx.tcx.item_name(def_id) - && name != kw::SelfUpper && !var_origin.span.from_expansion() { let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id)); @@ -301,20 +302,18 @@ impl<'tcx> InferCtxt<'tcx> { let mut inner = self.inner.borrow_mut(); let ty_vars = &inner.type_variables(); let var_origin = ty_vars.var_origin(ty_vid); - if let Some(def_id) = var_origin.param_def_id { - let name = self.tcx.item_name(def_id); - if name != kw::SelfUpper && !var_origin.span.from_expansion() { - return InferenceDiagnosticsData { - name: name.to_string(), - span: Some(var_origin.span), - kind: UnderspecifiedArgKind::Type { - prefix: "type parameter".into(), - }, - parent: InferenceDiagnosticsParentData::for_def_id( - self.tcx, def_id, - ), - }; - } + if let Some(def_id) = var_origin.param_def_id + // The `Self` param of a trait has the def-id of the trait, + // since it's a synthetic parameter. + && self.tcx.def_kind(def_id) == DefKind::TyParam + && !var_origin.span.from_expansion() + { + return InferenceDiagnosticsData { + name: self.tcx.item_name(def_id).to_string(), + span: Some(var_origin.span), + kind: UnderspecifiedArgKind::Type { prefix: "type parameter".into() }, + parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id), + }; } } From 25c0cf0a66354d779584f410c9b0060fbeb9be6f Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 5 Apr 2024 12:07:59 -0400 Subject: [PATCH 044/114] nits --- compiler/rustc_hir_typeck/src/closure.rs | 8 +++----- compiler/rustc_hir_typeck/src/pat.rs | 9 ++------- compiler/rustc_infer/src/infer/opaque_types/mod.rs | 3 --- compiler/rustc_infer/src/infer/type_variable.rs | 4 +++- compiler/rustc_lint/src/non_local_def.rs | 12 ++++-------- compiler/rustc_middle/src/infer/unify_key.rs | 4 +++- 6 files changed, 15 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index a6d548f19096..d6704d9e44f9 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -100,11 +100,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Create a type variable (for now) to represent the closure kind. // It will be unified during the upvar inference phase (`upvar.rs`) - None => self.next_ty_var(TypeVariableOrigin { - // FIXME(eddyb) distinguish closure kind inference variables from the rest. - param_def_id: None, - span: expr_span, - }), + None => { + self.next_ty_var(TypeVariableOrigin { param_def_id: None, span: expr_span }) + } }; let closure_args = ty::ClosureArgs::new( diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 6bc81fd6e6f2..c39bc71bd121 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1365,13 +1365,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let max_len = cmp::max(expected_len, elements.len()); - let element_tys_iter = (0..max_len).map(|_| { - self.next_ty_var( - // FIXME: `MiscVariable` for now -- obtaining the span and name information - // from all tuple elements isn't trivial. - TypeVariableOrigin { param_def_id: None, span }, - ) - }); + let element_tys_iter = + (0..max_len).map(|_| self.next_ty_var(TypeVariableOrigin { param_def_id: None, span })); let element_tys = tcx.mk_type_list_from_iter(element_tys_iter); let pat_ty = Ty::new_tup(tcx, element_tys); if let Some(err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, pat_info.top_info) { diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index cf850353c48d..94a546f87eee 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -65,9 +65,6 @@ impl<'tcx> InferCtxt<'tcx> { let span = if span.contains(def_span) { def_span } else { span }; let code = traits::ObligationCauseCode::OpaqueReturnType(None); let cause = ObligationCause::new(span, body_id, code); - // FIXME(compiler-errors): We probably should add a new TypeVariableOriginKind - // for opaque types, and then use that kind to fix the spans for type errors - // that we see later on. let ty_var = self.next_ty_var(TypeVariableOrigin { param_def_id: None, span }); obligations.extend( self.handle_opaque_type(ty, ty_var, &cause, param_env).unwrap().obligations, diff --git a/compiler/rustc_infer/src/infer/type_variable.rs b/compiler/rustc_infer/src/infer/type_variable.rs index e6cc950ab25b..96afa257ebba 100644 --- a/compiler/rustc_infer/src/infer/type_variable.rs +++ b/compiler/rustc_infer/src/infer/type_variable.rs @@ -37,7 +37,9 @@ pub struct TypeVariableTable<'a, 'tcx> { #[derive(Copy, Clone, Debug)] pub struct TypeVariableOrigin { pub span: Span, - // `DefId` of the type parameter this was instantiated for, if any. + /// `DefId` of the type parameter this was instantiated for, if any. + /// + /// This should only be used for diagnostics. pub param_def_id: Option, } diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 870e198d70af..4b06278330f3 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -1,9 +1,8 @@ use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, TyKind}; use rustc_hir::{Path, QPath}; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_infer::infer::InferCtxt; use rustc_infer::traits::{Obligation, ObligationCause}; -use rustc_middle::query::Key; use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable, TypeFolder}; use rustc_middle::ty::{EarlyBinder, TraitRef, TypeSuperFoldable}; use rustc_span::def_id::{DefId, LOCAL_CRATE}; @@ -313,13 +312,10 @@ impl<'a, 'tcx, F: FnMut(DefId) -> bool> TypeFolder> } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - if let Some(ty_did) = t.ty_def_id() - && (self.did_has_local_parent)(ty_did) + if let Some(def) = t.ty_adt_def() + && (self.did_has_local_parent)(def.did()) { - self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: self.infer_span, - }) + self.infcx.next_ty_var(TypeVariableOrigin { param_def_id: None, span: self.infer_span }) } else { t.super_fold_with(self) } diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 5280acd72ce7..105be21f2727 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -106,7 +106,9 @@ impl ToType for ty::FloatVarValue { #[derive(Copy, Clone, Debug)] pub struct ConstVariableOrigin { pub span: Span, - // `DefId` of the const parameter this was instantiated for, if any. + /// `DefId` of the const parameter this was instantiated for, if any. + /// + /// This should only be used for diagnostics. pub param_def_id: Option, } From 05bb3d2683f26d068f2bf7499519ff72fbc2740e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 17:14:59 -0400 Subject: [PATCH 045/114] Just use type_dependent_def_id to figure out what the method is for an expr --- .../src/diagnostics/conflict_errors.rs | 33 +++++++++---------- .../src/diagnostics/region_errors.rs | 13 +++----- compiler/rustc_hir_typeck/src/lib.rs | 25 +------------- compiler/rustc_middle/src/query/mod.rs | 3 -- 4 files changed, 21 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 48cd9c268a11..2ac84dd0ba92 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1813,32 +1813,31 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let hir = tcx.hir(); let Some(body_id) = tcx.hir_node(self.mir_hir_id()).body_id() else { return }; - struct FindUselessClone<'hir> { - tcx: TyCtxt<'hir>, - def_id: DefId, - pub clones: Vec<&'hir hir::Expr<'hir>>, + + struct FindUselessClone<'tcx> { + tcx: TyCtxt<'tcx>, + typeck_results: &'tcx ty::TypeckResults<'tcx>, + pub clones: Vec<&'tcx hir::Expr<'tcx>>, } - impl<'hir> FindUselessClone<'hir> { - pub fn new(tcx: TyCtxt<'hir>, def_id: DefId) -> Self { - Self { tcx, def_id, clones: vec![] } + impl<'tcx> FindUselessClone<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { + Self { tcx, typeck_results: tcx.typeck(def_id), clones: vec![] } } } - - impl<'v> Visitor<'v> for FindUselessClone<'v> { - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - if let hir::ExprKind::MethodCall(segment, _rcvr, args, _span) = ex.kind - && segment.ident.name == sym::clone - && args.len() == 0 - && let Some(def_id) = self.def_id.as_local() - && let Some(method) = self.tcx.lookup_method_for_diagnostic((def_id, ex.hir_id)) - && Some(self.tcx.parent(method)) == self.tcx.lang_items().clone_trait() + impl<'tcx> Visitor<'tcx> for FindUselessClone<'tcx> { + fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { + if let hir::ExprKind::MethodCall(..) = ex.kind + && let Some(method_def_id) = + self.typeck_results.type_dependent_def_id(ex.hir_id) + && self.tcx.lang_items().clone_trait() == Some(self.tcx.parent(method_def_id)) { self.clones.push(ex); } hir::intravisit::walk_expr(self, ex); } } - let mut expr_finder = FindUselessClone::new(tcx, self.mir_def_id().into()); + + let mut expr_finder = FindUselessClone::new(tcx, self.mir_def_id()); let body = hir.body(body_id).value; expr_finder.visit_expr(body); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 304d41d69417..d882f5db4102 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -1131,17 +1131,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }; // The found `Self` type of the method call. let Some(possible_rcvr_ty) = tables.node_type_opt(rcvr.hir_id) else { return }; - - // The `MethodCall` expression is `Res::Err`, so we search for the method on the `rcvr_ty`. - let Some(method) = tcx.lookup_method_for_diagnostic((self.mir_def_id(), expr.hir_id)) - else { - return; - }; + let Some(method_def_id) = tables.type_dependent_def_id(expr.hir_id) else { return }; // Get the type for the parameter corresponding to the argument the closure with the // lifetime error we had. let Some(input) = tcx - .fn_sig(method) + .fn_sig(method_def_id) .instantiate_identity() .inputs() .skip_binder() @@ -1156,7 +1151,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let ty::Param(closure_param) = input.kind() else { return }; // Get the arguments for the found method, only specifying that `Self` is the receiver type. - let args = GenericArgs::for_item(tcx, method, |param, _| { + let args = GenericArgs::for_item(tcx, method_def_id, |param, _| { if param.index == 0 { possible_rcvr_ty.into() } else if param.index == closure_param.index { @@ -1166,7 +1161,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } }); - let preds = tcx.predicates_of(method).instantiate(tcx, args); + let preds = tcx.predicates_of(method_def_id).instantiate(tcx, args); let ocx = ObligationCtxt::new(&self.infcx); ocx.register_obligations(preds.iter().map(|(pred, span)| { diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 476df9ae793f..700dde184f2d 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -56,7 +56,7 @@ use rustc_data_structures::unord::UnordSet; use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::intravisit::{Map, Visitor}; +use rustc_hir::intravisit::Visitor; use rustc_hir::{HirIdMap, Node}; use rustc_hir_analysis::check::check_abi; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; @@ -436,28 +436,6 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! { diag.emit() } -pub fn lookup_method_for_diagnostic<'tcx>( - tcx: TyCtxt<'tcx>, - (def_id, hir_id): (LocalDefId, hir::HirId), -) -> Option { - let root_ctxt = TypeckRootCtxt::new(tcx, def_id); - let param_env = tcx.param_env(def_id); - let fn_ctxt = FnCtxt::new(&root_ctxt, param_env, def_id); - let hir::Node::Expr(expr) = tcx.hir().hir_node(hir_id) else { - return None; - }; - let hir::ExprKind::MethodCall(segment, rcvr, _, _) = expr.kind else { - return None; - }; - let tables = tcx.typeck(def_id); - // The found `Self` type of the method call. - let possible_rcvr_ty = tables.node_type_opt(rcvr.hir_id)?; - fn_ctxt - .lookup_method_for_diagnostic(possible_rcvr_ty, segment, expr.span, expr, rcvr) - .ok() - .map(|method| method.def_id) -} - pub fn provide(providers: &mut Providers) { method::provide(providers); *providers = Providers { @@ -465,7 +443,6 @@ pub fn provide(providers: &mut Providers) { diagnostic_only_typeck, has_typeck_results, used_trait_imports, - lookup_method_for_diagnostic: lookup_method_for_diagnostic, ..*providers }; } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 394515f091f2..5ef7a20f460e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -983,9 +983,6 @@ rustc_queries! { query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } } - query lookup_method_for_diagnostic((def_id, hir_id): (LocalDefId, hir::HirId)) -> Option { - desc { |tcx| "lookup_method_for_diagnostics `{}`", tcx.def_path_str(def_id) } - } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet { desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) } From 98890be9c4572201fe2dc73dc6af70efe3071e83 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 17:37:56 -0400 Subject: [PATCH 046/114] Rebase fallout --- compiler/rustc_borrowck/src/diagnostics/region_errors.rs | 9 ++++----- .../src/infer/error_reporting/need_type_info.rs | 7 ++++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index 304d41d69417..079b0791beb2 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -26,7 +26,7 @@ use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_middle::ty::{Region, TyCtxt}; use rustc_span::symbol::{kw, Ident}; use rustc_span::Span; -use rustc_trait_selection::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_trait_selection::infer::type_variable::TypeVariableOrigin; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::{Obligation, ObligationCtxt}; @@ -1104,10 +1104,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); let closure_kind = args.as_closure().kind(); let closure_kind_ty = Ty::from_closure_kind(tcx, closure_kind); - let tupled_upvars_ty = self.infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::ClosureSynthetic, - span: closure_expr.span, - }); + let tupled_upvars_ty = self + .infcx + .next_ty_var(TypeVariableOrigin { param_def_id: None, span: closure_expr.span }); let closure_args = ty::ClosureArgs::new( tcx, ty::ClosureArgsParts { 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 6b90d6612f04..a2a38d1c507a 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 @@ -16,9 +16,10 @@ use rustc_middle::hir::nested_filter; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableValue}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; -use rustc_middle::ty::{self, InferConst}; -use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef}; -use rustc_middle::ty::{IsSuggestable, Ty, TyCtxt, TypeckResults}; +use rustc_middle::ty::{ + self, GenericArg, GenericArgKind, GenericArgsRef, InferConst, IsSuggestable, Ty, TyCtxt, + TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults, +}; use rustc_span::symbol::{sym, Ident}; use rustc_span::{BytePos, Span, DUMMY_SP}; use std::borrow::Cow; From ecef296a038772f04ed3c10530b123d68718ad20 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 6 Apr 2024 02:05:17 -0400 Subject: [PATCH 047/114] Simplify shallow resolver to just fold ty/consts --- .../src/type_check/relate_tys.rs | 2 +- .../src/infer/canonical/canonicalizer.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 166 ++++++++---------- .../rustc_infer/src/infer/relate/combine.rs | 4 +- compiler/rustc_infer/src/infer/resolve.rs | 14 +- .../src/solve/normalize.rs | 2 +- .../src/traits/coherence.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/select/candidate_assembly.rs | 6 +- .../src/traits/select/confirmation.rs | 9 +- .../src/traits/select/mod.rs | 8 +- .../rustc_trait_selection/src/traits/util.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 2 +- 13 files changed, 96 insertions(+), 125 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 78609a482ed2..1c6eccbdce75 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -437,7 +437,7 @@ impl<'bccx, 'tcx> TypeRelation<'tcx> for NllTypeRelating<'_, 'bccx, 'tcx> { a: ty::Const<'tcx>, b: ty::Const<'tcx>, ) -> RelateResult<'tcx, ty::Const<'tcx>> { - let a = self.type_checker.infcx.shallow_resolve(a); + let a = self.type_checker.infcx.shallow_resolve_const(a); assert!(!a.has_non_region_infer(), "unexpected inference var {:?}", a); assert!(!b.has_non_region_infer(), "unexpected inference var {:?}", b); diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 825c3bf82fc8..4d712e9ffd37 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -802,7 +802,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { const_var: ty::Const<'tcx>, ) -> ty::Const<'tcx> { debug_assert!( - !self.infcx.is_some_and(|infcx| const_var != infcx.shallow_resolve(const_var)) + !self.infcx.is_some_and(|infcx| const_var != infcx.shallow_resolve_const(const_var)) ); let var = self.canonical_var(info, const_var.into()); ty::Const::new_bound(self.tcx, self.binder_index, var, self.fold_ty(const_var.ty())) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f2fd50a47d51..e7c68d848b78 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1253,19 +1253,76 @@ impl<'tcx> InferCtxt<'tcx> { } } - /// Resolve any type variables found in `value` -- but only one - /// level. So, if the variable `?X` is bound to some type - /// `Foo`, then this would return `Foo` (but `?Y` may - /// itself be bound to a type). - /// - /// Useful when you only need to inspect the outermost level of - /// the type and don't care about nested types (or perhaps you - /// will be resolving them as well, e.g. in a loop). - pub fn shallow_resolve(&self, value: T) -> T - where - T: TypeFoldable>, - { - value.fold_with(&mut ShallowResolver { infcx: self }) + pub fn shallow_resolve(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Infer(v) = ty.kind() { self.fold_infer_ty(*v).unwrap_or(ty) } else { ty } + } + + // This is separate from `shallow_resolve` to keep that method small and inlinable. + #[inline(never)] + fn fold_infer_ty(&self, v: InferTy) -> Option> { + match v { + ty::TyVar(v) => { + // Not entirely obvious: if `typ` is a type variable, + // it can be resolved to an int/float variable, which + // can then be recursively resolved, hence the + // recursion. Note though that we prevent type + // variables from unifying to other type variables + // directly (though they may be embedded + // structurally), and we prevent cycles in any case, + // so this recursion should always be of very limited + // depth. + // + // Note: if these two lines are combined into one we get + // dynamic borrow errors on `self.inner`. + let known = self.inner.borrow_mut().type_variables().probe(v).known(); + known.map(|t| self.shallow_resolve(t)) + } + + ty::IntVar(v) => self + .inner + .borrow_mut() + .int_unification_table() + .probe_value(v) + .map(|v| v.to_type(self.tcx)), + + ty::FloatVar(v) => self + .inner + .borrow_mut() + .float_unification_table() + .probe_value(v) + .map(|v| v.to_type(self.tcx)), + + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => None, + } + } + + pub fn shallow_resolve_const(&self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + match ct.kind() { + ty::ConstKind::Infer(infer_ct) => match infer_ct { + InferConst::Var(vid) => self + .inner + .borrow_mut() + .const_unification_table() + .probe_value(vid) + .known() + .unwrap_or(ct), + InferConst::EffectVar(vid) => self + .inner + .borrow_mut() + .effect_unification_table() + .probe_value(vid) + .known() + .unwrap_or(ct), + InferConst::Fresh(_) => ct, + }, + ty::ConstKind::Param(_) + | ty::ConstKind::Bound(_, _) + | ty::ConstKind::Placeholder(_) + | ty::ConstKind::Unevaluated(_) + | ty::ConstKind::Value(_) + | ty::ConstKind::Error(_) + | ty::ConstKind::Expr(_) => ct, + } } pub fn root_var(&self, var: ty::TyVid) -> ty::TyVid { @@ -1782,89 +1839,6 @@ impl<'tcx> TypeFolder> for InferenceLiteralEraser<'tcx> { } } -struct ShallowResolver<'a, 'tcx> { - infcx: &'a InferCtxt<'tcx>, -} - -impl<'a, 'tcx> TypeFolder> for ShallowResolver<'a, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - /// If `ty` is a type variable of some kind, resolve it one level - /// (but do not resolve types found in the result). If `typ` is - /// not a type variable, just return it unmodified. - #[inline] - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Infer(v) = ty.kind() { self.fold_infer_ty(*v).unwrap_or(ty) } else { ty } - } - - fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - match ct.kind() { - ty::ConstKind::Infer(InferConst::Var(vid)) => self - .infcx - .inner - .borrow_mut() - .const_unification_table() - .probe_value(vid) - .known() - .unwrap_or(ct), - ty::ConstKind::Infer(InferConst::EffectVar(vid)) => self - .infcx - .inner - .borrow_mut() - .effect_unification_table() - .probe_value(vid) - .known() - .unwrap_or(ct), - _ => ct, - } - } -} - -impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { - // This is separate from `fold_ty` to keep that method small and inlinable. - #[inline(never)] - fn fold_infer_ty(&mut self, v: InferTy) -> Option> { - match v { - ty::TyVar(v) => { - // Not entirely obvious: if `typ` is a type variable, - // it can be resolved to an int/float variable, which - // can then be recursively resolved, hence the - // recursion. Note though that we prevent type - // variables from unifying to other type variables - // directly (though they may be embedded - // structurally), and we prevent cycles in any case, - // so this recursion should always be of very limited - // depth. - // - // Note: if these two lines are combined into one we get - // dynamic borrow errors on `self.inner`. - let known = self.infcx.inner.borrow_mut().type_variables().probe(v).known(); - known.map(|t| self.fold_ty(t)) - } - - ty::IntVar(v) => self - .infcx - .inner - .borrow_mut() - .int_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.infcx.tcx)), - - ty::FloatVar(v) => self - .infcx - .inner - .borrow_mut() - .float_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.infcx.tcx)), - - ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => None, - } - } -} - impl<'tcx> TypeTrace<'tcx> { pub fn span(&self) -> Span { self.cause.span diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs index 28b7db275a30..8a3125f9dedf 100644 --- a/compiler/rustc_infer/src/infer/relate/combine.rs +++ b/compiler/rustc_infer/src/infer/relate/combine.rs @@ -155,8 +155,8 @@ impl<'tcx> InferCtxt<'tcx> { return Ok(a); } - let a = self.shallow_resolve(a); - let b = self.shallow_resolve(b); + let a = self.shallow_resolve_const(a); + let b = self.shallow_resolve_const(b); // We should never have to relate the `ty` field on `Const` as it is checked elsewhere that consts have the // correct type for the generic param they are an argument for. However there have been a number of cases diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index d5999331dfab..758aac004dcf 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -12,21 +12,19 @@ use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; /// useful for printing messages etc but also required at various /// points for correctness. pub struct OpportunisticVarResolver<'a, 'tcx> { - // The shallow resolver is used to resolve inference variables at every - // level of the type. - shallow_resolver: crate::infer::ShallowResolver<'a, 'tcx>, + infcx: &'a InferCtxt<'tcx>, } impl<'a, 'tcx> OpportunisticVarResolver<'a, 'tcx> { #[inline] pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { - OpportunisticVarResolver { shallow_resolver: crate::infer::ShallowResolver { infcx } } + OpportunisticVarResolver { infcx } } } impl<'a, 'tcx> TypeFolder> for OpportunisticVarResolver<'a, 'tcx> { fn interner(&self) -> TyCtxt<'tcx> { - TypeFolder::interner(&self.shallow_resolver) + self.infcx.tcx } #[inline] @@ -34,7 +32,7 @@ impl<'a, 'tcx> TypeFolder> for OpportunisticVarResolver<'a, 'tcx> { if !t.has_non_region_infer() { t // micro-optimize -- if there is nothing in this type that this fold affects... } else { - let t = self.shallow_resolver.fold_ty(t); + let t = self.infcx.shallow_resolve(t); t.super_fold_with(self) } } @@ -43,7 +41,7 @@ impl<'a, 'tcx> TypeFolder> for OpportunisticVarResolver<'a, 'tcx> { if !ct.has_non_region_infer() { ct // micro-optimize -- if there is nothing in this const that this fold affects... } else { - let ct = self.shallow_resolver.fold_const(ct); + let ct = self.infcx.shallow_resolve_const(ct); ct.super_fold_with(self) } } @@ -160,7 +158,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for FullTypeResolver<'a, 'tcx> { if !c.has_infer() { Ok(c) // micro-optimize -- if there is nothing in this const that this fold affects... } else { - let c = self.infcx.shallow_resolve(c); + let c = self.infcx.shallow_resolve_const(c); match c.kind() { ty::ConstKind::Infer(InferConst::Var(vid)) => { return Err(FixupError::UnresolvedConst(vid)); diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 5b45e1a34e48..43f36d18cfc9 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -203,7 +203,7 @@ impl<'tcx> FallibleTypeFolder> for NormalizationFolder<'_, 'tcx> { #[instrument(level = "debug", skip(self), ret)] fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result, Self::Error> { let infcx = self.at.infcx; - debug_assert_eq!(ct, infcx.shallow_resolve(ct)); + debug_assert_eq!(ct, infcx.shallow_resolve_const(ct)); if !ct.has_aliases() { return Ok(ct); } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 77eaa4fd03eb..36028b516591 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -501,7 +501,7 @@ fn plug_infer_with_placeholders<'tcx>( } fn visit_const(&mut self, ct: ty::Const<'tcx>) { - let ct = self.infcx.shallow_resolve(ct); + let ct = self.infcx.shallow_resolve_const(ct); if ct.is_ct_infer() { let Ok(InferOk { value: (), obligations }) = self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq( diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 98d5b466cd00..8f5a30c436d3 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -162,7 +162,7 @@ fn pred_known_to_hold_modulo_regions<'tcx>( let errors = ocx.select_all_or_error(); match errors.as_slice() { // Only known to hold if we did no inference. - [] => infcx.shallow_resolve(goal) == goal, + [] => infcx.resolve_vars_if_possible(goal) == goal, errors => { debug!(?errors); 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 974e5ef0e166..c544a0b790fa 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -1165,8 +1165,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } - let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); - match self_ty.skip_binder().kind() { + let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder()); + match self_ty.kind() { ty::Alias(..) | ty::Dynamic(..) | ty::Error(_) @@ -1317,7 +1317,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); + let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty()); match self_ty.skip_binder().kind() { ty::FnPtr(_) => candidates.vec.push(BuiltinCandidate { has_nested: false }), diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 716b9a49ab54..4fa2455c42de 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -157,10 +157,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result>, SelectionError<'tcx>> { let tcx = self.tcx(); - let trait_predicate = self.infcx.shallow_resolve(obligation.predicate); let placeholder_trait_predicate = - self.infcx.enter_forall_and_leak_universe(trait_predicate).trait_ref; - let placeholder_self_ty = placeholder_trait_predicate.self_ty(); + self.infcx.enter_forall_and_leak_universe(obligation.predicate).trait_ref; + let placeholder_self_ty = self.infcx.shallow_resolve(placeholder_trait_predicate.self_ty()); let candidate_predicate = self .for_each_item_bound( placeholder_self_ty, @@ -422,7 +421,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result>, SelectionError<'tcx>> { debug!(?obligation, "confirm_auto_impl_candidate"); - let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty()); + let self_ty = obligation.predicate.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty)); let types = self.constituent_types_for_ty(self_ty)?; Ok(self.vtable_auto_impl(obligation, obligation.predicate.def_id(), types)) } @@ -1378,7 +1377,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let drop_trait = self.tcx().require_lang_item(LangItem::Drop, None); let tcx = self.tcx(); - let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); + let self_ty = obligation.self_ty().map_bound(|ty| self.infcx.shallow_resolve(ty)); let mut nested = vec![]; let cause = obligation.derived_cause(BuiltinDerivedObligation); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index e363119393ad..10370c7898b0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -571,7 +571,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { )?; // If the predicate has done any inference, then downgrade the // result to ambiguous. - if this.infcx.shallow_resolve(goal) != goal { + if this.infcx.resolve_vars_if_possible(goal) != goal { result = result.max(EvaluatedToAmbig); } Ok(result) @@ -1774,9 +1774,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // that means that we must have newly inferred something about the GAT. // We should give up in that case. if !generics.params.is_empty() - && obligation.predicate.args[generics.parent_count..] - .iter() - .any(|&p| p.has_non_region_infer() && self.infcx.shallow_resolve(p) != p) + && obligation.predicate.args[generics.parent_count..].iter().any(|&p| { + p.has_non_region_infer() && self.infcx.resolve_vars_if_possible(p) != p + }) { ProjectionMatchesProjection::Ambiguous } else { diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index d29fc7921bcb..a8ca7d164a09 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -649,7 +649,7 @@ impl<'tcx> TypeFolder> for PlaceholderReplacer<'_, 'tcx> { } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - let ct = self.infcx.shallow_resolve(ct); + let ct = self.infcx.shallow_resolve_const(ct); if let ty::ConstKind::Placeholder(p) = ct.kind() { let replace_var = self.mapped_consts.get(&p); match replace_var { diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 5553490542b7..f1c24b6adc1a 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -44,7 +44,7 @@ pub fn obligations<'tcx>( GenericArgKind::Const(ct) => { match ct.kind() { ty::ConstKind::Infer(_) => { - let resolved = infcx.shallow_resolve(ct); + let resolved = infcx.shallow_resolve_const(ct); if resolved == ct { // No progress. return None; From 31052bb8a493acbecbdd38860dc20c3c9903069a Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 6 Apr 2024 14:41:09 -0700 Subject: [PATCH 048/114] Add URL and crate_name to test cases --- tests/rustdoc/issue-56701.rs | 1 + tests/rustdoc/issue-56822.rs | 5 ++++- tests/rustdoc/issue-57180.rs | 1 + tests/rustdoc/issue-60482.rs | 1 + tests/rustdoc/issue-60726.rs | 5 ++++- tests/rustdoc/issue-61592.rs | 6 ++++-- tests/rustdoc/issue-67851-both.rs | 6 ++++-- tests/rustdoc/issue-67851-hidden.rs | 6 ++++-- tests/rustdoc/issue-67851-neither.rs | 7 +++++-- tests/rustdoc/issue-67851-private.rs | 6 ++++-- tests/rustdoc/issue-72340.rs | 2 ++ tests/rustdoc/issue-74083.rs | 5 ++++- tests/rustdoc/issue-75588.rs | 1 + tests/rustdoc/issue-76501.rs | 7 +++++-- tests/rustdoc/issue-78673.rs | 1 + tests/rustdoc/issue-78701.rs | 1 + tests/rustdoc/issue-79201.rs | 5 ++++- 17 files changed, 50 insertions(+), 16 deletions(-) diff --git a/tests/rustdoc/issue-56701.rs b/tests/rustdoc/issue-56701.rs index ba00743fcd12..d4e94323846d 100644 --- a/tests/rustdoc/issue-56701.rs +++ b/tests/rustdoc/issue-56701.rs @@ -1,4 +1,5 @@ // This shouldn't cause a stack overflow when rustdoc is run +// https://github.com/rust-lang/rust/issues/56701 use std::ops::Deref; use std::ops::DerefMut; diff --git a/tests/rustdoc/issue-56822.rs b/tests/rustdoc/issue-56822.rs index c9a74335702d..315b20ddd704 100644 --- a/tests/rustdoc/issue-56822.rs +++ b/tests/rustdoc/issue-56822.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/56822 +#![crate_name="foo"] + struct Wrapper(T); trait MyTrait { @@ -16,7 +19,7 @@ impl<'a, T> MyTrait for Inner<'a, T> { type Output = &'a T; } -// @has issue_56822/struct.Parser.html +// @has foo/struct.Parser.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \ // "impl<'a> Send for Parser<'a>" pub struct Parser<'a> { diff --git a/tests/rustdoc/issue-57180.rs b/tests/rustdoc/issue-57180.rs index aa6b77583993..264b53cbd9ad 100644 --- a/tests/rustdoc/issue-57180.rs +++ b/tests/rustdoc/issue-57180.rs @@ -1,4 +1,5 @@ //@ aux-build:issue-57180.rs +// https://github.com/rust-lang/rust/issues/57180 extern crate issue_57180; use issue_57180::Trait; diff --git a/tests/rustdoc/issue-60482.rs b/tests/rustdoc/issue-60482.rs index 0fd1daa746d4..e40af12e0225 100644 --- a/tests/rustdoc/issue-60482.rs +++ b/tests/rustdoc/issue-60482.rs @@ -1,4 +1,5 @@ // This code caused a panic in `pulldown-cmark` 0.4.1. +// https://github.com/rust-lang/rust/issues/60482 pub const BASIC_UNICODE: bool = true; diff --git a/tests/rustdoc/issue-60726.rs b/tests/rustdoc/issue-60726.rs index e337e4a4f7ad..ea10aee58e45 100644 --- a/tests/rustdoc/issue-60726.rs +++ b/tests/rustdoc/issue-60726.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/60726 +#![crate_name="foo"] + use std::marker::PhantomData; pub struct True; @@ -25,7 +28,7 @@ where I:InterfaceType {} -// @has issue_60726/struct.IntoIter.html +// @has foo/struct.IntoIter.html // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \ // "impl !Send for IntoIter" // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \ diff --git a/tests/rustdoc/issue-61592.rs b/tests/rustdoc/issue-61592.rs index 068310fa6a33..d403f2cc7ab1 100644 --- a/tests/rustdoc/issue-61592.rs +++ b/tests/rustdoc/issue-61592.rs @@ -1,14 +1,16 @@ //@ aux-build:issue-61592.rs +// https://github.com/rust-lang/rust/issues/61592 +#![crate_name="bar"] extern crate foo; -// @has issue_61592/index.html +// @has bar/index.html // @has - '//a[@href="#reexports"]' 'Re-exports' // @has - '//code' 'pub use foo::FooTrait as _;' // @!has - '//a[@href="trait._.html"]' '' pub use foo::FooTrait as _; -// @has issue_61592/index.html +// @has bar/index.html // @has - '//a[@href="#reexports"]' 'Re-exports' // @has - '//code' 'pub use foo::FooStruct as _;' // @!has - '//a[@href="struct._.html"]' '' diff --git a/tests/rustdoc/issue-67851-both.rs b/tests/rustdoc/issue-67851-both.rs index ed59652838e1..e6eb6a68ffdb 100644 --- a/tests/rustdoc/issue-67851-both.rs +++ b/tests/rustdoc/issue-67851-both.rs @@ -1,8 +1,10 @@ //@ compile-flags: -Zunstable-options --document-private-items --document-hidden-items +// https://github.com/rust-lang/rust/issues/67851 +#![crate_name="foo"] -// @has issue_67851_both/struct.Hidden.html +// @has foo/struct.Hidden.html #[doc(hidden)] pub struct Hidden; -// @has issue_67851_both/struct.Private.html +// @has foo/struct.Private.html struct Private; diff --git a/tests/rustdoc/issue-67851-hidden.rs b/tests/rustdoc/issue-67851-hidden.rs index 6d532adc06fd..9767f9c84f9f 100644 --- a/tests/rustdoc/issue-67851-hidden.rs +++ b/tests/rustdoc/issue-67851-hidden.rs @@ -1,8 +1,10 @@ //@ compile-flags: -Zunstable-options --document-hidden-items +// https://github.com/rust-lang/rust/issues/67851 +#![crate_name="foo"] -// @has issue_67851_hidden/struct.Hidden.html +// @has foo/struct.Hidden.html #[doc(hidden)] pub struct Hidden; -// @!has issue_67851_hidden/struct.Private.html +// @!has foo/struct.Private.html struct Private; diff --git a/tests/rustdoc/issue-67851-neither.rs b/tests/rustdoc/issue-67851-neither.rs index 4e3cd8328538..6c6e84da43d5 100644 --- a/tests/rustdoc/issue-67851-neither.rs +++ b/tests/rustdoc/issue-67851-neither.rs @@ -1,6 +1,9 @@ -// @!has issue_67851_neither/struct.Hidden.html +// https://github.com/rust-lang/rust/issues/67851 +#![crate_name="foo"] + +// @!has foo/struct.Hidden.html #[doc(hidden)] pub struct Hidden; -// @!has issue_67851_neither/struct.Private.html +// @!has foo/struct.Private.html struct Private; diff --git a/tests/rustdoc/issue-67851-private.rs b/tests/rustdoc/issue-67851-private.rs index ead7ddf397f8..4aa39f5b789c 100644 --- a/tests/rustdoc/issue-67851-private.rs +++ b/tests/rustdoc/issue-67851-private.rs @@ -1,8 +1,10 @@ //@ compile-flags: --document-private-items +// https://github.com/rust-lang/rust/issues/67851 +#![crate_name="foo"] -// @!has issue_67851_private/struct.Hidden.html +// @!has foo/struct.Hidden.html #[doc(hidden)] pub struct Hidden; -// @has issue_67851_private/struct.Private.html +// @has foo/struct.Private.html struct Private; diff --git a/tests/rustdoc/issue-72340.rs b/tests/rustdoc/issue-72340.rs index 64044cfe9472..880a308f9ab1 100644 --- a/tests/rustdoc/issue-72340.rs +++ b/tests/rustdoc/issue-72340.rs @@ -1,3 +1,5 @@ +// https://github.com/rust-lang/rust/issues/72340 + #![crate_name = "foo"] pub struct Body; diff --git a/tests/rustdoc/issue-74083.rs b/tests/rustdoc/issue-74083.rs index c7f5d7eaa585..0bed7e2fb628 100644 --- a/tests/rustdoc/issue-74083.rs +++ b/tests/rustdoc/issue-74083.rs @@ -1,3 +1,6 @@ +// https://github.com/rust-lang/rust/issues/74083 +#![crate_name="foo"] + use std::ops::Deref; pub struct Foo; @@ -6,7 +9,7 @@ impl Foo { pub fn foo(&mut self) {} } -// @has issue_74083/struct.Bar.html +// @has foo/struct.Bar.html // @!has - '//div[@class="sidebar-links"]/a[@href="#method.foo"]' 'foo' pub struct Bar { foo: Foo, diff --git a/tests/rustdoc/issue-75588.rs b/tests/rustdoc/issue-75588.rs index 4f790994b419..befddf6b7889 100644 --- a/tests/rustdoc/issue-75588.rs +++ b/tests/rustdoc/issue-75588.rs @@ -2,6 +2,7 @@ //@ aux-build:real_gimli.rs // Ensure unstably exported traits have their Implementors sections. +// https://github.com/rust-lang/rust/issues/75588 #![crate_name = "foo"] #![feature(extremely_unstable_foo)] diff --git a/tests/rustdoc/issue-76501.rs b/tests/rustdoc/issue-76501.rs index 5caea0ec9924..4a7284f98512 100644 --- a/tests/rustdoc/issue-76501.rs +++ b/tests/rustdoc/issue-76501.rs @@ -1,4 +1,7 @@ -// @has 'issue_76501/fn.bloop.html' '//pre' 'pub const fn bloop() -> i32' +// https://github.com/rust-lang/rust/issues/76501 +#![crate_name="foo"] + +// @has 'foo/fn.bloop.html' '//pre' 'pub const fn bloop() -> i32' /// A useless function that always returns 1. pub const fn bloop() -> i32 { 1 @@ -8,7 +11,7 @@ pub const fn bloop() -> i32 { pub struct Struct {} impl Struct { - // @has 'issue_76501/struct.Struct.html' '//*[@class="method"]' \ + // @has 'foo/struct.Struct.html' '//*[@class="method"]' \ // 'pub const fn blurp() -> i32' /// A useless function that always returns 1. pub const fn blurp() -> i32 { diff --git a/tests/rustdoc/issue-78673.rs b/tests/rustdoc/issue-78673.rs index d09141c32047..d7ceef2c0577 100644 --- a/tests/rustdoc/issue-78673.rs +++ b/tests/rustdoc/issue-78673.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/78673 #![crate_name = "issue_78673"] pub trait Something {} diff --git a/tests/rustdoc/issue-78701.rs b/tests/rustdoc/issue-78701.rs index 3f1638d5ffc4..89b7ccb52229 100644 --- a/tests/rustdoc/issue-78701.rs +++ b/tests/rustdoc/issue-78701.rs @@ -1,3 +1,4 @@ +// https://github.com/rust-lang/rust/issues/78701 #![crate_name = "foo"] // This test ensures that if a blanket impl has the same ID as another impl, it'll diff --git a/tests/rustdoc/issue-79201.rs b/tests/rustdoc/issue-79201.rs index f95d79cd493e..76260c4a502b 100644 --- a/tests/rustdoc/issue-79201.rs +++ b/tests/rustdoc/issue-79201.rs @@ -1,6 +1,9 @@ +// https://github.com/rust-lang/rust/issues/79201 +#![crate_name="foo"] + #![feature(doc_cfg)] -// @has 'issue_79201/trait.Foo.html' +// @has 'foo/trait.Foo.html' // @count - '//*[@class="stab portability"]' 6 // @matches - '//*[@class="stab portability"]' 'crate feature foo-root' // @matches - '//*[@class="stab portability"]' 'crate feature foo-public-mod' From 381a0e3cb0a71cbef439be974135562e64d40f38 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 6 Apr 2024 14:41:59 -0700 Subject: [PATCH 049/114] Move ice tests to rustdoc-ui --- tests/{rustdoc => rustdoc-ui}/auxiliary/issue-73061.rs | 0 .../issue-56701.rs => rustdoc-ui/ice-blanket-impl-56701.rs} | 1 + .../ice-cross-crate-opaque-assoc-type-73061.rs} | 3 ++- 3 files changed, 3 insertions(+), 1 deletion(-) rename tests/{rustdoc => rustdoc-ui}/auxiliary/issue-73061.rs (100%) rename tests/{rustdoc/issue-56701.rs => rustdoc-ui/ice-blanket-impl-56701.rs} (98%) rename tests/{rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs => rustdoc-ui/ice-cross-crate-opaque-assoc-type-73061.rs} (71%) diff --git a/tests/rustdoc/auxiliary/issue-73061.rs b/tests/rustdoc-ui/auxiliary/issue-73061.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-73061.rs rename to tests/rustdoc-ui/auxiliary/issue-73061.rs diff --git a/tests/rustdoc/issue-56701.rs b/tests/rustdoc-ui/ice-blanket-impl-56701.rs similarity index 98% rename from tests/rustdoc/issue-56701.rs rename to tests/rustdoc-ui/ice-blanket-impl-56701.rs index d4e94323846d..13b0fc9032a8 100644 --- a/tests/rustdoc/issue-56701.rs +++ b/tests/rustdoc-ui/ice-blanket-impl-56701.rs @@ -1,3 +1,4 @@ +//@ check-pass // This shouldn't cause a stack overflow when rustdoc is run // https://github.com/rust-lang/rust/issues/56701 diff --git a/tests/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs b/tests/rustdoc-ui/ice-cross-crate-opaque-assoc-type-73061.rs similarity index 71% rename from tests/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs rename to tests/rustdoc-ui/ice-cross-crate-opaque-assoc-type-73061.rs index e16aeac65cc5..1434bef49e0e 100644 --- a/tests/rustdoc/issue-73061-cross-crate-opaque-assoc-type.rs +++ b/tests/rustdoc-ui/ice-cross-crate-opaque-assoc-type-73061.rs @@ -1,5 +1,6 @@ -// Regression test for ICE #73061 +// Regression test for ICE https://github.com/rust-lang/rust/issues/73061 +//@ check-pass //@ aux-build:issue-73061.rs extern crate issue_73061; From 9a577e81c38e7ba88089c68c3e37d36a9816717b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 6 Apr 2024 14:58:34 -0700 Subject: [PATCH 050/114] rustdoc: rename `issue-\d+.rs` tests to have meaningful names --- tests/rustdoc/{issue-56822.rs => auto-trait-lifetimes-56822.rs} | 0 tests/rustdoc/{issue-78673.rs => blanket-impl-78673.rs} | 0 tests/rustdoc/{issue-76501.rs => const-fn-76501.rs} | 0 .../{issue-79201.rs => doc-cfg-inherit-from-module-79201.rs} | 0 .../{issue-67851-both.rs => doc-hidden-private-67851-both.rs} | 0 .../{issue-67851-hidden.rs => doc-hidden-private-67851-hidden.rs} | 0 ...issue-67851-neither.rs => doc-hidden-private-67851-neither.rs} | 0 ...issue-67851-private.rs => doc-hidden-private-67851-private.rs} | 0 ...licated-glob-reexport.rs => duplicated-glob-reexport-60522.rs} | 0 ...sue-74083.rs => hide-mut-methods-if-no-derefmut-impl-74083.rs} | 0 tests/rustdoc/{issue-57180.rs => ice-import-crate-57180.rs} | 0 tests/rustdoc/{issue-75588.rs => implementors-unstable-75588.rs} | 0 .../{issue-72340.rs => intra-doc-link-method-trait-impl-72340.rs} | 0 tests/rustdoc/{issue-60482.rs => markdown-60482.rs} | 0 tests/rustdoc/{issue-60726.rs => send-impl-conditional-60726.rs} | 0 .../{issue-78701.rs => sidebar-trait-impl-disambiguate-78701.rs} | 0 tests/rustdoc/{issue-61592.rs => underscore-import-61592.rs} | 0 17 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{issue-56822.rs => auto-trait-lifetimes-56822.rs} (100%) rename tests/rustdoc/{issue-78673.rs => blanket-impl-78673.rs} (100%) rename tests/rustdoc/{issue-76501.rs => const-fn-76501.rs} (100%) rename tests/rustdoc/{issue-79201.rs => doc-cfg-inherit-from-module-79201.rs} (100%) rename tests/rustdoc/{issue-67851-both.rs => doc-hidden-private-67851-both.rs} (100%) rename tests/rustdoc/{issue-67851-hidden.rs => doc-hidden-private-67851-hidden.rs} (100%) rename tests/rustdoc/{issue-67851-neither.rs => doc-hidden-private-67851-neither.rs} (100%) rename tests/rustdoc/{issue-67851-private.rs => doc-hidden-private-67851-private.rs} (100%) rename tests/rustdoc/{issue-60522-duplicated-glob-reexport.rs => duplicated-glob-reexport-60522.rs} (100%) rename tests/rustdoc/{issue-74083.rs => hide-mut-methods-if-no-derefmut-impl-74083.rs} (100%) rename tests/rustdoc/{issue-57180.rs => ice-import-crate-57180.rs} (100%) rename tests/rustdoc/{issue-75588.rs => implementors-unstable-75588.rs} (100%) rename tests/rustdoc/{issue-72340.rs => intra-doc-link-method-trait-impl-72340.rs} (100%) rename tests/rustdoc/{issue-60482.rs => markdown-60482.rs} (100%) rename tests/rustdoc/{issue-60726.rs => send-impl-conditional-60726.rs} (100%) rename tests/rustdoc/{issue-78701.rs => sidebar-trait-impl-disambiguate-78701.rs} (100%) rename tests/rustdoc/{issue-61592.rs => underscore-import-61592.rs} (100%) diff --git a/tests/rustdoc/issue-56822.rs b/tests/rustdoc/auto-trait-lifetimes-56822.rs similarity index 100% rename from tests/rustdoc/issue-56822.rs rename to tests/rustdoc/auto-trait-lifetimes-56822.rs diff --git a/tests/rustdoc/issue-78673.rs b/tests/rustdoc/blanket-impl-78673.rs similarity index 100% rename from tests/rustdoc/issue-78673.rs rename to tests/rustdoc/blanket-impl-78673.rs diff --git a/tests/rustdoc/issue-76501.rs b/tests/rustdoc/const-fn-76501.rs similarity index 100% rename from tests/rustdoc/issue-76501.rs rename to tests/rustdoc/const-fn-76501.rs diff --git a/tests/rustdoc/issue-79201.rs b/tests/rustdoc/doc-cfg-inherit-from-module-79201.rs similarity index 100% rename from tests/rustdoc/issue-79201.rs rename to tests/rustdoc/doc-cfg-inherit-from-module-79201.rs diff --git a/tests/rustdoc/issue-67851-both.rs b/tests/rustdoc/doc-hidden-private-67851-both.rs similarity index 100% rename from tests/rustdoc/issue-67851-both.rs rename to tests/rustdoc/doc-hidden-private-67851-both.rs diff --git a/tests/rustdoc/issue-67851-hidden.rs b/tests/rustdoc/doc-hidden-private-67851-hidden.rs similarity index 100% rename from tests/rustdoc/issue-67851-hidden.rs rename to tests/rustdoc/doc-hidden-private-67851-hidden.rs diff --git a/tests/rustdoc/issue-67851-neither.rs b/tests/rustdoc/doc-hidden-private-67851-neither.rs similarity index 100% rename from tests/rustdoc/issue-67851-neither.rs rename to tests/rustdoc/doc-hidden-private-67851-neither.rs diff --git a/tests/rustdoc/issue-67851-private.rs b/tests/rustdoc/doc-hidden-private-67851-private.rs similarity index 100% rename from tests/rustdoc/issue-67851-private.rs rename to tests/rustdoc/doc-hidden-private-67851-private.rs diff --git a/tests/rustdoc/issue-60522-duplicated-glob-reexport.rs b/tests/rustdoc/duplicated-glob-reexport-60522.rs similarity index 100% rename from tests/rustdoc/issue-60522-duplicated-glob-reexport.rs rename to tests/rustdoc/duplicated-glob-reexport-60522.rs diff --git a/tests/rustdoc/issue-74083.rs b/tests/rustdoc/hide-mut-methods-if-no-derefmut-impl-74083.rs similarity index 100% rename from tests/rustdoc/issue-74083.rs rename to tests/rustdoc/hide-mut-methods-if-no-derefmut-impl-74083.rs diff --git a/tests/rustdoc/issue-57180.rs b/tests/rustdoc/ice-import-crate-57180.rs similarity index 100% rename from tests/rustdoc/issue-57180.rs rename to tests/rustdoc/ice-import-crate-57180.rs diff --git a/tests/rustdoc/issue-75588.rs b/tests/rustdoc/implementors-unstable-75588.rs similarity index 100% rename from tests/rustdoc/issue-75588.rs rename to tests/rustdoc/implementors-unstable-75588.rs diff --git a/tests/rustdoc/issue-72340.rs b/tests/rustdoc/intra-doc-link-method-trait-impl-72340.rs similarity index 100% rename from tests/rustdoc/issue-72340.rs rename to tests/rustdoc/intra-doc-link-method-trait-impl-72340.rs diff --git a/tests/rustdoc/issue-60482.rs b/tests/rustdoc/markdown-60482.rs similarity index 100% rename from tests/rustdoc/issue-60482.rs rename to tests/rustdoc/markdown-60482.rs diff --git a/tests/rustdoc/issue-60726.rs b/tests/rustdoc/send-impl-conditional-60726.rs similarity index 100% rename from tests/rustdoc/issue-60726.rs rename to tests/rustdoc/send-impl-conditional-60726.rs diff --git a/tests/rustdoc/issue-78701.rs b/tests/rustdoc/sidebar-trait-impl-disambiguate-78701.rs similarity index 100% rename from tests/rustdoc/issue-78701.rs rename to tests/rustdoc/sidebar-trait-impl-disambiguate-78701.rs diff --git a/tests/rustdoc/issue-61592.rs b/tests/rustdoc/underscore-import-61592.rs similarity index 100% rename from tests/rustdoc/issue-61592.rs rename to tests/rustdoc/underscore-import-61592.rs From ecbe327e71f71eeb069fba8919391471f18a573e Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Mon, 15 Apr 2024 13:49:50 -0700 Subject: [PATCH 051/114] rustdoc: move tests into applicable subdirectories --- tests/rustdoc/{ => inline_cross}/auxiliary/issue-57180.rs | 0 tests/rustdoc/{ => inline_cross}/ice-import-crate-57180.rs | 0 tests/rustdoc/{ => synthetic_auto}/auto-trait-lifetimes-56822.rs | 0 tests/rustdoc/{ => synthetic_auto}/send-impl-conditional-60726.rs | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => inline_cross}/auxiliary/issue-57180.rs (100%) rename tests/rustdoc/{ => inline_cross}/ice-import-crate-57180.rs (100%) rename tests/rustdoc/{ => synthetic_auto}/auto-trait-lifetimes-56822.rs (100%) rename tests/rustdoc/{ => synthetic_auto}/send-impl-conditional-60726.rs (100%) diff --git a/tests/rustdoc/auxiliary/issue-57180.rs b/tests/rustdoc/inline_cross/auxiliary/issue-57180.rs similarity index 100% rename from tests/rustdoc/auxiliary/issue-57180.rs rename to tests/rustdoc/inline_cross/auxiliary/issue-57180.rs diff --git a/tests/rustdoc/ice-import-crate-57180.rs b/tests/rustdoc/inline_cross/ice-import-crate-57180.rs similarity index 100% rename from tests/rustdoc/ice-import-crate-57180.rs rename to tests/rustdoc/inline_cross/ice-import-crate-57180.rs diff --git a/tests/rustdoc/auto-trait-lifetimes-56822.rs b/tests/rustdoc/synthetic_auto/auto-trait-lifetimes-56822.rs similarity index 100% rename from tests/rustdoc/auto-trait-lifetimes-56822.rs rename to tests/rustdoc/synthetic_auto/auto-trait-lifetimes-56822.rs diff --git a/tests/rustdoc/send-impl-conditional-60726.rs b/tests/rustdoc/synthetic_auto/send-impl-conditional-60726.rs similarity index 100% rename from tests/rustdoc/send-impl-conditional-60726.rs rename to tests/rustdoc/synthetic_auto/send-impl-conditional-60726.rs From 619e0441784126defd42454ec1949e0a4dd0e4fa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 14 Apr 2024 10:26:59 -0400 Subject: [PATCH 052/114] Fix pretty hir for anon consts in diagnostics --- Cargo.lock | 1 + compiler/rustc_driver_impl/src/pretty.rs | 19 +------------------ compiler/rustc_hir_analysis/src/check/errs.rs | 8 ++++---- compiler/rustc_hir_pretty/src/lib.rs | 16 ++++++---------- compiler/rustc_hir_typeck/src/_match.rs | 2 +- compiler/rustc_hir_typeck/src/callee.rs | 3 ++- compiler/rustc_hir_typeck/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 6 +++--- compiler/rustc_middle/Cargo.toml | 1 + compiler/rustc_middle/src/hir/map/mod.rs | 7 +++++++ .../consts/value-suggestion-ice-123906.stderr | 2 +- ...dings-in-pattern-with-ty-err-doesnt-ice.rs | 2 +- ...s-in-pattern-with-ty-err-doesnt-ice.stderr | 4 +++- 13 files changed, 32 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f26dd7c43cf..9a414c3ef61a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4278,6 +4278,7 @@ dependencies = [ "rustc_fluent_macro", "rustc_graphviz", "rustc_hir", + "rustc_hir_pretty", "rustc_index", "rustc_macros", "rustc_query_system", diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index c0c6201f73d4..40f6f7649937 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -24,20 +24,6 @@ struct AstNoAnn; impl pprust_ast::PpAnn for AstNoAnn {} -struct HirNoAnn<'tcx> { - tcx: TyCtxt<'tcx>, -} - -impl<'tcx> pprust_hir::PpAnn for HirNoAnn<'tcx> { - fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { - pprust_hir::PpAnn::nested( - &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>), - state, - nested, - ) - } -} - struct AstIdentifiedAnn; impl pprust_ast::PpAnn for AstIdentifiedAnn { @@ -300,10 +286,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { ) }; match s { - PpHirMode::Normal => { - let annotation = HirNoAnn { tcx }; - f(&annotation) - } + PpHirMode::Normal => f(&tcx), PpHirMode::Identified => { let annotation = HirIdentifiedAnn { tcx }; f(&annotation) diff --git a/compiler/rustc_hir_analysis/src/check/errs.rs b/compiler/rustc_hir_analysis/src/check/errs.rs index 548f9b0810fa..a49626eed35a 100644 --- a/compiler/rustc_hir_analysis/src/check/errs.rs +++ b/compiler/rustc_hir_analysis/src/check/errs.rs @@ -12,7 +12,7 @@ pub fn maybe_expr_static_mut(tcx: TyCtxt<'_>, expr: hir::Expr<'_>) { let hir_id = expr.hir_id; if let hir::ExprKind::AddrOf(borrow_kind, m, expr) = expr.kind && matches!(borrow_kind, hir::BorrowKind::Ref) - && let Some(var) = is_path_static_mut(*expr) + && let Some(var) = path_if_static_mut(tcx, expr) { handle_static_mut_ref(tcx, span, var, span.edition().at_least_rust_2024(), m, hir_id); } @@ -24,7 +24,7 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) { && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind && let hir::ByRef::Yes(rmutbl) = ba.0 && let Some(init) = loc.init - && let Some(var) = is_path_static_mut(*init) + && let Some(var) = path_if_static_mut(tcx, init) { handle_static_mut_ref( tcx, @@ -37,13 +37,13 @@ pub fn maybe_stmt_static_mut(tcx: TyCtxt<'_>, stmt: hir::Stmt<'_>) { } } -fn is_path_static_mut(expr: hir::Expr<'_>) -> Option { +fn path_if_static_mut(tcx: TyCtxt<'_>, expr: &hir::Expr<'_>) -> Option { if let hir::ExprKind::Path(qpath) = expr.kind && let hir::QPath::Resolved(_, path) = qpath && let hir::def::Res::Def(def_kind, _) = path.res && let hir::def::DefKind::Static { mutability: Mutability::Mut, nested: false } = def_kind { - return Some(qpath_to_string(&qpath)); + return Some(qpath_to_string(&tcx, &qpath)); } None } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 39312614c1b1..151e4a368499 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -49,10 +49,6 @@ pub trait PpAnn { fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} } -pub struct NoAnn; - -impl PpAnn for NoAnn {} - impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { fn nested(&self, state: &mut State<'_>, nested: Nested) { match nested { @@ -190,16 +186,16 @@ where printer.s.eof() } -pub fn ty_to_string(ty: &hir::Ty<'_>) -> String { - to_string(&NoAnn, |s| s.print_type(ty)) +pub fn ty_to_string(ann: &dyn PpAnn, ty: &hir::Ty<'_>) -> String { + to_string(ann, |s| s.print_type(ty)) } -pub fn qpath_to_string(segment: &hir::QPath<'_>) -> String { - to_string(&NoAnn, |s| s.print_qpath(segment, false)) +pub fn qpath_to_string(ann: &dyn PpAnn, segment: &hir::QPath<'_>) -> String { + to_string(ann, |s| s.print_qpath(segment, false)) } -pub fn pat_to_string(pat: &hir::Pat<'_>) -> String { - to_string(&NoAnn, |s| s.print_pat(pat)) +pub fn pat_to_string(ann: &dyn PpAnn, pat: &hir::Pat<'_>) -> String { + to_string(ann, |s| s.print_pat(pat)) } impl<'a> State<'a> { diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 2a2fd0a41a62..01092a8a94e5 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -395,7 +395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return self.get_fn_decl(hir_id).map(|(_, fn_decl, _)| { let (ty, span) = match fn_decl.output { hir::FnRetTy::DefaultReturn(span) => ("()".to_string(), span), - hir::FnRetTy::Return(ty) => (ty_to_string(ty), ty.span), + hir::FnRetTy::Return(ty) => (ty_to_string(&self.tcx, ty), ty.span), }; (span, format!("expected `{ty}` because of this return type")) }); diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index aa94632b2b07..8f8ca1a12e58 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -724,7 +724,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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))); + unit_variant = + Some((removal_span, descr, rustc_hir_pretty::qpath_to_string(&self.tcx, qpath))); } let callee_ty = self.resolve_vars_if_possible(callee_ty); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 476df9ae793f..a159afbb3d8b 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -374,7 +374,7 @@ fn report_unexpected_variant_res( Res::Def(DefKind::Variant, _) => "struct variant", _ => res.descr(), }; - let path_str = rustc_hir_pretty::qpath_to_string(qpath); + let path_str = rustc_hir_pretty::qpath_to_string(&tcx, qpath); let err = tcx .dcx() .struct_span_err(span, format!("expected {expected}, found {res_descr} `{path_str}`")) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index bb47f8dfba46..6981e0dceca1 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1561,7 +1561,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand); if has_shorthand_field_name { - let path = rustc_hir_pretty::qpath_to_string(qpath); + let path = rustc_hir_pretty::qpath_to_string(&self.tcx, qpath); let mut err = struct_span_code_err!( self.dcx(), pat.span, @@ -1743,7 +1743,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; } - let path = rustc_hir_pretty::qpath_to_string(qpath); + let path = rustc_hir_pretty::qpath_to_string(&self.tcx, qpath); let mut err = struct_span_code_err!( self.dcx(), pat.span, @@ -1793,7 +1793,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { f } } - Err(_) => rustc_hir_pretty::pat_to_string(field.pat), + Err(_) => rustc_hir_pretty::pat_to_string(&self.tcx, field.pat), } }) .collect::>() diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 6c3ff237d598..d1cdabc293dd 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -25,6 +25,7 @@ rustc_feature = { path = "../rustc_feature" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } +rustc_hir_pretty = { path = "../rustc_hir_pretty" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_query_system = { path = "../rustc_query_system" } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 72f849b534a8..399bbf166e60 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -13,6 +13,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_hir::intravisit::Visitor; use rustc_hir::*; +use rustc_hir_pretty as pprust_hir; use rustc_middle::hir::nested_filter; use rustc_span::def_id::StableCrateId; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -999,6 +1000,12 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> { } } +impl<'tcx> pprust_hir::PpAnn for TyCtxt<'tcx> { + fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { + pprust_hir::PpAnn::nested(&(&self.hir() as &dyn intravisit::Map<'_>), state, nested) + } +} + pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { let krate = tcx.hir_crate(()); let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash"); diff --git a/tests/ui/consts/value-suggestion-ice-123906.stderr b/tests/ui/consts/value-suggestion-ice-123906.stderr index 8e2c316400d6..779a40e24509 100644 --- a/tests/ui/consts/value-suggestion-ice-123906.stderr +++ b/tests/ui/consts/value-suggestion-ice-123906.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/value-suggestion-ice-123906.rs:3:9 | LL | fn as_chunks() -> [u8; N] { - | ------- expected `[u8; ]` because of this return type + | ------- expected `[u8; N]` because of this return type LL | loop { | ---- this loop is expected to be of type `[u8; N]` LL | break; diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs index 5c96c653df52..196da30b8647 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs @@ -3,5 +3,5 @@ fn main() { //~^ ERROR expected a pattern, found an expression //~| ERROR cannot find type `T` in this scope //~| ERROR const and type arguments are not allowed on builtin type `str` -//~| ERROR expected unit struct, unit variant or constant, found associated function `str<, T>::as_bytes` +//~| ERROR expected unit struct, unit variant or constant, found associated function `str< } diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr index d62c019a1e19..8df0613695be 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr @@ -24,7 +24,9 @@ LL - let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; LL + let str::as_bytes; | -error[E0533]: expected unit struct, unit variant or constant, found associated function `str<, T>::as_bytes` +error[E0533]: expected unit struct, unit variant or constant, found associated function `str<{ + fn str() { let (/*ERROR*/); } + }, T>::as_bytes` --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:9 | LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; From 9d72808b1ea383628fcee2c09441bfce7c73ef51 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 14 Apr 2024 10:51:25 -0400 Subject: [PATCH 053/114] Add test --- tests/ui/enum/error-variant-with-turbofishes.rs | 8 ++++++++ tests/ui/enum/error-variant-with-turbofishes.stderr | 9 +++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/enum/error-variant-with-turbofishes.rs create mode 100644 tests/ui/enum/error-variant-with-turbofishes.stderr diff --git a/tests/ui/enum/error-variant-with-turbofishes.rs b/tests/ui/enum/error-variant-with-turbofishes.rs new file mode 100644 index 000000000000..a58d24ce20a8 --- /dev/null +++ b/tests/ui/enum/error-variant-with-turbofishes.rs @@ -0,0 +1,8 @@ +enum Struct { Variant { x: [(); N] } } + +fn test() { + let x = Struct::<0>::Variant; + //~^ ERROR expected value, found struct variant `Struct<0>::Variant` +} + +fn main() {} diff --git a/tests/ui/enum/error-variant-with-turbofishes.stderr b/tests/ui/enum/error-variant-with-turbofishes.stderr new file mode 100644 index 000000000000..66bed1c0d850 --- /dev/null +++ b/tests/ui/enum/error-variant-with-turbofishes.stderr @@ -0,0 +1,9 @@ +error[E0533]: expected value, found struct variant `Struct<0>::Variant` + --> $DIR/error-variant-with-turbofishes.rs:4:13 + | +LL | let x = Struct::<0>::Variant; + | ^^^^^^^^^^^^^^^^^^^^ not a value + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0533`. From 2beb6a4782b484c8d5159beb8231a4e883bb1113 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 14 Apr 2024 11:04:18 -0400 Subject: [PATCH 054/114] Fix clippy --- src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs | 2 +- src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs | 2 +- src/tools/clippy/clippy_lints/src/mut_reference.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs index 68841076f770..2c168405ee26 100644 --- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs @@ -77,7 +77,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) { let (help, final_suggestion) = if let Some(method) = omit_cast.corresponding_item() { // don't force absolute path - let method = qpath_to_string(method); + let method = qpath_to_string(&cx.tcx, method); ("try call directly", format!("{method}{turbofish}()")) } else { let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app); diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs index d1f637ec78c6..310675d01a20 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs @@ -19,7 +19,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<' if is_type_diagnostic_item(cx, ex_ty, sym::Result) { for arm in arms { if let PatKind::TupleStruct(ref path, inner, _) = arm.pat.kind { - let path_str = rustc_hir_pretty::qpath_to_string(path); + let path_str = rustc_hir_pretty::qpath_to_string(&cx.tcx, path); if path_str == "Err" { let mut matching_wild = inner.iter().any(is_wild); let mut ident_bind_name = kw::Underscore; diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index 6867f76a7235..0a3b769c3e60 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { cx, arguments.iter().collect(), cx.typeck_results().expr_ty(fn_expr), - &rustc_hir_pretty::qpath_to_string(path), + &rustc_hir_pretty::qpath_to_string(&cx.tcx, path), "function", ); } From 81bf9ae263ffbe75dc74b467b80e9ec4184d444a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 20:08:21 -0400 Subject: [PATCH 055/114] Make thir_tree and thir_flat into hooks --- compiler/rustc_middle/src/hooks/mod.rs | 6 ++++++ compiler/rustc_middle/src/query/mod.rs | 14 -------------- compiler/rustc_mir_build/src/lib.rs | 4 ++-- compiler/rustc_mir_build/src/thir/print.rs | 11 ++++++----- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index f7ce15d0a8dc..1872f568907c 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -102,4 +102,10 @@ declare_hooks! { /// turn a deserialized `DefPathHash` into its current `DefId`. /// Will fetch a DefId from a DefPathHash for a foreign crate. hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId; + + /// Create a THIR tree for debugging. + hook thir_tree(key: LocalDefId) -> String; + + /// Create a list-like THIR representation for debugging. + hook thir_flat(key: LocalDefId) -> String; } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 394515f091f2..2bef8f1fe3da 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -474,20 +474,6 @@ rustc_queries! { desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) } } - /// Create a THIR tree for debugging. - query thir_tree(key: LocalDefId) -> &'tcx String { - no_hash - arena_cache - desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key) } - } - - /// Create a list-like THIR representation for debugging. - query thir_flat(key: LocalDefId) -> &'tcx String { - no_hash - arena_cache - desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key) } - } - /// Set of all the `DefId`s in this crate that have MIR associated with /// them. This includes all the body owners, but also things like struct /// constructors. diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 82fb7d1ae4af..442f5fa7d172 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -34,6 +34,6 @@ pub fn provide(providers: &mut Providers) { build::closure_saved_names_of_captured_variables; providers.check_unsafety = check_unsafety::check_unsafety; providers.thir_body = thir::cx::thir_body; - providers.thir_tree = thir::print::thir_tree; - providers.thir_flat = thir::print::thir_flat; + providers.hooks.thir_tree = thir::print::thir_tree; + providers.hooks.thir_flat = thir::print::thir_flat; } diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs index ef15082a4813..49e48427b655 100644 --- a/compiler/rustc_mir_build/src/thir/print.rs +++ b/compiler/rustc_mir_build/src/thir/print.rs @@ -1,10 +1,11 @@ +use rustc_middle::query::TyCtxtAt; use rustc_middle::thir::*; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty; use rustc_span::def_id::LocalDefId; use std::fmt::{self, Write}; -pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { - match super::cx::thir_body(tcx, owner_def) { +pub(crate) fn thir_tree(tcx: TyCtxtAt<'_>, owner_def: LocalDefId) -> String { + match super::cx::thir_body(*tcx, owner_def) { Ok((thir, _)) => { let thir = thir.steal(); let mut printer = ThirPrinter::new(&thir); @@ -15,8 +16,8 @@ pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { } } -pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { - match super::cx::thir_body(tcx, owner_def) { +pub(crate) fn thir_flat(tcx: TyCtxtAt<'_>, owner_def: LocalDefId) -> String { + match super::cx::thir_body(*tcx, owner_def) { Ok((thir, _)) => format!("{:#?}", thir.steal()), Err(_) => "error".into(), } From 8d07d90572868e0ee099600e5e7b1ea9f1458943 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 21:27:26 -0400 Subject: [PATCH 056/114] Opaque types have no namespace --- compiler/rustc_hir/src/def.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 2662f5661ba5..37d9b2ffd6ab 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -207,7 +207,6 @@ impl DefKind { | DefKind::Enum | DefKind::Variant | DefKind::Trait - | DefKind::OpaqueTy | DefKind::TyAlias | DefKind::ForeignTy | DefKind::TraitAlias @@ -234,7 +233,8 @@ impl DefKind { | DefKind::Use | DefKind::ForeignMod | DefKind::GlobalAsm - | DefKind::Impl { .. } => None, + | DefKind::Impl { .. } + | DefKind::OpaqueTy => None, } } From 8a981b6fee5bb52af9311bd317dd8a01ec60dd83 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 21:36:52 -0400 Subject: [PATCH 057/114] Use /* value */ as a placeholder --- .../src/traits/error_reporting/suggestions.rs | 2 +- tests/ui/borrowck/borrowck-init-in-fru.stderr | 4 ++-- .../borrowck/borrowck-uninit-ref-chain.stderr | 4 ++-- tests/ui/borrowck/issue-103250.stderr | 4 ++-- .../ui/borrowck/suggest-assign-rvalue.stderr | 4 ++-- .../consts/value-suggestion-ice-123906.stderr | 4 ++-- tests/ui/loops/loop-break-value.stderr | 20 +++++++++---------- .../moves/issue-72649-uninit-in-loop.stderr | 8 ++++---- tests/ui/moves/move-into-dead-array-1.stderr | 4 ++-- tests/ui/moves/move-of-addr-of-mut.stderr | 4 ++-- tests/ui/nll/match-on-borrowed.stderr | 4 ++-- 11 files changed, 31 insertions(+), 31 deletions(-) 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 af8713ba3ff9..f05e91a29954 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4592,7 +4592,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .join(", "), if tys.len() == 1 { "," } else { "" } ), - _ => "value".to_string(), + _ => "/* value */".to_string(), }) } } diff --git a/tests/ui/borrowck/borrowck-init-in-fru.stderr b/tests/ui/borrowck/borrowck-init-in-fru.stderr index b5c332a90bcd..bfa86b44fe9d 100644 --- a/tests/ui/borrowck/borrowck-init-in-fru.stderr +++ b/tests/ui/borrowck/borrowck-init-in-fru.stderr @@ -8,8 +8,8 @@ LL | origin = Point { x: 10, ..origin }; | help: consider assigning a value | -LL | let mut origin: Point = value; - | +++++++ +LL | let mut origin: Point = /* value */; + | +++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr index d6759b8e1cf4..b1d508e2ac39 100644 --- a/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr +++ b/tests/ui/borrowck/borrowck-uninit-ref-chain.stderr @@ -21,8 +21,8 @@ LL | let _y = &**x; | help: consider assigning a value | -LL | let x: &&S = &&value; - | +++++++++ +LL | let x: &&S = &&/* value */; + | +++++++++++++++ error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:14:14 diff --git a/tests/ui/borrowck/issue-103250.stderr b/tests/ui/borrowck/issue-103250.stderr index 104bded5b0b5..cd048e03a678 100644 --- a/tests/ui/borrowck/issue-103250.stderr +++ b/tests/ui/borrowck/issue-103250.stderr @@ -9,8 +9,8 @@ LL | Err(last_error) | help: consider assigning a value | -LL | let mut last_error: Box = Box::new(value); - | +++++++++++++++++ +LL | let mut last_error: Box = Box::new(/* value */); + | +++++++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/borrowck/suggest-assign-rvalue.stderr b/tests/ui/borrowck/suggest-assign-rvalue.stderr index 4305539f1b62..daaef6e3892d 100644 --- a/tests/ui/borrowck/suggest-assign-rvalue.stderr +++ b/tests/ui/borrowck/suggest-assign-rvalue.stderr @@ -50,8 +50,8 @@ LL | println!("demo_no: {:?}", demo_no); = 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) help: consider assigning a value | -LL | let demo_no: DemoNoDef = value; - | +++++++ +LL | let demo_no: DemoNoDef = /* value */; + | +++++++++++++ error[E0381]: used binding `arr` isn't initialized --> $DIR/suggest-assign-rvalue.rs:34:27 diff --git a/tests/ui/consts/value-suggestion-ice-123906.stderr b/tests/ui/consts/value-suggestion-ice-123906.stderr index 8e2c316400d6..edb91063e5d4 100644 --- a/tests/ui/consts/value-suggestion-ice-123906.stderr +++ b/tests/ui/consts/value-suggestion-ice-123906.stderr @@ -10,8 +10,8 @@ LL | break; | help: give the `break` a value of the expected type | -LL | break value; - | +++++ +LL | break /* value */; + | +++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/loops/loop-break-value.stderr b/tests/ui/loops/loop-break-value.stderr index 0093182422e1..0912bdbb221e 100644 --- a/tests/ui/loops/loop-break-value.stderr +++ b/tests/ui/loops/loop-break-value.stderr @@ -246,8 +246,8 @@ LL | break; | help: give the `break` a value of the expected type | -LL | break value; - | +++++ +LL | break /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:112:9 @@ -260,8 +260,8 @@ LL | break; | help: give the `break` a value of the expected type | -LL | break value; - | +++++ +LL | break /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:124:9 @@ -274,8 +274,8 @@ LL | break 'a; | help: give the `break` a value of the expected type | -LL | break 'a value; - | +++++ +LL | break 'a /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:135:15 @@ -297,8 +297,8 @@ LL | break 'a; | help: give the `break` a value of the expected type | -LL | break 'a value; - | +++++ +LL | break 'a /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:147:15 @@ -320,8 +320,8 @@ LL | break 'a; | help: give the `break` a value of the expected type | -LL | break 'a value; - | +++++ +LL | break 'a /* value */; + | +++++++++++ error[E0308]: mismatched types --> $DIR/loop-break-value.rs:159:15 diff --git a/tests/ui/moves/issue-72649-uninit-in-loop.stderr b/tests/ui/moves/issue-72649-uninit-in-loop.stderr index 35216f8a66f5..a613f35a35e0 100644 --- a/tests/ui/moves/issue-72649-uninit-in-loop.stderr +++ b/tests/ui/moves/issue-72649-uninit-in-loop.stderr @@ -80,8 +80,8 @@ LL | let _used = value; | help: consider assigning a value | -LL | let value: NonCopy = value; - | +++++++ +LL | let value: NonCopy = /* value */; + | +++++++++++++ error[E0381]: used binding `value` isn't initialized --> $DIR/issue-72649-uninit-in-loop.rs:73:21 @@ -94,8 +94,8 @@ LL | let _used = value; | help: consider assigning a value | -LL | let mut value: NonCopy = value; - | +++++++ +LL | let mut value: NonCopy = /* value */; + | +++++++++++++ error: aborting due to 6 previous errors diff --git a/tests/ui/moves/move-into-dead-array-1.stderr b/tests/ui/moves/move-into-dead-array-1.stderr index d9b719730d69..6fb3fd83fc03 100644 --- a/tests/ui/moves/move-into-dead-array-1.stderr +++ b/tests/ui/moves/move-into-dead-array-1.stderr @@ -8,8 +8,8 @@ LL | a[i] = d(); | help: consider assigning a value | -LL | let mut a: [D; 4] = [value; 4]; - | ++++++++++++ +LL | let mut a: [D; 4] = [/* value */; 4]; + | ++++++++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/moves/move-of-addr-of-mut.stderr b/tests/ui/moves/move-of-addr-of-mut.stderr index 46f7d39a61af..c36ace6ca0f1 100644 --- a/tests/ui/moves/move-of-addr-of-mut.stderr +++ b/tests/ui/moves/move-of-addr-of-mut.stderr @@ -9,8 +9,8 @@ LL | std::ptr::addr_of_mut!(x); = note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider assigning a value | -LL | let mut x: S = value; - | +++++++ +LL | let mut x: S = /* value */; + | +++++++++++++ error: aborting due to 1 previous error diff --git a/tests/ui/nll/match-on-borrowed.stderr b/tests/ui/nll/match-on-borrowed.stderr index 4e0b048fb4b5..81163ebe2bcc 100644 --- a/tests/ui/nll/match-on-borrowed.stderr +++ b/tests/ui/nll/match-on-borrowed.stderr @@ -43,8 +43,8 @@ LL | match n {} | help: consider assigning a value | -LL | let n: Never = value; - | +++++++ +LL | let n: Never = /* value */; + | +++++++++++++ error: aborting due to 4 previous errors From c95761385ea72929c1901b8a2c74506960a9c220 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 21:45:47 -0400 Subject: [PATCH 058/114] Make array suggestions slightly more accurate --- .../src/traits/error_reporting/suggestions.rs | 13 ++++++++++--- tests/ui/moves/move-into-dead-array-1.stderr | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) 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 f05e91a29954..8f167711bdf6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4550,7 +4550,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { self.type_implements_trait(default_trait, [ty], param_env).must_apply_modulo_regions() }; - Some(match ty.kind() { + Some(match *ty.kind() { ty::Never | ty::Error(_) => return None, ty::Bool => "false".to_string(), ty::Char => "\'x\'".to_string(), @@ -4577,12 +4577,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let (ty::Str, hir::Mutability::Not) = (ty.kind(), mutability) { "\"\"".to_string() } else { - let ty = self.ty_kind_suggestion(param_env, *ty)?; + let ty = self.ty_kind_suggestion(param_env, ty)?; format!("&{}{ty}", mutability.prefix_str()) } } ty::Array(ty, len) if let Some(len) = len.try_eval_target_usize(tcx, param_env) => { - format!("[{}; {}]", self.ty_kind_suggestion(param_env, *ty)?, len) + if len == 0 { + "[]".to_string() + } else if self.type_is_copy_modulo_regions(param_env, ty) || len == 1 { + // Can only suggest `[ty; 0]` if sz == 1 or copy + format!("[{}; {}]", self.ty_kind_suggestion(param_env, ty)?, len) + } else { + "/* value */".to_string() + } } ty::Tuple(tys) => format!( "({}{})", diff --git a/tests/ui/moves/move-into-dead-array-1.stderr b/tests/ui/moves/move-into-dead-array-1.stderr index 6fb3fd83fc03..14208f5e7aa3 100644 --- a/tests/ui/moves/move-into-dead-array-1.stderr +++ b/tests/ui/moves/move-into-dead-array-1.stderr @@ -8,8 +8,8 @@ LL | a[i] = d(); | help: consider assigning a value | -LL | let mut a: [D; 4] = [/* value */; 4]; - | ++++++++++++++++++ +LL | let mut a: [D; 4] = /* value */; + | +++++++++++++ error: aborting due to 1 previous error From ff2e4ed1f18ccfbd9f7aab1f93c0873f57e0b71f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 21 Mar 2024 14:06:15 +1100 Subject: [PATCH 059/114] Factor out common code in interface tests. Replacing `mk_session` with `sess_and_cfgs`, which does a bit more of the shared stuff -- the option parsing and the `build_configuration` call. --- compiler/rustc_interface/src/tests.rs | 87 ++++++++++++--------------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d2fb65b5d4f8..2abe35948ea0 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -25,42 +25,46 @@ use std::num::NonZero; use std::path::{Path, PathBuf}; use std::sync::Arc; -fn mk_session(matches: getopts::Matches) -> (Session, Cfg) { +fn sess_and_cfg(args: &[&'static str], f: F) +where + F: FnOnce(Session, Cfg), +{ let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); early_dcx.initialize_checked_jobserver(); - let registry = registry::Registry::new(&[]); + let matches = optgroups().parse(args).unwrap(); let sessopts = build_session_options(&mut early_dcx, &matches); - let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); - let io = CompilerIO { - input: Input::Str { name: FileName::Custom(String::new()), input: String::new() }, - output_dir: None, - output_file: None, - temps_dir, - }; - let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone()); - let target = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot); - let sess = build_session( - early_dcx, - sessopts, - io, - None, - registry, - vec![], - Default::default(), - None, - target, - sysroot, - "", - None, - Arc::default(), - Default::default(), - ); - let cfg = parse_cfg(&sess.dcx(), matches.opt_strs("cfg")); - (sess, cfg) + rustc_span::create_default_session_globals_then(|| { + let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); + let io = CompilerIO { + input: Input::Str { name: FileName::Custom(String::new()), input: String::new() }, + output_dir: None, + output_file: None, + temps_dir, + }; + let sess = build_session( + early_dcx, + sessopts, + io, + None, + registry::Registry::new(&[]), + vec![], + Default::default(), + None, + target, + sysroot, + "", + None, + Arc::default(), + Default::default(), + ); + let cfg = parse_cfg(&sess.dcx(), matches.opt_strs("cfg")); + let cfg = build_configuration(&sess, cfg); + f(sess, cfg) + }); } fn new_public_extern_entry(locations: I) -> ExternEntry @@ -125,21 +129,15 @@ fn assert_non_crate_hash_different(x: &Options, y: &Options) { // When the user supplies --test we should implicitly supply --cfg test #[test] fn test_switch_implies_cfg_test() { - rustc_span::create_default_session_globals_then(|| { - let matches = optgroups().parse(&["--test".to_string()]).unwrap(); - let (sess, cfg) = mk_session(matches); - let cfg = build_configuration(&sess, cfg); + sess_and_cfg(&["--test"], |_sess, cfg| { assert!(cfg.contains(&(sym::test, None))); - }); + }) } // When the user supplies --test and --cfg test, don't implicitly add another --cfg test #[test] fn test_switch_implies_cfg_test_unless_cfg_test() { - rustc_span::create_default_session_globals_then(|| { - let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap(); - let (sess, cfg) = mk_session(matches); - let cfg = build_configuration(&sess, cfg); + sess_and_cfg(&["--test", "--cfg=test"], |_sess, cfg| { let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test); assert!(test_items.next().is_some()); assert!(test_items.next().is_none()); @@ -148,22 +146,15 @@ fn test_switch_implies_cfg_test_unless_cfg_test() { #[test] fn test_can_print_warnings() { - rustc_span::create_default_session_globals_then(|| { - let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap(); - let (sess, _) = mk_session(matches); + sess_and_cfg(&["-Awarnings"], |sess, _cfg| { assert!(!sess.dcx().can_emit_warnings()); }); - rustc_span::create_default_session_globals_then(|| { - let matches = - optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap(); - let (sess, _) = mk_session(matches); + sess_and_cfg(&["-Awarnings", "-Dwarnings"], |sess, _cfg| { assert!(sess.dcx().can_emit_warnings()); }); - rustc_span::create_default_session_globals_then(|| { - let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap(); - let (sess, _) = mk_session(matches); + sess_and_cfg(&["-Adead_code"], |sess, _cfg| { assert!(sess.dcx().can_emit_warnings()); }); } From 24e9a0c41b9fcd2d6cad9098ff479ab8ca286c34 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 15 Apr 2024 19:22:19 -0700 Subject: [PATCH 060/114] Fix docs for unstable_features lint. --- src/tools/lint-docs/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs index b7c8b9ed2e31..2566124a0375 100644 --- a/src/tools/lint-docs/src/lib.rs +++ b/src/tools/lint-docs/src/lib.rs @@ -270,7 +270,6 @@ impl<'a> LintExtractor<'a> { if matches!( lint.name.as_str(), "unused_features" // broken lint - | "unstable_features" // deprecated ) { return Ok(()); } From 62c32aeeab0558123f12a9372768ba567ce43361 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 21 Mar 2024 14:17:00 +1100 Subject: [PATCH 061/114] Construct `SourceMap` at the same time as `SessionGlobals`. Currently `SourceMap` is constructed slightly later than `SessionGlobals`, and inserted. This commit changes things so they are done at the same time. Benefits: - `SessionGlobals::source_map` changes from `Lock>>` to `Option>`. It's still optional, but mutability isn't required because it's initialized at construction. - `set_source_map` is removed, simplifying `run_compiler`, which is good because that's a critical function and it's nice to make it simpler. This requires moving things around a bit, so the necessary inputs are available when `SessionGlobals` is created, in particular the `loader` and `hash_kind`, which are no longer computed by `build_session`. These inputs are captured by the new `SourceMapInputs` type, which is threaded through various places. --- compiler/rustc_hir/src/tests.rs | 2 +- compiler/rustc_interface/src/interface.rs | 90 +++++++++---------- compiler/rustc_interface/src/tests.rs | 11 ++- compiler/rustc_interface/src/util.rs | 16 ++-- compiler/rustc_log/src/lib.rs | 2 +- compiler/rustc_session/src/config.rs | 12 ++- compiler/rustc_session/src/session.rs | 20 +---- compiler/rustc_span/src/lib.rs | 53 ++++------- compiler/rustc_span/src/source_map.rs | 26 ++++-- .../src/doc/needless_doctest_main.rs | 2 +- 10 files changed, 118 insertions(+), 116 deletions(-) diff --git a/compiler/rustc_hir/src/tests.rs b/compiler/rustc_hir/src/tests.rs index 74b8e88a9779..571923b54629 100644 --- a/compiler/rustc_hir/src/tests.rs +++ b/compiler/rustc_hir/src/tests.rs @@ -14,7 +14,7 @@ fn def_path_hash_depends_on_crate_id() { // the crate by changing the crate disambiguator (e.g. via bumping the // crate's version number). - create_session_globals_then(Edition::Edition2024, || { + create_session_globals_then(Edition::Edition2024, None, || { let id0 = StableCrateId::new(Symbol::intern("foo"), false, vec!["1".to_string()], ""); let id1 = StableCrateId::new(Symbol::intern("foo"), false, vec!["2".to_string()], ""); diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index da2fb490a36f..2ffb1426de48 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -21,7 +21,7 @@ use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileN use rustc_session::filesearch::{self, sysroot_candidates}; use rustc_session::parse::ParseSess; use rustc_session::{lint, CompilerIO, EarlyDiagCtxt, Session}; -use rustc_span::source_map::FileLoader; +use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs}; use rustc_span::symbol::sym; use rustc_span::FileName; use std::path::PathBuf; @@ -336,18 +336,23 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se let early_dcx = EarlyDiagCtxt::new(config.opts.error_format); early_dcx.initialize_checked_jobserver(); + crate::callbacks::setup_callbacks(); + + let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone()); + let target = config::build_target_config(&early_dcx, &config.opts, &sysroot); + let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); + let path_mapping = config.opts.file_path_mapping(); + let hash_kind = config.opts.unstable_opts.src_hash_algorithm(&target); + util::run_in_thread_pool_with_globals( config.opts.edition, config.opts.unstable_opts.threads, + SourceMapInputs { file_loader, path_mapping, hash_kind }, |current_gcx| { - crate::callbacks::setup_callbacks(); - + // The previous `early_dcx` can't be reused here because it doesn't + // impl `Send`. Creating a new one is fine. let early_dcx = EarlyDiagCtxt::new(config.opts.error_format); - let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone()); - - let target = config::build_target_config(&early_dcx, &config.opts, &sysroot); - let codegen_backend = match config.make_codegen_backend { None => util::get_codegen_backend( &early_dcx, @@ -372,9 +377,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.opts.unstable_opts.translate_directionality_markers, ) { Ok(bundle) => bundle, - Err(e) => { - early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")); - } + Err(e) => early_dcx.early_fatal(format!("failed to load fluent bundle: {e}")), }; let mut locale_resources = Vec::from(config.locale_resources); @@ -393,7 +396,6 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.registry.clone(), locale_resources, config.lint_caps, - config.file_loader, target, sysroot, util::rustc_version_str().unwrap_or("unknown"), @@ -440,45 +442,43 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se current_gcx, }; - rustc_span::set_source_map(compiler.sess.psess.clone_source_map(), move || { - // There are two paths out of `f`. - // - Normal exit. - // - Panic, e.g. triggered by `abort_if_errors`. - // - // We must run `finish_diagnostics` in both cases. - let res = { - // If `f` panics, `finish_diagnostics` will run during - // unwinding because of the `defer`. - let mut guar = None; - let sess_abort_guard = defer(|| { - guar = compiler.sess.finish_diagnostics(&config.registry); - }); + // There are two paths out of `f`. + // - Normal exit. + // - Panic, e.g. triggered by `abort_if_errors`. + // + // We must run `finish_diagnostics` in both cases. + let res = { + // If `f` panics, `finish_diagnostics` will run during + // unwinding because of the `defer`. + let mut guar = None; + let sess_abort_guard = defer(|| { + guar = compiler.sess.finish_diagnostics(&config.registry); + }); - let res = f(&compiler); + let res = f(&compiler); - // If `f` doesn't panic, `finish_diagnostics` will run - // normally when `sess_abort_guard` is dropped. - drop(sess_abort_guard); + // If `f` doesn't panic, `finish_diagnostics` will run + // normally when `sess_abort_guard` is dropped. + drop(sess_abort_guard); - // If `finish_diagnostics` emits errors (e.g. stashed - // errors) we can't return an error directly, because the - // return type of this function is `R`, not `Result`. - // But we need to communicate the errors' existence to the - // caller, otherwise the caller might mistakenly think that - // no errors occurred and return a zero exit code. So we - // abort (panic) instead, similar to if `f` had panicked. - if guar.is_some() { - compiler.sess.dcx().abort_if_errors(); - } - - res - }; - - let prof = compiler.sess.prof.clone(); - prof.generic_activity("drop_compiler").run(move || drop(compiler)); + // If `finish_diagnostics` emits errors (e.g. stashed + // errors) we can't return an error directly, because the + // return type of this function is `R`, not `Result`. + // But we need to communicate the errors' existence to the + // caller, otherwise the caller might mistakenly think that + // no errors occurred and return a zero exit code. So we + // abort (panic) instead, similar to if `f` had panicked. + if guar.is_some() { + compiler.sess.dcx().abort_if_errors(); + } res - }) + }; + + let prof = compiler.sess.prof.clone(); + prof.generic_activity("drop_compiler").run(move || drop(compiler)); + + res }, ) } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 2abe35948ea0..4a5bd9a3ceb6 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -16,6 +16,7 @@ use rustc_session::search_paths::SearchPath; use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; use rustc_session::{build_session, filesearch, getopts, CompilerIO, EarlyDiagCtxt, Session}; use rustc_span::edition::{Edition, DEFAULT_EDITION}; +use rustc_span::source_map::{RealFileLoader, SourceMapInputs}; use rustc_span::symbol::sym; use rustc_span::{FileName, SourceFileHashAlgorithm}; use rustc_target::spec::{CodeModel, LinkerFlavorCli, MergeFunctions, PanicStrategy, RelocModel}; @@ -36,8 +37,14 @@ where let sessopts = build_session_options(&mut early_dcx, &matches); let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone()); let target = rustc_session::config::build_target_config(&early_dcx, &sessopts, &sysroot); + let hash_kind = sessopts.unstable_opts.src_hash_algorithm(&target); + let sm_inputs = Some(SourceMapInputs { + file_loader: Box::new(RealFileLoader) as _, + path_mapping: sessopts.file_path_mapping(), + hash_kind, + }); - rustc_span::create_default_session_globals_then(|| { + rustc_span::create_session_globals_then(DEFAULT_EDITION, sm_inputs, || { let temps_dir = sessopts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); let io = CompilerIO { input: Input::Str { name: FileName::Custom(String::new()), input: String::new() }, @@ -45,6 +52,7 @@ where output_file: None, temps_dir, }; + let sess = build_session( early_dcx, sessopts, @@ -53,7 +61,6 @@ where registry::Registry::new(&[]), vec![], Default::default(), - None, target, sysroot, "", diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index d0f04fccc481..02dcfe9c8dff 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -14,6 +14,7 @@ use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer}; use rustc_session::{filesearch, Session}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; +use rustc_span::source_map::SourceMapInputs; use rustc_span::symbol::sym; use rustc_target::spec::Target; use session::output::{categorize_crate_type, CRATE_TYPES}; @@ -65,8 +66,9 @@ fn init_stack_size() -> usize { }) } -pub(crate) fn run_in_thread_with_globals R + Send, R: Send>( +fn run_in_thread_with_globals R + Send, R: Send>( edition: Edition, + sm_inputs: SourceMapInputs, f: F, ) -> R { // The "thread pool" is a single spawned thread in the non-parallel @@ -84,7 +86,9 @@ pub(crate) fn run_in_thread_with_globals R + Send, R: S // name contains null bytes. let r = builder .spawn_scoped(s, move || { - rustc_span::create_session_globals_then(edition, || f(CurrentGcx::new())) + rustc_span::create_session_globals_then(edition, Some(sm_inputs), || { + f(CurrentGcx::new()) + }) }) .unwrap() .join(); @@ -100,15 +104,17 @@ pub(crate) fn run_in_thread_with_globals R + Send, R: S pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( edition: Edition, _threads: usize, + sm_inputs: SourceMapInputs, f: F, ) -> R { - run_in_thread_with_globals(edition, f) + run_in_thread_with_globals(edition, sm_inputs, f) } #[cfg(parallel_compiler)] pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( edition: Edition, threads: usize, + sm_inputs: SourceMapInputs, f: F, ) -> R { use rustc_data_structures::{defer, jobserver, sync::FromDyn}; @@ -120,7 +126,7 @@ pub(crate) fn run_in_thread_pool_with_globals R + Send, let registry = sync::Registry::new(std::num::NonZero::new(threads).unwrap()); if !sync::is_dyn_thread_safe() { - return run_in_thread_with_globals(edition, |current_gcx| { + return run_in_thread_with_globals(edition, sm_inputs, |current_gcx| { // Register the thread for use with the `WorkerLocal` type. registry.register(); @@ -169,7 +175,7 @@ pub(crate) fn run_in_thread_pool_with_globals R + Send, // pool. Upon creation, each worker thread created gets a copy of the // session globals in TLS. This is possible because `SessionGlobals` impls // `Send` in the parallel compiler. - rustc_span::create_session_globals_then(edition, || { + rustc_span::create_session_globals_then(edition, Some(sm_inputs), || { rustc_span::with_session_globals(|session_globals| { let session_globals = FromDyn::from(session_globals); builder diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index e4b67cde244f..81257f9be882 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -17,7 +17,7 @@ //! rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap(); //! //! let edition = rustc_span::edition::Edition::Edition2021; -//! rustc_span::create_session_globals_then(edition, || { +//! rustc_span::create_session_globals_then(edition, None, || { //! /* ... */ //! }); //! } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7aca86f7169d..c7526f43087e 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1125,7 +1125,7 @@ impl Options { || self.unstable_opts.query_dep_graph } - pub(crate) fn file_path_mapping(&self) -> FilePathMapping { + pub fn file_path_mapping(&self) -> FilePathMapping { file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts) } @@ -1162,6 +1162,16 @@ impl UnstableOptions { track_diagnostics: self.track_diagnostics, } } + + pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm { + self.src_hash_algorithm.unwrap_or_else(|| { + if target.is_like_msvc { + SourceFileHashAlgorithm::Sha256 + } else { + SourceFileHashAlgorithm::Md5 + } + }) + } } // The type of entry function, so users can have their own entry functions diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 22ca8a3cf3ec..ecf70e0822e9 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -28,9 +28,9 @@ use rustc_errors::{ use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; use rustc_span::edition::Edition; -use rustc_span::source_map::{FileLoader, FilePathMapping, RealFileLoader, SourceMap}; +use rustc_span::source_map::{FilePathMapping, SourceMap}; use rustc_span::{FileNameDisplayPreference, RealFileName}; -use rustc_span::{SourceFileHashAlgorithm, Span, Symbol}; +use rustc_span::{Span, Symbol}; use rustc_target::asm::InlineAsmArch; use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel}; use rustc_target::spec::{ @@ -988,7 +988,6 @@ pub fn build_session( registry: rustc_errors::registry::Registry, fluent_resources: Vec<&'static str>, driver_lint_caps: FxHashMap, - file_loader: Option>, target: Target, sysroot: PathBuf, cfg_version: &'static str, @@ -1015,24 +1014,11 @@ pub fn build_session( early_dcx.early_warn(warning) } - let loader = file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); - let hash_kind = sopts.unstable_opts.src_hash_algorithm.unwrap_or_else(|| { - if target.is_like_msvc { - SourceFileHashAlgorithm::Sha256 - } else { - SourceFileHashAlgorithm::Md5 - } - }); - let source_map = Lrc::new(SourceMap::with_file_loader_and_hash_kind( - loader, - sopts.file_path_mapping(), - hash_kind, - )); - let fallback_bundle = fallback_fluent_bundle( fluent_resources, sopts.unstable_opts.translate_directionality_markers, ); + let source_map = rustc_span::source_map::get_source_map().unwrap(); let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle); let mut dcx = diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index c1e1175b4bd6..f749d4eb8336 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -49,7 +49,7 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; mod caching_source_map_view; pub mod source_map; pub use self::caching_source_map_view::CachingSourceMapView; -use source_map::SourceMap; +use source_map::{SourceMap, SourceMapInputs}; pub mod edition; use edition::Edition; @@ -104,35 +104,35 @@ pub struct SessionGlobals { metavar_spans: Lock>, hygiene_data: Lock, - /// A reference to the source map in the `Session`. It's an `Option` - /// because it can't be initialized until `Session` is created, which - /// happens after `SessionGlobals`. `set_source_map` does the - /// initialization. - /// - /// This field should only be used in places where the `Session` is truly - /// not available, such as `::fmt`. - source_map: Lock>>, + /// The session's source map, if there is one. This field should only be + /// used in places where the `Session` is truly not available, such as + /// `::fmt`. + source_map: Option>, } impl SessionGlobals { - pub fn new(edition: Edition) -> SessionGlobals { + pub fn new(edition: Edition, sm_inputs: Option) -> SessionGlobals { SessionGlobals { symbol_interner: symbol::Interner::fresh(), span_interner: Lock::new(span_encoding::SpanInterner::default()), metavar_spans: Default::default(), hygiene_data: Lock::new(hygiene::HygieneData::new(edition)), - source_map: Lock::new(None), + source_map: sm_inputs.map(|inputs| Lrc::new(SourceMap::with_inputs(inputs))), } } } -pub fn create_session_globals_then(edition: Edition, f: impl FnOnce() -> R) -> R { +pub fn create_session_globals_then( + edition: Edition, + sm_inputs: Option, + f: impl FnOnce() -> R, +) -> R { assert!( !SESSION_GLOBALS.is_set(), "SESSION_GLOBALS should never be overwritten! \ Use another thread if you need another SessionGlobals" ); - let session_globals = SessionGlobals::new(edition); + let session_globals = SessionGlobals::new(edition, sm_inputs); SESSION_GLOBALS.set(&session_globals, f) } @@ -145,12 +145,13 @@ pub fn set_session_globals_then(session_globals: &SessionGlobals, f: impl FnO SESSION_GLOBALS.set(session_globals, f) } +/// No source map. pub fn create_session_if_not_set_then(edition: Edition, f: F) -> R where F: FnOnce(&SessionGlobals) -> R, { if !SESSION_GLOBALS.is_set() { - let session_globals = SessionGlobals::new(edition); + let session_globals = SessionGlobals::new(edition, None); SESSION_GLOBALS.set(&session_globals, || SESSION_GLOBALS.with(f)) } else { SESSION_GLOBALS.with(f) @@ -164,8 +165,9 @@ where SESSION_GLOBALS.with(f) } +/// Default edition, no source map. pub fn create_default_session_globals_then(f: impl FnOnce() -> R) -> R { - create_session_globals_then(edition::DEFAULT_EDITION, f) + create_session_globals_then(edition::DEFAULT_EDITION, None, f) } // If this ever becomes non thread-local, `decode_syntax_context` @@ -1318,25 +1320,6 @@ impl Decodable for AttrId { } } -/// Insert `source_map` into the session globals for the duration of the -/// closure's execution. -pub fn set_source_map T>(source_map: Lrc, f: F) -> T { - with_session_globals(|session_globals| { - *session_globals.source_map.borrow_mut() = Some(source_map); - }); - struct ClearSourceMap; - impl Drop for ClearSourceMap { - fn drop(&mut self) { - with_session_globals(|session_globals| { - session_globals.source_map.borrow_mut().take(); - }); - } - } - - let _guard = ClearSourceMap; - f() -} - impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { // Use the global `SourceMap` to print the span. If that's not @@ -1352,7 +1335,7 @@ impl fmt::Debug for Span { if SESSION_GLOBALS.is_set() { with_session_globals(|session_globals| { - if let Some(source_map) = &*session_globals.source_map.borrow() { + if let Some(source_map) = &session_globals.source_map { write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt()) } else { fallback(*self, f) diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 93d5f06a1673..e3e76caebaf0 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -167,9 +167,17 @@ struct SourceMapFiles { stable_id_to_source_file: UnhashMap>, } +/// Used to construct a `SourceMap` with `SourceMap::with_inputs`. +pub struct SourceMapInputs { + pub file_loader: Box, + pub path_mapping: FilePathMapping, + pub hash_kind: SourceFileHashAlgorithm, +} + pub struct SourceMap { files: RwLock, file_loader: IntoDynSyncSend>, + // This is used to apply the file path remapping as specified via // `--remap-path-prefix` to all `SourceFile`s allocated within this `SourceMap`. path_mapping: FilePathMapping, @@ -180,17 +188,15 @@ pub struct SourceMap { impl SourceMap { pub fn new(path_mapping: FilePathMapping) -> SourceMap { - Self::with_file_loader_and_hash_kind( - Box::new(RealFileLoader), + Self::with_inputs(SourceMapInputs { + file_loader: Box::new(RealFileLoader), path_mapping, - SourceFileHashAlgorithm::Md5, - ) + hash_kind: SourceFileHashAlgorithm::Md5, + }) } - pub fn with_file_loader_and_hash_kind( - file_loader: Box, - path_mapping: FilePathMapping, - hash_kind: SourceFileHashAlgorithm, + pub fn with_inputs( + SourceMapInputs { file_loader, path_mapping, hash_kind }: SourceMapInputs, ) -> SourceMap { SourceMap { files: Default::default(), @@ -1054,6 +1060,10 @@ impl SourceMap { } } +pub fn get_source_map() -> Option> { + with_session_globals(|session_globals| session_globals.source_map.clone()) +} + #[derive(Clone)] pub struct FilePathMapping { mapping: Vec<(PathBuf, PathBuf)>, diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs index e55a988321b3..651f2ebaee6f 100644 --- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs +++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs @@ -38,7 +38,7 @@ pub fn check( // of all `#[test]` attributes in not ignored code examples fn check_code_sample(code: String, edition: Edition, ignore: bool) -> (bool, Vec>) { rustc_driver::catch_fatal_errors(|| { - rustc_span::create_session_globals_then(edition, || { + rustc_span::create_session_globals_then(edition, None, || { let mut test_attr_spans = vec![]; let filename = FileName::anon_source_code(&code); From 9b0ced000a7e9db6bed97046974adfa9bf3bc165 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 21 Mar 2024 14:54:24 +1100 Subject: [PATCH 062/114] Move `initialize_checked_jobserver`. Currently it's a method on `EarlyDiagCtxt`, which is not the right place for it at all -- `EarlyDiagCtxt` is used to issue diagnostics, but shouldn't be doing any of the actual checking. This commit moves it into a standalone function that takes an `EarlyDiagCtxt` as an argument, which is more sensible. This does require adding `EarlyDiagCtxt::early_struct_warn`, so a warning can be returned and then modified with a note. (And that likely explains why somebody put `initialize_checked_jobserver` into `EarlyDiagCtxt` in the first place.) --- compiler/rustc_interface/src/interface.rs | 15 ++++++++++++++- compiler/rustc_interface/src/tests.rs | 4 ++-- compiler/rustc_session/src/session.rs | 14 ++++---------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 2ffb1426de48..c5b81dbd6791 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -5,6 +5,7 @@ use rustc_ast::{LitKind, MetaItemKind}; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::defer; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::jobserver; use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::Lrc; use rustc_errors::registry::Registry; @@ -323,6 +324,18 @@ pub struct Config { pub expanded_args: Vec, } +/// Initialize jobserver before getting `jobserver::client` and `build_session`. +pub(crate) fn initialize_checked_jobserver(early_dcx: &EarlyDiagCtxt) { + jobserver::initialize_checked(|err| { + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + early_dcx + .early_struct_warn(err) + .with_note("the build environment is likely misconfigured") + .emit() + }); +} + // JUSTIFICATION: before session exists, only config #[allow(rustc::bad_opt_access)] #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable @@ -334,7 +347,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se // Check jobserver before run_in_thread_pool_with_globals, which call jobserver::acquire_thread let early_dcx = EarlyDiagCtxt::new(config.opts.error_format); - early_dcx.initialize_checked_jobserver(); + initialize_checked_jobserver(&early_dcx); crate::callbacks::setup_callbacks(); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 4a5bd9a3ceb6..6748a1fd976b 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -1,5 +1,5 @@ #![allow(rustc::bad_opt_access)] -use crate::interface::parse_cfg; +use crate::interface::{initialize_checked_jobserver, parse_cfg}; use rustc_data_structures::profiling::TimePassesFormat; use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig}; use rustc_session::config::{ @@ -31,7 +31,7 @@ where F: FnOnce(Session, Cfg), { let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default()); - early_dcx.initialize_checked_jobserver(); + initialize_checked_jobserver(&early_dcx); let matches = optgroups().parse(args).unwrap(); let sessopts = build_session_options(&mut early_dcx, &matches); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index ecf70e0822e9..8b844f340e5c 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1397,16 +1397,10 @@ impl EarlyDiagCtxt { self.dcx.warn(msg) } - pub fn initialize_checked_jobserver(&self) { - // initialize jobserver before getting `jobserver::client` and `build_session`. - jobserver::initialize_checked(|err| { - #[allow(rustc::untranslatable_diagnostic)] - #[allow(rustc::diagnostic_outside_of_impl)] - self.dcx - .struct_warn(err) - .with_note("the build environment is likely misconfigured") - .emit() - }); + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] + pub fn early_struct_warn(&self, msg: impl Into) -> Diag<'_, ()> { + self.dcx.struct_warn(msg) } } From 00838b314046fb4e1d203346465f787a69f7159e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 15 Apr 2024 17:49:24 -0400 Subject: [PATCH 063/114] Make suggest_deref_closure_return more idiomatic/easier to understand --- .../src/diagnostics/region_errors.rs | 135 ++++++++---------- 1 file changed, 63 insertions(+), 72 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index d3b0a9a85a35..2fe75fe2a2bf 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -26,7 +26,6 @@ use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_middle::ty::{Region, TyCtxt}; use rustc_span::symbol::{kw, Ident}; use rustc_span::Span; -use rustc_trait_selection::infer::type_variable::TypeVariableOrigin; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::{Obligation, ObligationCtxt}; @@ -813,7 +812,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr); self.suggest_move_on_borrowing_closure(&mut diag); - self.suggest_deref_closure_value(&mut diag); + self.suggest_deref_closure_return(&mut diag); diag } @@ -1048,115 +1047,107 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// When encountering a lifetime error caused by the return type of a closure, check the /// corresponding trait bound and see if dereferencing the closure return value would satisfy /// them. If so, we produce a structured suggestion. - fn suggest_deref_closure_value(&self, diag: &mut Diag<'_>) { + fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) { let tcx = self.infcx.tcx; - let map = tcx.hir(); // Get the closure return value and type. - let body_id = map.body_owned_by(self.mir_def_id()); - let body = &map.body(body_id); - let value = &body.value.peel_blocks(); - let hir::Node::Expr(closure_expr) = tcx.hir_node_by_def_id(self.mir_def_id()) else { + let closure_def_id = self.mir_def_id(); + let hir::Node::Expr( + closure_expr @ hir::Expr { + kind: hir::ExprKind::Closure(hir::Closure { body, .. }), .. + }, + ) = tcx.hir_node_by_def_id(closure_def_id) + else { return; }; - let fn_call_id = tcx.parent_hir_id(self.mir_hir_id()); - let hir::Node::Expr(expr) = tcx.hir_node(fn_call_id) else { return }; - let def_id = map.enclosing_body_owner(fn_call_id); - let tables = tcx.typeck(def_id); - let Some(return_value_ty) = tables.node_type_opt(value.hir_id) else { return }; - let return_value_ty = self.infcx.resolve_vars_if_possible(return_value_ty); + let ty::Closure(_, args) = *tcx.type_of(closure_def_id).instantiate_identity().kind() + else { + return; + }; + let args = args.as_closure(); + + // Make sure that the parent expression is a method call. + let parent_expr_id = tcx.parent_hir_id(self.mir_hir_id()); + let hir::Node::Expr( + parent_expr @ hir::Expr { + kind: hir::ExprKind::MethodCall(_, rcvr, call_args, _), .. + }, + ) = tcx.hir_node(parent_expr_id) + else { + return; + }; + let typeck_results = tcx.typeck(self.mir_def_id()); // We don't use `ty.peel_refs()` to get the number of `*`s needed to get the root type. - let mut ty = return_value_ty; + let liberated_sig = tcx.liberate_late_bound_regions(closure_def_id.to_def_id(), args.sig()); + let mut peeled_ty = liberated_sig.output(); let mut count = 0; - while let ty::Ref(_, t, _) = ty.kind() { - ty = *t; + while let ty::Ref(_, ref_ty, _) = *peeled_ty.kind() { + peeled_ty = ref_ty; count += 1; } - if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty) { + if !self.infcx.type_is_copy_modulo_regions(self.param_env, peeled_ty) { return; } // Build a new closure where the return type is an owned value, instead of a ref. - let Some(ty::Closure(did, args)) = - tables.node_type_opt(closure_expr.hir_id).as_ref().map(|ty| ty.kind()) - else { - return; - }; - let sig = args.as_closure().sig(); let closure_sig_as_fn_ptr_ty = Ty::new_fn_ptr( tcx, - sig.map_bound(|s| { - let unsafety = hir::Unsafety::Normal; - use rustc_target::spec::abi; - tcx.mk_fn_sig( - [s.inputs()[0]], - s.output().peel_refs(), - s.c_variadic, - unsafety, - abi::Abi::Rust, - ) - }), + ty::Binder::dummy(tcx.mk_fn_sig( + liberated_sig.inputs().iter().copied(), + peeled_ty, + liberated_sig.c_variadic, + hir::Unsafety::Normal, + rustc_target::spec::abi::Abi::Rust, + )), ); - let parent_args = GenericArgs::identity_for_item( + let closure_ty = Ty::new_closure( tcx, - tcx.typeck_root_def_id(self.mir_def_id().to_def_id()), + closure_def_id.to_def_id(), + ty::ClosureArgs::new( + tcx, + ty::ClosureArgsParts { + parent_args: args.parent_args(), + closure_kind_ty: args.kind_ty(), + tupled_upvars_ty: args.tupled_upvars_ty(), + closure_sig_as_fn_ptr_ty, + }, + ) + .args, ); - let closure_kind = args.as_closure().kind(); - let closure_kind_ty = Ty::from_closure_kind(tcx, closure_kind); - let tupled_upvars_ty = self - .infcx - .next_ty_var(TypeVariableOrigin { param_def_id: None, span: closure_expr.span }); - let closure_args = ty::ClosureArgs::new( - tcx, - ty::ClosureArgsParts { - parent_args, - closure_kind_ty, - closure_sig_as_fn_ptr_ty, - tupled_upvars_ty, - }, - ); - let closure_ty = Ty::new_closure(tcx, *did, closure_args.args); - let closure_ty = tcx.erase_regions(closure_ty); - let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else { return }; - let Some(pos) = args - .iter() - .enumerate() - .find(|(_, arg)| arg.hir_id == closure_expr.hir_id) - .map(|(i, _)| i) + let Some((closure_arg_pos, _)) = + call_args.iter().enumerate().find(|(_, arg)| arg.hir_id == closure_expr.hir_id) else { return; }; - // The found `Self` type of the method call. - let Some(possible_rcvr_ty) = tables.node_type_opt(rcvr.hir_id) else { return }; - let Some(method_def_id) = tables.type_dependent_def_id(expr.hir_id) else { return }; - // Get the type for the parameter corresponding to the argument the closure with the // lifetime error we had. - let Some(input) = tcx + let Some(method_def_id) = typeck_results.type_dependent_def_id(parent_expr.hir_id) else { + return; + }; + let Some(input_arg) = tcx .fn_sig(method_def_id) - .instantiate_identity() + .skip_binder() .inputs() .skip_binder() // Methods have a `self` arg, so `pos` is actually `+ 1` to match the method call arg. - .get(pos + 1) + .get(closure_arg_pos + 1) else { return; }; - - trace!(?input); - - let ty::Param(closure_param) = input.kind() else { return }; + // If this isn't a param, then we can't substitute a new closure. + let ty::Param(closure_param) = input_arg.kind() else { return }; // Get the arguments for the found method, only specifying that `Self` is the receiver type. + let Some(possible_rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id) else { return }; let args = GenericArgs::for_item(tcx, method_def_id, |param, _| { if param.index == 0 { possible_rcvr_ty.into() } else if param.index == closure_param.index { closure_ty.into() } else { - self.infcx.var_for_def(expr.span, param) + self.infcx.var_for_def(parent_expr.span, param) } }); @@ -1170,7 +1161,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if ocx.select_all_or_error().is_empty() { diag.span_suggestion_verbose( - value.span.shrink_to_lo(), + tcx.hir().body(*body).value.peel_blocks().span.shrink_to_lo(), "dereference the return value", "*".repeat(count), Applicability::MachineApplicable, From ef1d084c0b5b0ff7143bbca966442cd24151313b Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 5 Apr 2024 23:27:29 -0400 Subject: [PATCH 064/114] Match ergonomics 2024: `mut` doesn't reset binding mode --- compiler/rustc_feature/src/unstable.rs | 2 ++ compiler/rustc_hir_typeck/src/pat.rs | 16 +++++++--- compiler/rustc_span/src/symbol.rs | 1 + ...e-gate-mut_dont_reset_binding_mode_2024.rs | 14 +++++++++ ...te-mut_dont_reset_binding_mode_2024.stderr | 31 +++++++++++++++++++ .../mut_dont_reset_binding_mode_2021.rs | 15 +++++++++ .../mut_dont_reset_binding_mode_2021.stderr | 31 +++++++++++++++++++ .../mut_dont_reset_binding_mode_2024.rs | 15 +++++++++ 8 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.rs create mode 100644 tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.stderr create mode 100644 tests/ui/pattern/mut_dont_reset_binding_mode_2021.rs create mode 100644 tests/ui/pattern/mut_dont_reset_binding_mode_2021.stderr create mode 100644 tests/ui/pattern/mut_dont_reset_binding_mode_2024.rs diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e6b19817de38..2a753af93872 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -533,6 +533,8 @@ declare_features! ( (unstable, more_qualified_paths, "1.54.0", Some(86935)), /// Allows the `#[must_not_suspend]` attribute. (unstable, must_not_suspend, "1.57.0", Some(83310)), + /// Make `mut` not reset the binding mode on edition >= 2024. + (unstable, mut_dont_reset_binding_mode_2024, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows `mut ref` and `mut ref mut` identifier patterns. (incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows using `#[naked]` on functions. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index db4bd132b7e3..06f6a7f6bf28 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -629,12 +629,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { - let PatInfo { binding_mode: def_bm, top_info: ti, .. } = pat_info; + let PatInfo { binding_mode: BindingAnnotation(def_br, _), top_info: ti, .. } = pat_info; // Determine the binding mode... let bm = match ba { - BindingAnnotation(ByRef::No, Mutability::Not) => def_bm, - _ => ba, + BindingAnnotation(ByRef::No, Mutability::Mut) + if !(pat.span.at_least_rust_2024() + && self.tcx.features().mut_dont_reset_binding_mode_2024) + && matches!(def_br, ByRef::Yes(_)) => + { + // `mut x` resets the binding mode in edition <= 2021. + BindingAnnotation(ByRef::No, Mutability::Mut) + } + BindingAnnotation(ByRef::No, mutbl) => BindingAnnotation(def_br, mutbl), + BindingAnnotation(ByRef::Yes(_), _) => ba, }; // ...and store it in a side table: self.typeck_results.borrow_mut().pat_binding_modes_mut().insert(pat.hir_id, bm); @@ -743,7 +751,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - // Precondition: pat is a Ref(_) pattern + /// Precondition: pat is a `Ref(_)` pattern fn borrow_pat_suggestion(&self, err: &mut Diag<'_>, pat: &Pat<'_>) { let tcx = self.tcx; if let PatKind::Ref(inner, mutbl) = pat.kind diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index bfd0f77c237b..02550fd655cb 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1194,6 +1194,7 @@ symbols! { multiple_supertrait_upcastable, must_not_suspend, must_use, + mut_dont_reset_binding_mode_2024, mut_ref, naked, naked_functions, diff --git a/tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.rs b/tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.rs new file mode 100644 index 000000000000..15c542e6bf10 --- /dev/null +++ b/tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.rs @@ -0,0 +1,14 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + a = &42; + //~^ ERROR: mismatched types + + let Foo(mut a) = &mut Foo(0); + a = &mut 42; + //~^ ERROR: mismatched types +} diff --git a/tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.stderr b/tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.stderr new file mode 100644 index 000000000000..1624883de60c --- /dev/null +++ b/tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/feature-gate-mut_dont_reset_binding_mode_2024.rs:8:9 + | +LL | let Foo(mut a) = &Foo(0); + | ----- expected due to the type of this binding +LL | a = &42; + | ^^^ expected `u8`, found `&{integer}` + | +help: consider removing the borrow + | +LL - a = &42; +LL + a = 42; + | + +error[E0308]: mismatched types + --> $DIR/feature-gate-mut_dont_reset_binding_mode_2024.rs:12:9 + | +LL | let Foo(mut a) = &mut Foo(0); + | ----- expected due to the type of this binding +LL | a = &mut 42; + | ^^^^^^^ expected `u8`, found `&mut {integer}` + | +help: consider removing the borrow + | +LL - a = &mut 42; +LL + a = 42; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2021.rs b/tests/ui/pattern/mut_dont_reset_binding_mode_2021.rs new file mode 100644 index 000000000000..a9e12472734f --- /dev/null +++ b/tests/ui/pattern/mut_dont_reset_binding_mode_2021.rs @@ -0,0 +1,15 @@ +//@ edition: 2021 +//@ compile-flags: -Zunstable-options +#![feature(mut_dont_reset_binding_mode_2024)] + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + a = &42; + //~^ ERROR: mismatched types + + let Foo(mut a) = &mut Foo(0); + a = &mut 42; + //~^ ERROR: mismatched types +} diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2021.stderr b/tests/ui/pattern/mut_dont_reset_binding_mode_2021.stderr new file mode 100644 index 000000000000..16818c900b34 --- /dev/null +++ b/tests/ui/pattern/mut_dont_reset_binding_mode_2021.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/mut_dont_reset_binding_mode_2021.rs:9:9 + | +LL | let Foo(mut a) = &Foo(0); + | ----- expected due to the type of this binding +LL | a = &42; + | ^^^ expected `u8`, found `&{integer}` + | +help: consider removing the borrow + | +LL - a = &42; +LL + a = 42; + | + +error[E0308]: mismatched types + --> $DIR/mut_dont_reset_binding_mode_2021.rs:13:9 + | +LL | let Foo(mut a) = &mut Foo(0); + | ----- expected due to the type of this binding +LL | a = &mut 42; + | ^^^^^^^ expected `u8`, found `&mut {integer}` + | +help: consider removing the borrow + | +LL - a = &mut 42; +LL + a = 42; + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2024.rs b/tests/ui/pattern/mut_dont_reset_binding_mode_2024.rs new file mode 100644 index 000000000000..9ac5ec50c74c --- /dev/null +++ b/tests/ui/pattern/mut_dont_reset_binding_mode_2024.rs @@ -0,0 +1,15 @@ +//@ run-pass +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +#![feature(mut_dont_reset_binding_mode_2024)] +#![allow(unused)] + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + a = &42; + + let Foo(mut a) = &mut Foo(0); + a = &mut 42; +} From 83f330fbd45be04a693e89e9602f0ab2ffab16e2 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 5 Apr 2024 23:28:34 -0400 Subject: [PATCH 065/114] Migration lint Rustfix remains TODO --- compiler/rustc_hir_typeck/messages.ftl | 4 +++ compiler/rustc_hir_typeck/src/errors.rs | 8 +++++ compiler/rustc_hir_typeck/src/pat.rs | 7 ++++ compiler/rustc_lint_defs/src/builtin.rs | 36 +++++++++++++++++++ .../mut_dont_reset_binding_mode_2024_lint.rs | 18 ++++++++++ ...t_dont_reset_binding_mode_2024_lint.stderr | 35 ++++++++++++++++++ 6 files changed, 108 insertions(+) create mode 100644 tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs create mode 100644 tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 18d9d739dd69..07b4948872dd 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -46,6 +46,10 @@ hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty` +hir_typeck_dereferencing_mut_binding = dereferencing `mut` binding + .label = `mut` dereferences the type of this binding + .help = this will change in edition 2024 + hir_typeck_expected_default_return_type = expected `()` because of default return type hir_typeck_expected_return_type = expected `{$expected}` because of return type diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index d399730bf3df..3dc9c7b86f71 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -632,3 +632,11 @@ pub enum SuggestBoxingForReturnImplTrait { ends: Vec, }, } + +#[derive(LintDiagnostic)] +#[diag(hir_typeck_dereferencing_mut_binding)] +pub struct DereferencingMutBinding { + #[label] + #[help] + pub span: Span, +} diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 06f6a7f6bf28..252125aba7c1 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -10,6 +10,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Mutability, Pat, PatKind}; use rustc_infer::infer; use rustc_infer::infer::type_variable::TypeVariableOrigin; +use rustc_lint as lint; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::{self, Adt, Ty, TypeVisitableExt}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; @@ -639,6 +640,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && matches!(def_br, ByRef::Yes(_)) => { // `mut x` resets the binding mode in edition <= 2021. + self.tcx.emit_node_span_lint( + lint::builtin::DEREFERENCING_MUT_BINDING, + pat.hir_id, + pat.span, + errors::DereferencingMutBinding { span: pat.span }, + ); BindingAnnotation(ByRef::No, Mutability::Mut) } BindingAnnotation(ByRef::No, mutbl) => BindingAnnotation(def_br, mutbl), diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 2713690f8120..bc36a587a9ec 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -38,6 +38,7 @@ declare_lint_pass! { DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME, DEPRECATED_IN_FUTURE, DEPRECATED_WHERE_CLAUSE_LOCATION, + DEREFERENCING_MUT_BINDING, DUPLICATE_MACRO_ATTRIBUTES, ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, ELIDED_LIFETIMES_IN_PATHS, @@ -1627,6 +1628,41 @@ declare_lint! { "detect mut variables which don't need to be mutable" } +declare_lint! { + /// The `dereferencing_mut_binding` lint detects a `mut x` pattern that resets the binding mode, + /// as this behavior will change in rust 2024. + /// + /// ### Example + /// + /// ```rust + /// # #![warn(dereferencing_mut_binding)] + /// let x = Some(123u32); + /// let _y = match &x { + /// Some(mut x) => { + /// x += 1; + /// x + /// } + /// None => 0, + /// }; + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Without the `mut`, `x` would have type `&u32`. Pre-2024, adding `mut` makes `x` have type + /// `u32`, which was deeped surprising. After edition 2024, adding `mut` will not change the + /// type of `x`. This lint warns users of editions before 2024 to update their code. + pub DEREFERENCING_MUT_BINDING, + Allow, + "detects `mut x` bindings that change the type of `x`", + @feature_gate = sym::mut_dont_reset_binding_mode_2024; + @future_incompatible = FutureIncompatibleInfo { + reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), + reference: "123076", + }; +} + declare_lint! { /// The `unconditional_recursion` lint detects functions that cannot /// return without calling themselves. diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs b/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs new file mode 100644 index 000000000000..2992e61fbbcd --- /dev/null +++ b/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs @@ -0,0 +1,18 @@ +//@ edition: 2021 +#![feature(mut_dont_reset_binding_mode_2024)] +#![allow(unused)] +#![forbid(dereferencing_mut_binding)] + +struct Foo(u8); + +fn main() { + let Foo(mut a) = &Foo(0); + //~^ ERROR: dereferencing `mut` binding + //~| WARN: this changes meaning in Rust 2024 + a = 42; + + let Foo(mut a) = &mut Foo(0); + //~^ ERROR: dereferencing `mut` binding + //~| WARN: this changes meaning in Rust 2024 + a = 42; +} diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr b/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr new file mode 100644 index 000000000000..72b72f0df5d9 --- /dev/null +++ b/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr @@ -0,0 +1,35 @@ +error: dereferencing `mut` binding + --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:9:13 + | +LL | let Foo(mut a) = &Foo(0); + | ^^^^^ `mut` dereferences the type of this binding + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 +help: this will change in edition 2024 + --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:9:13 + | +LL | let Foo(mut a) = &Foo(0); + | ^^^^^ +note: the lint level is defined here + --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:4:11 + | +LL | #![forbid(dereferencing_mut_binding)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: dereferencing `mut` binding + --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:14:13 + | +LL | let Foo(mut a) = &mut Foo(0); + | ^^^^^ `mut` dereferences the type of this binding + | + = warning: this changes meaning in Rust 2024 + = note: for more information, see 123076 +help: this will change in edition 2024 + --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:14:13 + | +LL | let Foo(mut a) = &mut Foo(0); + | ^^^^^ + +error: aborting due to 2 previous errors + From d5d700d5c65df24dfeec32f6fbd9d1d7b81c70b2 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 6 Apr 2024 00:29:35 -0400 Subject: [PATCH 066/114] Temporarily remove future compatibility label from migration lint The lint is unstable, and the lint group `rust_2024_compatibility` must keep working on stable --- compiler/rustc_lint_defs/src/builtin.rs | 5 +++-- tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs | 2 -- .../pattern/mut_dont_reset_binding_mode_2024_lint.stderr | 8 ++------ 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index bc36a587a9ec..5859f7b4319a 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1657,10 +1657,11 @@ declare_lint! { Allow, "detects `mut x` bindings that change the type of `x`", @feature_gate = sym::mut_dont_reset_binding_mode_2024; - @future_incompatible = FutureIncompatibleInfo { + // FIXME uncomment below upon stabilization + /*@future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), reference: "123076", - }; + };*/ } declare_lint! { diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs b/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs index 2992e61fbbcd..2e8a82d12cd6 100644 --- a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs +++ b/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs @@ -8,11 +8,9 @@ struct Foo(u8); fn main() { let Foo(mut a) = &Foo(0); //~^ ERROR: dereferencing `mut` binding - //~| WARN: this changes meaning in Rust 2024 a = 42; let Foo(mut a) = &mut Foo(0); //~^ ERROR: dereferencing `mut` binding - //~| WARN: this changes meaning in Rust 2024 a = 42; } diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr b/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr index 72b72f0df5d9..4db775f0f518 100644 --- a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr +++ b/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr @@ -4,8 +4,6 @@ error: dereferencing `mut` binding LL | let Foo(mut a) = &Foo(0); | ^^^^^ `mut` dereferences the type of this binding | - = warning: this changes meaning in Rust 2024 - = note: for more information, see 123076 help: this will change in edition 2024 --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:9:13 | @@ -18,15 +16,13 @@ LL | #![forbid(dereferencing_mut_binding)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: dereferencing `mut` binding - --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:14:13 + --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:13:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^^ `mut` dereferences the type of this binding | - = warning: this changes meaning in Rust 2024 - = note: for more information, see 123076 help: this will change in edition 2024 - --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:14:13 + --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:13:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^^ From 1b2e471b43610e74c7cc6e7a38d48293420e157f Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 14 Apr 2024 11:07:23 -0400 Subject: [PATCH 067/114] Fix typo Co-authored-by: Guillaume Boisseau --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 5859f7b4319a..3d80eb1cec9e 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1651,7 +1651,7 @@ declare_lint! { /// ### Explanation /// /// Without the `mut`, `x` would have type `&u32`. Pre-2024, adding `mut` makes `x` have type - /// `u32`, which was deeped surprising. After edition 2024, adding `mut` will not change the + /// `u32`, which was deemed surprising. After edition 2024, adding `mut` will not change the /// type of `x`. This lint warns users of editions before 2024 to update their code. pub DEREFERENCING_MUT_BINDING, Allow, From e13911e6e8d0d85802789a2d75aeb0e4b49ebb33 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 14 Apr 2024 11:12:52 -0400 Subject: [PATCH 068/114] Rename feature gate --- compiler/rustc_feature/src/unstable.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 2 +- compiler/rustc_lint_defs/src/builtin.rs | 2 +- compiler/rustc_span/src/symbol.rs | 2 +- ... => feature-gate-mut_preserve_binding_mode_2024.rs} | 0 ...feature-gate-mut_preserve_binding_mode_2024.stderr} | 4 ++-- ..._mode_2021.rs => mut_preserve_binding_mode_2021.rs} | 2 +- ...21.stderr => mut_preserve_binding_mode_2021.stderr} | 4 ++-- ..._mode_2024.rs => mut_preserve_binding_mode_2024.rs} | 2 +- ..._lint.rs => mut_preserve_binding_mode_2024_lint.rs} | 2 +- ...derr => mut_preserve_binding_mode_2024_lint.stderr} | 10 +++++----- 11 files changed, 16 insertions(+), 16 deletions(-) rename tests/ui/pattern/{feature-gate-mut_dont_reset_binding_mode_2024.rs => feature-gate-mut_preserve_binding_mode_2024.rs} (100%) rename tests/ui/pattern/{feature-gate-mut_dont_reset_binding_mode_2024.stderr => feature-gate-mut_preserve_binding_mode_2024.stderr} (84%) rename tests/ui/pattern/{mut_dont_reset_binding_mode_2021.rs => mut_preserve_binding_mode_2021.rs} (84%) rename tests/ui/pattern/{mut_dont_reset_binding_mode_2021.stderr => mut_preserve_binding_mode_2021.stderr} (87%) rename tests/ui/pattern/{mut_dont_reset_binding_mode_2024.rs => mut_preserve_binding_mode_2024.rs} (82%) rename tests/ui/pattern/{mut_dont_reset_binding_mode_2024_lint.rs => mut_preserve_binding_mode_2024_lint.rs} (86%) rename tests/ui/pattern/{mut_dont_reset_binding_mode_2024_lint.stderr => mut_preserve_binding_mode_2024_lint.stderr} (70%) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 2a753af93872..3fc05752dd1e 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -534,7 +534,7 @@ declare_features! ( /// Allows the `#[must_not_suspend]` attribute. (unstable, must_not_suspend, "1.57.0", Some(83310)), /// Make `mut` not reset the binding mode on edition >= 2024. - (unstable, mut_dont_reset_binding_mode_2024, "CURRENT_RUSTC_VERSION", Some(123076)), + (unstable, mut_preserve_binding_mode_2024, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows `mut ref` and `mut ref mut` identifier patterns. (incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows using `#[naked]` on functions. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 252125aba7c1..cdc6c4d809d1 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -636,7 +636,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let bm = match ba { BindingAnnotation(ByRef::No, Mutability::Mut) if !(pat.span.at_least_rust_2024() - && self.tcx.features().mut_dont_reset_binding_mode_2024) + && self.tcx.features().mut_preserve_binding_mode_2024) && matches!(def_br, ByRef::Yes(_)) => { // `mut x` resets the binding mode in edition <= 2021. diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 3d80eb1cec9e..e74cc388cab4 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -1656,7 +1656,7 @@ declare_lint! { pub DEREFERENCING_MUT_BINDING, Allow, "detects `mut x` bindings that change the type of `x`", - @feature_gate = sym::mut_dont_reset_binding_mode_2024; + @feature_gate = sym::mut_preserve_binding_mode_2024; // FIXME uncomment below upon stabilization /*@future_incompatible = FutureIncompatibleInfo { reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 02550fd655cb..0a95d86ccc89 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1194,7 +1194,7 @@ symbols! { multiple_supertrait_upcastable, must_not_suspend, must_use, - mut_dont_reset_binding_mode_2024, + mut_preserve_binding_mode_2024, mut_ref, naked, naked_functions, diff --git a/tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.rs b/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.rs similarity index 100% rename from tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.rs rename to tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.rs diff --git a/tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.stderr b/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr similarity index 84% rename from tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.stderr rename to tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr index 1624883de60c..6d0a034be21c 100644 --- a/tests/ui/pattern/feature-gate-mut_dont_reset_binding_mode_2024.stderr +++ b/tests/ui/pattern/feature-gate-mut_preserve_binding_mode_2024.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/feature-gate-mut_dont_reset_binding_mode_2024.rs:8:9 + --> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:8:9 | LL | let Foo(mut a) = &Foo(0); | ----- expected due to the type of this binding @@ -13,7 +13,7 @@ LL + a = 42; | error[E0308]: mismatched types - --> $DIR/feature-gate-mut_dont_reset_binding_mode_2024.rs:12:9 + --> $DIR/feature-gate-mut_preserve_binding_mode_2024.rs:12:9 | LL | let Foo(mut a) = &mut Foo(0); | ----- expected due to the type of this binding diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2021.rs b/tests/ui/pattern/mut_preserve_binding_mode_2021.rs similarity index 84% rename from tests/ui/pattern/mut_dont_reset_binding_mode_2021.rs rename to tests/ui/pattern/mut_preserve_binding_mode_2021.rs index a9e12472734f..658ba2851ccb 100644 --- a/tests/ui/pattern/mut_dont_reset_binding_mode_2021.rs +++ b/tests/ui/pattern/mut_preserve_binding_mode_2021.rs @@ -1,6 +1,6 @@ //@ edition: 2021 //@ compile-flags: -Zunstable-options -#![feature(mut_dont_reset_binding_mode_2024)] +#![feature(mut_preserve_binding_mode_2024)] struct Foo(u8); diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2021.stderr b/tests/ui/pattern/mut_preserve_binding_mode_2021.stderr similarity index 87% rename from tests/ui/pattern/mut_dont_reset_binding_mode_2021.stderr rename to tests/ui/pattern/mut_preserve_binding_mode_2021.stderr index 16818c900b34..9487aa64b4f6 100644 --- a/tests/ui/pattern/mut_dont_reset_binding_mode_2021.stderr +++ b/tests/ui/pattern/mut_preserve_binding_mode_2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/mut_dont_reset_binding_mode_2021.rs:9:9 + --> $DIR/mut_preserve_binding_mode_2021.rs:9:9 | LL | let Foo(mut a) = &Foo(0); | ----- expected due to the type of this binding @@ -13,7 +13,7 @@ LL + a = 42; | error[E0308]: mismatched types - --> $DIR/mut_dont_reset_binding_mode_2021.rs:13:9 + --> $DIR/mut_preserve_binding_mode_2021.rs:13:9 | LL | let Foo(mut a) = &mut Foo(0); | ----- expected due to the type of this binding diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2024.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs similarity index 82% rename from tests/ui/pattern/mut_dont_reset_binding_mode_2024.rs rename to tests/ui/pattern/mut_preserve_binding_mode_2024.rs index 9ac5ec50c74c..a5d7ac9d8e6d 100644 --- a/tests/ui/pattern/mut_dont_reset_binding_mode_2024.rs +++ b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs @@ -1,7 +1,7 @@ //@ run-pass //@ edition: 2024 //@ compile-flags: -Zunstable-options -#![feature(mut_dont_reset_binding_mode_2024)] +#![feature(mut_preserve_binding_mode_2024)] #![allow(unused)] struct Foo(u8); diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs similarity index 86% rename from tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs rename to tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs index 2e8a82d12cd6..d3e3ffffcc5e 100644 --- a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.rs +++ b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs @@ -1,5 +1,5 @@ //@ edition: 2021 -#![feature(mut_dont_reset_binding_mode_2024)] +#![feature(mut_preserve_binding_mode_2024)] #![allow(unused)] #![forbid(dereferencing_mut_binding)] diff --git a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr similarity index 70% rename from tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr rename to tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr index 4db775f0f518..e8d11acd83e5 100644 --- a/tests/ui/pattern/mut_dont_reset_binding_mode_2024_lint.stderr +++ b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.stderr @@ -1,28 +1,28 @@ error: dereferencing `mut` binding - --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:9:13 + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^^ `mut` dereferences the type of this binding | help: this will change in edition 2024 - --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:9:13 + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:9:13 | LL | let Foo(mut a) = &Foo(0); | ^^^^^ note: the lint level is defined here - --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:4:11 + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:4:11 | LL | #![forbid(dereferencing_mut_binding)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: dereferencing `mut` binding - --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:13:13 + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^^ `mut` dereferences the type of this binding | help: this will change in edition 2024 - --> $DIR/mut_dont_reset_binding_mode_2024_lint.rs:13:13 + --> $DIR/mut_preserve_binding_mode_2024_lint.rs:13:13 | LL | let Foo(mut a) = &mut Foo(0); | ^^^^^ From 1b6d435cf3e94548f3da6a0409c5786c4accfaa4 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 14 Apr 2024 11:17:58 -0400 Subject: [PATCH 069/114] Mark gate as incomplete --- compiler/rustc_feature/src/unstable.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 3fc05752dd1e..eaaf4026cd75 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -534,7 +534,7 @@ declare_features! ( /// Allows the `#[must_not_suspend]` attribute. (unstable, must_not_suspend, "1.57.0", Some(83310)), /// Make `mut` not reset the binding mode on edition >= 2024. - (unstable, mut_preserve_binding_mode_2024, "CURRENT_RUSTC_VERSION", Some(123076)), + (incomplete, mut_preserve_binding_mode_2024, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows `mut ref` and `mut ref mut` identifier patterns. (incomplete, mut_ref, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows using `#[naked]` on functions. From 7a3211726bb101ab0c0138b2dcff44a175ff74c4 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 14 Apr 2024 13:33:11 -0400 Subject: [PATCH 070/114] Fix tests --- tests/ui/pattern/mut_preserve_binding_mode_2021.rs | 1 + tests/ui/pattern/mut_preserve_binding_mode_2021.stderr | 4 ++-- tests/ui/pattern/mut_preserve_binding_mode_2024.rs | 2 +- tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2021.rs b/tests/ui/pattern/mut_preserve_binding_mode_2021.rs index 658ba2851ccb..befa49fdc247 100644 --- a/tests/ui/pattern/mut_preserve_binding_mode_2021.rs +++ b/tests/ui/pattern/mut_preserve_binding_mode_2021.rs @@ -1,6 +1,7 @@ //@ edition: 2021 //@ compile-flags: -Zunstable-options #![feature(mut_preserve_binding_mode_2024)] +#![allow(incomplete_features)] struct Foo(u8); diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2021.stderr b/tests/ui/pattern/mut_preserve_binding_mode_2021.stderr index 9487aa64b4f6..b800cc4a0f45 100644 --- a/tests/ui/pattern/mut_preserve_binding_mode_2021.stderr +++ b/tests/ui/pattern/mut_preserve_binding_mode_2021.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/mut_preserve_binding_mode_2021.rs:9:9 + --> $DIR/mut_preserve_binding_mode_2021.rs:10:9 | LL | let Foo(mut a) = &Foo(0); | ----- expected due to the type of this binding @@ -13,7 +13,7 @@ LL + a = 42; | error[E0308]: mismatched types - --> $DIR/mut_preserve_binding_mode_2021.rs:13:9 + --> $DIR/mut_preserve_binding_mode_2021.rs:14:9 | LL | let Foo(mut a) = &mut Foo(0); | ----- expected due to the type of this binding diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs index a5d7ac9d8e6d..5454962e16ce 100644 --- a/tests/ui/pattern/mut_preserve_binding_mode_2024.rs +++ b/tests/ui/pattern/mut_preserve_binding_mode_2024.rs @@ -2,7 +2,7 @@ //@ edition: 2024 //@ compile-flags: -Zunstable-options #![feature(mut_preserve_binding_mode_2024)] -#![allow(unused)] +#![allow(incomplete_features, unused)] struct Foo(u8); diff --git a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs index d3e3ffffcc5e..249f251d2cd2 100644 --- a/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs +++ b/tests/ui/pattern/mut_preserve_binding_mode_2024_lint.rs @@ -1,6 +1,6 @@ //@ edition: 2021 #![feature(mut_preserve_binding_mode_2024)] -#![allow(unused)] +#![allow(incomplete_features, unused)] #![forbid(dereferencing_mut_binding)] struct Foo(u8); From 93544d5db3d8f0d0e5d2ea344154689008fa2ff8 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 31 Mar 2024 22:27:19 -0500 Subject: [PATCH 071/114] Match ergonomics 2024: Implement eat-one-layer --- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_hir_typeck/src/pat.rs | 118 +++++++++------- compiler/rustc_span/src/symbol.rs | 1 + ...feature-gate-ref_pat_eat_one_layer_2024.rs | 37 +++++ ...ure-gate-ref_pat_eat_one_layer_2024.stderr | 128 ++++++++++++++++++ .../ref_pat_eat_one_layer_2021.rs | 37 +++++ .../ref_pat_eat_one_layer_2021.stderr | 128 ++++++++++++++++++ .../ref_pat_eat_one_layer_2024.rs | 32 +++++ .../ref_pat_eat_one_layer_2024_fail.rs | 13 ++ .../ref_pat_eat_one_layer_2024_fail.stderr | 25 ++++ 10 files changed, 471 insertions(+), 50 deletions(-) create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index e6b19817de38..5d17675a5325 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -571,6 +571,8 @@ declare_features! ( (unstable, proc_macro_hygiene, "1.30.0", Some(54727)), /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions. (unstable, raw_ref_op, "1.41.0", Some(64490)), + /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024. + (incomplete, ref_pat_eat_one_layer_2024, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references. (incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)), /// Allows using the `#[register_tool]` attribute. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index db4bd132b7e3..ff7716ce7eae 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -294,7 +294,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { AdjustMode::Pass => (expected, def_bm, false), AdjustMode::Reset => (expected, INITIAL_BM, false), AdjustMode::ResetAndConsumeRef(mutbl) => { - (expected, INITIAL_BM, def_bm.0 == ByRef::Yes(mutbl)) + let mutbls_match = def_bm.0 == ByRef::Yes(mutbl); + if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + if mutbls_match { + (expected, INITIAL_BM, true) + } else { + (expected, def_bm, false) + } + } else { + (expected, INITIAL_BM, mutbls_match) + } } AdjustMode::Peel => { let peeled = self.peel_off_references(pat, expected, def_bm); @@ -2056,61 +2065,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat_info: PatInfo<'tcx, '_>, consumed_inherited_ref: bool, ) -> Ty<'tcx> { - let tcx = self.tcx; - let expected = self.shallow_resolve(expected); - let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { - Ok(()) => { - // `demand::subtype` would be good enough, but using `eqtype` turns - // out to be equally general. See (note_1) for details. + if consumed_inherited_ref + && pat.span.at_least_rust_2024() + && self.tcx.features().ref_pat_eat_one_layer_2024 + { + self.typeck_results.borrow_mut().skipped_ref_pats_mut().insert(pat.hir_id); + self.check_pat(inner, expected, pat_info); + expected + } else { + let tcx = self.tcx; + let expected = self.shallow_resolve(expected); + let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { + Ok(()) => { + // `demand::subtype` would be good enough, but using `eqtype` turns + // out to be equally general. See (note_1) for details. - // Take region, inner-type from expected type if we can, - // to avoid creating needless variables. This also helps with - // the bad interactions of the given hack detailed in (note_1). - debug!("check_pat_ref: expected={:?}", expected); - match *expected.kind() { - ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), - _ => { - if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere { - // We already matched against a match-ergonmics inserted reference, - // so we don't need to match against a reference from the original type. - // Save this infor for use in lowering later - self.typeck_results - .borrow_mut() - .skipped_ref_pats_mut() - .insert(pat.hir_id); - (expected, expected) - } else { - let inner_ty = self.next_ty_var(TypeVariableOrigin { - param_def_id: None, - span: inner.span, - }); - let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); - debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); - let err = self.demand_eqtype_pat_diag( - pat.span, - expected, - ref_ty, - pat_info.top_info, - ); + // Take region, inner-type from expected type if we can, + // to avoid creating needless variables. This also helps with + // the bad interactions of the given hack detailed in (note_1). + debug!("check_pat_ref: expected={:?}", expected); + match *expected.kind() { + ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), + _ => { + if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere { + // We already matched against a match-ergonmics inserted reference, + // so we don't need to match against a reference from the original type. + // Save this infor for use in lowering later + self.typeck_results + .borrow_mut() + .skipped_ref_pats_mut() + .insert(pat.hir_id); + (expected, expected) + } else { + let inner_ty = self.next_ty_var(TypeVariableOrigin { + param_def_id: None, + span: inner.span, + }); + let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); + debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); + let err = self.demand_eqtype_pat_diag( + pat.span, + expected, + ref_ty, + pat_info.top_info, + ); - // Look for a case like `fn foo(&foo: u32)` and suggest - // `fn foo(foo: &u32)` - if let Some(mut err) = err { - self.borrow_pat_suggestion(&mut err, pat); - err.emit(); + // Look for a case like `fn foo(&foo: u32)` and suggest + // `fn foo(foo: &u32)` + if let Some(mut err) = err { + self.borrow_pat_suggestion(&mut err, pat); + err.emit(); + } + (ref_ty, inner_ty) } - (ref_ty, inner_ty) } } } - } - Err(guar) => { - let err = Ty::new_error(tcx, guar); - (err, err) - } - }; - self.check_pat(inner, inner_ty, pat_info); - ref_ty + Err(guar) => { + let err = Ty::new_error(tcx, guar); + (err, err) + } + }; + self.check_pat(inner, inner_ty, pat_info); + ref_ty + } } /// Create a reference type with a fresh region variable. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index bfd0f77c237b..baf7fab3ad85 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1460,6 +1460,7 @@ symbols! { receiver, recursion_limit, reexport_test_harness_main, + ref_pat_eat_one_layer_2024, ref_pat_everywhere, ref_unwind_safe_trait, reference, diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs new file mode 100644 index 000000000000..83f1ee6a77e8 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.rs @@ -0,0 +1,37 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options + +pub fn main() { + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(Some(&0)) { + let _: &u32 = x; + //~^ ERROR: mismatched types + } + if let Some(Some(&&x)) = &Some(Some(&0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr new file mode 100644 index 000000000000..132fe421a18d --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/feature-gate-ref_pat_eat_one_layer_2024.stderr @@ -0,0 +1,128 @@ +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:5:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(Some(x)) = &Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:10:23 + | +LL | let _: &u32 = x; + | ---- ^ expected `&u32`, found integer + | | + | expected due to this + | +help: consider borrowing here + | +LL | let _: &u32 = &x; + | + + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:13:23 + | +LL | if let Some(Some(&&x)) = &Some(Some(&0)) { + | ^^ --------------- this expression has type `&Option>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&&x)) = &Some(Some(&0)) { +LL + if let Some(Some(&x)) = &Some(Some(&0)) { + | + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:17:17 + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:21:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:25:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(Some(x)) = &Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:29:27 + | +LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23 + | +LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/feature-gate-ref_pat_eat_one_layer_2024.rs:33:23 + | +LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(&Some(x)) = &mut Some(&Some(0)) { + | ~ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs new file mode 100644 index 000000000000..d28567f2859a --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.rs @@ -0,0 +1,37 @@ +//@ edition: 2021 +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] +pub fn main() { + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(Some(&0)) { + let _: &u32 = x; + //~^ ERROR: mismatched types + } + if let Some(Some(&&x)) = &Some(Some(&0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(x)) = &Some(Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } + if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + //~^ ERROR: mismatched types + let _: u32 = x; + } +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr new file mode 100644 index 000000000000..28706f89c066 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2021.stderr @@ -0,0 +1,128 @@ +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:5:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(Some(x)) = &Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:10:23 + | +LL | let _: &u32 = x; + | ---- ^ expected `&u32`, found integer + | | + | expected due to this + | +help: consider borrowing here + | +LL | let _: &u32 = &x; + | + + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:13:23 + | +LL | if let Some(Some(&&x)) = &Some(Some(&0)) { + | ^^ --------------- this expression has type `&Option>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL - if let Some(Some(&&x)) = &Some(Some(&0)) { +LL + if let Some(Some(&x)) = &Some(Some(&0)) { + | + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:17:17 + | +LL | if let Some(&Some(x)) = &Some(Some(0)) { + | ^^^^^^^^ -------------- this expression has type `&Option>` + | | + | expected `Option<{integer}>`, found `&_` + | + = note: expected enum `Option<{integer}>` + found reference `&_` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/ref_pat_eat_one_layer_2021.rs:21:22 + | +LL | if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(Some(x)) = &mut Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:25:22 + | +LL | if let Some(Some(&x)) = &Some(&Some(0)) { + | ^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(Some(x)) = &Some(&Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:29:27 + | +LL | if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(&mut Some(x)) = &Some(&mut Some(0)) { + | ~ + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23 + | +LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` +note: to declare a mutable binding use: `mut x` + --> $DIR/ref_pat_eat_one_layer_2021.rs:33:23 + | +LL | if let Some(&Some(&mut x)) = &mut Some(&Some(0)) { + | ^^^^^^ +help: consider removing `&mut` from the pattern + | +LL | if let Some(&Some(x)) = &mut Some(&Some(0)) { + | ~ + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs new file mode 100644 index 000000000000..f83784273836 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -0,0 +1,32 @@ +//@ run-pass +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(Some(&x)) = &Some(&Some(0)) { + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(Some(&0)) { + let _: &u32 = x; + } + if let Some(Some(&&x)) = &Some(Some(&0)) { + let _: u32 = x; + } + if let Some(&Some(x)) = &Some(Some(0)) { + let _: u32 = x; + } + if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) { + let _: u32 = x; + } + if let Some(Some(&x)) = &Some(&Some(0)) { + let _: u32 = x; + } + if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { + let _: u32 = x; + } + if let Some(&Some(&mut x)) = &mut Some(& Some(0)) { + let _: u32 = x; + } +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs new file mode 100644 index 000000000000..566196c1a323 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -0,0 +1,13 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(&mut Some(&_)) = &Some(&Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(&_)) = &Some(&mut Some(0)) { + //~^ ERROR: mismatched types + } +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr new file mode 100644 index 000000000000..96a107b5c508 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -0,0 +1,25 @@ +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:7:17 + | +LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { + | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` + | | + | types differ in mutability + | + = note: expected reference `&Option<{integer}>` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23 + | +LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { + | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` + | | + | expected integer, found `&_` + | + = note: expected type `{integer}` + found reference `&_` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 4cd87c463c2a58379b2efd45cdc92027f2965611 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 5 Apr 2024 21:18:05 -0400 Subject: [PATCH 072/114] Properly downgrade inherited mutability --- compiler/rustc_hir_typeck/src/pat.rs | 6 +++- .../ref_pat_eat_one_layer_2024.rs | 11 +++++++- .../ref_pat_eat_one_layer_2024_fail.rs | 7 +++++ .../ref_pat_eat_one_layer_2024_fail.stderr | 28 ++++++++++++++++++- .../ref_pat_eat_one_layer_2024_fail2.rs | 11 ++++++++ .../ref_pat_eat_one_layer_2024_fail2.stderr | 17 +++++++++++ 6 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs create mode 100644 tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index ff7716ce7eae..bec177a2845a 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -299,7 +299,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if mutbls_match { (expected, INITIAL_BM, true) } else { - (expected, def_bm, false) + let mut new_bm = def_bm; + if new_bm.0 == ByRef::Yes(Mutability::Mut) && mutbl == Mutability::Not { + new_bm.0 = ByRef::Yes(Mutability::Not); + } + (expected, new_bm, false) } } else { (expected, INITIAL_BM, mutbls_match) diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs index f83784273836..3cf6008609de 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -26,7 +26,16 @@ pub fn main() { if let Some(&mut Some(&x)) = &Some(&mut Some(0)) { let _: u32 = x; } - if let Some(&Some(&mut x)) = &mut Some(& Some(0)) { + if let Some(&Some(&x)) = &mut Some(&Some(0)) { let _: u32 = x; } + if let Some(&Some(x)) = &mut Some(&Some(0)) { + let _: &u32 = x; + } + if let Some(&Some(&mut ref x)) = Some(&Some(&mut 0)) { + let _: &u32 = x; + } + if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { + let _: &u32 = x; + } } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index 566196c1a323..f8385d2e0494 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -10,4 +10,11 @@ pub fn main() { if let Some(&Some(&_)) = &Some(&mut Some(0)) { //~^ ERROR: mismatched types } + if let Some(&Some(x)) = &mut Some(&Some(0)) { + let _: &mut u32 = x; + //~^ ERROR: mismatched types + } + if let Some(&Some(&x)) = Some(&Some(&mut 0)) { + //~^ ERROR: mismatched types + } } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr index 96a107b5c508..8b714cfcc3ec 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -20,6 +20,32 @@ LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { = note: expected type `{integer}` found reference `&_` -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27 + | +LL | let _: &mut u32 = x; + | -------- ^ types differ in mutability + | | + | expected due to this + | + = note: expected mutable reference `&mut u32` + found reference `&{integer}` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23 + | +LL | if let Some(&Some(&x)) = Some(&Some(&mut 0)) { + | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` + | | + | types differ in mutability + | + = note: expected mutable reference `&mut {integer}` + found reference `&_` +help: consider removing `&` from the pattern + | +LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { + | ~ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs new file mode 100644 index 000000000000..364554884073 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.rs @@ -0,0 +1,11 @@ +//@ edition: 2024 +//@ compile-flags: -Zunstable-options +#![allow(incomplete_features)] +#![feature(ref_pat_eat_one_layer_2024)] + +pub fn main() { + if let Some(&Some(x)) = Some(&Some(&mut 0)) { + //~^ ERROR: cannot move out of a shared reference [E0507] + let _: &u32 = x; + } +} diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr new file mode 100644 index 000000000000..ccfb5c7a0c07 --- /dev/null +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail2.stderr @@ -0,0 +1,17 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/ref_pat_eat_one_layer_2024_fail2.rs:7:29 + | +LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { + | - ^^^^^^^^^^^^^^^^^^^ + | | + | data moved here + | move occurs because `x` has type `&mut u32`, which does not implement the `Copy` trait + | +help: consider borrowing the pattern binding + | +LL | if let Some(&Some(ref x)) = Some(&Some(&mut 0)) { + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0507`. From b6c409723b6438a10db53f12ae6e79f530df8a1b Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Fri, 5 Apr 2024 22:07:57 -0400 Subject: [PATCH 073/114] Support `let &mut x = &&mut 0;` --- compiler/rustc_hir_typeck/src/pat.rs | 23 +++++++++----- .../ref_pat_eat_one_layer_2024.rs | 9 ++++++ .../ref_pat_eat_one_layer_2024_fail.rs | 8 +++++ .../ref_pat_eat_one_layer_2024_fail.stderr | 30 +++++++++++++++++-- 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index bec177a2845a..5930cc0698ab 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -299,18 +299,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if mutbls_match { (expected, INITIAL_BM, true) } else { - let mut new_bm = def_bm; - if new_bm.0 == ByRef::Yes(Mutability::Mut) && mutbl == Mutability::Not { - new_bm.0 = ByRef::Yes(Mutability::Not); - } - (expected, new_bm, false) + let (new_ty, new_bm) = if mutbl == Mutability::Mut { + self.peel_off_references(pat, expected, def_bm, Mutability::Not) + } else { + let new_byref = if def_bm.0 == ByRef::Yes(Mutability::Mut) { + ByRef::Yes(Mutability::Not) + } else { + def_bm.0 + }; + (expected, BindingAnnotation(new_byref, def_bm.1)) + }; + (new_ty, new_bm, false) } } else { (expected, INITIAL_BM, mutbls_match) } } AdjustMode::Peel => { - let peeled = self.peel_off_references(pat, expected, def_bm); + let peeled = self.peel_off_references(pat, expected, def_bm, Mutability::Mut); (peeled.0, peeled.1, false) } } @@ -392,6 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, mut def_bm: BindingAnnotation, + max_mutability: Mutability, ) -> (Ty<'tcx>, BindingAnnotation) { let mut expected = self.try_structurally_resolve_type(pat.span, expected); // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example, @@ -403,7 +410,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // // See the examples in `ui/match-defbm*.rs`. let mut pat_adjustments = vec![]; - while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() { + while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() + && inner_mutability <= max_mutability + { debug!("inspecting {:?}", expected); debug!("current discriminant is Ref, inserting implicit deref"); diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs index 3cf6008609de..2c426f469d84 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -38,4 +38,13 @@ pub fn main() { if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { let _: &u32 = x; } + + let &mut x = &&mut 0; + let _: &u32 = x; + + let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&mut 0; + let _: &u32 = x; + + let &mut &mut &mut &mut x = &mut &&&&mut &&&mut &mut 0; + let _: &u32 = x; } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index f8385d2e0494..9e14a524e2b7 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -17,4 +17,12 @@ pub fn main() { if let Some(&Some(&x)) = Some(&Some(&mut 0)) { //~^ ERROR: mismatched types } + + let &mut x = &&0; + //~^ ERROR: mismatched types + let _: &u32 = x; + + let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + //~^ ERROR: mismatched types + let _: &u32 = x; } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr index 8b714cfcc3ec..074c5d298a55 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -4,9 +4,9 @@ error[E0308]: mismatched types LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { | ^^^^^^^^^^^^^ --------------- this expression has type `&Option<&Option<{integer}>>` | | - | types differ in mutability + | expected `Option<{integer}>`, found `&mut _` | - = note: expected reference `&Option<{integer}>` + = note: expected enum `Option<{integer}>` found mutable reference `&mut _` error[E0308]: mismatched types @@ -46,6 +46,30 @@ help: consider removing `&` from the pattern LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { | ~ -error: aborting due to 4 previous errors +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:9 + | +LL | let &mut x = &&0; + | ^^^^^^ --- this expression has type `&&{integer}` + | | + | expected integer, found `&mut _` + | help: to declare a mutable variable use: `mut x` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:9 + | +LL | let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` + | | + | expected integer, found `&mut _` + | help: to declare a mutable variable use: `mut x` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0308`. From e3945bd3a8236ea6e1f6e1e04842c56a3c689cc5 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sat, 6 Apr 2024 17:07:09 -0400 Subject: [PATCH 074/114] Ensure inherited reference is never set to `&mut` behind an `&` --- compiler/rustc_ast/src/ast.rs | 8 ++ compiler/rustc_hir_typeck/src/pat.rs | 91 +++++++++++-------- .../rustc_mir_build/src/thir/pattern/mod.rs | 2 +- .../ref_pat_eat_one_layer_2024.rs | 15 +++ .../ref_pat_eat_one_layer_2024_fail.rs | 19 ++-- .../ref_pat_eat_one_layer_2024_fail.stderr | 56 ++++++++---- 6 files changed, 124 insertions(+), 67 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5b708cf4e1a5..fc7f64c73926 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -36,6 +36,7 @@ use rustc_macros::HashStable_Generic; use rustc_span::source_map::{respan, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP}; +use std::cmp; use std::fmt; use std::mem; use thin_vec::{thin_vec, ThinVec}; @@ -731,6 +732,13 @@ impl BindingAnnotation { Self::MUT_REF_MUT => "mut ref mut ", } } + + pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self { + if let ByRef::Yes(old_mutbl) = self.0 { + self.0 = ByRef::Yes(cmp::min(old_mutbl, mutbl)); + } + self + } } #[derive(Clone, Encodable, Decodable, Debug)] diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 5930cc0698ab..801c735ade38 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -79,6 +79,7 @@ struct TopInfo<'tcx> { #[derive(Copy, Clone)] struct PatInfo<'tcx, 'a> { binding_mode: BindingAnnotation, + max_ref_mutbl: Mutability, top_info: TopInfo<'tcx>, decl_origin: Option>, @@ -160,8 +161,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { decl_origin: Option>, ) { let info = TopInfo { expected, origin_expr, span }; - let pat_info = - PatInfo { binding_mode: INITIAL_BM, top_info: info, decl_origin, current_depth: 0 }; + let pat_info = PatInfo { + binding_mode: INITIAL_BM, + max_ref_mutbl: Mutability::Mut, + top_info: info, + decl_origin, + current_depth: 0, + }; self.check_pat(pat, expected, pat_info); } @@ -172,7 +178,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Conversely, inside this module, `check_pat_top` should never be used. #[instrument(level = "debug", skip(self, pat_info))] fn check_pat(&self, pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>) { - let PatInfo { binding_mode: def_bm, top_info: ti, current_depth, .. } = pat_info; + let PatInfo { binding_mode: def_bm, max_ref_mutbl, top_info: ti, current_depth, .. } = + pat_info; let path_res = match &pat.kind { PatKind::Path(qpath) => Some( @@ -181,10 +188,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => None, }; let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res)); - let (expected, def_bm, ref_pattern_already_consumed) = - self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode); + let (expected, def_bm, max_ref_mutbl, ref_pattern_already_consumed) = + self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode, max_ref_mutbl); let pat_info = PatInfo { binding_mode: def_bm, + max_ref_mutbl, top_info: ti, decl_origin: pat_info.decl_origin, current_depth: current_depth + 1, @@ -289,35 +297,43 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, def_bm: BindingAnnotation, adjust_mode: AdjustMode, - ) -> (Ty<'tcx>, BindingAnnotation, bool) { + max_ref_mutbl: Mutability, + ) -> (Ty<'tcx>, BindingAnnotation, Mutability, bool) { + if let ByRef::Yes(mutbl) = def_bm.0 { + debug_assert!(mutbl <= max_ref_mutbl); + } match adjust_mode { - AdjustMode::Pass => (expected, def_bm, false), - AdjustMode::Reset => (expected, INITIAL_BM, false), - AdjustMode::ResetAndConsumeRef(mutbl) => { - let mutbls_match = def_bm.0 == ByRef::Yes(mutbl); + AdjustMode::Pass => (expected, def_bm, max_ref_mutbl, false), + AdjustMode::Reset => (expected, INITIAL_BM, Mutability::Mut, false), + AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => { + let mutbls_match = def_bm.0 == ByRef::Yes(ref_pat_mutbl); if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + let max_ref_mutbl = cmp::min(max_ref_mutbl, ref_pat_mutbl); if mutbls_match { - (expected, INITIAL_BM, true) + debug!("consuming inherited reference"); + (expected, INITIAL_BM, max_ref_mutbl, true) } else { - let (new_ty, new_bm) = if mutbl == Mutability::Mut { - self.peel_off_references(pat, expected, def_bm, Mutability::Not) + let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut { + self.peel_off_references( + pat, + expected, + def_bm, + Mutability::Not, + max_ref_mutbl, + ) } else { - let new_byref = if def_bm.0 == ByRef::Yes(Mutability::Mut) { - ByRef::Yes(Mutability::Not) - } else { - def_bm.0 - }; - (expected, BindingAnnotation(new_byref, def_bm.1)) + (expected, def_bm.cap_ref_mutability(Mutability::Not), Mutability::Not) }; - (new_ty, new_bm, false) + (new_ty, new_bm, max_ref_mutbl, false) } } else { - (expected, INITIAL_BM, mutbls_match) + (expected, INITIAL_BM, max_ref_mutbl, mutbls_match) } } AdjustMode::Peel => { - let peeled = self.peel_off_references(pat, expected, def_bm, Mutability::Mut); - (peeled.0, peeled.1, false) + let peeled = + self.peel_off_references(pat, expected, def_bm, Mutability::Mut, max_ref_mutbl); + (peeled.0, peeled.1, peeled.2, false) } } } @@ -398,8 +414,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat: &'tcx Pat<'tcx>, expected: Ty<'tcx>, mut def_bm: BindingAnnotation, - max_mutability: Mutability, - ) -> (Ty<'tcx>, BindingAnnotation) { + max_peelable_mutability: Mutability, + mut max_ref_mutability: Mutability, + ) -> (Ty<'tcx>, BindingAnnotation, Mutability) { let mut expected = self.try_structurally_resolve_type(pat.span, expected); // Peel off as many `&` or `&mut` from the scrutinee type as possible. For example, // for `match &&&mut Some(5)` the loop runs three times, aborting when it reaches @@ -411,7 +428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // See the examples in `ui/match-defbm*.rs`. let mut pat_adjustments = vec![]; while let ty::Ref(_, inner_ty, inner_mutability) = *expected.kind() - && inner_mutability <= max_mutability + && inner_mutability <= max_peelable_mutability { debug!("inspecting {:?}", expected); @@ -430,6 +447,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This is because a `& &mut` cannot mutate the underlying value. ByRef::Yes(Mutability::Not) => Mutability::Not, }); + + if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + max_ref_mutability = cmp::min(max_ref_mutability, inner_mutability); + def_bm = def_bm.cap_ref_mutability(max_ref_mutability); + } } if !pat_adjustments.is_empty() { @@ -440,7 +462,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .insert(pat.hir_id, pat_adjustments); } - (expected, def_bm) + (expected, def_bm, max_ref_mutability) } fn check_pat_lit( @@ -1116,15 +1138,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, pat_info: PatInfo<'tcx, '_>, ) -> Ty<'tcx> { - let PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth } = pat_info; let tcx = self.tcx; let on_error = |e| { for pat in subpats { - self.check_pat( - pat, - Ty::new_error(tcx, e), - PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth }, - ); + self.check_pat(pat, Ty::new_error(tcx, e), pat_info); } }; let report_unexpected_res = |res: Res| { @@ -1169,7 +1186,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let pat_ty = pat_ty.no_bound_vars().expect("expected fn type"); // Type-check the tuple struct pattern against the expected type. - let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, ti); + let diag = self.demand_eqtype_pat_diag(pat.span, expected, pat_ty, pat_info.top_info); let had_err = if let Some(err) = diag { err.emit(); true @@ -1187,11 +1204,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { let field = &variant.fields[FieldIdx::from_usize(i)]; let field_ty = self.field_ty(subpat.span, field, args); - self.check_pat( - subpat, - field_ty, - PatInfo { binding_mode: def_bm, top_info: ti, decl_origin, current_depth }, - ); + self.check_pat(subpat, field_ty, pat_info); self.tcx.check_stability( variant.fields[FieldIdx::from_usize(i)].did, diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 133cf8e33492..bcb43a005470 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Ref(inner, _) if self.typeck_results.skipped_ref_pats().contains(pat.hir_id) => { - self.lower_pattern_unadjusted(inner) + self.lower_pattern(inner) } _ => self.lower_pattern_unadjusted(pat), }; diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs index 2c426f469d84..f1ac3e340e91 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024.rs @@ -38,6 +38,21 @@ pub fn main() { if let Some(Some(&mut x)) = &Some(Some(&mut 0)) { let _: &u32 = x; } + if let &Some(Some(x)) = &Some(&mut Some(0)) { + let _: &u32 = x; + } + if let Some(&Some(&x)) = &Some(&mut Some(0)) { + let _: u32 = x; + } + if let Some(&Some(&x)) = &Some(&Some(0)) { + let _: u32 = x; + } + if let Some(&Some(&x)) = &Some(&mut Some(0)) { + let _: u32 = x; + } + if let Some(&Some(Some(&x))) = &Some(Some(&mut Some(0))) { + let _: u32 = x; + } let &mut x = &&mut 0; let _: &u32 = x; diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs index 9e14a524e2b7..ec091bb17467 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.rs @@ -7,22 +7,27 @@ pub fn main() { if let Some(&mut Some(&_)) = &Some(&Some(0)) { //~^ ERROR: mismatched types } - if let Some(&Some(&_)) = &Some(&mut Some(0)) { + if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { //~^ ERROR: mismatched types } if let Some(&Some(x)) = &mut Some(&Some(0)) { let _: &mut u32 = x; //~^ ERROR: mismatched types } - if let Some(&Some(&x)) = Some(&Some(&mut 0)) { + if let Some(&Some(&_)) = Some(&Some(&mut 0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + //~^ ERROR: mismatched types + } + if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { //~^ ERROR: mismatched types } - let &mut x = &&0; - //~^ ERROR: mismatched types - let _: &u32 = x; - let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; + let &mut _= &&0; + //~^ ERROR: mismatched types + + let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; //~^ ERROR: mismatched types - let _: &u32 = x; } diff --git a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr index 074c5d298a55..be71ee606c76 100644 --- a/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr +++ b/tests/ui/match/ref_pat_eat_one_layer_2024/ref_pat_eat_one_layer_2024_fail.stderr @@ -12,13 +12,13 @@ LL | if let Some(&mut Some(&_)) = &Some(&Some(0)) { error[E0308]: mismatched types --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:10:23 | -LL | if let Some(&Some(&_)) = &Some(&mut Some(0)) { - | ^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` +LL | if let Some(&Some(&mut _)) = &Some(&mut Some(0)) { + | ^^^^^^ ------------------- this expression has type `&Option<&mut Option<{integer}>>` | | - | expected integer, found `&_` + | expected integer, found `&mut _` | - = note: expected type `{integer}` - found reference `&_` + = note: expected type `{integer}` + found mutable reference `&mut _` error[E0308]: mismatched types --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:14:27 @@ -34,42 +34,58 @@ LL | let _: &mut u32 = x; error[E0308]: mismatched types --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:17:23 | -LL | if let Some(&Some(&x)) = Some(&Some(&mut 0)) { +LL | if let Some(&Some(&_)) = Some(&Some(&mut 0)) { | ^^ ------------------- this expression has type `Option<&Option<&mut {integer}>>` | | | types differ in mutability | = note: expected mutable reference `&mut {integer}` found reference `&_` -help: consider removing `&` from the pattern - | -LL | if let Some(&Some(x)) = Some(&Some(&mut 0)) { - | ~ error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:21:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:20:23 | -LL | let &mut x = &&0; - | ^^^^^^ --- this expression has type `&&{integer}` - | | - | expected integer, found `&mut _` - | help: to declare a mutable variable use: `mut x` +LL | if let Some(&Some(&mut _)) = &mut Some(&Some(0)) { + | ^^^^^^ ------------------- this expression has type `&mut Option<&Option<{integer}>>` + | | + | expected integer, found `&mut _` | = note: expected type `{integer}` found mutable reference `&mut _` error[E0308]: mismatched types - --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:25:9 + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:23:29 | -LL | let &mut x = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; +LL | if let Some(&Some(Some((&mut _)))) = &Some(Some(&mut Some(0))) { + | ^^^^^^ ------------------------- this expression has type `&Option>>` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:28:9 + | +LL | let &mut _= &&0; + | ^^^^^^ --- this expression has type `&&{integer}` + | | + | expected integer, found `&mut _` + | + = note: expected type `{integer}` + found mutable reference `&mut _` + +error[E0308]: mismatched types + --> $DIR/ref_pat_eat_one_layer_2024_fail.rs:31:9 + | +LL | let &mut _ = &&&&&&&&&&&&&&&&&&&&&&&&&&&&0; | ^^^^^^ ----------------------------- this expression has type `&&&&&&&&&&&&&&&&&&&&&&&&&&&&{integer}` | | | expected integer, found `&mut _` - | help: to declare a mutable variable use: `mut x` | = note: expected type `{integer}` found mutable reference `&mut _` -error: aborting due to 6 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0308`. From 88cd821e6275ed18e493fd22201ee313154ea6a7 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 14 Apr 2024 10:52:37 -0400 Subject: [PATCH 075/114] Address review comments --- compiler/rustc_ast/src/ast.rs | 4 ++-- compiler/rustc_hir_typeck/src/pat.rs | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fc7f64c73926..334ce5e060b8 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -734,8 +734,8 @@ impl BindingAnnotation { } pub fn cap_ref_mutability(mut self, mutbl: Mutability) -> Self { - if let ByRef::Yes(old_mutbl) = self.0 { - self.0 = ByRef::Yes(cmp::min(old_mutbl, mutbl)); + if let ByRef::Yes(old_mutbl) = &mut self.0 { + *old_mutbl = cmp::min(*old_mutbl, mutbl); } self } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 801c735ade38..28681365af54 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -447,10 +447,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // This is because a `& &mut` cannot mutate the underlying value. ByRef::Yes(Mutability::Not) => Mutability::Not, }); + } - if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { - max_ref_mutability = cmp::min(max_ref_mutability, inner_mutability); - def_bm = def_bm.cap_ref_mutability(max_ref_mutability); + if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { + def_bm = def_bm.cap_ref_mutability(max_ref_mutability); + if def_bm.0 == ByRef::Yes(Mutability::Not) { + max_ref_mutability = Mutability::Not; } } From 3efbe3e70ceb9825bcced29422e5f4a695bb254b Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Sun, 14 Apr 2024 11:01:00 -0400 Subject: [PATCH 076/114] Simplify `calc_default_binding_mode` --- compiler/rustc_hir_typeck/src/pat.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 28681365af54..d66d327c49a4 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -308,10 +308,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { AdjustMode::ResetAndConsumeRef(ref_pat_mutbl) => { let mutbls_match = def_bm.0 == ByRef::Yes(ref_pat_mutbl); if pat.span.at_least_rust_2024() && self.tcx.features().ref_pat_eat_one_layer_2024 { - let max_ref_mutbl = cmp::min(max_ref_mutbl, ref_pat_mutbl); if mutbls_match { debug!("consuming inherited reference"); - (expected, INITIAL_BM, max_ref_mutbl, true) + (expected, INITIAL_BM, cmp::min(max_ref_mutbl, ref_pat_mutbl), true) } else { let (new_ty, new_bm, max_ref_mutbl) = if ref_pat_mutbl == Mutability::Mut { self.peel_off_references( From c0e7659cae9413210148b60278d5c9c2571308b7 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 16 Apr 2024 15:03:58 +1000 Subject: [PATCH 077/114] Move size assertions for `mir::syntax` types into the same file A redundant size assertion for `StatementKind` was added in #122937, because the existing assertion was in a different file. This patch cleans that up, and also moves the `TerminatorKind` assertion into the same file where it belongs, to avoid the same thing happening again. --- compiler/rustc_middle/src/mir/mod.rs | 2 -- compiler/rustc_middle/src/mir/syntax.rs | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 601bfc770f4d..ff5afbbe5d05 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1823,9 +1823,7 @@ mod size_asserts { static_assert_size!(LocalDecl<'_>, 40); static_assert_size!(SourceScopeData<'_>, 64); static_assert_size!(Statement<'_>, 32); - static_assert_size!(StatementKind<'_>, 16); static_assert_size!(Terminator<'_>, 112); - static_assert_size!(TerminatorKind<'_>, 96); static_assert_size!(VarDebugInfo<'_>, 88); // tidy-alphabetical-end } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index c78c225b0cdf..9b4095740264 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1463,5 +1463,6 @@ mod size_asserts { static_assert_size!(PlaceElem<'_>, 24); static_assert_size!(Rvalue<'_>, 40); static_assert_size!(StatementKind<'_>, 16); + static_assert_size!(TerminatorKind<'_>, 96); // tidy-alphabetical-end } From 27374a0214a7b057c19af3af85253268095d8db8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Mar 2024 16:39:02 +1100 Subject: [PATCH 078/114] Avoid unnecessary `rustc_span::DUMMY_SP` usage. In some cases `DUMMY_SP` is already imported. In other cases this commit adds the necessary import, in files where `DUMMY_SP` is used more than once. --- compiler/rustc_ast_pretty/src/pprust/tests.rs | 10 ++++------ .../rustc_builtin_macros/src/deriving/generic/ty.rs | 3 +-- .../rustc_hir_analysis/src/collect/predicates_of.rs | 2 +- compiler/rustc_hir_typeck/src/coercion.rs | 11 +++++------ compiler/rustc_hir_typeck/src/fallback.rs | 9 +++------ compiler/rustc_hir_typeck/src/method/confirm.rs | 4 ++-- compiler/rustc_hir_typeck/src/method/suggest.rs | 13 ++++--------- compiler/rustc_mir_transform/src/gvn.rs | 4 ++-- compiler/rustc_parse/src/parser/item.rs | 7 ++----- .../src/traits/const_evaluatable.rs | 9 ++++----- src/librustdoc/clean/types.rs | 2 +- src/librustdoc/html/render/mod.rs | 6 +++--- src/tools/clippy/clippy_lints/src/non_copy_const.rs | 8 +++----- 13 files changed, 35 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/tests.rs b/compiler/rustc_ast_pretty/src/pprust/tests.rs index 3b2b60a86f06..5b5ffbc6f882 100644 --- a/compiler/rustc_ast_pretty/src/pprust/tests.rs +++ b/compiler/rustc_ast_pretty/src/pprust/tests.rs @@ -3,6 +3,7 @@ use super::*; use rustc_ast as ast; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::Ident; +use rustc_span::DUMMY_SP; use thin_vec::ThinVec; fn fun_to_string( @@ -28,10 +29,7 @@ fn test_fun_to_string() { create_default_session_globals_then(|| { let abba_ident = Ident::from_str("abba"); - let decl = ast::FnDecl { - inputs: ThinVec::new(), - output: ast::FnRetTy::Default(rustc_span::DUMMY_SP), - }; + let decl = ast::FnDecl { inputs: ThinVec::new(), output: ast::FnRetTy::Default(DUMMY_SP) }; let generics = ast::Generics::default(); assert_eq!( fun_to_string(&decl, ast::FnHeader::default(), abba_ident, &generics), @@ -48,7 +46,7 @@ fn test_variant_to_string() { let var = ast::Variant { ident, vis: ast::Visibility { - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, kind: ast::VisibilityKind::Inherited, tokens: None, }, @@ -56,7 +54,7 @@ fn test_variant_to_string() { id: ast::DUMMY_NODE_ID, data: ast::VariantData::Unit(ast::DUMMY_NODE_ID), disr_expr: None, - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, is_placeholder: false, }; diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 603cefdd3862..188833246832 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -8,8 +8,7 @@ use rustc_ast::{self as ast, Expr, GenericArg, GenericParamKind, Generics, SelfK use rustc_expand::base::ExtCtxt; use rustc_span::source_map::respan; use rustc_span::symbol::{kw, Ident, Symbol}; -use rustc_span::Span; -use rustc_span::DUMMY_SP; +use rustc_span::{Span, DUMMY_SP}; use thin_vec::ThinVec; /// A path, e.g., `::std::option::Option::` (global). Has support diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index efd3ceebe6ca..472657290ed1 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -37,7 +37,7 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic // 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 span = rustc_span::DUMMY_SP; + let span = DUMMY_SP; result.predicates = tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once(( diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 53043fc6c68e..9ebb5f95f05f 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -59,8 +59,7 @@ use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; -use rustc_span::DesugaringKind; -use rustc_span::{BytePos, Span}; +use rustc_span::{BytePos, DesugaringKind, Span, DUMMY_SP}; use rustc_target::spec::abi::Abi; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; @@ -1045,7 +1044,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let source = self.resolve_vars_with_obligations(expr_ty); debug!("coercion::can_with_predicates({:?} -> {:?})", source, target); - let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable); + let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion let coerce = Coerce::new(self, cause, AllowTwoPhase::No); self.probe(|_| { @@ -1062,11 +1061,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// how many dereference steps needed to achieve `expr_ty <: target`. If /// it's not possible, return `None`. pub fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option { - let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable); + let cause = self.cause(DUMMY_SP, ObligationCauseCode::ExprAssignable); // We don't ever need two-phase here since we throw out the result of the coercion let coerce = Coerce::new(self, cause, AllowTwoPhase::No); coerce - .autoderef(rustc_span::DUMMY_SP, expr_ty) + .autoderef(DUMMY_SP, expr_ty) .find_map(|(ty, steps)| self.probe(|_| coerce.unify(ty, target)).ok().map(|_| steps)) } @@ -1077,7 +1076,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// trait or region sub-obligations. (presumably we could, but it's not /// particularly important for diagnostics...) pub fn deref_once_mutably_for_diagnostic(&self, expr_ty: Ty<'tcx>) -> Option> { - self.autoderef(rustc_span::DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| { + self.autoderef(DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| { self.infcx .type_implements_trait( self.tcx.lang_items().deref_mut_trait()?, diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 69399b50695d..c0b3984e3e17 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -5,6 +5,7 @@ use rustc_data_structures::{ }; use rustc_infer::infer::{DefineOpaqueTypes, InferOk}; use rustc_middle::ty::{self, Ty}; +use rustc_span::DUMMY_SP; #[derive(Copy, Clone)] pub enum DivergingFallbackBehavior { @@ -102,7 +103,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // that field is only used for type fallback diagnostics. for effect in unsolved_effects { let expected = self.tcx.consts.true_; - let cause = self.misc(rustc_span::DUMMY_SP); + let cause = self.misc(DUMMY_SP); match self.at(&cause, self.param_env).eq(DefineOpaqueTypes::Yes, expected, effect) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); @@ -165,11 +166,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { }; debug!("fallback_if_possible(ty={:?}): defaulting to `{:?}`", ty, fallback); - let span = self - .infcx - .type_var_origin(ty) - .map(|origin| origin.span) - .unwrap_or(rustc_span::DUMMY_SP); + let span = self.infcx.type_var_origin(ty).map(|origin| origin.span).unwrap_or(DUMMY_SP); self.demand_eqtype(span, ty, fallback); self.fallback_has_occurred.set(true); true diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 36860e446fc2..02759064abd4 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -173,7 +173,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let Some((ty, n)) = autoderef.nth(pick.autoderefs) else { return Ty::new_error_with_message( self.tcx, - rustc_span::DUMMY_SP, + DUMMY_SP, format!("failed autoderef {}", pick.autoderefs), ); }; @@ -608,7 +608,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { let span = predicates .iter() .find_map(|(p, span)| if p == pred { Some(span) } else { None }) - .unwrap_or(rustc_span::DUMMY_SP); + .unwrap_or(DUMMY_SP); Some((trait_pred, span)) } _ => None, diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 8a16e726451a..46227e406a32 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1844,23 +1844,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { has_unsuggestable_args = true; match arg.unpack() { GenericArgKind::Lifetime(_) => self - .next_region_var(RegionVariableOrigin::MiscVariable( - rustc_span::DUMMY_SP, - )) + .next_region_var(RegionVariableOrigin::MiscVariable(DUMMY_SP)) .into(), GenericArgKind::Type(_) => self .next_ty_var(TypeVariableOrigin { - span: rustc_span::DUMMY_SP, + span: DUMMY_SP, param_def_id: None, }) .into(), GenericArgKind::Const(arg) => self .next_const_var( arg.ty(), - ConstVariableOrigin { - span: rustc_span::DUMMY_SP, - param_def_id: None, - }, + ConstVariableOrigin { span: DUMMY_SP, param_def_id: None }, ) .into(), } @@ -2758,7 +2753,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let SelfSource::QPath(ty) = self_source else { return; }; - for (deref_ty, _) in self.autoderef(rustc_span::DUMMY_SP, rcvr_ty).skip(1) { + for (deref_ty, _) in self.autoderef(DUMMY_SP, rcvr_ty).skip(1) { if let Ok(pick) = self.probe_for_name( Mode::Path, item_name, diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index d4f736d2a50f..8e8d78226c30 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -1202,7 +1202,7 @@ impl<'tcx> VnState<'_, 'tcx> { // not give the same value as the former mention. && value.is_deterministic() { - return Some(ConstOperand { span: rustc_span::DUMMY_SP, user_ty: None, const_: value }); + return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_: value }); } let op = self.evaluated[index].as_ref()?; @@ -1219,7 +1219,7 @@ impl<'tcx> VnState<'_, 'tcx> { assert!(!value.may_have_provenance(self.tcx, op.layout.size)); let const_ = Const::Val(value, op.layout.ty); - Some(ConstOperand { span: rustc_span::DUMMY_SP, user_ty: None, const_ }) + Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_ }) } /// If there is a local which is assigned `index`, and its assignment strictly dominates `loc`, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 003479b9d8ec..1260c20fd55f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1968,11 +1968,8 @@ impl<'a> Parser<'a> { } else if matches!(is_raw, IdentIsRaw::No) && ident.is_reserved() { let snapshot = self.create_snapshot_for_diagnostic(); let err = if self.check_fn_front_matter(false, Case::Sensitive) { - let inherited_vis = Visibility { - span: rustc_span::DUMMY_SP, - kind: VisibilityKind::Inherited, - tokens: None, - }; + let inherited_vis = + Visibility { span: DUMMY_SP, kind: VisibilityKind::Inherited, tokens: None }; // We use `parse_fn` to get a span for the function let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true }; match self.parse_fn( diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 9ca1dd4557dc..a8be5627fed8 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -8,15 +8,14 @@ //! In this case we try to build an abstract representation of this constant using //! `thir_abstract_const` which can then be checked for structural equality with other //! generic constants mentioned in the `caller_bounds` of the current environment. + use rustc_hir::def::DefKind; use rustc_infer::infer::InferCtxt; use rustc_middle::mir::interpret::ErrorHandled; - use rustc_middle::traits::ObligationCause; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor}; - -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use crate::traits::ObligationCtxt; @@ -116,12 +115,12 @@ pub fn is_const_evaluatable<'tcx>( tcx.dcx() .struct_span_fatal( // Slightly better span than just using `span` alone - if span == rustc_span::DUMMY_SP { tcx.def_span(uv.def) } else { span }, + if span == DUMMY_SP { tcx.def_span(uv.def) } else { span }, "failed to evaluate generic const expression", ) .with_note("the crate this constant originates from uses `#![feature(generic_const_exprs)]`") .with_span_suggestion_verbose( - rustc_span::DUMMY_SP, + DUMMY_SP, "consider enabling this feature", "#![feature(generic_const_exprs)]\n", rustc_errors::Applicability::MaybeIncorrect, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index b592bd76e4c3..aeb7137b7224 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -408,7 +408,7 @@ impl Item { pub(crate) fn attr_span(&self, tcx: TyCtxt<'_>) -> rustc_span::Span { span_of_fragments(&self.attrs.doc_strings) - .unwrap_or_else(|| self.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner())) + .unwrap_or_else(|| self.span(tcx).map_or(DUMMY_SP, |span| span.inner())) } /// Combine all doc strings into a single value handling indentation and newlines as needed. diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 4e46f847fd76..a949f7957536 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -56,7 +56,7 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_session::RustcVersion; use rustc_span::{ symbol::{sym, Symbol}, - BytePos, FileName, RealFileName, + BytePos, FileName, RealFileName, DUMMY_SP, }; use serde::ser::SerializeMap; use serde::{Serialize, Serializer}; @@ -2414,7 +2414,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c let contents = match fs::read_to_string(&path) { Ok(contents) => contents, Err(err) => { - let span = item.span(tcx).map_or(rustc_span::DUMMY_SP, |span| span.inner()); + let span = item.span(tcx).map_or(DUMMY_SP, |span| span.inner()); tcx.dcx().span_err(span, format!("failed to read file {}: {err}", path.display())); return false; } @@ -2495,7 +2495,7 @@ fn render_call_locations(mut w: W, cx: &mut Context<'_>, item: &c file.start_pos + BytePos(byte_max), )) })() - .unwrap_or(rustc_span::DUMMY_SP); + .unwrap_or(DUMMY_SP); let mut decoration_info = FxHashMap::default(); decoration_info.insert("highlight focus", vec![byte_ranges.remove(0)]); diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 73fc34c2450f..5ca388d67a17 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId}; use rustc_middle::ty::adjustment::Adjust; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::impl_lint_pass; -use rustc_span::{sym, InnerSpan, Span}; +use rustc_span::{sym, DUMMY_SP, InnerSpan, Span}; use rustc_target::abi::VariantIdx; // FIXME: this is a correctness problem but there's no suitable @@ -290,9 +290,7 @@ impl NonCopyConst { promoted: None, }; let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx); - let result = cx - .tcx - .const_eval_global_id_for_typeck(param_env, cid, rustc_span::DUMMY_SP); + let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, DUMMY_SP); self.is_value_unfrozen_raw(cx, result, ty) } @@ -303,7 +301,7 @@ impl NonCopyConst { cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), - rustc_span::DUMMY_SP, + DUMMY_SP, ); self.is_value_unfrozen_raw(cx, result, ty) } From e93f75428934cce6c14b34fdb44d06affe3f4802 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Mar 2024 16:54:36 +1100 Subject: [PATCH 079/114] Always use `ty::` qualifier for `TyKind` enum variants. Because that's the way it should be done. --- .../rustc_const_eval/src/transform/check_consts/ops.rs | 9 +++++---- compiler/rustc_hir_typeck/src/method/prelude2021.rs | 8 ++++---- compiler/rustc_hir_typeck/src/pat.rs | 4 ++-- src/librustdoc/html/render/type_layout.rs | 5 ++--- src/tools/clippy/clippy_lints/src/derivable_impls.rs | 6 +++--- .../clippy/clippy_lints/src/from_raw_with_void_ptr.rs | 4 ++-- src/tools/clippy/clippy_lints/src/functions/result.rs | 6 +++--- .../clippy/clippy_lints/src/implicit_saturating_add.rs | 3 ++- src/tools/clippy/clippy_lints/src/large_enum_variant.rs | 6 +++--- .../clippy/clippy_lints/src/methods/unnecessary_join.rs | 6 +++--- src/tools/clippy/clippy_lints/src/mut_key.rs | 4 ++-- .../clippy/clippy_lints/src/zero_sized_map_values.rs | 4 ++-- 12 files changed, 33 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index e87e60f62dc8..9775f1980c59 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -9,9 +9,10 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_middle::mir::{self, CallSource}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::TraitRef; -use rustc_middle::ty::{suggest_constraining_type_param, Adt, Closure, FnDef, FnPtr, Param, Ty}; -use rustc_middle::ty::{GenericArgKind, GenericArgsRef}; +use rustc_middle::ty::{ + self as middle_ty, suggest_constraining_type_param, Closure, FnDef, FnPtr, GenericArgKind, + GenericArgsRef, Param, TraitRef, Ty, +}; use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; @@ -123,7 +124,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { ); } } - Adt(..) => { + middle_ty::Adt(..) => { let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 819641283451..22eef8e53dae 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -8,7 +8,7 @@ use hir::ItemKind; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_infer::infer::type_variable::TypeVariableOrigin; -use rustc_middle::ty::{Adt, Array, Ref, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::{Empty, Underscore}; use rustc_span::symbol::{sym, Ident}; @@ -44,7 +44,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // but `[T; N].into_iter()` doesn't resolve to IntoIterator::into_iter // before Rust 2021, which results in the same problem. // It is only a problem for arrays. - sym::into_iter if let Array(..) = self_ty.kind() => { + sym::into_iter if let ty::Array(..) = self_ty.kind() => { // In this case, it wasn't really a prelude addition that was the problem. // Instead, the problem is that the array-into_iter hack will no longer apply in Rust 2021. rustc_lint::ARRAY_INTO_ITER @@ -64,7 +64,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pick.autoref_or_ptr_adjustment, Some(probe::AutorefOrPtrAdjustment::Autoref { .. }) ) - && matches!(self_ty.kind(), Ref(..)) + && matches!(self_ty.kind(), ty::Ref(..)) { return; } @@ -278,7 +278,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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() { + if let ty::Adt(def, _) = self_ty.kind() { let generics = self.tcx.generics_of(def.did()); if !generics.params.is_empty() { let counts = generics.own_counts(); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index db4bd132b7e3..506eb4b88859 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -11,7 +11,7 @@ use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Mutability, Pat, P use rustc_infer::infer; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::ty::{self, Adt, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::DesugaringKind; @@ -1046,7 +1046,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => { let (type_def_id, item_def_id) = match pat_ty.kind() { - Adt(def, _) => match res { + ty::Adt(def, _) => match res { Res::Def(DefKind::Const, def_id) => (Some(def.did()), Some(def_id)), _ => (None, None), }, diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index 738ea0aee7e9..a27e327f2353 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -3,8 +3,7 @@ use askama::Template; use rustc_data_structures::captures::Captures; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; -use rustc_middle::ty::layout::LayoutError; -use rustc_middle::ty::Adt; +use rustc_middle::ty::{self, layout::LayoutError}; use rustc_span::symbol::Symbol; use rustc_target::abi::{Primitive, TagEncoding, Variants}; @@ -57,7 +56,7 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>( variants .iter_enumerated() .map(|(variant_idx, variant_layout)| { - let Adt(adt, _) = type_layout.ty.kind() else { + let ty::Adt(adt, _) = type_layout.ty.kind() else { span_bug!(tcx.def_span(ty_def_id), "not an adt") }; let name = adt.variant(variant_idx).name; diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 80327586fedc..0c9ad5e8d001 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -9,7 +9,7 @@ use rustc_hir::{ }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, PointerCoercion}; -use rustc_middle::ty::{self, Adt, AdtDef, GenericArgsRef, Ty, TypeckResults}; +use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty, TypeckResults}; use rustc_session::impl_lint_pass; use rustc_span::sym; @@ -79,7 +79,7 @@ fn is_path_self(e: &Expr<'_>) -> bool { fn contains_trait_object(ty: Ty<'_>) -> bool { match ty.kind() { ty::Ref(_, ty, _) => contains_trait_object(*ty), - Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object), + ty::Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object), ty::Dynamic(..) => true, _ => false, } @@ -198,7 +198,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir) && let ImplItemKind::Fn(_, b) = &impl_item.kind && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b) - && let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() + && let &ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind() && let attrs = cx.tcx.hir().attrs(item.hir_id()) && !attrs.iter().any(|attr| attr.doc_str().is_some()) && cx.tcx.hir().attrs(impl_item_hir).is_empty() diff --git a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs index ba2495c17a21..d62d008d480f 100644 --- a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs +++ b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs @@ -4,7 +4,7 @@ use clippy_utils::ty::is_c_void; use rustc_hir::def_id::DefId; use rustc_hir::{Expr, ExprKind, QPath}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::RawPtr; +use rustc_middle::ty; use rustc_session::declare_lint_pass; use rustc_span::sym; @@ -44,7 +44,7 @@ impl LateLintPass<'_> for FromRawWithVoidPtr { && seg.ident.name == sym!(from_raw) && let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id)) && let arg_kind = cx.typeck_results().expr_ty(arg).kind() - && let RawPtr(ty, _) = arg_kind + && let ty::RawPtr(ty, _) = arg_kind && is_c_void(cx, *ty) { let msg = format!("creating a `{type_str}` from a void raw pointer"); diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs index 93f088d3e339..c3a0b40a677a 100644 --- a/src/tools/clippy/clippy_lints/src/functions/result.rs +++ b/src/tools/clippy/clippy_lints/src/functions/result.rs @@ -2,7 +2,7 @@ use rustc_errors::Diag; use rustc_hir as hir; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{Adt, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_span::{sym, Span}; use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then}; @@ -25,7 +25,7 @@ fn result_err_ty<'tcx>( .tcx .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(id).instantiate_identity().output()) && is_type_diagnostic_item(cx, ty, sym::Result) - && let Adt(_, args) = ty.kind() + && let ty::Adt(_, args) = ty.kind() { let err_ty = args.type_at(1); Some((hir_ty, err_ty)) @@ -86,7 +86,7 @@ fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: S } fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty_span: Span, large_err_threshold: u64) { - if let Adt(adt, subst) = err_ty.kind() + if let ty::Adt(adt, subst) = err_ty.kind() && let Some(local_def_id) = err_ty .ty_adt_def() .expect("already checked this is adt") diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs index b8d7e8f3b07c..f225c6e7f049 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs @@ -7,7 +7,7 @@ use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{Int, IntTy, Ty, Uint, UintTy}; +use rustc_middle::ty::{IntTy, Ty, UintTy}; use rustc_session::declare_lint_pass; declare_clippy_lint! { @@ -97,6 +97,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { } fn get_int_max(ty: Ty<'_>) -> Option { + use rustc_middle::ty::{Int, Uint}; match ty.peel_refs().kind() { Int(IntTy::I8) => i8::MAX.try_into().ok(), Int(IntTy::I16) => i16::MAX.try_into().ok(), diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs index 6feb18855764..0bf7389ef9cc 100644 --- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs +++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs @@ -7,7 +7,7 @@ use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{Adt, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use rustc_span::Span; @@ -82,7 +82,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { } if let ItemKind::Enum(ref def, _) = item.kind { let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); - let Adt(adt, subst) = ty.kind() else { + let ty::Adt(adt, subst) = ty.kind() else { panic!("already checked whether this is an enum") }; if adt.variants().len() <= 1 { @@ -167,7 +167,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { } fn maybe_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - if let Adt(_def, args) = ty.kind() + if let ty::Adt(_def, args) = ty.kind() && args.types().next().is_some() && let Some(copy_trait) = cx.tcx.lang_items().copy_trait() { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs index c3ad4db38759..efd1a718504c 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_join.rs @@ -4,7 +4,7 @@ use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, LangItem}; use rustc_lint::LateContext; -use rustc_middle::ty::{Ref, Slice}; +use rustc_middle::ty; use rustc_span::Span; use super::UNNECESSARY_JOIN; @@ -18,9 +18,9 @@ pub(super) fn check<'tcx>( ) { let applicability = Applicability::MachineApplicable; let collect_output_adjusted_type = cx.typeck_results().expr_ty_adjusted(join_self_arg); - if let Ref(_, ref_type, _) = collect_output_adjusted_type.kind() + if let ty::Ref(_, ref_type, _) = collect_output_adjusted_type.kind() // the turbofish for collect is ::> - && let Slice(slice) = ref_type.kind() + && let ty::Slice(slice) = ref_type.kind() && is_type_lang_item(cx, *slice, LangItem::String) // the argument for join is "" && let ExprKind::Lit(spanned) = &join_arg.kind diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs index 79f0a398d55d..8c2f43c97f4d 100644 --- a/src/tools/clippy/clippy_lints/src/mut_key.rs +++ b/src/tools/clippy/clippy_lints/src/mut_key.rs @@ -4,7 +4,7 @@ use clippy_utils::{def_path_def_ids, trait_ref_of_method}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::{Adt, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::sym; @@ -153,7 +153,7 @@ impl MutableKeyType { // generics (because the compiler cannot ensure immutability for unknown types). fn check_ty_<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { let ty = ty.peel_refs(); - if let Adt(def, args) = ty.kind() { + if let ty::Adt(def, args) = ty.kind() { let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet] .iter() .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did())); diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index d1f7c6417c7e..e14480b86556 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -4,7 +4,7 @@ use rustc_hir::{self as hir, HirId, ItemKind, Node}; use rustc_hir_analysis::lower_ty; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf as _; -use rustc_middle::ty::{Adt, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_session::declare_lint_pass; use rustc_span::sym; @@ -49,7 +49,7 @@ impl LateLintPass<'_> for ZeroSizedMapValues { && !in_trait_impl(cx, hir_ty.hir_id) && let ty = ty_from_hir_ty(cx, hir_ty) && (is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap)) - && let Adt(_, args) = ty.kind() + && let ty::Adt(_, args) = ty.kind() && let ty = args.type_at(1) // Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of // https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/sty.rs#L968 From 4b27cc8b7ab0551475ce1799e8cc43c5d1327f7e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 6 Mar 2024 17:24:13 +1100 Subject: [PATCH 080/114] Avoid lots of `hir::HirId{,Map,Set}` qualifiers. Because they're a bit redundant. --- compiler/rustc_ast_lowering/src/expr.rs | 11 +++-- compiler/rustc_ast_lowering/src/lib.rs | 37 ++++++--------- .../src/collect/resolve_bound_vars.rs | 20 ++++---- .../src/hir_ty_lowering/mod.rs | 37 +++++---------- compiler/rustc_hir_pretty/src/lib.rs | 17 +++---- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../rustc_hir_typeck/src/expr_use_visitor.rs | 22 ++++----- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 38 +++++++-------- .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 19 +++----- .../src/fn_ctxt/suggestions.rs | 8 ++-- .../rustc_hir_typeck/src/gather_locals.rs | 12 ++--- compiler/rustc_hir_typeck/src/lib.rs | 6 +-- .../src/mem_categorization.rs | 30 +++++------- compiler/rustc_hir_typeck/src/method/probe.rs | 15 +++--- .../rustc_hir_typeck/src/typeck_root_ctxt.rs | 6 +-- compiler/rustc_hir_typeck/src/upvar.rs | 29 ++++++------ compiler/rustc_hir_typeck/src/writeback.rs | 25 +++++----- compiler/rustc_lint/src/late.rs | 9 ++-- compiler/rustc_middle/src/middle/region.rs | 14 ++---- compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/thir.rs | 14 +++--- compiler/rustc_middle/src/traits/mod.rs | 31 ++++++------ compiler/rustc_middle/src/ty/closure.rs | 13 ++--- .../rustc_middle/src/ty/typeck_results.rs | 47 +++++++++---------- compiler/rustc_mir_build/src/build/mod.rs | 10 ++-- .../rustc_mir_build/src/check_unsafety.rs | 24 ++++------ compiler/rustc_passes/src/hir_stats.rs | 4 +- compiler/rustc_passes/src/liveness.rs | 2 +- compiler/rustc_passes/src/naked_functions.rs | 6 +-- compiler/rustc_passes/src/upvars.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 4 +- .../src/functions/not_unsafe_ptr_arg_deref.rs | 4 +- .../clippy_lints/src/index_refutable_slice.rs | 13 ++--- .../src/operators/assign_op_pattern.rs | 33 ++++++------- src/tools/clippy/clippy_lints/src/ptr.rs | 4 +- .../src/significant_drop_tightening.rs | 18 +++---- 36 files changed, 276 insertions(+), 312 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 389cf4e31321..66841c094cec 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -14,6 +14,7 @@ use rustc_ast::*; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; +use rustc_hir::HirId; use rustc_middle::span_bug; use rustc_session::errors::report_lit_error; use rustc_span::source_map::{respan, Spanned}; @@ -701,8 +702,8 @@ impl<'hir> LoweringContext<'_, 'hir> { pub(super) fn maybe_forward_track_caller( &mut self, span: Span, - outer_hir_id: hir::HirId, - inner_hir_id: hir::HirId, + outer_hir_id: HirId, + inner_hir_id: HirId, ) { if self.tcx.features().async_fn_track_caller && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id) @@ -1048,7 +1049,7 @@ impl<'hir> LoweringContext<'_, 'hir> { binder: &ClosureBinder, capture_clause: CaptureBy, closure_id: NodeId, - closure_hir_id: hir::HirId, + closure_hir_id: HirId, coroutine_kind: CoroutineKind, decl: &FnDecl, body: &Expr, @@ -2036,7 +2037,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, sp: Span, ident: Ident, - binding: hir::HirId, + binding: HirId, ) -> &'hir hir::Expr<'hir> { self.arena.alloc(self.expr_ident_mut(sp, ident, binding)) } @@ -2045,7 +2046,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, span: Span, ident: Ident, - binding: hir::HirId, + binding: HirId, ) -> hir::Expr<'hir> { let hir_id = self.next_id(); let res = Res::Local(binding); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5005c22d4cc3..7f153c52fcb8 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -56,7 +56,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, LocalDefIdMap, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{ - ConstArg, GenericArg, ItemLocalMap, MissingLifetimeKind, ParamName, TraitCandidate, + ConstArg, GenericArg, HirId, ItemLocalMap, MissingLifetimeKind, ParamName, TraitCandidate, }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_macros::extension; @@ -107,7 +107,7 @@ struct LoweringContext<'a, 'hir> { /// When inside an `async` context, this is the `HirId` of the /// `task_context` local bound to the resume argument of the coroutine. - task_context: Option, + task_context: Option, /// Used to get the current `fn`'s def span to point to when using `await` /// outside of an `async fn`. @@ -661,18 +661,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// `HirIdValidator` later on, which makes sure that all `NodeId`s got mapped /// properly. Calling the method twice with the same `NodeId` is fine though. #[instrument(level = "debug", skip(self), ret)] - fn lower_node_id(&mut self, ast_node_id: NodeId) -> hir::HirId { + fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId { assert_ne!(ast_node_id, DUMMY_NODE_ID); match self.node_id_to_local_id.entry(ast_node_id) { - Entry::Occupied(o) => { - hir::HirId { owner: self.current_hir_id_owner, local_id: *o.get() } - } + Entry::Occupied(o) => HirId { owner: self.current_hir_id_owner, local_id: *o.get() }, Entry::Vacant(v) => { // Generate a new `HirId`. let owner = self.current_hir_id_owner; let local_id = self.item_local_id_counter; - let hir_id = hir::HirId { owner, local_id }; + let hir_id = HirId { owner, local_id }; v.insert(local_id); self.item_local_id_counter.increment_by(1); @@ -693,12 +691,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Generate a new `HirId` without a backing `NodeId`. #[instrument(level = "debug", skip(self), ret)] - fn next_id(&mut self) -> hir::HirId { + fn next_id(&mut self) -> HirId { let owner = self.current_hir_id_owner; let local_id = self.item_local_id_counter; assert_ne!(local_id, hir::ItemLocalId::ZERO); self.item_local_id_counter.increment_by(1); - hir::HirId { owner, local_id } + HirId { owner, local_id } } #[instrument(level = "trace", skip(self))] @@ -706,7 +704,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let res: Result = res.apply_id(|id| { let owner = self.current_hir_id_owner; let local_id = self.node_id_to_local_id.get(&id).copied().ok_or(())?; - Ok(hir::HirId { owner, local_id }) + Ok(HirId { owner, local_id }) }); trace!(?res); @@ -889,7 +887,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ret } - fn lower_attrs(&mut self, id: hir::HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> { + fn lower_attrs(&mut self, id: HirId, attrs: &[Attribute]) -> Option<&'hir [Attribute]> { if attrs.is_empty() { None } else { @@ -921,7 +919,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Attribute { kind, id: attr.id, style: attr.style, span: self.lower_span(attr.span) } } - fn alias_attrs(&mut self, id: hir::HirId, target_id: hir::HirId) { + fn alias_attrs(&mut self, id: HirId, target_id: HirId) { debug_assert_eq!(id.owner, self.current_hir_id_owner); debug_assert_eq!(target_id.owner, self.current_hir_id_owner); if let Some(&a) = self.attrs.get(&target_id.local_id) { @@ -2421,11 +2419,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.pat(span, hir::PatKind::Struct(qpath, fields, false)) } - fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, hir::HirId) { + fn pat_ident(&mut self, span: Span, ident: Ident) -> (&'hir hir::Pat<'hir>, HirId) { self.pat_ident_binding_mode(span, ident, hir::BindingAnnotation::NONE) } - fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, hir::HirId) { + fn pat_ident_mut(&mut self, span: Span, ident: Ident) -> (hir::Pat<'hir>, HirId) { self.pat_ident_binding_mode_mut(span, ident, hir::BindingAnnotation::NONE) } @@ -2434,7 +2432,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, ident: Ident, bm: hir::BindingAnnotation, - ) -> (&'hir hir::Pat<'hir>, hir::HirId) { + ) -> (&'hir hir::Pat<'hir>, HirId) { let (pat, hir_id) = self.pat_ident_binding_mode_mut(span, ident, bm); (self.arena.alloc(pat), hir_id) } @@ -2444,7 +2442,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: Span, ident: Ident, bm: hir::BindingAnnotation, - ) -> (hir::Pat<'hir>, hir::HirId) { + ) -> (hir::Pat<'hir>, HirId) { let hir_id = self.next_id(); ( @@ -2476,12 +2474,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn ty_path( - &mut self, - mut hir_id: hir::HirId, - span: Span, - qpath: hir::QPath<'hir>, - ) -> hir::Ty<'hir> { + fn ty_path(&mut self, mut hir_id: HirId, span: Span, qpath: hir::QPath<'hir>) -> hir::Ty<'hir> { let kind = match qpath { hir::QPath::Resolved(None, path) => { // Turn trait object paths into `TyKind::TraitObject` instead. diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 3d16f1420d99..7f33580b52fb 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -13,7 +13,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeName, Node}; +use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirId, HirIdMap, LifetimeName, Node}; use rustc_macros::extension; use rustc_middle::bug; use rustc_middle::hir::nested_filter; @@ -107,7 +107,7 @@ enum Scope<'a> { /// queried later. However, if we enter an elision scope, we have to /// later append the elided bound vars to the list and need to know what /// to append to. - hir_id: hir::HirId, + hir_id: HirId, s: ScopeRef<'a>, @@ -781,7 +781,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { } } - fn visit_path(&mut self, path: &hir::Path<'tcx>, hir_id: hir::HirId) { + fn visit_path(&mut self, path: &hir::Path<'tcx>, hir_id: HirId) { for (i, segment) in path.segments.iter().enumerate() { let depth = path.segments.len() - i - 1; if let Some(args) = segment.args { @@ -983,7 +983,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { } } - fn record_late_bound_vars(&mut self, hir_id: hir::HirId, binder: Vec) { + fn record_late_bound_vars(&mut self, hir_id: HirId, binder: Vec) { if let Some(old) = self.map.late_bound_vars.insert(hir_id, binder) { bug!( "overwrote bound vars for {hir_id:?}:\nold={old:?}\nnew={:?}", @@ -1010,12 +1010,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { /// already in scope (for a fn item, that will be 0, but for a method it might not be). Late /// bound lifetimes are resolved by name and associated with a binder ID (`binder_id`), so the /// ordering is not important there. - fn visit_early_late( - &mut self, - hir_id: hir::HirId, - generics: &'tcx hir::Generics<'tcx>, - walk: F, - ) where + fn visit_early_late(&mut self, hir_id: HirId, generics: &'tcx hir::Generics<'tcx>, walk: F) + where F: for<'b, 'c> FnOnce(&'b mut BoundVarContext<'c, 'tcx>), { let mut named_late_bound_vars = 0; @@ -1062,7 +1058,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { self.with(scope, walk); } - fn visit_early(&mut self, hir_id: hir::HirId, generics: &'tcx hir::Generics<'tcx>, walk: F) + fn visit_early(&mut self, hir_id: HirId, generics: &'tcx hir::Generics<'tcx>, walk: F) where F: for<'b, 'c> FnOnce(&'b mut BoundVarContext<'c, 'tcx>), { @@ -1288,7 +1284,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { ); } - fn resolve_type_ref(&mut self, param_def_id: LocalDefId, hir_id: hir::HirId) { + fn resolve_type_ref(&mut self, param_def_id: LocalDefId, hir_id: HirId) { // Walk up the scope chain, tracking the number of fn scopes // that we pass through, until we find a lifetime with the // given name or we run out of scopes. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 63aeb165a480..0fe02856a62f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -35,7 +35,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::{walk_generics, Visitor as _}; -use rustc_hir::{GenericArg, GenericArgs}; +use rustc_hir::{GenericArg, GenericArgs, HirId}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::ObligationCause; use rustc_middle::middle::stability::AllowUnstable; @@ -158,7 +158,7 @@ pub trait HirTyLowerer<'tcx> { fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option>; /// Record the lowered type of a HIR node in this context. - fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span); + fn record_ty(&self, hir_id: HirId, ty: Ty<'tcx>, span: Span); /// The inference context of the lowering context if applicable. fn infcx(&self) -> Option<&InferCtxt<'tcx>>; @@ -999,7 +999,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { #[instrument(level = "debug", skip_all, ret)] pub fn lower_assoc_path( &self, - hir_ref_id: hir::HirId, + hir_ref_id: HirId, span: Span, qself_ty: Ty<'tcx>, qself: &'tcx hir::Ty<'tcx>, @@ -1200,7 +1200,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { segment: &hir::PathSegment<'tcx>, adt_did: DefId, self_ty: Ty<'tcx>, - block: hir::HirId, + block: HirId, span: Span, ) -> Result, DefId)>, ErrorGuaranteed> { let tcx = self.tcx(); @@ -1349,13 +1349,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } } - fn probe_assoc_ty( - &self, - name: Ident, - block: hir::HirId, - span: Span, - scope: DefId, - ) -> Option { + fn probe_assoc_ty(&self, name: Ident, block: HirId, span: Span, scope: DefId) -> Option { let (item, def_scope) = self.probe_assoc_ty_unchecked(name, block, scope)?; self.check_assoc_ty(item, name, def_scope, block, span); Some(item) @@ -1364,7 +1358,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { fn probe_assoc_ty_unchecked( &self, name: Ident, - block: hir::HirId, + block: HirId, scope: DefId, ) -> Option<(DefId, DefId)> { let tcx = self.tcx(); @@ -1381,14 +1375,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some((item.def_id, def_scope)) } - fn check_assoc_ty( - &self, - item: DefId, - name: Ident, - def_scope: DefId, - block: hir::HirId, - span: Span, - ) { + fn check_assoc_ty(&self, item: DefId, name: Ident, def_scope: DefId, block: HirId, span: Span) { let tcx = self.tcx(); let kind = DefKind::AssocTy; @@ -1714,7 +1701,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &self, opt_self_ty: Option>, path: &hir::Path<'tcx>, - hir_id: hir::HirId, + hir_id: HirId, permit_variants: bool, ) -> Ty<'tcx> { debug!(?path.res, ?opt_self_ty, ?path.segments); @@ -1887,7 +1874,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// Early-bound type parameters get lowered to [`ty::Param`] /// and late-bound ones to [`ty::Bound`]. - pub(crate) fn lower_ty_param(&self, hir_id: hir::HirId) -> Ty<'tcx> { + pub(crate) fn lower_ty_param(&self, hir_id: HirId) -> Ty<'tcx> { let tcx = self.tcx(); match tcx.named_bound_var(hir_id) { Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => { @@ -1914,7 +1901,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// /// Early-bound const parameters get lowered to [`ty::ConstKind::Param`] /// and late-bound ones to [`ty::ConstKind::Bound`]. - pub(crate) fn lower_const_param(&self, hir_id: hir::HirId, param_ty: Ty<'tcx>) -> Const<'tcx> { + pub(crate) fn lower_const_param(&self, hir_id: HirId, param_ty: Ty<'tcx>) -> Const<'tcx> { let tcx = self.tcx(); match tcx.named_bound_var(hir_id) { Some(rbv::ResolvedArg::EarlyBound(def_id)) => { @@ -2341,7 +2328,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { #[instrument(level = "debug", skip(self, hir_id, unsafety, abi, decl, generics, hir_ty), ret)] pub fn lower_fn_ty( &self, - hir_id: hir::HirId, + hir_id: HirId, unsafety: hir::Unsafety, abi: abi::Abi, decl: &hir::FnDecl<'tcx>, @@ -2469,7 +2456,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { /// corresponds to the return type. fn suggest_trait_fn_ty_for_impl_fn_infer( &self, - fn_hir_id: hir::HirId, + fn_hir_id: HirId, arg_idx: Option, ) -> Option> { let tcx = self.tcx(); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 151e4a368499..0ba2a473966c 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -9,9 +9,10 @@ use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; use rustc_ast_pretty::pprust::{Comments, PrintState}; use rustc_hir as hir; -use rustc_hir::LifetimeParamKind; -use rustc_hir::{BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Node, Term}; -use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; +use rustc_hir::{ + BindingAnnotation, ByRef, GenericArg, GenericBound, GenericParam, GenericParamKind, HirId, + LifetimeParamKind, Node, PatKind, RangeEnd, Term, TraitBoundModifier, +}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::FileName; @@ -20,7 +21,7 @@ use rustc_target::spec::abi::Abi; use std::cell::Cell; use std::vec; -pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId) -> String { +pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: HirId) -> String { to_string(&map, |s| s.print_node(map.hir_node(hir_id))) } @@ -28,7 +29,7 @@ pub enum AnnNode<'a> { Name(&'a Symbol), Block(&'a hir::Block<'a>), Item(&'a hir::Item<'a>), - SubItem(hir::HirId), + SubItem(HirId), Expr(&'a hir::Expr<'a>), Pat(&'a hir::Pat<'a>), Arm(&'a hir::Arm<'a>), @@ -65,12 +66,12 @@ impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { pub struct State<'a> { pub s: pp::Printer, comments: Option>, - attrs: &'a dyn Fn(hir::HirId) -> &'a [ast::Attribute], + attrs: &'a dyn Fn(HirId) -> &'a [ast::Attribute], ann: &'a (dyn PpAnn + 'a), } impl<'a> State<'a> { - fn attrs(&self, id: hir::HirId) -> &'a [ast::Attribute] { + fn attrs(&self, id: HirId) -> &'a [ast::Attribute] { (self.attrs)(id) } @@ -159,7 +160,7 @@ pub fn print_crate<'a>( krate: &hir::Mod<'_>, filename: FileName, input: String, - attrs: &'a dyn Fn(hir::HirId) -> &'a [ast::Attribute], + attrs: &'a dyn Fn(HirId) -> &'a [ast::Attribute], ann: &'a dyn PpAnn, ) -> String { let mut s = State { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 5a9fbc0aef5f..8923137fdd82 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2851,7 +2851,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, base_ty: Ty<'tcx>, mod_id: DefId, - hir_id: hir::HirId, + hir_id: HirId, ) -> Vec<(Vec<&'tcx ty::FieldDef>, GenericArgsRef<'tcx>)> { debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_ty); diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 5986b9596663..a0a5a75d3820 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -13,7 +13,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::LocalDefId; -use rustc_hir::PatKind; +use rustc_hir::{HirId, PatKind}; use rustc_infer::infer::InferCtxt; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; @@ -39,20 +39,20 @@ pub trait Delegate<'tcx> { /// diagnostics. Around pattern matching such as `let pat = expr`, the diagnostic /// id will be the id of the expression `expr` but the place itself will have /// the id of the binding in the pattern `pat`. - fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId); + fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId); /// The value found at `place` is being borrowed with kind `bk`. /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). fn borrow( &mut self, place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, bk: ty::BorrowKind, ); /// The value found at `place` is being copied. /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). - fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn copy(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { // In most cases, copying data from `x` is equivalent to doing `*&x`, so by default // we treat a copy of `x` as a borrow of `x`. self.borrow(place_with_id, diag_expr_id, ty::BorrowKind::ImmBorrow) @@ -60,12 +60,12 @@ pub trait Delegate<'tcx> { /// The path at `assignee_place` is being assigned to. /// `diag_expr_id` is the id used for diagnostics (see `consume` for more details). - fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId); + fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId); /// The path at `binding_place` is a binding that is being initialized. /// /// This covers cases such as `let x = 42;` - fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn bind(&mut self, binding_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { // Bindings can normally be treated as a regular assignment, so by default we // forward this to the mutate callback. self.mutate(binding_place, diag_expr_id) @@ -76,7 +76,7 @@ pub trait Delegate<'tcx> { &mut self, place_with_id: &PlaceWithHirId<'tcx>, cause: FakeReadCause, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, ); } @@ -154,7 +154,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { self.mc.tcx() } - fn delegate_consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn delegate_consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { delegate_consume(&self.mc, self.delegate, place_with_id, diag_expr_id) } @@ -775,8 +775,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { /// closure as the DefId. fn walk_captures(&mut self, closure_expr: &hir::Closure<'_>) { fn upvar_is_local_variable( - upvars: Option<&FxIndexMap>, - upvar_id: hir::HirId, + upvars: Option<&FxIndexMap>, + upvar_id: HirId, body_owner_is_closure: bool, ) -> bool { upvars.map(|upvars| !upvars.contains_key(&upvar_id)).unwrap_or(body_owner_is_closure) @@ -902,7 +902,7 @@ fn delegate_consume<'a, 'tcx>( mc: &mc::MemCategorizationContext<'a, 'tcx>, delegate: &mut (dyn Delegate<'tcx> + 'a), place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, ) { debug!("delegate_consume(place_with_id={:?})", place_with_id); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 2d5ba447e4e6..786754ed12f0 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; -use rustc_hir::{ExprKind, GenericArg, Node, QPath}; +use rustc_hir::{ExprKind, GenericArg, HirId, Node, QPath}; use rustc_hir_analysis::hir_ty_lowering::errors::GenericsArgsErrExtend; use rustc_hir_analysis::hir_ty_lowering::generics::{ check_generic_arg_count_for_call, lower_generic_args, @@ -47,7 +47,7 @@ use std::slice; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Produces warning on the given node, if the current point in the /// function is unreachable, and there hasn't been another warning. - pub(in super::super) fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) { + pub(in super::super) fn warn_if_unreachable(&self, id: HirId, span: Span, kind: &str) { // FIXME: Combine these two 'if' expressions into one once // let chains are implemented if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() { @@ -130,14 +130,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("{self:p}") } - pub fn local_ty(&self, span: Span, nid: hir::HirId) -> Ty<'tcx> { + pub fn local_ty(&self, span: Span, nid: HirId) -> Ty<'tcx> { self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| { span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid)) }) } #[inline] - pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) { + pub fn write_ty(&self, id: HirId, ty: Ty<'tcx>) { debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag()); let mut typeck = self.typeck_results.borrow_mut(); let mut node_ty = typeck.node_types_mut(); @@ -161,7 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn write_field_index( &self, - hir_id: hir::HirId, + hir_id: HirId, index: FieldIdx, nested_fields: Vec<(Ty<'tcx>, FieldIdx)>, ) { @@ -174,7 +174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self))] pub(in super::super) fn write_resolution( &self, - hir_id: hir::HirId, + hir_id: HirId, r: Result<(DefKind, DefId), ErrorGuaranteed>, ) { self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r); @@ -183,7 +183,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(level = "debug", skip(self))] pub fn write_method_call_and_enforce_effects( &self, - hir_id: hir::HirId, + hir_id: HirId, span: Span, method: MethodCallee<'tcx>, ) { @@ -192,7 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.write_args(hir_id, method.args); } - pub fn write_args(&self, node_id: hir::HirId, args: GenericArgsRef<'tcx>) { + pub fn write_args(&self, node_id: HirId, args: GenericArgsRef<'tcx>) { if !args.is_empty() { debug!("write_args({:?}, {:?}) in fcx {}", node_id, args, self.tag()); @@ -210,7 +210,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub fn write_user_type_annotation_from_args( &self, - hir_id: hir::HirId, + hir_id: HirId, def_id: DefId, args: GenericArgsRef<'tcx>, user_self_ty: Option>, @@ -230,7 +230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub fn write_user_type_annotation( &self, - hir_id: hir::HirId, + hir_id: HirId, canonical_user_type_annotation: CanonicalUserType<'tcx>, ) { debug!("fcx {}", self.tag()); @@ -464,7 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { t.has_free_regions() || t.has_aliases() || t.has_infer_types() } - pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { + pub fn node_ty(&self, id: HirId) -> Ty<'tcx> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => t, None if let Some(e) = self.tainted_by_errors() => Ty::new_error(self.tcx, e), @@ -478,7 +478,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn node_ty_opt(&self, id: hir::HirId) -> Option> { + pub fn node_ty_opt(&self, id: HirId) -> Option> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => Some(t), None if let Some(e) = self.tainted_by_errors() => Some(Ty::new_error(self.tcx, e)), @@ -742,7 +742,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, lang_item: hir::LangItem, span: Span, - hir_id: hir::HirId, + hir_id: HirId, ) -> (Res, Ty<'tcx>) { let def_id = self.tcx.require_lang_item(lang_item, Some(span)); let def_kind = self.tcx.def_kind(def_id); @@ -790,7 +790,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn resolve_ty_and_res_fully_qualified_call( &self, qpath: &'tcx QPath<'tcx>, - hir_id: hir::HirId, + hir_id: HirId, span: Span, args: Option<&'tcx [hir::Expr<'tcx>]>, ) -> (Res, Option>, &'tcx [hir::PathSegment<'tcx>]) { @@ -984,7 +984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// suggestion can be made, `None` otherwise. pub fn get_fn_decl( &self, - blk_id: hir::HirId, + blk_id: HirId, ) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, bool)> { // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or // `while` before reaching it, as block tail returns are not available in them. @@ -1080,7 +1080,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res: Res, span: Span, path_span: Span, - hir_id: hir::HirId, + hir_id: HirId, ) -> (Ty<'tcx>, Res) { let tcx = self.tcx; @@ -1450,7 +1450,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, def_id: DefId, args: GenericArgsRef<'tcx>, - hir_id: hir::HirId, + hir_id: HirId, ) { self.add_required_obligations_with_code(span, def_id, args, |idx, span| { if span.is_dummy() { @@ -1541,7 +1541,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn with_breakable_ctxt R, R>( &self, - id: hir::HirId, + id: HirId, ctxt: BreakableCtxt<'tcx>, f: F, ) -> (BreakableCtxt<'tcx>, R) { @@ -1580,7 +1580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Returns `true` if an expression is contained inside the LHS of an assignment expression. - pub(in super::super) fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool { + pub(in super::super) fn expr_in_place(&self, mut expr_id: HirId) -> bool { let mut contained_in_place = false; while let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr_id) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index f346c6446e00..4a73ce2e6409 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -24,7 +24,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; -use rustc_hir::{ExprKind, Node, QPath}; +use rustc_hir::{ExprKind, HirId, Node, QPath}; use rustc_hir_analysis::check::intrinsicck::InlineAsmCtxt; use rustc_hir_analysis::check::potentially_plural_count; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; @@ -1489,7 +1489,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn check_struct_path( &self, qpath: &QPath<'tcx>, - hir_id: hir::HirId, + hir_id: HirId, ) -> Result<(&'tcx ty::VariantDef, Ty<'tcx>), ErrorGuaranteed> { let path_span = qpath.span(); let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id); @@ -1554,7 +1554,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn check_decl_initializer( &self, - hir_id: hir::HirId, + hir_id: HirId, pat: &'tcx hir::Pat<'tcx>, init: &'tcx hir::Expr<'tcx>, ) -> Ty<'tcx> { @@ -1879,7 +1879,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty } - fn parent_item_span(&self, id: hir::HirId) -> Option { + fn parent_item_span(&self, id: HirId) -> Option { let node = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(id).def_id); match node { Node::Item(&hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) @@ -1897,7 +1897,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise. pub(crate) fn get_parent_fn_decl( &self, - blk_id: hir::HirId, + blk_id: HirId, ) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> { let parent = self.tcx.hir_node_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id); self.get_node_fn_decl(parent).map(|(_, fn_decl, ident, _)| (fn_decl, ident)) @@ -1939,12 +1939,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr.span } - fn overwrite_local_ty_if_err( - &self, - hir_id: hir::HirId, - pat: &'tcx hir::Pat<'tcx>, - ty: Ty<'tcx>, - ) { + fn overwrite_local_ty_if_err(&self, hir_id: HirId, pat: &'tcx hir::Pat<'tcx>, ty: Ty<'tcx>) { if let Err(guar) = ty.error_reported() { struct OverwritePatternsWithError { pat_hir_ids: Vec, @@ -1977,7 +1972,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, qpath: &QPath<'tcx>, path_span: Span, - hir_id: hir::HirId, + hir_id: HirId, ) -> (Res, LoweredTy<'tcx>) { match *qpath { QPath::Resolved(ref maybe_qself, path) => { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index ce203eae95fd..43e5ab0ed53f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -71,7 +71,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &'tcx hir::Expr<'tcx>, expected: Ty<'tcx>, found: Ty<'tcx>, - blk_id: hir::HirId, + blk_id: HirId, ) -> bool { let expr = expr.peel_drop_temps(); let mut pointing_at_return_type = false; @@ -1031,7 +1031,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn_decl: &hir::FnDecl<'tcx>, expected: Ty<'tcx>, found: Ty<'tcx>, - id: hir::HirId, + id: HirId, fn_id: LocalDefId, ) { if !expected.is_unit() { @@ -1600,12 +1600,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn is_loop(&self, id: hir::HirId) -> bool { + fn is_loop(&self, id: HirId) -> bool { let node = self.tcx.hir_node(id); matches!(node, Node::Expr(Expr { kind: ExprKind::Loop(..), .. })) } - fn is_local_statement(&self, id: hir::HirId) -> bool { + fn is_local_statement(&self, id: HirId) -> bool { let node = self.tcx.hir_node(id); matches!(node, Node::Stmt(Stmt { kind: StmtKind::Let(..), .. })) } diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index 0b985e40c4e0..fe0a46924de4 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -1,7 +1,7 @@ use crate::FnCtxt; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::PatKind; +use rustc_hir::{HirId, PatKind}; use rustc_infer::infer::type_variable::TypeVariableOrigin; use rustc_middle::ty::Ty; use rustc_middle::ty::UserType; @@ -33,7 +33,7 @@ impl<'a> DeclOrigin<'a> { /// /// It must have a hir_id, as this is how we connect gather_locals to the check functions. pub(super) struct Declaration<'a> { - pub hir_id: hir::HirId, + pub hir_id: HirId, pub pat: &'a hir::Pat<'a>, pub ty: Option<&'a hir::Ty<'a>>, pub span: Span, @@ -48,8 +48,8 @@ impl<'a> From<&'a hir::LetStmt<'a>> for Declaration<'a> { } } -impl<'a> From<(&'a hir::LetExpr<'a>, hir::HirId)> for Declaration<'a> { - fn from((let_expr, hir_id): (&'a hir::LetExpr<'a>, hir::HirId)) -> Self { +impl<'a> From<(&'a hir::LetExpr<'a>, HirId)> for Declaration<'a> { + fn from((let_expr, hir_id): (&'a hir::LetExpr<'a>, HirId)) -> Self { let hir::LetExpr { pat, ty, span, init, is_recovered: _ } = *let_expr; Declaration { hir_id, pat, ty, span, init: Some(init), origin: DeclOrigin::LetExpr } } @@ -60,7 +60,7 @@ pub(super) struct GatherLocalsVisitor<'a, 'tcx> { // parameters are special cases of patterns, but we want to handle them as // *distinct* cases. so track when we are hitting a pattern *within* an fn // parameter. - outermost_fn_param_pat: Option<(Span, hir::HirId)>, + outermost_fn_param_pat: Option<(Span, HirId)>, } impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { @@ -68,7 +68,7 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> { Self { fcx, outermost_fn_param_pat: None } } - fn assign(&mut self, span: Span, nid: hir::HirId, ty_opt: Option>) -> Ty<'tcx> { + fn assign(&mut self, span: Span, nid: HirId, ty_opt: Option>) -> Ty<'tcx> { match ty_opt { None => { // Infer the variable's type. diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 901edb9ecd5b..121815ecc0ba 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -57,7 +57,7 @@ use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{HirIdMap, Node}; +use rustc_hir::{HirId, HirIdMap, Node}; use rustc_hir_analysis::check::check_abi; use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer; use rustc_infer::infer::type_variable::TypeVariableOrigin; @@ -339,13 +339,13 @@ pub struct EnclosingBreakables<'tcx> { } impl<'tcx> EnclosingBreakables<'tcx> { - fn find_breakable(&mut self, target_id: hir::HirId) -> &mut BreakableCtxt<'tcx> { + fn find_breakable(&mut self, target_id: HirId) -> &mut BreakableCtxt<'tcx> { self.opt_find_breakable(target_id).unwrap_or_else(|| { bug!("could not find enclosing breakable with id {}", target_id); }) } - fn opt_find_breakable(&mut self, target_id: hir::HirId) -> Option<&mut BreakableCtxt<'tcx>> { + fn opt_find_breakable(&mut self, target_id: HirId) -> Option<&mut BreakableCtxt<'tcx>> { match self.by_id.get(&target_id) { Some(ix) => Some(&mut self.stack[*ix]), None => None, diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index f2425d034495..859877962fe7 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -58,24 +58,24 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::pat_util::EnumerateAndAdjustIterator; -use rustc_hir::PatKind; +use rustc_hir::{HirId, PatKind}; use rustc_infer::infer::InferCtxt; use rustc_span::Span; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_trait_selection::infer::InferCtxtExt; pub(crate) trait HirNode { - fn hir_id(&self) -> hir::HirId; + fn hir_id(&self) -> HirId; } impl HirNode for hir::Expr<'_> { - fn hir_id(&self) -> hir::HirId { + fn hir_id(&self) -> HirId { self.hir_id } } impl HirNode for hir::Pat<'_> { - fn hir_id(&self) -> hir::HirId { + fn hir_id(&self) -> HirId { self.hir_id } } @@ -86,7 +86,7 @@ pub(crate) struct MemCategorizationContext<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, body_owner: LocalDefId, - upvars: Option<&'tcx FxIndexMap>, + upvars: Option<&'tcx FxIndexMap>, } pub(crate) type McResult = Result; @@ -127,11 +127,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { self.infcx.tainted_by_errors().is_some() } - fn resolve_type_vars_or_error( - &self, - id: hir::HirId, - ty: Option>, - ) -> McResult> { + fn resolve_type_vars_or_error(&self, id: HirId, ty: Option>) -> McResult> { match ty { Some(ty) => { let ty = self.resolve_vars_if_possible(ty); @@ -153,7 +149,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { } } - pub(crate) fn node_ty(&self, hir_id: hir::HirId) -> McResult> { + pub(crate) fn node_ty(&self, hir_id: HirId) -> McResult> { self.resolve_type_vars_or_error(hir_id, self.typeck_results.node_type_opt(hir_id)) } @@ -377,7 +373,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { #[instrument(level = "debug", skip(self, span), ret)] pub(crate) fn cat_res( &self, - hir_id: hir::HirId, + hir_id: HirId, span: Span, expr_ty: Ty<'tcx>, res: Res, @@ -416,7 +412,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { /// environment and upvar reference as appropriate. Only regionck cares /// about these dereferences, so we let it compute them as needed. #[instrument(level = "debug", skip(self), ret)] - fn cat_upvar(&self, hir_id: hir::HirId, var_id: hir::HirId) -> McResult> { + fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> McResult> { let closure_expr_def_id = self.body_owner; let upvar_id = ty::UpvarId { @@ -429,7 +425,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { } #[instrument(level = "debug", skip(self), ret)] - pub(crate) fn cat_rvalue(&self, hir_id: hir::HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> { + pub(crate) fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> { PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new()) } @@ -523,7 +519,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { fn variant_index_for_adt( &self, qpath: &hir::QPath<'_>, - pat_hir_id: hir::HirId, + pat_hir_id: HirId, span: Span, ) -> McResult { let res = self.typeck_results.qpath_res(qpath, pat_hir_id); @@ -556,7 +552,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { /// Here `pat_hir_id` is the HirId of the pattern itself. fn total_fields_in_adt_variant( &self, - pat_hir_id: hir::HirId, + pat_hir_id: HirId, variant_index: VariantIdx, span: Span, ) -> McResult { @@ -573,7 +569,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { /// Returns the total number of fields in a tuple used within a Tuple pattern. /// Here `pat_hir_id` is the HirId of the pattern itself. - fn total_fields_in_tuple(&self, pat_hir_id: hir::HirId, span: Span) -> McResult { + fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult { let ty = self.typeck_results.node_type(pat_hir_id); match ty.kind() { ty::Tuple(args) => Ok(args.len()), diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 28e17e1de36c..f8cc34398a75 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -8,6 +8,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::DefKind; +use rustc_hir::HirId; use rustc_hir_analysis::autoderef::{self, Autoderef}; use rustc_infer::infer::canonical::OriginalQueryValues; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; @@ -86,7 +87,7 @@ pub(crate) struct ProbeContext<'a, 'tcx> { Vec<(ty::Predicate<'tcx>, Option>, Option>)>, >, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, } impl<'a, 'tcx> Deref for ProbeContext<'a, 'tcx> { @@ -263,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mode: Mode, return_type: Ty<'tcx>, self_ty: Ty<'tcx>, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, candidate_filter: impl Fn(&ty::AssocItem) -> bool, ) -> Vec { let method_names = self @@ -307,7 +308,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type: Option>, is_suggestion: IsSuggestion, self_ty: Ty<'tcx>, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, scope: ProbeScope, ) -> PickResult<'tcx> { self.probe_op( @@ -331,7 +332,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type: Option>, is_suggestion: IsSuggestion, self_ty: Ty<'tcx>, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, scope: ProbeScope, ) -> Vec> { self.probe_op( @@ -362,7 +363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return_type: Option>, is_suggestion: IsSuggestion, self_ty: Ty<'tcx>, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, scope: ProbeScope, op: OP, ) -> Result> @@ -589,7 +590,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { return_type: Option>, orig_steps_var_values: &'a OriginalQueryValues<'tcx>, steps: &'tcx [CandidateStep<'tcx>], - scope_expr_id: hir::HirId, + scope_expr_id: HirId, ) -> ProbeContext<'a, 'tcx> { ProbeContext { fcx, @@ -1381,7 +1382,7 @@ impl<'tcx> Pick<'tcx> { &self, tcx: TyCtxt<'tcx>, span: Span, - scope_expr_id: hir::HirId, + scope_expr_id: HirId, ) { if self.unstable_candidates.is_empty() { return; diff --git a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs index 694ddd0e3e88..31ce271a5fc4 100644 --- a/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs +++ b/compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs @@ -3,7 +3,7 @@ use super::callee::DeferredCallResolution; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_hir::HirIdMap; +use rustc_hir::{HirId, HirIdMap}; use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt}; use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -52,9 +52,9 @@ pub(crate) struct TypeckRootCtxt<'tcx> { pub(super) deferred_cast_checks: RefCell>>, - pub(super) deferred_transmute_checks: RefCell, Ty<'tcx>, hir::HirId)>>, + pub(super) deferred_transmute_checks: RefCell, Ty<'tcx>, HirId)>>, - pub(super) deferred_asm_checks: RefCell, hir::HirId)>>, + pub(super) deferred_asm_checks: RefCell, HirId)>>, pub(super) deferred_coroutine_interiors: RefCell)>>, diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 86f36eedd900..60a5838cafce 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -38,6 +38,7 @@ use rustc_errors::{Applicability, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::HirId; use rustc_infer::infer::UpvarRegion; use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind}; use rustc_middle::mir::FakeReadCause; @@ -88,7 +89,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] enum UpvarMigrationInfo { /// We previously captured all of `x`, but now we capture some sub-path. - CapturingPrecise { source_expr: Option, var_name: String }, + CapturingPrecise { source_expr: Option, var_name: String }, CapturingNothing { // where the variable appears in the closure (but is not captured) use_span: Span, @@ -131,7 +132,7 @@ struct MigrationLintNote { /// Intermediate format to store the hir id of the root variable and a HashSet containing /// information on why the root variable should be fully captured struct NeededMigration { - var_hir_id: hir::HirId, + var_hir_id: HirId, diagnostics_info: Vec, } @@ -163,7 +164,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { #[instrument(skip(self, body), level = "debug")] fn analyze_closure( &self, - closure_hir_id: hir::HirId, + closure_hir_id: HirId, span: Span, body_id: hir::BodyId, body: &'tcx hir::Body<'tcx>, @@ -1098,7 +1099,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn compute_2229_migrations_for_trait( &self, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, - var_hir_id: hir::HirId, + var_hir_id: HirId, closure_clause: hir::CaptureBy, ) -> Option>> { let auto_traits_def_id = [ @@ -1210,7 +1211,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { closure_span: Span, min_captures: Option<&ty::RootVariableMinCaptureList<'tcx>>, closure_clause: hir::CaptureBy, - var_hir_id: hir::HirId, + var_hir_id: HirId, ) -> Option> { let ty = self.resolve_vars_if_possible(self.node_ty(var_hir_id)); @@ -1650,7 +1651,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fn place_for_root_variable( &self, closure_def_id: LocalDefId, - var_hir_id: hir::HirId, + var_hir_id: HirId, ) -> Place<'tcx> { let upvar_id = ty::UpvarId::new(var_hir_id, closure_def_id); @@ -1881,7 +1882,7 @@ fn apply_capture_kind_on_capture_ty<'tcx>( } /// Returns the Span of where the value with the provided HirId would be dropped -fn drop_location_span(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> Span { +fn drop_location_span(tcx: TyCtxt<'_>, hir_id: HirId) -> Span { let owner_id = tcx.hir().get_enclosing_scope(hir_id).unwrap(); let owner_node = tcx.hir_node(owner_id); @@ -1933,7 +1934,7 @@ struct InferBorrowKind<'tcx> { /// Place { V1, [ProjectionKind::Field(Index=1, Variant=0)] } : CaptureKind { E2, MutableBorrow } /// ``` capture_information: InferredCaptureInformation<'tcx>, - fake_reads: Vec<(Place<'tcx>, FakeReadCause, hir::HirId)>, + fake_reads: Vec<(Place<'tcx>, FakeReadCause, HirId)>, } impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { @@ -1941,7 +1942,7 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { &mut self, place: &PlaceWithHirId<'tcx>, cause: FakeReadCause, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, ) { let PlaceBase::Upvar(_) = place.place.base else { return }; @@ -1956,7 +1957,7 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { } #[instrument(skip(self), level = "debug")] - fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return }; assert_eq!(self.closure_def_id, upvar_id.closure_expr_id); @@ -1974,7 +1975,7 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { fn borrow( &mut self, place_with_id: &PlaceWithHirId<'tcx>, - diag_expr_id: hir::HirId, + diag_expr_id: HirId, bk: ty::BorrowKind, ) { let PlaceBase::Upvar(upvar_id) = place_with_id.place.base else { return }; @@ -2005,7 +2006,7 @@ impl<'tcx> euv::Delegate<'tcx> for InferBorrowKind<'tcx> { } #[instrument(skip(self), level = "debug")] - fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: hir::HirId) { + fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) { self.borrow(assignee_place, diag_expr_id, ty::BorrowKind::MutBorrow); } } @@ -2192,14 +2193,14 @@ fn construct_capture_info_string<'tcx>( format!("{place_str} -> {capture_kind_str}") } -fn var_name(tcx: TyCtxt<'_>, var_hir_id: hir::HirId) -> Symbol { +fn var_name(tcx: TyCtxt<'_>, var_hir_id: HirId) -> Symbol { tcx.hir().name(var_hir_id) } #[instrument(level = "debug", skip(tcx))] fn should_do_rust_2021_incompatible_closure_captures_analysis( tcx: TyCtxt<'_>, - closure_id: hir::HirId, + closure_id: HirId, ) -> bool { if tcx.sess.at_least_rust_2021() { return false; diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 6604bf094c14..875f8b23a84b 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -7,6 +7,7 @@ use rustc_data_structures::unord::ExtendUnord; use rustc_errors::{ErrorGuaranteed, StashKey}; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir::HirId; use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion}; @@ -134,7 +135,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { self.fcx.tcx } - fn write_ty_to_typeck_results(&mut self, hir_id: hir::HirId, ty: Ty<'tcx>) { + fn write_ty_to_typeck_results(&mut self, hir_id: HirId, ty: Ty<'tcx>) { debug!("write_ty_to_typeck_results({:?}, {:?})", hir_id, ty); assert!( !ty.has_infer() && !ty.has_placeholders() && !ty.has_free_regions(), @@ -461,7 +462,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fcx_typeck_results.closure_kind_origins().items_in_stable_order(); for (local_id, origin) in fcx_closure_kind_origins { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; let place_span = origin.0; let place = self.resolve(origin.1.clone(), &place_span); self.typeck_results.closure_kind_origins_mut().insert(hir_id, (place_span, place)); @@ -490,7 +491,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let mut errors_buffer = Vec::new(); for (local_id, c_ty) in sorted_user_provided_types { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; if let ty::UserType::TypeOf(_, user_args) = c_ty.value { // This is a unit-testing mechanism. @@ -513,7 +514,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { self.typeck_results.user_provided_types_mut().extend( fcx_typeck_results.user_provided_types().items().map(|(local_id, c_ty)| { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; if cfg!(debug_assertions) && c_ty.has_infer() { span_bug!( @@ -604,7 +605,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } } - fn visit_field_id(&mut self, hir_id: hir::HirId) { + fn visit_field_id(&mut self, hir_id: HirId) { if let Some(index) = self.fcx.typeck_results.borrow_mut().field_indices_mut().remove(hir_id) { self.typeck_results.field_indices_mut().insert(hir_id, index); @@ -617,7 +618,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } #[instrument(skip(self, span), level = "debug")] - fn visit_node_id(&mut self, span: Span, hir_id: hir::HirId) { + fn visit_node_id(&mut self, span: Span, hir_id: HirId) { // Export associated path extensions and method resolutions. if let Some(def) = self.fcx.typeck_results.borrow_mut().type_dependent_defs_mut().remove(hir_id) @@ -644,7 +645,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } #[instrument(skip(self, span), level = "debug")] - fn visit_adjustments(&mut self, span: Span, hir_id: hir::HirId) { + fn visit_adjustments(&mut self, span: Span, hir_id: HirId) { let adjustment = self.fcx.typeck_results.borrow_mut().adjustments_mut().remove(hir_id); match adjustment { None => { @@ -660,7 +661,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { } #[instrument(skip(self, span), level = "debug")] - fn visit_pat_adjustments(&mut self, span: Span, hir_id: hir::HirId) { + fn visit_pat_adjustments(&mut self, span: Span, hir_id: HirId) { let adjustment = self.fcx.typeck_results.borrow_mut().pat_adjustments_mut().remove(hir_id); match adjustment { None => { @@ -691,7 +692,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let fcx_liberated_fn_sigs = fcx_typeck_results.liberated_fn_sigs().items_in_stable_order(); for (local_id, &fn_sig) in fcx_liberated_fn_sigs { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; let fn_sig = self.resolve(fn_sig, &hir_id); self.typeck_results.liberated_fn_sigs_mut().insert(hir_id, fn_sig); } @@ -705,7 +706,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let fcx_fru_field_types = fcx_typeck_results.fru_field_types().items_in_stable_order(); for (local_id, ftys) in fcx_fru_field_types { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; let ftys = self.resolve(ftys.clone(), &hir_id); self.typeck_results.fru_field_types_mut().insert(hir_id, ftys); } @@ -719,7 +720,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { for (local_id, &(container, ref indices)) in fcx_typeck_results.offset_of_data().items_in_stable_order() { - let hir_id = hir::HirId { owner: common_hir_owner, local_id }; + let hir_id = HirId { owner: common_hir_owner, local_id }; let container = self.resolve(container, &hir_id); self.typeck_results.offset_of_data_mut().insert(hir_id, (container, indices.clone())); } @@ -754,7 +755,7 @@ impl Locatable for Span { } } -impl Locatable for hir::HirId { +impl Locatable for HirId { fn to_span(&self, tcx: TyCtxt<'_>) -> Span { tcx.hir().span(*self) } diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs index 99207e3f315c..ca188277b9de 100644 --- a/compiler/rustc_lint/src/late.rs +++ b/compiler/rustc_lint/src/late.rs @@ -20,6 +20,7 @@ use rustc_data_structures::sync::{join, Lrc}; use rustc_hir as hir; use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit as hir_visit; +use rustc_hir::HirId; use rustc_middle::hir::nested_filter; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint::LintPass; @@ -53,7 +54,7 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { /// Merge the lints specified by any lint attributes into the /// current lint context, call the provided function, then reset the /// lints in effect to their previous state. - fn with_lint_attrs(&mut self, id: hir::HirId, f: F) + fn with_lint_attrs(&mut self, id: HirId, f: F) where F: FnOnce(&mut Self), { @@ -81,7 +82,7 @@ impl<'tcx, T: LateLintPass<'tcx>> LateContextAndPass<'tcx, T> { self.context.param_env = old_param_env; } - fn process_mod(&mut self, m: &'tcx hir::Mod<'tcx>, n: hir::HirId) { + fn process_mod(&mut self, m: &'tcx hir::Mod<'tcx>, n: HirId) { lint_callback!(self, check_mod, m, n); hir_visit::walk_mod(self, m, n); } @@ -231,7 +232,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas hir_visit::walk_inf(self, inf); } - fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, _: Span, n: hir::HirId) { + fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, _: Span, n: HirId) { if !self.context.only_module { self.process_mod(m, n); } @@ -305,7 +306,7 @@ impl<'tcx, T: LateLintPass<'tcx>> hir_visit::Visitor<'tcx> for LateContextAndPas hir_visit::walk_lifetime(self, lt); } - fn visit_path(&mut self, p: &hir::Path<'tcx>, id: hir::HirId) { + fn visit_path(&mut self, p: &hir::Path<'tcx>, id: HirId) { lint_callback!(self, check_path, p, id); hir_visit::walk_path(self, p); } diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index b9914f6cb7a0..5ae60e042771 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -10,7 +10,7 @@ use crate::ty::TyCtxt; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::unord::UnordMap; use rustc_hir as hir; -use rustc_hir::{HirIdMap, Node}; +use rustc_hir::{HirId, HirIdMap, Node}; use rustc_macros::HashStable; use rustc_span::{Span, DUMMY_SP}; @@ -164,10 +164,10 @@ impl Scope { self.id } - pub fn hir_id(&self, scope_tree: &ScopeTree) -> Option { + pub fn hir_id(&self, scope_tree: &ScopeTree) -> Option { scope_tree .root_body - .map(|hir_id| hir::HirId { owner: hir_id.owner, local_id: self.item_local_id() }) + .map(|hir_id| HirId { owner: hir_id.owner, local_id: self.item_local_id() }) } /// Returns the span of this `Scope`. Note that in general the @@ -207,7 +207,7 @@ pub type ScopeDepth = u32; #[derive(Default, Debug, HashStable)] pub struct ScopeTree { /// If not empty, this body is the root of this region hierarchy. - pub root_body: Option, + pub root_body: Option, /// Maps from a scope ID to the enclosing scope id; /// this is usually corresponding to the lexical nesting, though @@ -341,11 +341,7 @@ impl ScopeTree { self.var_map.insert(var, lifetime); } - pub fn record_rvalue_candidate( - &mut self, - var: hir::HirId, - candidate_type: RvalueCandidateType, - ) { + pub fn record_rvalue_candidate(&mut self, var: HirId, candidate_type: RvalueCandidateType) { debug!("record_rvalue_candidate(var={var:?}, type={candidate_type:?})"); match &candidate_type { RvalueCandidateType::Borrow { lifetime: Some(lifetime), .. } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 601bfc770f4d..d3d6756aa46c 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1545,7 +1545,7 @@ pub struct SourceScopeData<'tcx> { #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)] pub struct SourceScopeLocalData { /// An `HirId` with lint levels equivalent to this scope's lint levels. - pub lint_root: hir::HirId, + pub lint_root: HirId, } /// A collection of projections into user types. diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index f10b204cd477..8763e94c8b05 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -12,7 +12,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_errors::{DiagArgValue, IntoDiagArg}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_hir::{BindingAnnotation, ByRef, MatchSource, RangeEnd}; +use rustc_hir::{BindingAnnotation, ByRef, HirId, MatchSource, RangeEnd}; use rustc_index::newtype_index; use rustc_index::IndexVec; use rustc_middle::middle::region; @@ -115,13 +115,13 @@ pub struct Param<'tcx> { /// Whether this param is `self`, and how it is bound. pub self_kind: Option, /// HirId for lints. - pub hir_id: Option, + pub hir_id: Option, } #[derive(Copy, Clone, Debug, HashStable)] pub enum LintLevel { Inherited, - Explicit(hir::HirId), + Explicit(HirId), } #[derive(Clone, Debug, HashStable)] @@ -167,7 +167,7 @@ pub struct ClosureExpr<'tcx> { pub args: UpvarArgs<'tcx>, pub upvars: Box<[ExprId]>, pub movability: Option, - pub fake_reads: Vec<(ExprId, FakeReadCause, hir::HirId)>, + pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>, } #[derive(Clone, Debug, HashStable)] @@ -184,7 +184,7 @@ pub enum BlockSafety { /// A compiler-generated unsafe block BuiltinUnsafe, /// An `unsafe` block. The `HirId` is the ID of the block. - ExplicitUnsafe(hir::HirId), + ExplicitUnsafe(HirId), } #[derive(Clone, Debug, HashStable)] @@ -233,7 +233,7 @@ pub enum StmtKind<'tcx> { } #[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)] -pub struct LocalVarId(pub hir::HirId); +pub struct LocalVarId(pub HirId); /// A THIR expression. #[derive(Clone, Debug, HashStable)] @@ -356,7 +356,7 @@ pub enum ExprKind<'tcx> { /// A `match` expression. Match { scrutinee: ExprId, - scrutinee_hir_id: hir::HirId, + scrutinee_hir_id: HirId, arms: Box<[ArmId]>, match_source: MatchSource, }, diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 790e11b8e4bd..28f6184a34e3 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -19,6 +19,7 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diag, EmissionGuarantee}; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::HirId; use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; @@ -262,10 +263,10 @@ pub enum ObligationCauseCode<'tcx> { /// expression that caused the obligation, and the `usize` /// indicates exactly which predicate it is in the list of /// instantiated predicates. - ExprItemObligation(DefId, rustc_hir::HirId, usize), + ExprItemObligation(DefId, HirId, usize), /// Combines `ExprItemObligation` and `BindingObligation`. - ExprBindingObligation(DefId, Span, rustc_hir::HirId, usize), + ExprBindingObligation(DefId, Span, HirId, usize), /// A type like `&'a T` is WF only if `T: 'a`. ReferenceOutlivesReferent(Ty<'tcx>), @@ -287,9 +288,9 @@ pub enum ObligationCauseCode<'tcx> { /// `S { ... }` must be `Sized`. StructInitializerSized, /// Type of each variable must be `Sized`. - VariableType(hir::HirId), + VariableType(HirId), /// Argument type must be `Sized`. - SizedArgumentType(Option), + SizedArgumentType(Option), /// Return type must be `Sized`. SizedReturnType, /// Return type of a call expression must be `Sized`. @@ -335,9 +336,9 @@ pub enum ObligationCauseCode<'tcx> { FunctionArgumentObligation { /// The node of the relevant argument in the function call. - arg_hir_id: hir::HirId, + arg_hir_id: HirId, /// The node of the function call. - call_hir_id: hir::HirId, + call_hir_id: HirId, /// The obligation introduced by this argument. parent_code: InternedObligationCauseCode<'tcx>, }, @@ -402,18 +403,18 @@ pub enum ObligationCauseCode<'tcx> { ReturnNoExpression, /// `return` with an expression - ReturnValue(hir::HirId), + ReturnValue(HirId), /// Opaque return type of this function OpaqueReturnType(Option<(Ty<'tcx>, Span)>), /// Block implicit return - BlockTailExpression(hir::HirId, hir::MatchSource), + BlockTailExpression(HirId, hir::MatchSource), /// #[feature(trivial_bounds)] is not enabled TrivialBound, - AwaitableExpr(hir::HirId), + AwaitableExpr(HirId), ForLoopIterator, @@ -431,8 +432,8 @@ pub enum ObligationCauseCode<'tcx> { MatchImpl(ObligationCause<'tcx>, DefId), BinOp { - lhs_hir_id: hir::HirId, - rhs_hir_id: Option, + lhs_hir_id: HirId, + rhs_hir_id: Option, rhs_span: Option, rhs_is_lit: bool, output_ty: Option>, @@ -562,10 +563,10 @@ pub enum StatementAsExpression { #[derive(Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] #[derive(TypeVisitable, TypeFoldable)] pub struct MatchExpressionArmCause<'tcx> { - pub arm_block_id: Option, + pub arm_block_id: Option, pub arm_ty: Ty<'tcx>, pub arm_span: Span, - pub prior_arm_block_id: Option, + pub prior_arm_block_id: Option, pub prior_arm_ty: Ty<'tcx>, pub prior_arm_span: Span, pub scrut_span: Span, @@ -578,8 +579,8 @@ pub struct MatchExpressionArmCause<'tcx> { #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)] pub struct IfExpressionCause<'tcx> { - pub then_id: hir::HirId, - pub else_id: hir::HirId, + pub then_id: HirId, + pub else_id: HirId, pub then_ty: Ty<'tcx>, pub else_ty: Ty<'tcx>, pub outer_span: Option, diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 211d403998f8..11167515b7ca 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -10,6 +10,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; +use rustc_hir::HirId; use rustc_span::def_id::LocalDefIdMap; use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; @@ -25,7 +26,7 @@ pub const CAPTURE_STRUCT_LOCAL: mir::Local = mir::Local::from_u32(1); #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] pub struct UpvarPath { - pub hir_id: hir::HirId, + pub hir_id: HirId, } /// Upvars do not get their own `NodeId`. Instead, we use the pair of @@ -39,7 +40,7 @@ pub struct UpvarId { } impl UpvarId { - pub fn new(var_hir_id: hir::HirId, closure_def_id: LocalDefId) -> UpvarId { + pub fn new(var_hir_id: HirId, closure_def_id: LocalDefId) -> UpvarId { UpvarId { var_path: UpvarPath { hir_id: var_hir_id }, closure_expr_id: closure_def_id } } } @@ -68,7 +69,7 @@ pub type MinCaptureInformationMap<'tcx> = LocalDefIdMap = FxIndexMap>; +pub type RootVariableMinCaptureList<'tcx> = FxIndexMap>; /// Part of `MinCaptureInformationMap`; List of `CapturePlace`s. pub type MinCaptureList<'tcx> = Vec>; @@ -135,7 +136,7 @@ impl<'tcx> CapturedPlace<'tcx> { /// Returns the hir-id of the root variable for the captured place. /// e.g., if `a.b.c` was captured, would return the hir-id for `a`. - pub fn get_root_variable(&self) -> hir::HirId { + pub fn get_root_variable(&self) -> HirId { match self.place.base { HirPlaceBase::Upvar(upvar_id) => upvar_id.var_path.hir_id, base => bug!("Expected upvar, found={:?}", base), @@ -286,12 +287,12 @@ pub struct CaptureInfo { /// /// In this example, if `capture_disjoint_fields` is **not** set, then x will be captured, /// but we won't see it being used during capture analysis, since it's essentially a discard. - pub capture_kind_expr_id: Option, + pub capture_kind_expr_id: Option, /// Expr Id pointing to use that resulted the corresponding place being captured /// /// See `capture_kind_expr_id` for example. /// - pub path_expr_id: Option, + pub path_expr_id: Option, /// Capture mode that was selected pub capture_kind: UpvarCapture, diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 995feeaa1487..818fb78793ef 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -192,7 +192,7 @@ pub struct TypeckResults<'tcx> { /// we never capture `t`. This becomes an issue when we build MIR as we require /// information on `t` in order to create place `t.0` and `t.1`. We can solve this /// issue by fake reading `t`. - pub closure_fake_reads: LocalDefIdMap, FakeReadCause, hir::HirId)>>, + pub closure_fake_reads: LocalDefIdMap, FakeReadCause, HirId)>>, /// Tracks the rvalue scoping rules which defines finer scoping for rvalue expressions /// by applying extended parameter rules. @@ -251,7 +251,7 @@ impl<'tcx> TypeckResults<'tcx> { } /// Returns the final resolution of a `QPath` in an `Expr` or `Pat` node. - pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: hir::HirId) -> Res { + pub fn qpath_res(&self, qpath: &hir::QPath<'_>, id: HirId) -> Res { match *qpath { hir::QPath::Resolved(_, path) => path.res, hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self @@ -289,11 +289,11 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices } } - pub fn field_index(&self, id: hir::HirId) -> FieldIdx { + pub fn field_index(&self, id: HirId) -> FieldIdx { self.field_indices().get(id).cloned().expect("no index for a field") } - pub fn opt_field_index(&self, id: hir::HirId) -> Option { + pub fn opt_field_index(&self, id: HirId) -> Option { self.field_indices().get(id).cloned() } @@ -305,7 +305,7 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.nested_fields } } - pub fn nested_field_tys_and_indices(&self, id: hir::HirId) -> &[(Ty<'tcx>, FieldIdx)] { + pub fn nested_field_tys_and_indices(&self, id: HirId) -> &[(Ty<'tcx>, FieldIdx)] { self.nested_fields().get(id).map_or(&[], Vec::as_slice) } @@ -327,13 +327,13 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types } } - pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> { + pub fn node_type(&self, id: HirId) -> Ty<'tcx> { self.node_type_opt(id).unwrap_or_else(|| { bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir().node_to_string(id))) }) } - pub fn node_type_opt(&self, id: hir::HirId) -> Option> { + pub fn node_type_opt(&self, id: HirId) -> Option> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.node_types.get(&id.local_id).cloned() } @@ -342,12 +342,12 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_args } } - pub fn node_args(&self, id: hir::HirId) -> GenericArgsRef<'tcx> { + pub fn node_args(&self, id: HirId) -> GenericArgsRef<'tcx> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.node_args.get(&id.local_id).cloned().unwrap_or_else(|| GenericArgs::empty()) } - pub fn node_args_opt(&self, id: hir::HirId) -> Option> { + pub fn node_args_opt(&self, id: HirId) -> Option> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.node_args.get(&id.local_id).cloned() } @@ -512,7 +512,7 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.fru_field_types } } - pub fn is_coercion_cast(&self, hir_id: hir::HirId) -> bool { + pub fn is_coercion_cast(&self, hir_id: HirId) -> bool { validate_hir_id_for_typeck_results(self.hir_owner, hir_id); self.coercion_casts.contains(&hir_id.local_id) } @@ -546,7 +546,7 @@ impl<'tcx> TypeckResults<'tcx> { /// would result in lookup errors, or worse, in silently wrong data being /// stored/returned. #[inline] -fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) { +fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) { if hir_id.owner != hir_owner { invalid_hir_id_for_typeck_results(hir_owner, hir_id); } @@ -554,7 +554,7 @@ fn validate_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) { #[cold] #[inline(never)] -fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: hir::HirId) { +fn invalid_hir_id_for_typeck_results(hir_owner: OwnerId, hir_id: HirId) { ty::tls::with(|tcx| { bug!( "node {} cannot be placed in TypeckResults with hir_owner {:?}", @@ -570,12 +570,12 @@ pub struct LocalTableInContext<'a, V> { } impl<'a, V> LocalTableInContext<'a, V> { - pub fn contains_key(&self, id: hir::HirId) -> bool { + pub fn contains_key(&self, id: HirId) -> bool { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.contains_key(&id.local_id) } - pub fn get(&self, id: hir::HirId) -> Option<&'a V> { + pub fn get(&self, id: HirId) -> Option<&'a V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.get(&id.local_id) } @@ -592,10 +592,10 @@ impl<'a, V> LocalTableInContext<'a, V> { } } -impl<'a, V> ::std::ops::Index for LocalTableInContext<'a, V> { +impl<'a, V> ::std::ops::Index for LocalTableInContext<'a, V> { type Output = V; - fn index(&self, key: hir::HirId) -> &V { + fn index(&self, key: HirId) -> &V { self.get(key).expect("LocalTableInContext: key not found") } } @@ -606,35 +606,32 @@ pub struct LocalTableInContextMut<'a, V> { } impl<'a, V> LocalTableInContextMut<'a, V> { - pub fn get_mut(&mut self, id: hir::HirId) -> Option<&mut V> { + pub fn get_mut(&mut self, id: HirId) -> Option<&mut V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.get_mut(&id.local_id) } - pub fn get(&mut self, id: hir::HirId) -> Option<&V> { + pub fn get(&mut self, id: HirId) -> Option<&V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.get(&id.local_id) } - pub fn entry(&mut self, id: hir::HirId) -> Entry<'_, hir::ItemLocalId, V> { + pub fn entry(&mut self, id: HirId) -> Entry<'_, hir::ItemLocalId, V> { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.entry(id.local_id) } - pub fn insert(&mut self, id: hir::HirId, val: V) -> Option { + pub fn insert(&mut self, id: HirId, val: V) -> Option { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.insert(id.local_id, val) } - pub fn remove(&mut self, id: hir::HirId) -> Option { + pub fn remove(&mut self, id: HirId) -> Option { validate_hir_id_for_typeck_results(self.hir_owner, id); self.data.remove(&id.local_id) } - pub fn extend( - &mut self, - items: UnordItems<(hir::HirId, V), impl Iterator>, - ) { + pub fn extend(&mut self, items: UnordItems<(HirId, V), impl Iterator>) { self.data.extend_unord(items.map(|(id, value)| { validate_hir_id_for_typeck_results(self.hir_owner, id); (id.local_id, value) diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 6972bc00e0b2..b5d72619a387 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -9,7 +9,7 @@ use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, BindingAnnotation, ByRef, Node}; +use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Node}; use rustc_index::bit_set::GrowableBitSet; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; @@ -158,7 +158,7 @@ struct Builder<'a, 'tcx> { cfg: CFG<'tcx>, def_id: LocalDefId, - hir_id: hir::HirId, + hir_id: HirId, parent_module: DefId, check_overflow: bool, fn_span: Span, @@ -222,7 +222,7 @@ struct Builder<'a, 'tcx> { coverage_branch_info: Option, } -type CaptureMap<'tcx> = SortedIndexMultiMap>; +type CaptureMap<'tcx> = SortedIndexMultiMap>; #[derive(Debug)] struct Capture<'tcx> { @@ -721,7 +721,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { thir: &'a Thir<'tcx>, infcx: InferCtxt<'tcx>, def: LocalDefId, - hir_id: hir::HirId, + hir_id: HirId, span: Span, arg_count: usize, return_ty: Ty<'tcx>, @@ -981,7 +981,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn set_correct_source_scope_for_arg( &mut self, - arg_hir_id: hir::HirId, + arg_hir_id: HirId, original_source_scope: SourceScope, pattern_span: Span, ) { diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 8aa9a75d96af..9ee0fb79bf4f 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -1,10 +1,8 @@ -use std::borrow::Cow; - use crate::build::ExprCategory; use crate::errors::*; use rustc_errors::DiagArgValue; -use rustc_hir::{self as hir, BindingAnnotation, ByRef, Mutability}; +use rustc_hir::{self as hir, BindingAnnotation, ByRef, HirId, Mutability}; use rustc_middle::mir::BorrowKind; use rustc_middle::thir::visit::Visitor; use rustc_middle::thir::*; @@ -16,6 +14,7 @@ use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::symbol::Symbol; use rustc_span::{sym, Span}; +use std::borrow::Cow; use std::mem; use std::ops::Bound; @@ -24,7 +23,7 @@ struct UnsafetyVisitor<'a, 'tcx> { thir: &'a Thir<'tcx>, /// The `HirId` of the current scope, which would be the `HirId` /// of the current HIR node, modulo adjustments. Used for lint levels. - hir_context: hir::HirId, + hir_context: HirId, /// The current "safety context". This notably tracks whether we are in an /// `unsafe` block, and whether it has been used. safety_context: SafetyContext, @@ -123,7 +122,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> { fn warn_unused_unsafe( &mut self, - hir_id: hir::HirId, + hir_id: HirId, block_span: Span, enclosing_unsafe: Option, ) { @@ -537,22 +536,17 @@ enum SafetyContext { Safe, BuiltinUnsafeBlock, UnsafeFn, - UnsafeBlock { - span: Span, - hir_id: hir::HirId, - used: bool, - nested_used_blocks: Vec, - }, + UnsafeBlock { span: Span, hir_id: HirId, used: bool, nested_used_blocks: Vec }, } #[derive(Clone, Copy)] struct NestedUsedBlock { - hir_id: hir::HirId, + hir_id: HirId, span: Span, } struct UnusedUnsafeWarning { - hir_id: hir::HirId, + hir_id: HirId, block_span: Span, enclosing_unsafe: Option, } @@ -585,7 +579,7 @@ impl UnsafeOpKind { pub fn emit_unsafe_op_in_unsafe_fn_lint( &self, tcx: TyCtxt<'_>, - hir_id: hir::HirId, + hir_id: HirId, span: Span, suggest_unsafe_block: bool, ) { @@ -726,7 +720,7 @@ impl UnsafeOpKind { &self, tcx: TyCtxt<'_>, span: Span, - hir_context: hir::HirId, + hir_context: HirId, unsafe_op_in_unsafe_fn_allowed: bool, ) { let note_non_inherited = tcx.hir().parent_iter(hir_context).find(|(id, node)| { diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 72c6a714e4d5..49408c5618b0 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -389,7 +389,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_fn(self, fk, fd, b, id) } - fn visit_use(&mut self, p: &'v hir::UsePath<'v>, hir_id: hir::HirId) { + fn visit_use(&mut self, p: &'v hir::UsePath<'v>, hir_id: HirId) { // This is `visit_use`, but the type is `Path` so record it that way. self.record("Path", Id::None, p); hir_visit::walk_use(self, p, hir_id) @@ -462,7 +462,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> { hir_visit::walk_lifetime(self, lifetime) } - fn visit_path(&mut self, path: &hir::Path<'v>, _id: hir::HirId) { + fn visit_path(&mut self, path: &hir::Path<'v>, _id: HirId) { self.record("Path", Id::None, path); hir_visit::walk_path(self, path) } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 125084f47505..c7729302783f 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -602,7 +602,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { String::from_utf8(wr).unwrap() } - fn log_liveness(&self, entry_ln: LiveNode, hir_id: hir::HirId) { + fn log_liveness(&self, entry_ln: LiveNode, hir_id: HirId) { // hack to skip the loop unless debug! is enabled: debug!( "^^ liveness computation results for body {} (entry={:?})", diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index bd34b0597e25..a1f37ee3b834 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -5,7 +5,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{LocalDefId, LocalModDefId}; use rustc_hir::intravisit::Visitor; -use rustc_hir::{ExprKind, InlineAsmOperand, StmtKind}; +use rustc_hir::{ExprKind, HirIdSet, InlineAsmOperand, StmtKind}; use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::UNDEFINED_NAKED_FUNCTION_ABI; @@ -94,7 +94,7 @@ fn check_no_patterns(tcx: TyCtxt<'_>, params: &[hir::Param<'_>]) { /// Checks that function parameters aren't used in the function body. fn check_no_parameters_use<'tcx>(tcx: TyCtxt<'tcx>, body: &'tcx hir::Body<'tcx>) { - let mut params = hir::HirIdSet::default(); + let mut params = HirIdSet::default(); for param in body.params { param.pat.each_binding(|_binding_mode, hir_id, _span, _ident| { params.insert(hir_id); @@ -105,7 +105,7 @@ fn check_no_parameters_use<'tcx>(tcx: TyCtxt<'tcx>, body: &'tcx hir::Body<'tcx>) struct CheckParameters<'tcx> { tcx: TyCtxt<'tcx>, - params: hir::HirIdSet, + params: HirIdSet, } impl<'tcx> Visitor<'tcx> for CheckParameters<'tcx> { diff --git a/compiler/rustc_passes/src/upvars.rs b/compiler/rustc_passes/src/upvars.rs index 4d44e8762b0d..2eed58d10bb7 100644 --- a/compiler/rustc_passes/src/upvars.rs +++ b/compiler/rustc_passes/src/upvars.rs @@ -66,7 +66,7 @@ impl CaptureCollector<'_, '_> { } impl<'tcx> Visitor<'tcx> for CaptureCollector<'_, 'tcx> { - fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) { + fn visit_path(&mut self, path: &hir::Path<'tcx>, _: HirId) { if let Res::Local(var_id) = path.res { self.visit_local_use(var_id, path.span); } 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 bbb634dacdfb..ae38649da029 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -4251,7 +4251,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { type_diffs: &[TypeError<'tcx>], span: Span, prev_ty: Ty<'tcx>, - body_id: hir::HirId, + body_id: HirId, param_env: ty::ParamEnv<'tcx>, ) -> Vec))>> { let ocx = ObligationCtxt::new(self.infcx); @@ -4757,7 +4757,7 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { /// Collect all the awaited expressions within the input expression. #[derive(Default)] struct AwaitsVisitor { - awaits: Vec, + awaits: Vec, } impl<'v> Visitor<'v> for AwaitsVisitor { diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs index 2d757883f266..995dd782cbbd 100644 --- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs +++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs @@ -1,4 +1,4 @@ -use rustc_hir::{self as hir, intravisit, HirIdSet}; +use rustc_hir::{self as hir, intravisit, HirId, HirIdSet}; use rustc_lint::LateContext; use rustc_middle::ty; use rustc_span::def_id::LocalDefId; @@ -74,7 +74,7 @@ fn check_raw_ptr<'tcx>( } } -fn raw_ptr_arg(cx: &LateContext<'_>, arg: &hir::Param<'_>) -> Option { +fn raw_ptr_arg(cx: &LateContext<'_>, arg: &hir::Param<'_>) -> Option { if let (&hir::PatKind::Binding(_, id, _, _), Some(&ty::RawPtr(_, _))) = ( &arg.pat.kind, cx.maybe_typeck_results() diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs index 4d1f89b1d9d9..6ddc8346511d 100644 --- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs +++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs @@ -7,6 +7,7 @@ use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_hir::HirId; use rustc_hir::intravisit::{self, Visitor}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; @@ -87,9 +88,9 @@ impl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice { extract_msrv_attr!(LateContext); } -fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap { - let mut removed_pat: FxHashSet = FxHashSet::default(); - let mut slices: FxIndexMap = FxIndexMap::default(); +fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap { + let mut removed_pat: FxHashSet = FxHashSet::default(); + let mut slices: FxIndexMap = FxIndexMap::default(); pat.walk_always(|pat| { // We'll just ignore mut and ref mut for simplicity sake right now if let hir::PatKind::Binding( @@ -206,10 +207,10 @@ impl SliceLintInformation { fn filter_lintable_slices<'tcx>( cx: &LateContext<'tcx>, - slice_lint_info: FxIndexMap, + slice_lint_info: FxIndexMap, max_suggested_slice: u64, scope: &'tcx hir::Expr<'tcx>, -) -> FxIndexMap { +) -> FxIndexMap { let mut visitor = SliceIndexLintingVisitor { cx, slice_lint_info, @@ -223,7 +224,7 @@ fn filter_lintable_slices<'tcx>( struct SliceIndexLintingVisitor<'a, 'tcx> { cx: &'a LateContext<'tcx>, - slice_lint_info: FxIndexMap, + slice_lint_info: FxIndexMap, max_suggested_slice: u64, } diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs index 2f85130fba11..435eb9048f58 100644 --- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs @@ -6,6 +6,7 @@ use clippy_utils::{binop_traits, eq_expr_value, trait_ref_of_method}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_hir::{HirId, HirIdSet}; use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId}; use rustc_lint::LateContext; use rustc_middle::mir::FakeReadCause; @@ -98,10 +99,10 @@ pub(super) fn check<'tcx>( } } -fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet { - struct S(hir::HirIdSet); +fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { + struct S(HirIdSet); impl Delegate<'_> for S { - fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: hir::HirId, kind: BorrowKind) { + fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: HirId, kind: BorrowKind) { if matches!(kind, BorrowKind::ImmBorrow | BorrowKind::UniqueImmBorrow) { self.0.insert(match place.place.base { PlaceBase::Local(id) => id, @@ -111,13 +112,13 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet } } - fn consume(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} - fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} - fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: hir::HirId) {} - fn copy(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} + fn consume(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: HirId) {} + fn copy(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} } - let mut s = S(hir::HirIdSet::default()); + let mut s = S(HirIdSet::default()); let infcx = cx.tcx.infer_ctxt().build(); let mut v = ExprUseVisitor::new( &mut s, @@ -130,10 +131,10 @@ fn imm_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet s.0 } -fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet { - struct S(hir::HirIdSet); +fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> HirIdSet { + struct S(HirIdSet); impl Delegate<'_> for S { - fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: hir::HirId, kind: BorrowKind) { + fn borrow(&mut self, place: &PlaceWithHirId<'_>, _: HirId, kind: BorrowKind) { if matches!(kind, BorrowKind::MutBorrow) { self.0.insert(match place.place.base { PlaceBase::Local(id) => id, @@ -143,13 +144,13 @@ fn mut_borrows_in_expr(cx: &LateContext<'_>, e: &hir::Expr<'_>) -> hir::HirIdSet } } - fn consume(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} - fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} - fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: hir::HirId) {} - fn copy(&mut self, _: &PlaceWithHirId<'_>, _: hir::HirId) {} + fn consume(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn mutate(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} + fn fake_read(&mut self, _: &PlaceWithHirId<'_>, _: FakeReadCause, _: HirId) {} + fn copy(&mut self, _: &PlaceWithHirId<'_>, _: HirId) {} } - let mut s = S(hir::HirIdSet::default()); + let mut s = S(HirIdSet::default()); let infcx = cx.tcx.infer_ctxt().build(); let mut v = ExprUseVisitor::new( &mut s, diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 83b32000a9f9..d6592622f0bb 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -8,7 +8,7 @@ use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_i use hir::LifetimeName; use rustc_errors::{Applicability, MultiSpan}; use rustc_hir::def_id::DefId; -use rustc_hir::hir_id::HirIdMap; +use rustc_hir::hir_id::{HirId, HirIdMap}; use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{ self as hir, AnonConst, BinOpKind, BindingAnnotation, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, @@ -324,7 +324,7 @@ struct PtrArgReplacement { struct PtrArg<'tcx> { idx: usize, - emission_id: hir::HirId, + emission_id: HirId, span: Span, ty_did: DefId, ty_name: Symbol, diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs index d3540bc8e1c3..038eb92d652b 100644 --- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs +++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_expr, Visitor}; -use rustc_hir::{self as hir}; +use rustc_hir::{self as hir, HirId}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::{GenericArgKind, Ty}; use rustc_session::impl_lint_pass; @@ -55,7 +55,7 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]); #[derive(Default)] pub struct SignificantDropTightening<'tcx> { - apas: FxIndexMap, + apas: FxIndexMap, /// Auxiliary structure used to avoid having to verify the same type multiple times. seen_types: FxHashSet>, type_cache: FxHashMap, bool>, @@ -359,9 +359,9 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o /// Auxiliary parameters used on each block check of an item struct AuxParams<'others, 'stmt, 'tcx> { //// See [AuxParamsAttr]. - apas: &'others mut FxIndexMap, + apas: &'others mut FxIndexMap, /// The current block identifier that is being visited. - curr_block_hir_id: hir::HirId, + curr_block_hir_id: HirId, /// The current block span that is being visited. curr_block_span: Span, /// The current statement that is being visited. @@ -369,10 +369,10 @@ struct AuxParams<'others, 'stmt, 'tcx> { } impl<'others, 'stmt, 'tcx> AuxParams<'others, 'stmt, 'tcx> { - fn new(apas: &'others mut FxIndexMap, curr_stmt: &'stmt hir::Stmt<'tcx>) -> Self { + fn new(apas: &'others mut FxIndexMap, curr_stmt: &'stmt hir::Stmt<'tcx>) -> Self { Self { apas, - curr_block_hir_id: hir::HirId::INVALID, + curr_block_hir_id: HirId::INVALID, curr_block_span: DUMMY_SP, curr_stmt: Cow::Borrowed(curr_stmt), } @@ -389,7 +389,7 @@ struct AuxParamsAttr { has_expensive_expr_after_last_attr: bool, /// The identifier of the block that involves the first `#[has_significant_drop]`. - first_block_hir_id: hir::HirId, + first_block_hir_id: HirId, /// The span of the block that involves the first `#[has_significant_drop]`. first_block_span: Span, /// The binding or variable that references the initial construction of the type marked with @@ -414,7 +414,7 @@ impl Default for AuxParamsAttr { Self { counter: 0, has_expensive_expr_after_last_attr: false, - first_block_hir_id: hir::HirId::INVALID, + first_block_hir_id: HirId::INVALID, first_bind_ident: Ident::empty(), first_block_span: DUMMY_SP, first_method_span: DUMMY_SP, @@ -428,7 +428,7 @@ impl Default for AuxParamsAttr { fn dummy_stmt_expr<'any>(expr: &'any hir::Expr<'any>) -> hir::Stmt<'any> { hir::Stmt { - hir_id: hir::HirId::INVALID, + hir_id: HirId::INVALID, kind: hir::StmtKind::Expr(expr), span: DUMMY_SP, } From b03ae74c84977517639449e35473fcedd6409ab3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 16 Apr 2024 15:48:47 +1000 Subject: [PATCH 081/114] Rename a tiny module. So it doesn't clash with `rustc_middle::ty`. --- .../rustc_const_eval/src/transform/check_consts/check.rs | 2 +- .../rustc_const_eval/src/transform/check_consts/ops.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 543996c86bac..1ea30e3a2aff 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -168,7 +168,7 @@ impl<'ck, 'mir, 'tcx> TypeVisitor> for LocalReturnTyVisitor<'ck, 'm match t.kind() { ty::FnPtr(_) => {} ty::Ref(_, _, hir::Mutability::Mut) => { - self.checker.check_op(ops::ty::MutRef(self.kind)); + self.checker.check_op(ops::mut_ref::MutRef(self.kind)); t.super_visit_with(self) } _ => t.super_visit_with(self), diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 9775f1980c59..dda8f3ed87d2 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -10,8 +10,8 @@ use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; use rustc_middle::mir::{self, CallSource}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self as middle_ty, suggest_constraining_type_param, Closure, FnDef, FnPtr, GenericArgKind, - GenericArgsRef, Param, TraitRef, Ty, + self, suggest_constraining_type_param, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, + Param, TraitRef, Ty, }; use rustc_middle::util::{call_kind, CallDesugaringKind, CallKind}; use rustc_session::parse::feature_err; @@ -124,7 +124,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { ); } } - middle_ty::Adt(..) => { + ty::Adt(..) => { let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); @@ -621,7 +621,7 @@ impl<'tcx> NonConstOp<'tcx> for ThreadLocalAccess { } /// Types that cannot appear in the signature or locals of a `const fn`. -pub mod ty { +pub mod mut_ref { use super::*; #[derive(Debug)] From 876ac7b1c3fcd99b06a3170bd4abdc7e3317a005 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 16 Apr 2024 08:52:06 +0200 Subject: [PATCH 082/114] avoid passing --sysroot twice in bootstrap --- src/tools/miri/cargo-miri/src/phases.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index ca8b35a17be5..b774ca8fa725 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -412,8 +412,11 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { // Arguments are treated very differently depending on whether this crate is // for interpretation by Miri, or for use by a build script / proc macro. if target_crate { - // Set the sysroot. - cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap()); + if phase != RustcPhase::Setup { + // Set the sysroot -- except during setup, where we don't have an existing sysroot yet + // and where the bootstrap wrapper adds its own `--sysroot` flag so we can't set ours. + cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap()); + } // Forward arguments, but patched. let emit_flag = "--emit"; @@ -578,9 +581,9 @@ pub fn phase_runner(mut binary_args: impl Iterator, phase: Runner } if phase != RunnerPhase::Rustdoc { - // Set the sysroot. Not necessary in rustdoc, where we already set the sysroot when invoking - // rustdoc itself, which will forward that flag when invoking rustc (i.e., us), so the flag - // is present in `info.args`. + // Set the sysroot. Not necessary in rustdoc, where we already set the sysroot in + // `phase_rustdoc`. rustdoc will forward that flag when invoking rustc (i.e., us), so the + // flag is present in `info.args`. cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap()); } // Forward rustc arguments. From c30e15adedba70d99a09146707814d14a93364a1 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Tue, 16 Apr 2024 12:42:48 +0530 Subject: [PATCH 083/114] Fail candidate assembly for erroneous types Trait predicates for types which have errors may still evaluate to OK leading to downstream ICEs. Now we return a selection error for such types in candidate assembly and thereby prevent such issues --- .../error_reporting/type_err_ctxt_ext.rs | 5 +++- .../src/traits/select/candidate_assembly.rs | 8 +++++++ compiler/rustc_ty_utils/src/ty.rs | 4 ++-- tests/crashes/123154.rs | 12 ---------- tests/ui/closures/issue-78720.rs | 1 - tests/ui/closures/issue-78720.stderr | 16 ++++--------- .../ice-type-mismatch-when-copying-112824.rs | 1 - ...e-type-mismatch-when-copying-112824.stderr | 8 +------ .../ice-unsized-struct-const-eval-123154.rs | 15 ++++++++++++ ...ce-unsized-struct-const-eval-123154.stderr | 24 +++++++++++++++++++ .../issue-68830-spurious-diagnostics.rs | 1 + .../issue-68830-spurious-diagnostics.stderr | 14 +++++++++-- 12 files changed, 72 insertions(+), 37 deletions(-) delete mode 100644 tests/crashes/123154.rs create mode 100644 tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs create mode 100644 tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 3dc54b338017..925fe98d2937 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -984,7 +984,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // Already reported in the query. SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(guar)) | // Already reported. - Overflow(OverflowError::Error(guar)) => return guar, + Overflow(OverflowError::Error(guar)) => { + self.set_tainted_by_errors(guar); + return guar + }, Overflow(_) => { bug!("overflow should be handled before the `report_selection_error` path"); 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 974e5ef0e166..3ef7cc01f902 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -87,6 +87,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if lang_items.sized_trait() == Some(def_id) { // Sized is never implementable by end-users, it is // always automatically computed. + + // FIXME: Consider moving this check to the top level as it + // may also be useful for predicates other than `Sized` + // Error type cannot possibly implement `Sized` (fixes #123154) + if let Err(e) = obligation.predicate.skip_binder().self_ty().error_reported() { + return Err(SelectionError::Overflow(e.into())); + } + let sized_conditions = self.sized_conditions(obligation); self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); } else if lang_items.unsize_trait() == Some(def_id) { diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index f33234122c9d..2139b8c665bf 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -91,8 +91,8 @@ fn adt_sized_constraint<'tcx>( let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?; - if constraint_ty.references_error() { - return None; + if let Err(guar) = constraint_ty.error_reported() { + return Some(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))); } // perf hack: if there is a `constraint_ty: Sized` bound, then we know diff --git a/tests/crashes/123154.rs b/tests/crashes/123154.rs deleted file mode 100644 index 510ae8adf350..000000000000 --- a/tests/crashes/123154.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: #123154 -struct AA { - pub data: [&usize] -} - -impl AA { - const fn new() -> Self { } -} - -static AA = AA::new(); - -fn main() { } diff --git a/tests/ui/closures/issue-78720.rs b/tests/ui/closures/issue-78720.rs index 0c4f337ba57b..81af030fe556 100644 --- a/tests/ui/closures/issue-78720.rs +++ b/tests/ui/closures/issue-78720.rs @@ -1,6 +1,5 @@ fn server() -> impl { //~^ ERROR at least one trait must be specified - //~| ERROR type annotations needed ().map2(|| "") } diff --git a/tests/ui/closures/issue-78720.stderr b/tests/ui/closures/issue-78720.stderr index 2f57c7616f12..5d65c87b0fd6 100644 --- a/tests/ui/closures/issue-78720.stderr +++ b/tests/ui/closures/issue-78720.stderr @@ -5,7 +5,7 @@ LL | fn server() -> impl { | ^^^^ error[E0412]: cannot find type `F` in this scope - --> $DIR/issue-78720.rs:14:12 + --> $DIR/issue-78720.rs:13:12 | LL | _func: F, | ^ @@ -22,14 +22,8 @@ help: you might be missing a type parameter LL | struct Map2 { | +++ -error[E0282]: type annotations needed - --> $DIR/issue-78720.rs:1:16 - | -LL | fn server() -> impl { - | ^^^^ cannot infer type - error[E0308]: mismatched types - --> $DIR/issue-78720.rs:8:39 + --> $DIR/issue-78720.rs:7:39 | LL | fn map2(self, f: F) -> Map2 {} | ^^ expected `Map2`, found `()` @@ -38,7 +32,7 @@ LL | fn map2(self, f: F) -> Map2 {} found unit type `()` error[E0277]: the size for values of type `Self` cannot be known at compilation time - --> $DIR/issue-78720.rs:8:16 + --> $DIR/issue-78720.rs:7:16 | LL | fn map2(self, f: F) -> Map2 {} | ^^^^ doesn't have a size known at compile-time @@ -53,7 +47,7 @@ help: function arguments must have a statically known size, borrowed types alway LL | fn map2(&self, f: F) -> Map2 {} | + -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0282, E0308, E0412. +Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs index dc9782295c13..a41a159c1fd7 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs @@ -13,7 +13,6 @@ impl Opcode2 { pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) { move |i| match msg_type { Opcode2::OP2 => unimplemented!(), - //~^ ERROR could not evaluate constant pattern } } diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr index 9442eac0cf54..d95a8861230e 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr @@ -17,13 +17,7 @@ help: you might be missing a type parameter LL | pub struct Opcode2(&'a S); | +++ -error: could not evaluate constant pattern - --> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9 - | -LL | Opcode2::OP2 => unimplemented!(), - | ^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0261, E0412. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs new file mode 100644 index 000000000000..24a2cd19b187 --- /dev/null +++ b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.rs @@ -0,0 +1,15 @@ +// Regression test for #123154 + +struct AA { + pub data: [&usize] + //~^ ERROR missing lifetime specifier +} + +impl AA { + const fn new() -> Self { } + //~^ ERROR mismatched types +} + +static ST: AA = AA::new(); + +fn main() {} diff --git a/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr new file mode 100644 index 000000000000..9657e5cdda15 --- /dev/null +++ b/tests/ui/consts/const-eval/ice-unsized-struct-const-eval-123154.stderr @@ -0,0 +1,24 @@ +error[E0106]: missing lifetime specifier + --> $DIR/ice-unsized-struct-const-eval-123154.rs:4:16 + | +LL | pub data: [&usize] + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL ~ struct AA<'a> { +LL ~ pub data: [&'a usize] + | + +error[E0308]: mismatched types + --> $DIR/ice-unsized-struct-const-eval-123154.rs:9:23 + | +LL | const fn new() -> Self { } + | --- ^^^^ expected `AA`, found `()` + | | + | implicitly returns `()` as its body has no tail or `return` expression + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0106, E0308. +For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs index d11ec7983321..a7487b8aecb9 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs @@ -17,6 +17,7 @@ impl MyTrait for D { } impl MyTrait for BadStruct { +//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` fn foo() {} } diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr index 0ecec03a023e..13f6ae0805da 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr @@ -4,6 +4,16 @@ error[E0412]: cannot find type `MissingType` in this scope LL | err: MissingType | ^^^^^^^^^^^ not found in this scope -error: aborting due to 1 previous error +error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` + --> $DIR/issue-68830-spurious-diagnostics.rs:19:1 + | +LL | impl MyTrait for D { + | --------------------------- first implementation here +... +LL | impl MyTrait for BadStruct { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct` -For more information about this error, try `rustc --explain E0412`. +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0412. +For more information about an error, try `rustc --explain E0119`. From 82e7773bc1ab8b89c7b8c0a107c1f5741fe0bf1e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 15 Apr 2024 18:29:32 +0000 Subject: [PATCH 084/114] Subtype predicates only exist on inference types, so we can allow them to register opaque types within them. --- compiler/rustc_infer/src/infer/mod.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 0b8061104ab4..76a40ecd5bc4 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -945,14 +945,27 @@ impl<'tcx> InferCtxt<'tcx> { (&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => { return Err((a_vid, b_vid)); } + // We don't silently want to constrain hidden types here, so we assert that either one side is + // an infer var, so it'll get constrained to whatever the other side is, or there are no opaque + // types involved. + // We don't expect this to actually get hit, but if it does, we now at least know how to write + // a test for it. + (_, ty::Infer(ty::TyVar(_))) => {} + (ty::Infer(ty::TyVar(_)), _) => {} + _ if (r_a, r_b).has_opaque_types() => { + span_bug!( + cause.span(), + "opaque types got hidden types registered from within subtype predicate: {r_a:?} vs {r_b:?}" + ) + } _ => {} } self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| { if a_is_expected { - Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::No, a, b)) + Ok(self.at(cause, param_env).sub(DefineOpaqueTypes::Yes, a, b)) } else { - Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::No, b, a)) + Ok(self.at(cause, param_env).sup(DefineOpaqueTypes::Yes, b, a)) } }) } From 801413ecd18f8f1180cc74ca93f9279f3e95c862 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Apr 2024 10:57:41 +0000 Subject: [PATCH 085/114] Taint const qualifs if a static is referenced that didn't pass wfcheck --- .../src/transform/check_consts/check.rs | 5 +++ tests/crashes/123153.rs | 17 --------- tests/ui/statics/unsized_type2.rs | 21 +++++++++++ tests/ui/statics/unsized_type2.stderr | 37 +++++++++++++++++++ 4 files changed, 63 insertions(+), 17 deletions(-) delete mode 100644 tests/crashes/123153.rs create mode 100644 tests/ui/statics/unsized_type2.rs create mode 100644 tests/ui/statics/unsized_type2.stderr diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 543996c86bac..eb7f93857301 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -331,6 +331,11 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { if self.tcx.is_thread_local_static(def_id) { self.tcx.dcx().span_bug(span, "tls access is checked in `Rvalue::ThreadLocalRef`"); } + if let Some(def_id) = def_id.as_local() + && let Err(guar) = self.tcx.at(span).check_well_formed(hir::OwnerId { def_id }) + { + self.error_emitted = Some(guar); + } self.check_op_spanned(ops::StaticAccess, span) } diff --git a/tests/crashes/123153.rs b/tests/crashes/123153.rs deleted file mode 100644 index d2c32ecd73e7..000000000000 --- a/tests/crashes/123153.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #123153 -pub struct wl_interface { - pub version: str, -} - -pub struct Interface { - pub other_interfaces: &'static [&'static Interface], - pub c_ptr: Option<&'static wl_interface>, -} - -pub static mut wl_callback_interface: wl_interface = wl_interface { version: 0 }; - -pub static WL_CALLBACK_INTERFACE: Interface = - Interface { other_interfaces: &[], c_ptr: Some(unsafe { &wl_callback_interface }) }; - - -fn main() {} diff --git a/tests/ui/statics/unsized_type2.rs b/tests/ui/statics/unsized_type2.rs new file mode 100644 index 000000000000..303926849e69 --- /dev/null +++ b/tests/ui/statics/unsized_type2.rs @@ -0,0 +1,21 @@ +//! This test used to actually start evaluating the static even though +//! there were errors in typeck. +//! issue: rust-lang/rust#123153 + +pub struct Foo { + pub version: str, +} + +pub struct Bar { + pub ok: &'static [&'static Bar], + pub bad: &'static Foo, +} + +pub static WITH_ERROR: Foo = Foo { version: 0 }; +//~^ ERROR the size for values of type `str` cannot be known at compilation time +//~| ERROR the size for values of type `str` cannot be known at compilation time +//~| ERROR mismatched types + +pub static USE_WITH_ERROR: Bar = Bar { ok: &[], bad: &WITH_ERROR }; + +fn main() {} diff --git a/tests/ui/statics/unsized_type2.stderr b/tests/ui/statics/unsized_type2.stderr new file mode 100644 index 000000000000..4e47b37afdca --- /dev/null +++ b/tests/ui/statics/unsized_type2.stderr @@ -0,0 +1,37 @@ +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized_type2.rs:14:24 + | +LL | pub static WITH_ERROR: Foo = Foo { version: 0 }; + | ^^^ doesn't have a size known at compile-time + | + = help: within `Foo`, the trait `Sized` is not implemented for `str`, which is required by `Foo: Sized` +note: required because it appears within the type `Foo` + --> $DIR/unsized_type2.rs:5:12 + | +LL | pub struct Foo { + | ^^^ + +error[E0277]: the size for values of type `str` cannot be known at compilation time + --> $DIR/unsized_type2.rs:14:30 + | +LL | pub static WITH_ERROR: Foo = Foo { version: 0 }; + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `Foo`, the trait `Sized` is not implemented for `str`, which is required by `Foo: Sized` +note: required because it appears within the type `Foo` + --> $DIR/unsized_type2.rs:5:12 + | +LL | pub struct Foo { + | ^^^ + = note: constant expressions must have a statically known size + +error[E0308]: mismatched types + --> $DIR/unsized_type2.rs:14:45 + | +LL | pub static WITH_ERROR: Foo = Foo { version: 0 }; + | ^ expected `str`, found integer + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. From fe18afe48caa890fc343d99a176db8fe8310dbfc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Apr 2024 10:07:11 +0000 Subject: [PATCH 086/114] Unset test env vars before setting new ones. If you want to override an env var, don't unset it, just set it --- src/tools/compiletest/src/runtest.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 38d22fef1132..1dd639a89188 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2173,8 +2173,8 @@ impl<'test> TestCx<'test> { let aux_dir = self.aux_output_dir(); self.build_all_auxiliary(&self.testpaths, &aux_dir, &mut rustc); - self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove); rustc.envs(self.props.rustc_env.clone()); + self.props.unset_rustc_env.iter().fold(&mut rustc, Command::env_remove); self.compose_and_run( rustc, self.config.compile_lib_path.to_str().unwrap(), @@ -2220,10 +2220,10 @@ impl<'test> TestCx<'test> { ); aux_cx.build_all_auxiliary(of, &aux_dir, &mut aux_rustc); + aux_rustc.envs(aux_props.rustc_env.clone()); for key in &aux_props.unset_rustc_env { aux_rustc.env_remove(key); } - aux_rustc.envs(aux_props.rustc_env.clone()); let (aux_type, crate_type) = if is_bin { (AuxType::Bin, Some("bin")) From 4f75d67b6fd0bd677c17d5060facd31c70dd4afe Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Apr 2024 10:07:56 +0000 Subject: [PATCH 087/114] Make ui_test backtraces short by default --- src/tools/compiletest/src/header.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index f78e0363f55b..daa605f6d03a 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -265,7 +265,10 @@ impl TestProps { aux_bins: vec![], aux_crates: vec![], revisions: vec![], - rustc_env: vec![("RUSTC_ICE".to_string(), "0".to_string())], + rustc_env: vec![ + ("RUSTC_ICE".to_string(), "0".to_string()), + ("RUST_BACKTRACE".to_string(), "short".to_string()), + ], unset_rustc_env: vec![("RUSTC_LOG_COLOR".to_string())], exec_env: vec![], unset_exec_env: vec![], From 0a88339a57557152bb32c4969f2f76955793133e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 9 Apr 2024 10:08:20 +0000 Subject: [PATCH 088/114] Don't ICE for kind mismatches during error rendering --- .../error_reporting/type_err_ctxt_ext.rs | 3 ++ tests/ui/const-generics/kind_mismatch.rs | 24 ++++++++++++ tests/ui/const-generics/kind_mismatch.stderr | 39 +++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 tests/ui/const-generics/kind_mismatch.rs create mode 100644 tests/ui/const-generics/kind_mismatch.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 3dc54b338017..4aa5f9752ab2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -1974,6 +1974,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { for (obligation_arg, impl_arg) in std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args) { + if (obligation_arg, impl_arg).references_error() { + return false; + } if let Err(terr) = ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg) { diff --git a/tests/ui/const-generics/kind_mismatch.rs b/tests/ui/const-generics/kind_mismatch.rs new file mode 100644 index 000000000000..bab58d5952a5 --- /dev/null +++ b/tests/ui/const-generics/kind_mismatch.rs @@ -0,0 +1,24 @@ +//! This test used to ICE in typeck because of the type/const mismatch, +//! even though wfcheck already errored. +//! issue: rust-lang/rust#123457 + +pub struct KeyHolder {} + +pub trait ContainsKey {} + +pub trait SubsetExcept

{} + +impl ContainsKey for KeyHolder {} +//~^ ERROR: type provided when a constant was expected +//~| ERROR: type provided when a constant was expected + +impl> SubsetExcept

for T {} + +pub fn remove_key>() -> S { + loop {} +} + +fn main() { + let map: KeyHolder<0> = remove_key::<_, _>(); + //~^ ERROR: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied +} diff --git a/tests/ui/const-generics/kind_mismatch.stderr b/tests/ui/const-generics/kind_mismatch.stderr new file mode 100644 index 000000000000..80968ebea687 --- /dev/null +++ b/tests/ui/const-generics/kind_mismatch.stderr @@ -0,0 +1,39 @@ +error[E0747]: type provided when a constant was expected + --> $DIR/kind_mismatch.rs:11:38 + | +LL | impl ContainsKey for KeyHolder {} + | - ^ + | | + | help: consider changing this type parameter to a const parameter: `const K: u8` + +error[E0747]: type provided when a constant was expected + --> $DIR/kind_mismatch.rs:11:21 + | +LL | impl ContainsKey for KeyHolder {} + | - ^ + | | + | help: consider changing this type parameter to a const parameter: `const K: u8` + +error[E0277]: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied + --> $DIR/kind_mismatch.rs:22:45 + | +LL | let map: KeyHolder<0> = remove_key::<_, _>(); + | ^ the trait `ContainsKey<0>` is not implemented for `KeyHolder<0>`, which is required by `KeyHolder<0>: SubsetExcept<_>` + | +note: required for `KeyHolder<0>` to implement `SubsetExcept<_>` + --> $DIR/kind_mismatch.rs:15:28 + | +LL | impl> SubsetExcept

for T {} + | -------------- ^^^^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here +note: required by a bound in `remove_key` + --> $DIR/kind_mismatch.rs:17:25 + | +LL | pub fn remove_key>() -> S { + | ^^^^^^^^^^^^^^^ required by this bound in `remove_key` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0747. +For more information about an error, try `rustc --explain E0277`. From a5a1775c117e8238cc58b4db1ad8e731177795ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Tue, 16 Apr 2024 13:26:51 +0200 Subject: [PATCH 089/114] rustdoc: update module-level docs of `rustdoc::clean` --- src/librustdoc/clean/mod.rs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 925d41e67f8f..fc4f48262e5d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1,5 +1,25 @@ -//! This module contains the "cleaned" pieces of the AST, and the functions -//! that clean them. +//! This module defines the primary IR[^1] used in rustdoc together with the procedures that +//! transform rustc data types into it. +//! +//! This IR — commonly referred to as the *cleaned AST* — is modeled after the [AST][ast]. +//! +//! There are two kinds of transformation — *cleaning* — procedures: +//! +//! 1. Cleans [HIR][hir] types. Used for user-written code and inlined local re-exports +//! both found in the local crate. +//! 2. Cleans [`rustc_middle::ty`] types. Used for inlined cross-crate re-exports and anything +//! output by the trait solver (e.g., when synthesizing blanket and auto-trait impls). +//! They usually have `ty` or `middle` in their name. +//! +//! Their name is prefixed by `clean_`. +//! +//! Both the HIR and the `rustc_middle::ty` IR are quite removed from the source code. +//! The cleaned AST on the other hand is closer to it which simplifies the rendering process. +//! Furthermore, operating on a single IR instead of two avoids duplicating efforts down the line. +//! +//! This IR is consumed by both the HTML and the JSON backend. +//! +//! [^1]: Intermediate representation. mod auto_trait; mod blanket_impl; From d8745f934650115821b2af5755871e9c4df408fd Mon Sep 17 00:00:00 2001 From: Hrvoje Niksic Date: Thu, 8 Feb 2024 12:25:30 +0100 Subject: [PATCH 090/114] Update usage note on OpenOptions::append() Avoid implying that concatenating data before passing it to `write()` (with or without `BufWriter`) ensures atomicity. --- library/std/src/fs.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 8a24949631c5..1293abddaf36 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -980,15 +980,21 @@ impl OpenOptions { /// Note that setting `.write(true).append(true)` has the same effect as /// setting only `.append(true)`. /// - /// For most filesystems, the operating system guarantees that all writes are - /// atomic: no writes get mangled because another process writes at the same - /// time. + /// Append mode guarantees that writes will be positioned at the current end of file, + /// even when there are other processes or threads appending to the same file. This is + /// unlike [seek]\([SeekFrom]::[End]\(0)) followed by `write()`, which + /// has a race between seeking and writing during which another writer can write, with + /// our `write()` overwriting their data. /// - /// One maybe obvious note when using append-mode: make sure that all data - /// that belongs together is written to the file in one operation. This - /// can be done by concatenating strings before passing them to [`write()`], - /// or using a buffered writer (with a buffer of adequate size), - /// and calling [`flush()`] when the message is complete. + /// Keep in mind that this does not necessarily guarantee that data appended by + /// different processes or threads does not interleave. The amount of data accepted a + /// single `write()` call depends on the operating system and file system. A + /// successful `write()` is allowed to write only part of the given data, so even if + /// you're careful to provide the whole message in a single call to `write()`, there + /// is no guarantee that it will be written out in full. If you rely on the filesystem + /// accepting the message in a single write, make sure that all data that belongs + /// together is written in one operation. This can be done by concatenating strings + /// before passing them to [`write()`]. /// /// If a file is opened with both read and append access, beware that after /// opening, and after every write, the position for reading may be set at the @@ -1003,6 +1009,9 @@ impl OpenOptions { /// [`write()`]: Write::write "io::Write::write" /// [`flush()`]: Write::flush "io::Write::flush" /// [stream_position]: Seek::stream_position "io::Seek::stream_position" + /// [seek]: Seek::seek "io::Seek::seek" + /// [Current]: SeekFrom::Current "io::SeekFrom::Current" + /// [End]: SeekFrom::End "io::SeekFrom::End" /// /// # Examples /// From 8606efa5d24b1aeefa14b285920a0291953149fa Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 16 Apr 2024 14:13:18 +0200 Subject: [PATCH 091/114] Box::into_raw: make Miri understand that this is a box-to-raw cast --- library/alloc/src/boxed.rs | 8 ++++-- .../newtype_pair_retagging.stack.stderr | 2 +- .../newtype_retagging.stack.stderr | 2 +- .../miri/tests/pass/issues/issue-miri-3473.rs | 28 +++++++++++++++++++ .../pass/stacked-borrows/stacked-borrows.rs | 12 ++++++++ 5 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 src/tools/miri/tests/pass/issues/issue-miri-3473.rs diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 7c3fa2312e5f..ed3ad8b39a53 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1058,7 +1058,8 @@ impl Box { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Self) -> *mut T { - Self::into_raw_with_allocator(b).0 + // Make sure Miri realizes that we transition from a noalias pointer to a raw pointer here. + unsafe { addr_of_mut!(*&mut *Self::into_raw_with_allocator(b).0) } } /// Consumes the `Box`, returning a wrapped raw pointer and the allocator. @@ -1112,7 +1113,10 @@ impl Box { pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) { let mut b = mem::ManuallyDrop::new(b); // We carefully get the raw pointer out in a way that Miri's aliasing model understands what - // is happening: using the primitive "deref" of `Box`. + // is happening: using the primitive "deref" of `Box`. In case `A` is *not* `Global`, we + // want *no* aliasing requirements here! + // In case `A` *is* `Global`, this does not quite have the right behavior; `into_raw` + // works around that. let ptr = addr_of_mut!(**b); let alloc = unsafe { ptr::read(&b.1) }; (ptr, alloc) diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr index 867907e98e66..c26c7f397b09 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr @@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: was created by a Unique retag at offsets [0x0..0x4] +help: was created by a SharedReadWrite retag at offsets [0x0..0x4] --> $DIR/newtype_pair_retagging.rs:LL:CC | LL | let ptr = Box::into_raw(Box::new(0i32)); diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr index 56715938e978..ae54da70fe2d 100644 --- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr +++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr @@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc) | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: was created by a Unique retag at offsets [0x0..0x4] +help: was created by a SharedReadWrite retag at offsets [0x0..0x4] --> $DIR/newtype_retagging.rs:LL:CC | LL | let ptr = Box::into_raw(Box::new(0i32)); diff --git a/src/tools/miri/tests/pass/issues/issue-miri-3473.rs b/src/tools/miri/tests/pass/issues/issue-miri-3473.rs new file mode 100644 index 000000000000..77b960c1cdca --- /dev/null +++ b/src/tools/miri/tests/pass/issues/issue-miri-3473.rs @@ -0,0 +1,28 @@ +//@revisions: stack tree +//@[tree]compile-flags: -Zmiri-tree-borrows +use std::cell::UnsafeCell; + +#[repr(C)] +#[derive(Default)] +struct Node { + _meta: UnsafeCell, + value: usize, +} + +impl Node { + fn value(&self) -> &usize { + &self.value + } +} + +/// This used to cause Stacked Borrows errors because of trouble around conversion +/// from Box to raw pointer. +fn main() { + unsafe { + let a = Box::into_raw(Box::new(Node::default())); + let ptr = &*a; + *UnsafeCell::raw_get(a.cast::>()) = 2; + assert_eq!(*ptr.value(), 0); + drop(Box::from_raw(a)); + } +} diff --git a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs index 734411ccc724..43ba490d5bb4 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs @@ -20,6 +20,7 @@ fn main() { wide_raw_ptr_in_tuple(); not_unpin_not_protected(); write_does_not_invalidate_all_aliases(); + box_into_raw_allows_interior_mutable_alias(); } // Make sure that reading from an `&mut` does, like reborrowing to `&`, @@ -263,3 +264,14 @@ fn write_does_not_invalidate_all_aliases() { other::lib2(); assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated } + +fn box_into_raw_allows_interior_mutable_alias() { unsafe { + let b = Box::new(std::cell::Cell::new(42)); + let raw = Box::into_raw(b); + let c = &*raw; + let d = raw.cast::(); // bypassing `Cell` -- only okay in Miri tests + // `c` and `d` should permit arbitrary aliasing with each other now. + *d = 1; + c.set(2); + drop(Box::from_raw(raw)); +} } From 780dfb803fe1b0ad139bac9736ce847c75ab1c81 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 16 Apr 2024 15:20:12 +0200 Subject: [PATCH 092/114] Outline default query and hook provider function implementations --- compiler/rustc_middle/src/hooks/mod.rs | 15 +++++---- compiler/rustc_middle/src/query/plumbing.rs | 36 ++++++++++++--------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_middle/src/hooks/mod.rs b/compiler/rustc_middle/src/hooks/mod.rs index f7ce15d0a8dc..669265c86f5c 100644 --- a/compiler/rustc_middle/src/hooks/mod.rs +++ b/compiler/rustc_middle/src/hooks/mod.rs @@ -47,12 +47,7 @@ macro_rules! declare_hooks { impl Default for Providers { fn default() -> Self { Providers { - $($name: |_, $($arg,)*| bug!( - "`tcx.{}{:?}` cannot be called as `{}` was never assigned to a provider function.\n", - stringify!($name), - ($($arg,)*), - stringify!($name), - ),)* + $($name: |_, $($arg,)*| default_hook(stringify!($name), &($($arg,)*))),* } } } @@ -84,7 +79,6 @@ declare_hooks! { /// via `mir_built` hook build_mir(key: LocalDefId) -> mir::Body<'tcx>; - /// Imports all `SourceFile`s from the given crate into the current session. /// This normally happens automatically when we decode a `Span` from /// that crate's metadata - however, the incr comp cache needs @@ -103,3 +97,10 @@ declare_hooks! { /// Will fetch a DefId from a DefPathHash for a foreign crate. hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId; } + +#[cold] +fn default_hook(name: &str, args: &dyn std::fmt::Debug) -> ! { + bug!( + "`tcx.{name}{args:?}` cannot be called as `{name}` was never assigned to a provider function" + ) +} diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index 4ce6f7747a56..643861972c4b 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -266,13 +266,7 @@ macro_rules! separate_provide_extern_default { () }; ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => { - |_, key| bug!( - "`tcx.{}({:?})` unsupported by its crate; \ - perhaps the `{}` query was never assigned a provider function", - stringify!($name), - key, - stringify!($name), - ) + |_, key| $crate::query::plumbing::default_extern_query(stringify!($name), &key) }; ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => { separate_provide_extern_default!([$($modifiers)*][$($args)*]) @@ -462,15 +456,7 @@ macro_rules! define_callbacks { impl Default for Providers { fn default() -> Self { Providers { - $($name: |_, key| bug!( - "`tcx.{}({:?})` is not supported for this key;\n\ - hint: Queries can be either made to the local crate, or the external crate. \ - This error means you tried to use it for one that's not supported.\n\ - If that's not the case, {} was likely never assigned to a provider function.\n", - stringify!($name), - key, - stringify!($name), - ),)* + $($name: |_, key| $crate::query::plumbing::default_query(stringify!($name), &key)),* } } } @@ -661,3 +647,21 @@ use super::erase::EraseType; #[derive(Copy, Clone, Debug, HashStable)] pub struct CyclePlaceholder(pub ErrorGuaranteed); + +#[cold] +pub(crate) fn default_query(name: &str, key: &dyn std::fmt::Debug) -> ! { + bug!( + "`tcx.{name}({key:?})` is not supported for this key;\n\ + hint: Queries can be either made to the local crate, or the external crate. \ + This error means you tried to use it for one that's not supported.\n\ + If that's not the case, {name} was likely never assigned to a provider function.\n", + ) +} + +#[cold] +pub(crate) fn default_extern_query(name: &str, key: &dyn std::fmt::Debug) -> ! { + bug!( + "`tcx.{name}({key:?})` unsupported by its crate; \ + perhaps the `{name}` query was never assigned a provider function", + ) +} From e03926c1438173843429f570513972cc6f2e2f6c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 16 Apr 2024 14:00:53 +0000 Subject: [PATCH 093/114] Change a diagnostics-path-only `DefineOpaqueTypes` to `Yes`. --- compiler/rustc_hir_typeck/src/method/probe.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 28e17e1de36c..f1e3f38febd7 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -1696,7 +1696,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let ProbeResult::Match = result && self .at(&ObligationCause::dummy(), self.param_env) - .sup(DefineOpaqueTypes::No, return_ty, xform_ret_ty) + .sup(DefineOpaqueTypes::Yes, return_ty, xform_ret_ty) .is_err() { result = ProbeResult::BadReturnType; From 864eb7fa14c25de655e03d692c5da798d3d98413 Mon Sep 17 00:00:00 2001 From: Arthur Carcano Date: Fri, 12 Apr 2024 17:47:30 +0200 Subject: [PATCH 094/114] Remove uneeded clones now that TrustedStep implies Copy This is a follow up to 11fa1764ee4819aa674ca861c5e9a8fafd7a59e6 --- library/core/src/iter/range.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 5eea764b28ad..644a16929439 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -1156,11 +1156,11 @@ impl RangeInclusiveIteratorImpl for ops::RangeInclusive { let is_iterating = self.start < self.end; Some(if is_iterating { // SAFETY: just checked precondition - let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) }; + let n = unsafe { Step::forward_unchecked(self.start, 1) }; mem::replace(&mut self.start, n) } else { self.exhausted = true; - self.start.clone() + self.start }) } @@ -1179,7 +1179,7 @@ impl RangeInclusiveIteratorImpl for ops::RangeInclusive { while self.start < self.end { // SAFETY: just checked precondition - let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) }; + let n = unsafe { Step::forward_unchecked(self.start, 1) }; let n = mem::replace(&mut self.start, n); accum = f(accum, n)?; } @@ -1187,7 +1187,7 @@ impl RangeInclusiveIteratorImpl for ops::RangeInclusive { self.exhausted = true; if self.start == self.end { - accum = f(accum, self.start.clone())?; + accum = f(accum, self.start)?; } try { accum } @@ -1201,11 +1201,11 @@ impl RangeInclusiveIteratorImpl for ops::RangeInclusive { let is_iterating = self.start < self.end; Some(if is_iterating { // SAFETY: just checked precondition - let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) }; + let n = unsafe { Step::backward_unchecked(self.end, 1) }; mem::replace(&mut self.end, n) } else { self.exhausted = true; - self.end.clone() + self.end }) } @@ -1224,7 +1224,7 @@ impl RangeInclusiveIteratorImpl for ops::RangeInclusive { while self.start < self.end { // SAFETY: just checked precondition - let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) }; + let n = unsafe { Step::backward_unchecked(self.end, 1) }; let n = mem::replace(&mut self.end, n); accum = f(accum, n)?; } @@ -1232,7 +1232,7 @@ impl RangeInclusiveIteratorImpl for ops::RangeInclusive { self.exhausted = true; if self.start == self.end { - accum = f(accum, self.start.clone())?; + accum = f(accum, self.start)?; } try { accum } From 18bfca50f1a6d9ccf322fa4dafec3a67a39ef300 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 16 Apr 2024 16:37:34 +0200 Subject: [PATCH 095/114] interpret: pass MemoryKind to before_memory_deallocation --- .../rustc_const_eval/src/interpret/machine.rs | 1 + compiler/rustc_const_eval/src/interpret/memory.rs | 1 + src/tools/miri/src/borrow_tracker/mod.rs | 2 +- .../src/borrow_tracker/stacked_borrows/mod.rs | 2 +- .../miri/src/borrow_tracker/tree_borrows/mod.rs | 2 +- src/tools/miri/src/concurrency/data_race.rs | 2 +- src/tools/miri/src/diagnostics.rs | 4 ++-- src/tools/miri/src/lib.rs | 2 +- src/tools/miri/src/machine.rs | 15 ++++++++------- src/tools/miri/src/shims/os_str.rs | 8 ++++---- 10 files changed, 21 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 827d8fd9417c..be66ac548d39 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -427,6 +427,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { _prov: (AllocId, Self::ProvenanceExtra), _size: Size, _align: Align, + _kind: MemoryKind, ) -> InterpResult<'tcx> { Ok(()) } diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 9b1d9cf932bd..ca2beb40ce84 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -355,6 +355,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (alloc_id, prov), size, alloc.align, + kind, )?; // Don't forget to remember size and align of this now-dead allocation diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index 8d76a488269f..f21315790a57 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -260,7 +260,7 @@ impl GlobalStateInner { &mut self, id: AllocId, alloc_size: Size, - kind: MemoryKind, + kind: MemoryKind, machine: &MiriMachine<'_, '_>, ) -> AllocState { match self.borrow_tracker_method { diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index 96ff298402d4..b4005515d9d9 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -509,7 +509,7 @@ impl Stacks { id: AllocId, size: Size, state: &mut GlobalStateInner, - kind: MemoryKind, + kind: MemoryKind, machine: &MiriMachine<'_, '_>, ) -> Self { let (base_tag, perm) = match kind { diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index a3d49756e4c8..492e324de454 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -34,7 +34,7 @@ impl<'tcx> Tree { id: AllocId, size: Size, state: &mut GlobalStateInner, - _kind: MemoryKind, + _kind: MemoryKind, machine: &MiriMachine<'_, 'tcx>, ) -> Self { let tag = state.base_ptr_tag(id, machine); // Fresh tag for the root diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs index d51160b2831d..95049b91cbad 100644 --- a/src/tools/miri/src/concurrency/data_race.rs +++ b/src/tools/miri/src/concurrency/data_race.rs @@ -844,7 +844,7 @@ impl VClockAlloc { global: &GlobalState, thread_mgr: &ThreadManager<'_, '_>, len: Size, - kind: MemoryKind, + kind: MemoryKind, current_span: Span, ) -> VClockAlloc { let (alloc_timestamp, alloc_index) = match kind { diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index 30349c003a94..a2b817ea0d57 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -115,7 +115,7 @@ pub enum NonHaltingDiagnostic { /// This `Item` was popped from the borrow stack. The string explains the reason. PoppedPointerTag(Item, String), CreatedCallId(CallId), - CreatedAlloc(AllocId, Size, Align, MemoryKind), + CreatedAlloc(AllocId, Size, Align, MemoryKind), FreedAlloc(AllocId), AccessedAlloc(AllocId, AccessKind), RejectedIsolatedOp(String), @@ -414,7 +414,7 @@ pub fn report_error<'tcx, 'mir>( pub fn report_leaks<'mir, 'tcx>( ecx: &InterpCx<'mir, 'tcx, MiriMachine<'mir, 'tcx>>, - leaks: Vec<(AllocId, MemoryKind, Allocation>)>, + leaks: Vec<(AllocId, MemoryKind, Allocation>)>, ) { let mut any_pruned = false; for (id, kind, mut alloc) in leaks { diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 7821aa9efd4c..42e66057b9d1 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -125,7 +125,7 @@ pub use crate::eval::{ }; pub use crate::helpers::{AccessKind, EvalContextExt as _}; pub use crate::machine::{ - AllocExtra, FrameExtra, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind, + AllocExtra, FrameExtra, MemoryKind, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind, PrimitiveLayouts, Provenance, ProvenanceExtra, }; pub use crate::mono_hash_map::MonoHashMap; diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index ff081328a722..1d06d5c69d36 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -135,9 +135,9 @@ pub enum MiriMemoryKind { Mmap, } -impl From for MemoryKind { +impl From for MemoryKind { #[inline(always)] - fn from(kind: MiriMemoryKind) -> MemoryKind { + fn from(kind: MiriMemoryKind) -> MemoryKind { MemoryKind::Machine(kind) } } @@ -185,6 +185,8 @@ impl fmt::Display for MiriMemoryKind { } } +pub type MemoryKind = interpret::MemoryKind; + /// Pointer provenance. #[derive(Clone, Copy)] pub enum Provenance { @@ -863,10 +865,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { type ProvenanceExtra = ProvenanceExtra; type Bytes = Box<[u8]>; - type MemoryMap = MonoHashMap< - AllocId, - (MemoryKind, Allocation), - >; + type MemoryMap = + MonoHashMap)>; const GLOBAL_KIND: Option = Some(MiriMemoryKind::Global); @@ -1088,7 +1088,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { ecx: &MiriInterpCx<'mir, 'tcx>, id: AllocId, alloc: Cow<'b, Allocation>, - kind: Option>, + kind: Option, ) -> InterpResult<'tcx, Cow<'b, Allocation>> { let kind = kind.expect("we set our STATIC_KIND so this cannot be None"); if ecx.machine.tracked_alloc_ids.contains(&id) { @@ -1280,6 +1280,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { (alloc_id, prove_extra): (AllocId, Self::ProvenanceExtra), size: Size, align: Align, + _kind: MemoryKind, ) -> InterpResult<'tcx> { if machine.tracked_alloc_ids.contains(&alloc_id) { machine.emit_diagnostic(NonHaltingDiagnostic::FreedAlloc(alloc_id)); diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs index 62ce2ee58ae6..a27c9b746da2 100644 --- a/src/tools/miri/src/shims/os_str.rs +++ b/src/tools/miri/src/shims/os_str.rs @@ -136,7 +136,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn alloc_os_str_as_c_str( &mut self, os_str: &OsStr, - memkind: MemoryKind, + memkind: MemoryKind, ) -> InterpResult<'tcx, Pointer>> { let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0` terminator. let this = self.eval_context_mut(); @@ -152,7 +152,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn alloc_os_str_as_wide_str( &mut self, os_str: &OsStr, - memkind: MemoryKind, + memkind: MemoryKind, ) -> InterpResult<'tcx, Pointer>> { let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0x0000` terminator. let this = self.eval_context_mut(); @@ -229,7 +229,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn alloc_path_as_c_str( &mut self, path: &Path, - memkind: MemoryKind, + memkind: MemoryKind, ) -> InterpResult<'tcx, Pointer>> { let this = self.eval_context_mut(); let os_str = @@ -242,7 +242,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn alloc_path_as_wide_str( &mut self, path: &Path, - memkind: MemoryKind, + memkind: MemoryKind, ) -> InterpResult<'tcx, Pointer>> { let this = self.eval_context_mut(); let os_str = From 10b6ca139eed124e20fb49dae5ec463a8b611ac2 Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 16 Apr 2024 16:50:21 +0200 Subject: [PATCH 096/114] std: fix lint on SGX --- library/std/src/sys/pal/sgx/waitqueue/mod.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/pal/sgx/waitqueue/mod.rs b/library/std/src/sys/pal/sgx/waitqueue/mod.rs index ea49bb280346..f5668a9493fb 100644 --- a/library/std/src/sys/pal/sgx/waitqueue/mod.rs +++ b/library/std/src/sys/pal/sgx/waitqueue/mod.rs @@ -64,7 +64,7 @@ impl WaitVariable { #[derive(Copy, Clone)] pub enum NotifiedTcs { Single(Tcs), - All { count: NonZero }, + All { _count: NonZero }, } /// An RAII guard that will notify a set of target threads as well as unlock @@ -232,7 +232,10 @@ impl WaitQueue { } if let Some(count) = NonZero::new(count) { - Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::All { count } }) + Ok(WaitGuard { + mutex_guard: Some(guard), + notified_tcs: NotifiedTcs::All { _count: count }, + }) } else { Err(guard) } From a03aeca99a1679e27d7439e6030fe759eb1f6f04 Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Tue, 16 Apr 2024 10:25:17 -0400 Subject: [PATCH 097/114] Allow workproducts without object files. This pull request partially reverts changes from e16c3b4a4421 Original motivation for this assert was described with "A WorkProduct without a saved file is useless" which was true at the time but now it is possible to have work products with other types of files (llvm-ir, asm, etc) and there are bugreports for this failure: For example: https://github.com/rust-lang/rust/issues/123695 Fixes https://github.com/rust-lang/rust/issues/123234 Now existing `assert` and `.unwrap_or_else` are unified into a single check that emits slightly more user friendly error message if an object files was meant to be produced but it's missing --- compiler/rustc_codegen_ssa/src/back/write.rs | 13 ++++------- .../artifact-incr-cache-no-obj/lib.rs | 6 +++++ .../artifact-incr-cache-no-obj/rmake.rs | 23 +++++++++++++++++++ 3 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 tests/run-make/artifact-incr-cache-no-obj/lib.rs create mode 100644 tests/run-make/artifact-incr-cache-no-obj/rmake.rs diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index e7f692144ff0..c4f062405bb5 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -907,8 +907,6 @@ fn execute_copy_from_cache_work_item( module: CachedModuleCodegen, module_config: &ModuleConfig, ) -> WorkItemResult { - assert!(module_config.emit_obj != EmitObj::None); - let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap(); let load_from_incr_comp_dir = |output_path: PathBuf, saved_path: &str| { @@ -928,12 +926,6 @@ fn execute_copy_from_cache_work_item( } }; - let object = load_from_incr_comp_dir( - cgcx.output_filenames.temp_path(OutputType::Object, Some(&module.name)), - module.source.saved_files.get("o").unwrap_or_else(|| { - cgcx.create_dcx().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name }) - }), - ); let dwarf_object = module.source.saved_files.get("dwo").as_ref().and_then(|saved_dwarf_object_file| { let dwarf_obj_out = cgcx @@ -955,9 +947,14 @@ fn execute_copy_from_cache_work_item( } }; + let should_emit_obj = module_config.emit_obj != EmitObj::None; let assembly = load_from_incr_cache(module_config.emit_asm, OutputType::Assembly); let llvm_ir = load_from_incr_cache(module_config.emit_ir, OutputType::LlvmAssembly); let bytecode = load_from_incr_cache(module_config.emit_bc, OutputType::Bitcode); + let object = load_from_incr_cache(should_emit_obj, OutputType::Object); + if should_emit_obj && object.is_none() { + cgcx.create_dcx().emit_fatal(errors::NoSavedObjectFile { cgu_name: &module.name }) + } WorkItemResult::Finished(CompiledModule { name: module.name, diff --git a/tests/run-make/artifact-incr-cache-no-obj/lib.rs b/tests/run-make/artifact-incr-cache-no-obj/lib.rs new file mode 100644 index 000000000000..fa4048594e36 --- /dev/null +++ b/tests/run-make/artifact-incr-cache-no-obj/lib.rs @@ -0,0 +1,6 @@ +#![crate_name = "foo"] + +#[inline(never)] +pub fn add(a: u32, b: u32) -> u32 { + a + b +} diff --git a/tests/run-make/artifact-incr-cache-no-obj/rmake.rs b/tests/run-make/artifact-incr-cache-no-obj/rmake.rs new file mode 100644 index 000000000000..de55de2a1ee2 --- /dev/null +++ b/tests/run-make/artifact-incr-cache-no-obj/rmake.rs @@ -0,0 +1,23 @@ +// emitting an object file is not necessary if user didn't ask for one +// +// This test is similar to run-make/artifact-incr-cache but it doesn't +// require to emit an object file +// +// Fixes: rust-lang/rust#123234 + +extern crate run_make_support; + +use run_make_support::{rustc, tmp_dir}; + +fn main() { + let inc_dir = tmp_dir(); + + for _ in 0..=1 { + rustc() + .input("lib.rs") + .crate_type("lib") + .emit("asm,dep-info,link,mir,llvm-ir,llvm-bc") + .incremental(&inc_dir) + .run(); + } +} From 5b8b9cfaaac046d105a1d716b182a84dbd582678 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 16 Apr 2024 17:33:12 +0200 Subject: [PATCH 098/114] interpret: remove outdated comment --- compiler/rustc_const_eval/src/interpret/machine.rs | 2 -- compiler/rustc_const_eval/src/interpret/memory.rs | 1 - 2 files changed, 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs index 827d8fd9417c..9c110202fe0a 100644 --- a/compiler/rustc_const_eval/src/interpret/machine.rs +++ b/compiler/rustc_const_eval/src/interpret/machine.rs @@ -347,8 +347,6 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized { /// allocation (because a copy had to be done to adjust things), machine memory will /// cache the result. (This relies on `AllocMap::get_or` being able to add the /// owned allocation to the map even when the map is shared.) - /// - /// This must only fail if `alloc` contains provenance. fn adjust_allocation<'b>( ecx: &InterpCx<'mir, 'tcx, Self>, id: AllocId, diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index 9b1d9cf932bd..bd228122dbae 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -227,7 +227,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.allocate_raw_ptr(alloc, kind) } - /// This can fail only if `alloc` contains provenance. pub fn allocate_raw_ptr( &mut self, alloc: Allocation, From 9cc4e2361ecffd6848f69f28e926e7ed952fca6d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 16 Apr 2024 15:54:29 +0000 Subject: [PATCH 099/114] Prefer identity equality over equating types during coercion. These types are always generic only over their own generic parameters with no inference variables involved. --- .../src/coherence/builtin.rs | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 5e4048476561..0b6c60e4ba29 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -10,8 +10,8 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::ItemKind; use rustc_infer::infer::outlives::env::OutlivesEnvironment; +use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::{self, RegionResolutionError}; -use rustc_infer::infer::{DefineOpaqueTypes, TyCtxtInferExt}; use rustc_infer::traits::Obligation; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt}; @@ -189,10 +189,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() // even if they do not carry that attribute. use rustc_type_ir::TyKind::*; match (source.kind(), target.kind()) { - (&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) - if infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, r_a, *r_b).is_ok() - && mutbl_a == *mutbl_b => - { + (&Ref(r_a, _, mutbl_a), Ref(r_b, _, mutbl_b)) if r_a == *r_b && mutbl_a == *mutbl_b => { Ok(()) } (&RawPtr(_, a_mutbl), &RawPtr(_, b_mutbl)) if a_mutbl == b_mutbl => Ok(()), @@ -230,18 +227,14 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() } } - if let Ok(ok) = - infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b) - { - if ok.obligations.is_empty() { - res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST { - span, - name: field.name, - ty: ty_a, - })); + if ty_a == ty_b { + res = Err(tcx.dcx().emit_err(errors::DispatchFromDynZST { + span, + name: field.name, + ty: ty_a, + })); - return false; - } + return false; } return true; @@ -433,14 +426,12 @@ pub fn coerce_unsized_info<'tcx>( // something more accepting, but we use // equality because we want to be able to // perform this check without computing - // variance where possible. (This is because - // we may have to evaluate constraint + // variance or constraining opaque types' hidden types. + // (This is because we may have to evaluate constraint // expressions in the course of execution.) // See e.g., #41936. - if let Ok(ok) = infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, a, b) { - if ok.obligations.is_empty() { - return None; - } + if a == b { + return None; } // Collect up all fields that were significantly changed From 81b7944163b48ce051248bc84f30b6ea65d7c1c0 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 22 Mar 2024 18:05:56 +0300 Subject: [PATCH 100/114] create new build step `clippy` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/check.rs | 111 +------ src/bootstrap/src/core/build_steps/clippy.rs | 307 +++++++++++++++++++ src/bootstrap/src/core/build_steps/mod.rs | 1 + src/bootstrap/src/core/builder.rs | 14 +- src/bootstrap/src/core/config/tests.rs | 2 +- 5 files changed, 335 insertions(+), 100 deletions(-) create mode 100644 src/bootstrap/src/core/build_steps/clippy.rs diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 37d91b14ca1b..654ef1ec6a7f 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -11,6 +11,14 @@ use crate::core::config::TargetSelection; use crate::{Compiler, Mode, Subcommand}; use std::path::{Path, PathBuf}; +pub fn cargo_subcommand(kind: Kind) -> &'static str { + match kind { + Kind::Check | Kind::Clippy => "check", + Kind::Fix => "fix", + _ => unreachable!(), + } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Std { pub target: TargetSelection, @@ -22,97 +30,6 @@ pub struct Std { crates: Vec, } -/// Returns args for the subcommand itself (not for cargo) -fn args(builder: &Builder<'_>) -> Vec { - fn strings<'a>(arr: &'a [&str]) -> impl Iterator + 'a { - arr.iter().copied().map(String::from) - } - - if let Subcommand::Clippy { fix, allow_dirty, allow_staged, allow, deny, warn, forbid } = - &builder.config.cmd - { - // disable the most spammy clippy lints - let ignored_lints = [ - "many_single_char_names", // there are a lot in stdarch - "collapsible_if", - "type_complexity", - "missing_safety_doc", // almost 3K warnings - "too_many_arguments", - "needless_lifetimes", // people want to keep the lifetimes - "wrong_self_convention", - ]; - let mut args = vec![]; - if *fix { - #[rustfmt::skip] - args.extend(strings(&[ - "--fix", "-Zunstable-options", - // FIXME: currently, `--fix` gives an error while checking tests for libtest, - // possibly because libtest is not yet built in the sysroot. - // As a workaround, avoid checking tests and benches when passed --fix. - "--lib", "--bins", "--examples", - ])); - - if *allow_dirty { - args.push("--allow-dirty".to_owned()); - } - - if *allow_staged { - args.push("--allow-staged".to_owned()); - } - } - - args.extend(strings(&["--"])); - - if deny.is_empty() && forbid.is_empty() { - args.extend(strings(&["--cap-lints", "warn"])); - } - - let all_args = std::env::args().collect::>(); - args.extend(get_clippy_rules_in_order(&all_args, allow, deny, warn, forbid)); - - args.extend(ignored_lints.iter().map(|lint| format!("-Aclippy::{}", lint))); - args.extend(builder.config.free_args.clone()); - args - } else { - builder.config.free_args.clone() - } -} - -/// We need to keep the order of the given clippy lint rules before passing them. -/// Since clap doesn't offer any useful interface for this purpose out of the box, -/// we have to handle it manually. -pub(crate) fn get_clippy_rules_in_order( - all_args: &[String], - allow_rules: &[String], - deny_rules: &[String], - warn_rules: &[String], - forbid_rules: &[String], -) -> Vec { - let mut result = vec![]; - - for (prefix, item) in - [("-A", allow_rules), ("-D", deny_rules), ("-W", warn_rules), ("-F", forbid_rules)] - { - item.iter().for_each(|v| { - let rule = format!("{prefix}{v}"); - let position = all_args.iter().position(|t| t == &rule).unwrap(); - result.push((position, rule)); - }); - } - - result.sort_by_key(|&(position, _)| position); - result.into_iter().map(|v| v.1).collect() -} - -fn cargo_subcommand(kind: Kind) -> &'static str { - match kind { - Kind::Check => "check", - Kind::Clippy => "clippy", - Kind::Fix => "fix", - _ => unreachable!(), - } -} - impl Std { pub fn new(target: TargetSelection) -> Self { Self { target, crates: vec![] } @@ -164,7 +81,7 @@ impl Step for Std { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &libstd_stamp(builder, compiler, target), vec![], true, @@ -221,7 +138,7 @@ impl Step for Std { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &libstd_test_stamp(builder, compiler, target), vec![], true, @@ -318,7 +235,7 @@ impl Step for Rustc { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &librustc_stamp(builder, compiler, target), vec![], true, @@ -384,7 +301,7 @@ impl Step for CodegenBackend { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &codegen_backend_stamp(builder, compiler, target, backend), vec![], true, @@ -450,7 +367,7 @@ impl Step for RustAnalyzer { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &stamp(builder, compiler, target), vec![], true, @@ -513,7 +430,7 @@ macro_rules! tool_check_step { run_cargo( builder, cargo, - args(builder), + builder.config.free_args.clone(), &stamp(builder, compiler, target), vec![], true, diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs new file mode 100644 index 000000000000..e2c2d3c9ef83 --- /dev/null +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -0,0 +1,307 @@ +use std::path::Path; + +use crate::builder::Builder; +use crate::builder::ShouldRun; +use crate::core::builder; +use crate::core::builder::crate_description; +use crate::core::builder::Alias; +use crate::core::builder::RunConfig; +use crate::core::builder::Step; +use crate::Mode; +use crate::Subcommand; +use crate::TargetSelection; + +use super::check; +use super::compile; +use super::compile::librustc_stamp; +use super::compile::libstd_stamp; +use super::compile::run_cargo; +use super::compile::rustc_cargo; +use super::compile::std_cargo; +use super::tool::prepare_tool_cargo; +use super::tool::SourceType; + +// Disable the most spammy clippy lints +const IGNORED_RULES_FOR_STD_AND_RUSTC: &[&str] = &[ + "many_single_char_names", // there are a lot in stdarch + "collapsible_if", + "type_complexity", + "missing_safety_doc", // almost 3K warnings + "too_many_arguments", + "needless_lifetimes", // people want to keep the lifetimes + "wrong_self_convention", +]; + +fn lint_args(builder: &Builder<'_>, ignored_rules: &[&str]) -> Vec { + fn strings<'a>(arr: &'a [&str]) -> impl Iterator + 'a { + arr.iter().copied().map(String::from) + } + + let Subcommand::Clippy { fix, allow_dirty, allow_staged, allow, deny, warn, forbid } = + &builder.config.cmd + else { + unreachable!("clippy::lint_args can only be called from `clippy` subcommands."); + }; + + let mut args = vec![]; + if *fix { + #[rustfmt::skip] + args.extend(strings(&[ + "--fix", "-Zunstable-options", + // FIXME: currently, `--fix` gives an error while checking tests for libtest, + // possibly because libtest is not yet built in the sysroot. + // As a workaround, avoid checking tests and benches when passed --fix. + "--lib", "--bins", "--examples", + ])); + + if *allow_dirty { + args.push("--allow-dirty".to_owned()); + } + + if *allow_staged { + args.push("--allow-staged".to_owned()); + } + } + + args.extend(strings(&["--"])); + + if deny.is_empty() && forbid.is_empty() { + args.extend(strings(&["--cap-lints", "warn"])); + } + + let all_args = std::env::args().collect::>(); + args.extend(get_clippy_rules_in_order(&all_args, allow, deny, warn, forbid)); + + args.extend(ignored_rules.iter().map(|lint| format!("-Aclippy::{}", lint))); + args.extend(builder.config.free_args.clone()); + args +} + +/// We need to keep the order of the given clippy lint rules before passing them. +/// Since clap doesn't offer any useful interface for this purpose out of the box, +/// we have to handle it manually. +pub(crate) fn get_clippy_rules_in_order( + all_args: &[String], + allow_rules: &[String], + deny_rules: &[String], + warn_rules: &[String], + forbid_rules: &[String], +) -> Vec { + let mut result = vec![]; + + for (prefix, item) in + [("-A", allow_rules), ("-D", deny_rules), ("-W", warn_rules), ("-F", forbid_rules)] + { + item.iter().for_each(|v| { + let rule = format!("{prefix}{v}"); + let position = all_args.iter().position(|t| t == &rule).unwrap(); + result.push((position, rule)); + }); + } + + result.sort_by_key(|&(position, _)| position); + result.into_iter().map(|v| v.1).collect() +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Std { + pub target: TargetSelection, + /// Whether to lint only a subset of crates. + crates: Vec, +} + +impl Step for Std { + type Output = (); + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.crate_or_deps("sysroot").path("library") + } + + fn make_run(run: RunConfig<'_>) { + let crates = run.make_run_crates(Alias::Library); + run.builder.ensure(Std { target: run.target, crates }); + } + + fn run(self, builder: &Builder<'_>) { + builder.update_submodule(&Path::new("library").join("stdarch")); + + let target = self.target; + let compiler = builder.compiler(builder.top_stage, builder.config.build); + + let mut cargo = + builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, "clippy"); + + std_cargo(builder, target, compiler.stage, &mut cargo); + + if matches!(builder.config.cmd, Subcommand::Fix { .. }) { + // By default, cargo tries to fix all targets. Tell it not to fix tests until we've added `test` to the sysroot. + cargo.arg("--lib"); + } + + for krate in &*self.crates { + cargo.arg("-p").arg(krate); + } + + let _guard = builder.msg_check( + format_args!("library artifacts{}", crate_description(&self.crates)), + target, + ); + + run_cargo( + builder, + cargo, + lint_args(builder, IGNORED_RULES_FOR_STD_AND_RUSTC), + &libstd_stamp(builder, compiler, target), + vec![], + true, + false, + ); + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct Rustc { + pub target: TargetSelection, + /// Whether to lint only a subset of crates. + crates: Vec, +} + +impl Step for Rustc { + type Output = (); + const ONLY_HOSTS: bool = true; + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.crate_or_deps("rustc-main").path("compiler") + } + + fn make_run(run: RunConfig<'_>) { + let crates = run.make_run_crates(Alias::Compiler); + run.builder.ensure(Rustc { target: run.target, crates }); + } + + /// Lints the compiler. + /// + /// This will lint the compiler for a particular stage of the build using + /// the `compiler` targeting the `target` architecture. + fn run(self, builder: &Builder<'_>) { + let compiler = builder.compiler(builder.top_stage, builder.config.build); + let target = self.target; + + if compiler.stage != 0 { + // If we're not in stage 0, then we won't have a std from the beta + // compiler around. That means we need to make sure there's one in + // the sysroot for the compiler to find. Otherwise, we're going to + // fail when building crates that need to generate code (e.g., build + // scripts and their dependencies). + builder.ensure(compile::Std::new(compiler, compiler.host)); + builder.ensure(compile::Std::new(compiler, target)); + } else { + builder.ensure(check::Std::new(target)); + } + + let mut cargo = builder::Cargo::new( + builder, + compiler, + Mode::Rustc, + SourceType::InTree, + target, + "clippy", + ); + + rustc_cargo(builder, &mut cargo, target, compiler.stage); + + // Explicitly pass -p for all compiler crates -- this will force cargo + // to also check the tests/benches/examples for these crates, rather + // than just the leaf crate. + for krate in &*self.crates { + cargo.arg("-p").arg(krate); + } + + let _guard = builder.msg_check( + format_args!("compiler artifacts{}", crate_description(&self.crates)), + target, + ); + + run_cargo( + builder, + cargo, + lint_args(builder, IGNORED_RULES_FOR_STD_AND_RUSTC), + &librustc_stamp(builder, compiler, target), + vec![], + true, + false, + ); + } +} + +macro_rules! lint_any { + ($( + $name:ident, $path:expr, $tool_name:expr + $(,is_external_tool = $external:expr)* + $(,is_unstable_tool = $unstable:expr)* + $(,allow_features = $allow_features:expr)? + ; + )+) => { + $( + + #[derive(Debug, Clone, Hash, PartialEq, Eq)] + pub struct $name { + pub target: TargetSelection, + } + + impl Step for $name { + type Output = (); + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path($path) + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure($name { + target: run.target, + }); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let compiler = builder.compiler(builder.top_stage, builder.config.build); + let target = self.target; + + builder.ensure(check::Rustc::new(target, builder)); + + let cargo = prepare_tool_cargo( + builder, + compiler, + Mode::ToolRustc, + target, + "clippy", + $path, + SourceType::InTree, + &[], + ); + + run_cargo( + builder, + cargo, + lint_args(builder, &[]), + &libstd_stamp(builder, compiler, target), + vec![], + true, + false, + ); + } + } + )+ + } +} + +lint_any!( + Bootstrap, "src/bootstrap", "bootstrap"; + BuildHelper, "src/tools/build_helper", "build_helper"; + CoverageDump, "src/tools/coverage-dump", "coverage-dump"; + Tidy, "src/tools/tidy", "tidy"; + Compiletest, "src/tools/compiletest", "compiletest"; + RemoteTestServer, "src/tools/remote-test-server", "remote-test-server"; + RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; +); diff --git a/src/bootstrap/src/core/build_steps/mod.rs b/src/bootstrap/src/core/build_steps/mod.rs index 50d83789be82..9b7378165de4 100644 --- a/src/bootstrap/src/core/build_steps/mod.rs +++ b/src/bootstrap/src/core/build_steps/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod check; pub(crate) mod clean; +pub(crate) mod clippy; pub(crate) mod compile; pub(crate) mod dist; pub(crate) mod doc; diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index f31bc46d25fc..6ee37acc9054 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -13,7 +13,7 @@ use std::process::Command; use std::sync::OnceLock; use std::time::{Duration, Instant}; -use crate::core::build_steps::llvm; +use crate::core::build_steps::{clippy, llvm}; use crate::core::build_steps::tool::{self, SourceType}; use crate::core::build_steps::{check, clean, compile, dist, doc, install, run, setup, test}; use crate::core::config::flags::{Color, Subcommand}; @@ -726,7 +726,17 @@ impl<'a> Builder<'a> { tool::CoverageDump, tool::LlvmBitcodeLinker ), - Kind::Check | Kind::Clippy | Kind::Fix => describe!( + Kind::Clippy => describe!( + clippy::Std, + clippy::Rustc, + clippy::Bootstrap, + clippy::BuildHelper, + clippy::CoverageDump, + clippy::Tidy, + clippy::RemoteTestServer, + clippy::RemoteTestClient, + ), + Kind::Check | Kind::Fix => describe!( check::Std, check::Rustc, check::Rustdoc, diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs index 8cd538953c56..59e16b654272 100644 --- a/src/bootstrap/src/core/config/tests.rs +++ b/src/bootstrap/src/core/config/tests.rs @@ -1,5 +1,5 @@ use super::{flags::Flags, ChangeIdWrapper, Config}; -use crate::core::build_steps::check::get_clippy_rules_in_order; +use crate::core::build_steps::clippy::get_clippy_rules_in_order; use crate::core::config::{LldMode, TomlConfig}; use clap::CommandFactory; From 8a865a0fa9b1aacbcf84ad64ddb9f125f6007544 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 22 Mar 2024 18:15:18 +0300 Subject: [PATCH 101/114] create `Builder::msg_clippy` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/clippy.rs | 11 +++-------- src/bootstrap/src/core/builder.rs | 3 ++- src/bootstrap/src/lib.rs | 10 ++++++++++ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index e2c2d3c9ef83..190ea1752d84 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -134,16 +134,11 @@ impl Step for Std { std_cargo(builder, target, compiler.stage, &mut cargo); - if matches!(builder.config.cmd, Subcommand::Fix { .. }) { - // By default, cargo tries to fix all targets. Tell it not to fix tests until we've added `test` to the sysroot. - cargo.arg("--lib"); - } - for krate in &*self.crates { cargo.arg("-p").arg(krate); } - let _guard = builder.msg_check( + let _guard = builder.msg_clippy( format_args!("library artifacts{}", crate_description(&self.crates)), target, ); @@ -213,13 +208,13 @@ impl Step for Rustc { rustc_cargo(builder, &mut cargo, target, compiler.stage); // Explicitly pass -p for all compiler crates -- this will force cargo - // to also check the tests/benches/examples for these crates, rather + // to also lint the tests/benches/examples for these crates, rather // than just the leaf crate. for krate in &*self.crates { cargo.arg("-p").arg(krate); } - let _guard = builder.msg_check( + let _guard = builder.msg_clippy( format_args!("compiler artifacts{}", crate_description(&self.crates)), target, ); diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 6ee37acc9054..9d2352135c2f 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -13,9 +13,9 @@ use std::process::Command; use std::sync::OnceLock; use std::time::{Duration, Instant}; -use crate::core::build_steps::{clippy, llvm}; use crate::core::build_steps::tool::{self, SourceType}; use crate::core::build_steps::{check, clean, compile, dist, doc, install, run, setup, test}; +use crate::core::build_steps::{clippy, llvm}; use crate::core::config::flags::{Color, Subcommand}; use crate::core::config::{DryRun, SplitDebuginfo, TargetSelection}; use crate::prepare_behaviour_dump_dir; @@ -672,6 +672,7 @@ impl Kind { Kind::Doc => "Documenting", Kind::Run => "Running", Kind::Suggest => "Suggesting", + Kind::Clippy => "Linting", _ => { let title_letter = self.as_str()[0..1].to_ascii_uppercase(); return format!("{title_letter}{}ing", &self.as_str()[1..]); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 1a8322c0dfd8..e1ae9fe2bf71 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1078,6 +1078,16 @@ impl Build { } } + #[must_use = "Groups should not be dropped until the Step finishes running"] + #[track_caller] + fn msg_clippy( + &self, + what: impl Display, + target: impl Into>, + ) -> Option { + self.msg(Kind::Clippy, self.config.stage, what, self.config.build, target) + } + #[must_use = "Groups should not be dropped until the Step finishes running"] #[track_caller] fn msg_check( From 77ba3f289109ae9823d86a9ad8dbf160b42ad76e Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 22 Mar 2024 18:23:01 +0300 Subject: [PATCH 102/114] support different `Kind`s in `Builder::msg_tool` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/clippy.rs | 12 +++++++++++- src/bootstrap/src/core/build_steps/tool.rs | 7 +++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index 190ea1752d84..21ac6c505c30 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -5,6 +5,7 @@ use crate::builder::ShouldRun; use crate::core::builder; use crate::core::builder::crate_description; use crate::core::builder::Alias; +use crate::core::builder::Kind; use crate::core::builder::RunConfig; use crate::core::builder::Step; use crate::Mode; @@ -233,7 +234,7 @@ impl Step for Rustc { macro_rules! lint_any { ($( - $name:ident, $path:expr, $tool_name:expr + $name:ident, $path:expr, $readable_name:expr $(,is_external_tool = $external:expr)* $(,is_unstable_tool = $unstable:expr)* $(,allow_features = $allow_features:expr)? @@ -276,6 +277,15 @@ macro_rules! lint_any { &[], ); + let _guard = builder.msg_tool( + Kind::Clippy, + Mode::ToolRustc, + $readable_name, + compiler.stage, + &compiler.host, + &target, + ); + run_cargo( builder, cargo, diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 8d1ff2fcb245..45b1d5a05f35 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -36,8 +36,9 @@ struct ToolBuild { impl Builder<'_> { #[track_caller] - fn msg_tool( + pub(crate) fn msg_tool( &self, + kind: Kind, mode: Mode, tool: &str, build_stage: u32, @@ -47,7 +48,7 @@ impl Builder<'_> { match mode { // depends on compiler stage, different to host compiler Mode::ToolRustc => self.msg_sysroot_tool( - Kind::Build, + kind, build_stage, format_args!("tool {tool}"), *host, @@ -100,6 +101,7 @@ impl Step for ToolBuild { cargo.allow_features(self.allow_features); } let _guard = builder.msg_tool( + Kind::Build, self.mode, self.tool, self.compiler.stage, @@ -481,6 +483,7 @@ impl Step for Rustdoc { ); let _guard = builder.msg_tool( + Kind::Build, Mode::ToolRustc, "rustdoc", build_compiler.stage, From 489e5d0ad0894cdfdf0e639d723a2cff88f7610a Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 22 Mar 2024 18:43:06 +0300 Subject: [PATCH 103/114] for clippy, skip output handling in `run_cargo` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/compile.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 9420e40d6c2b..b2ee2c8f1f79 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2012,7 +2012,7 @@ pub fn run_cargo( crate::exit!(1); } - if builder.config.dry_run() { + if builder.config.dry_run() || builder.kind == Kind::Clippy { return Vec::new(); } From bbacfe0cb64c4541097ed21f3cb0d3511bf0028f Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 22 Mar 2024 18:52:37 +0300 Subject: [PATCH 104/114] add simple top-level doc-comment for build_steps/clippy Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/clippy.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index 21ac6c505c30..7374c2b1cf29 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -1,3 +1,5 @@ +//! Implementation of running clippy on the compiler, standard library and various tools. + use std::path::Path; use crate::builder::Builder; From a01897345cead40cd3c349529a67e796a4395a09 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 22 Mar 2024 19:00:48 +0300 Subject: [PATCH 105/114] fix sysroot bug and update step message format Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/clippy.rs | 25 +++++--------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index 7374c2b1cf29..15d676bea205 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -141,10 +141,8 @@ impl Step for Std { cargo.arg("-p").arg(krate); } - let _guard = builder.msg_clippy( - format_args!("library artifacts{}", crate_description(&self.crates)), - target, - ); + let _guard = + builder.msg_clippy(format_args!("library{}", crate_description(&self.crates)), target); run_cargo( builder, @@ -187,17 +185,8 @@ impl Step for Rustc { let compiler = builder.compiler(builder.top_stage, builder.config.build); let target = self.target; - if compiler.stage != 0 { - // If we're not in stage 0, then we won't have a std from the beta - // compiler around. That means we need to make sure there's one in - // the sysroot for the compiler to find. Otherwise, we're going to - // fail when building crates that need to generate code (e.g., build - // scripts and their dependencies). - builder.ensure(compile::Std::new(compiler, compiler.host)); - builder.ensure(compile::Std::new(compiler, target)); - } else { - builder.ensure(check::Std::new(target)); - } + builder.ensure(compile::Std::new(compiler, compiler.host)); + builder.ensure(compile::Std::new(compiler, target)); let mut cargo = builder::Cargo::new( builder, @@ -217,10 +206,8 @@ impl Step for Rustc { cargo.arg("-p").arg(krate); } - let _guard = builder.msg_clippy( - format_args!("compiler artifacts{}", crate_description(&self.crates)), - target, - ); + let _guard = + builder.msg_clippy(format_args!("compiler{}", crate_description(&self.crates)), target); run_cargo( builder, From 5253fe4520dc14934f9cd99859da42a18686550f Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 22 Mar 2024 19:02:02 +0300 Subject: [PATCH 106/114] update `mingw-check` clippy invocation Previously this command was linting compiler and library together. As we no longer run clippy on the entire tree unless it's explicitly requested, we need to update this command by adding `library` path. Signed-off-by: onur-ozkan --- src/ci/docker/host-x86_64/mingw-check/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index 6918574814ff..ae8dfadec738 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -46,7 +46,7 @@ ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ # We also skip the x86_64-unknown-linux-gnu target as it is well-tested by other jobs. python3 ../x.py check --stage 0 --set build.optimized-compiler-builtins=false core alloc std --target=aarch64-unknown-linux-gnu,i686-pc-windows-msvc,i686-unknown-linux-gnu,x86_64-apple-darwin,x86_64-pc-windows-gnu,x86_64-pc-windows-msvc && \ python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ - python3 ../x.py clippy compiler -Aclippy::all -Dclippy::correctness && \ + python3 ../x.py clippy compiler library -Aclippy::all -Dclippy::correctness && \ python3 ../x.py build --stage 0 src/tools/build-manifest && \ python3 ../x.py test --stage 0 src/tools/compiletest && \ python3 ../x.py test --stage 0 core alloc std test proc_macro && \ From 16cf0e660737e23a32e48c2459c219ff433a9518 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 22 Mar 2024 20:19:24 +0300 Subject: [PATCH 107/114] allow running clippy on most of the in-tree tools Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/check.rs | 4 +- src/bootstrap/src/core/build_steps/clippy.rs | 49 +++++++++++++++---- src/bootstrap/src/core/build_steps/compile.rs | 2 +- src/bootstrap/src/core/builder.rs | 22 ++++++++- 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 654ef1ec6a7f..927d72e8ccb4 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -13,7 +13,9 @@ use std::path::{Path, PathBuf}; pub fn cargo_subcommand(kind: Kind) -> &'static str { match kind { - Kind::Check | Kind::Clippy => "check", + Kind::Check + // We ensure check steps for both std and rustc from build_steps/clippy, so handle `Kind::Clippy` as well. + | Kind::Clippy => "check", Kind::Fix => "fix", _ => unreachable!(), } diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index 15d676bea205..33323ec1e5de 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -185,8 +185,17 @@ impl Step for Rustc { let compiler = builder.compiler(builder.top_stage, builder.config.build); let target = self.target; - builder.ensure(compile::Std::new(compiler, compiler.host)); - builder.ensure(compile::Std::new(compiler, target)); + if compiler.stage != 0 { + // If we're not in stage 0, then we won't have a std from the beta + // compiler around. That means we need to make sure there's one in + // the sysroot for the compiler to find. Otherwise, we're going to + // fail when building crates that need to generate code (e.g., build + // scripts and their dependencies). + builder.ensure(compile::Std::new(compiler, compiler.host)); + builder.ensure(compile::Std::new(compiler, target)); + } else { + builder.ensure(check::Std::new(target)); + } let mut cargo = builder::Cargo::new( builder, @@ -197,7 +206,7 @@ impl Step for Rustc { "clippy", ); - rustc_cargo(builder, &mut cargo, target, compiler.stage); + rustc_cargo(builder, &mut cargo, target, &compiler); // Explicitly pass -p for all compiler crates -- this will force cargo // to also lint the tests/benches/examples for these crates, rather @@ -224,9 +233,7 @@ impl Step for Rustc { macro_rules! lint_any { ($( $name:ident, $path:expr, $readable_name:expr - $(,is_external_tool = $external:expr)* - $(,is_unstable_tool = $unstable:expr)* - $(,allow_features = $allow_features:expr)? + $(,lint_by_default = $lint_by_default:expr)* ; )+) => { $( @@ -238,6 +245,7 @@ macro_rules! lint_any { impl Step for $name { type Output = (); + const DEFAULT: bool = if false $(|| $lint_by_default)* { true } else { false }; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.path($path) @@ -275,11 +283,15 @@ macro_rules! lint_any { &target, ); + let stamp = builder + .cargo_out(compiler, Mode::ToolRustc, target) + .join(format!(".{}-check.stamp", stringify!($name).to_lowercase())); + run_cargo( builder, cargo, lint_args(builder, &[]), - &libstd_stamp(builder, compiler, target), + &stamp, vec![], true, false, @@ -293,9 +305,26 @@ macro_rules! lint_any { lint_any!( Bootstrap, "src/bootstrap", "bootstrap"; BuildHelper, "src/tools/build_helper", "build_helper"; - CoverageDump, "src/tools/coverage-dump", "coverage-dump"; - Tidy, "src/tools/tidy", "tidy"; + BuildManifest, "src/tools/build-manifest", "build-manifest"; + CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri"; + Clippy, "src/tools/clippy", "clippy"; + CollectLicenseMetadata, "src/tools/collect-license-metadata", "collect-license-metadata"; Compiletest, "src/tools/compiletest", "compiletest"; - RemoteTestServer, "src/tools/remote-test-server", "remote-test-server"; + CoverageDump, "src/tools/coverage-dump", "coverage-dump"; + Jsondocck, "src/tools/jsondocck", "jsondocck"; + Jsondoclint, "src/tools/jsondoclint", "jsondoclint"; + LintDocs, "src/tools/lint-docs", "lint-docs"; + LlvmBitcodeLinker, "src/tools/llvm-bitcode-linker", "llvm-bitcode-linker"; + Miri, "src/tools/miri", "miri"; + MiroptTestTools, "src/tools/miropt-test-tools", "miropt-test-tools"; + OptDist, "src/tools/opt-dist", "opt-dist"; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; + RemoteTestServer, "src/tools/remote-test-server", "remote-test-server"; + Rls, "src/tools/rls", "rls"; + RustAnalyzer, "src/tools/rust-analyzer", "rust-analyzer"; + RustDemangler, "src/tools/rust-demangler", "rust-demangler"; + Rustdoc, "src/tools/rustdoc", "clippy"; + Rustfmt, "src/tools/rustfmt", "rustfmt"; + RustInstaller, "src/tools/rust-installer", "rust-installer"; + Tidy, "src/tools/tidy", "tidy"; ); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index b2ee2c8f1f79..9420e40d6c2b 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2012,7 +2012,7 @@ pub fn run_cargo( crate::exit!(1); } - if builder.config.dry_run() || builder.kind == Kind::Clippy { + if builder.config.dry_run() { return Vec::new(); } diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs index 9d2352135c2f..499a74be6b15 100644 --- a/src/bootstrap/src/core/builder.rs +++ b/src/bootstrap/src/core/builder.rs @@ -732,10 +732,28 @@ impl<'a> Builder<'a> { clippy::Rustc, clippy::Bootstrap, clippy::BuildHelper, + clippy::BuildManifest, + clippy::CargoMiri, + clippy::Clippy, + clippy::CollectLicenseMetadata, + clippy::Compiletest, clippy::CoverageDump, - clippy::Tidy, - clippy::RemoteTestServer, + clippy::Jsondocck, + clippy::Jsondoclint, + clippy::LintDocs, + clippy::LlvmBitcodeLinker, + clippy::Miri, + clippy::MiroptTestTools, + clippy::OptDist, clippy::RemoteTestClient, + clippy::RemoteTestServer, + clippy::Rls, + clippy::RustAnalyzer, + clippy::RustDemangler, + clippy::Rustdoc, + clippy::Rustfmt, + clippy::RustInstaller, + clippy::Tidy, ), Kind::Check | Kind::Fix => describe!( check::Std, From f25668cff5930bc815f84b33861cf57fa5dd4200 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 16 Apr 2024 12:41:44 -0700 Subject: [PATCH 108/114] Remove `default_hidden_visibility: false` from wasm targets To the best of my ability I believe that this is no longer necessary. I don't fully recall why this was first added but I believe it had to do with symbols all being exported by default and this was required to undo that. Regardless nowadays the default output of rustc seems suitable so it seems best to keep wasm in line with other targets. --- compiler/rustc_target/src/spec/base/wasm.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/compiler/rustc_target/src/spec/base/wasm.rs b/compiler/rustc_target/src/spec/base/wasm.rs index 4b4d2aca26e4..f237391016e7 100644 --- a/compiler/rustc_target/src/spec/base/wasm.rs +++ b/compiler/rustc_target/src/spec/base/wasm.rs @@ -80,9 +80,6 @@ pub fn options() -> TargetOptions { // threaded model which will legalize atomics to normal operations. singlethread: true, - // no dynamic linking, no need for default visibility! - default_hidden_visibility: true, - // Symbol visibility takes care of this for the WebAssembly. // Additionally the only known linker, LLD, doesn't support the script // arguments just yet From cea6cb3a68337b62aafde638f42bb1629058526f Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Tue, 16 Apr 2024 16:53:29 -0400 Subject: [PATCH 109/114] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 48eca1b16469..6f06fe908a5e 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 48eca1b164695022295ce466b64b44e4e0228b08 +Subproject commit 6f06fe908a5ee0f415c187f868ea627e82efe07d From 9a67a6cb0433d1403c913a842a94bbb26a01c4d8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 17 Apr 2024 08:37:04 +1000 Subject: [PATCH 110/114] Reinstate nnethercote to the review rotation. --- triagebot.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/triagebot.toml b/triagebot.toml index 6f8ed2edbfb3..731642ca74cb 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -800,6 +800,7 @@ compiler-team = [ compiler-team-contributors = [ "@TaKO8Ki", "@Nadrieril", + "@nnethercote", "@fmease", "@fee1-dead", "@BoxyUwU", @@ -857,14 +858,17 @@ parser = [ "@compiler-errors", "@davidtwco", "@estebank", + "@nnethercote", "@petrochenkov", "@spastorino", ] lexer = [ + "@nnethercote", "@petrochenkov", "@estebank", ] arena = [ + "@nnethercote", "@spastorino", ] mir = [ From e480cabe3ae2b9363ebf92ab702c310f72c13a5a Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 16 Apr 2024 18:19:27 -0700 Subject: [PATCH 111/114] Fix empty-set symbol in comments --- compiler/rustc_ast/src/token.rs | 2 +- compiler/rustc_parse/src/parser/item.rs | 2 +- library/proc_macro/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index f07036dea0f8..5b41ac8a69ee 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -51,7 +51,7 @@ pub enum Delimiter { Brace, /// `[ ... ]` Bracket, - /// `Ø ... Ø` + /// `∅ ... ∅` /// An invisible delimiter, that may, for example, appear around tokens coming from a /// "macro variable" `$var`. It is important to preserve operator priorities in cases like /// `$var * 3` where `$var` is `1 + 2`. diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index b711ee9a8ee7..1b335573b16d 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1063,7 +1063,7 @@ impl<'a> Parser<'a> { /// Parses a `UseTreeKind::Nested(list)`. /// /// ```text - /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`] + /// USE_TREE_LIST = ∅ | (USE_TREE `,`)* USE_TREE [`,`] /// ``` fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> { self.parse_delim_comma_seq(Delimiter::Brace, |p| { diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index a3ebef45c884..c8db028b651f 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -811,7 +811,7 @@ pub enum Delimiter { /// `[ ... ]` #[stable(feature = "proc_macro_lib2", since = "1.29.0")] Bracket, - /// `Ø ... Ø` + /// `∅ ... ∅` /// An invisible delimiter, that may, for example, appear around tokens coming from a /// "macro variable" `$var`. It is important to preserve operator priorities in cases like /// `$var * 3` where `$var` is `1 + 2`. From c021367de1897288f81e7f8bba23c2d2325e57f4 Mon Sep 17 00:00:00 2001 From: beetrees Date: Wed, 17 Apr 2024 03:10:09 +0100 Subject: [PATCH 112/114] Make the comments for `ReturnDest` variants doc comments --- compiler/rustc_codegen_ssa/src/mir/block.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 24f2c50e882f..452398e6d828 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -1861,12 +1861,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } enum ReturnDest<'tcx, V> { - // Do nothing; the return value is indirect or ignored. + /// Do nothing; the return value is indirect or ignored. Nothing, - // Store the return value to the pointer. + /// Store the return value to the pointer. Store(PlaceRef<'tcx, V>), - // Store an indirect return value to an operand local place. + /// Store an indirect return value to an operand local place. IndirectOperand(PlaceRef<'tcx, V>, mir::Local), - // Store a direct return value to an operand local place. + /// Store a direct return value to an operand local place. DirectOperand(mir::Local), } From af28716f190813e6adb82018401aa99c075f6f22 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Wed, 17 Apr 2024 04:57:09 +0000 Subject: [PATCH 113/114] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index dfa7f8ca5074..bd87405da3d6 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -63f70b3d104e20289a1a0df82747066c3d85b9a1 +803e33a4460c82581bd01d4008d0f44aef1ddfe8 From 2cb03ef7394bbcbdefea6dfb13a4d7c0458992fe Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Wed, 17 Apr 2024 05:09:14 +0000 Subject: [PATCH 114/114] fmt --- .../pass/stacked-borrows/stacked-borrows.rs | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs index 43ba490d5bb4..c75824d7f9be 100644 --- a/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs +++ b/src/tools/miri/tests/pass/stacked-borrows/stacked-borrows.rs @@ -265,13 +265,15 @@ fn write_does_not_invalidate_all_aliases() { assert_eq!(*x, 1337); // oops, the value changed! I guess not all pointers were invalidated } -fn box_into_raw_allows_interior_mutable_alias() { unsafe { - let b = Box::new(std::cell::Cell::new(42)); - let raw = Box::into_raw(b); - let c = &*raw; - let d = raw.cast::(); // bypassing `Cell` -- only okay in Miri tests - // `c` and `d` should permit arbitrary aliasing with each other now. - *d = 1; - c.set(2); - drop(Box::from_raw(raw)); -} } +fn box_into_raw_allows_interior_mutable_alias() { + unsafe { + let b = Box::new(std::cell::Cell::new(42)); + let raw = Box::into_raw(b); + let c = &*raw; + let d = raw.cast::(); // bypassing `Cell` -- only okay in Miri tests + // `c` and `d` should permit arbitrary aliasing with each other now. + *d = 1; + c.set(2); + drop(Box::from_raw(raw)); + } +}