From 19352e9d9336b851aba2130ff6e448a481262861 Mon Sep 17 00:00:00 2001 From: LimpSquid Date: Thu, 19 Jun 2025 21:28:16 +0200 Subject: [PATCH 01/62] Add methods for converting bool to `Result<(), E>` --- library/core/src/bool.rs | 67 +++++++++++++++++++++++++++++++++ library/coretests/tests/bool.rs | 8 ++++ library/coretests/tests/lib.rs | 1 + 3 files changed, 76 insertions(+) diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index 2016ece007eb..99268d6182f6 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -61,4 +61,71 @@ impl bool { pub fn then T>(self, f: F) -> Option { if self { Some(f()) } else { None } } + + /// Returns `Ok(())` if the `bool` is [`true`](../std/keyword.true.html), + /// or `Err(err)` otherwise. + /// + /// Arguments passed to `ok_or` are eagerly evaluated; if you are + /// passing the result of a function call, it is recommended to use + /// [`ok_or_else`], which is lazily evaluated. + /// + /// [`ok_or_else`]: bool::ok_or_else + /// + /// # Examples + /// + /// ``` + /// #![feature(bool_to_result)] + /// + /// assert_eq!(false.ok_or(0), Err(0)); + /// assert_eq!(true.ok_or(0), Ok(())); + /// ``` + /// + /// ``` + /// #![feature(bool_to_result)] + /// + /// let mut a = 0; + /// let mut function_with_side_effects = || { a += 1; }; + /// + /// assert!(true.ok_or(function_with_side_effects()).is_ok()); + /// assert!(false.ok_or(function_with_side_effects()).is_err()); + /// + /// // `a` is incremented twice because the value passed to `ok_or` is + /// // evaluated eagerly. + /// assert_eq!(a, 2); + /// ``` + #[unstable(feature = "bool_to_result", issue = "142748")] + #[inline] + pub fn ok_or(self, err: E) -> Result<(), E> { + if self { Ok(()) } else { Err(err) } + } + + /// Returns `Ok(())` if the `bool` is [`true`](../std/keyword.true.html), + /// or `Err(f())` otherwise. + /// + /// # Examples + /// + /// ``` + /// #![feature(bool_to_result)] + /// + /// assert_eq!(false.ok_or_else(|| 0), Err(0)); + /// assert_eq!(true.ok_or_else(|| 0), Ok(())); + /// ``` + /// + /// ``` + /// #![feature(bool_to_result)] + /// + /// let mut a = 0; + /// + /// assert!(true.ok_or_else(|| { a += 1; }).is_ok()); + /// assert!(false.ok_or_else(|| { a += 1; }).is_err()); + /// + /// // `a` is incremented once because the closure is evaluated lazily by + /// // `ok_or_else`. + /// assert_eq!(a, 1); + /// ``` + #[unstable(feature = "bool_to_result", issue = "142748")] + #[inline] + pub fn ok_or_else E>(self, f: F) -> Result<(), E> { + if self { Ok(()) } else { Err(f()) } + } } diff --git a/library/coretests/tests/bool.rs b/library/coretests/tests/bool.rs index bcd6dc2abac6..eb5f0f50663e 100644 --- a/library/coretests/tests/bool.rs +++ b/library/coretests/tests/bool.rs @@ -105,3 +105,11 @@ fn test_bool_to_option() { assert_eq!(D, Some(0)); */ } + +#[test] +fn test_bool_to_result() { + assert_eq!(false.ok_or(0), Err(0)); + assert_eq!(true.ok_or(0), Ok(())); + assert_eq!(false.ok_or_else(|| 0), Err(0)); + assert_eq!(true.ok_or_else(|| 0), Ok(())); +} diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs index 5449132413b5..1c371cd30ac9 100644 --- a/library/coretests/tests/lib.rs +++ b/library/coretests/tests/lib.rs @@ -11,6 +11,7 @@ #![feature(async_iter_from_iter)] #![feature(async_iterator)] #![feature(bigint_helper_methods)] +#![feature(bool_to_result)] #![feature(bstr)] #![feature(cfg_target_has_reliable_f16_f128)] #![feature(char_max_len)] From 10c95375569c7ca90ddc5e0741fbed4498e02167 Mon Sep 17 00:00:00 2001 From: The rustc-dev-guide Cronjob Bot Date: Thu, 26 Jun 2025 04:07:24 +0000 Subject: [PATCH 02/62] Preparing for merge from rustc --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index 30ba3070e1f4..c986141b6548 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -d1d8e386c5e84c4ba857f56c3291f73c27e2d62a +bc4376fa73b636eb6f2c7d48b1f731d70f022c4b From 005dd432ed4e6f19a3508908e440f18cb19c4047 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 26 Jun 2025 22:32:39 +0800 Subject: [PATCH 03/62] Add `arguments sharing and isolation` section in `diagnostic-struct` of rdg Signed-off-by: xizheyin --- .../src/diagnostics/diagnostic-structs.md | 47 +++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md index e01b8f2f1356..ea6cdf024e1d 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md @@ -1,14 +1,18 @@ # Diagnostic and subdiagnostic structs rustc has three diagnostic traits that can be used to create diagnostics: -`Diagnostic`, `LintDiagnostic`, and `Subdiagnostic`. For simple diagnostics, -instead of using the `Diag` API to create and emit diagnostics, -derived impls can be used. They are only suitable for simple diagnostics that +`Diagnostic`, `LintDiagnostic`, and `Subdiagnostic`. + +For simple diagnostics, +derived impls can be used, e.g. `#[derive(Diagnostic)]`. They are only suitable for simple diagnostics that don't require much logic in deciding whether or not to add additional subdiagnostics. -Such diagnostic can be translated into -different languages and each has a slug that uniquely identifies the -diagnostic. +In cases where diagnostics require more complex or dynamic behavior, such as conditionally adding subdiagnostics, +customizing the rendering logic, or selecting messages at runtime, you will need to manually implement +the corresponding trait (`Diagnostic`, `LintDiagnostic`, or `Subdiagnostic`). +This approach provides greater flexibility and is recommended for diagnostics that go beyond simple, static structures. + +Diagnostic can be translated into different languages and each has a slug that uniquely identifies the diagnostic. ## `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` @@ -142,7 +146,7 @@ tcx.dcx().emit_err(FieldAlreadyDeclared { }); ``` -### Reference +### Reference for `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` support the following attributes: @@ -330,7 +334,34 @@ function ([example][subdiag_use_1] and [example][subdiag_use_2]) on a diagnostic or by assigning it to a `#[subdiagnostic]`-annotated field of a diagnostic struct. -### Reference +### Argument sharing and isolation + +Subdiagnostics will add their own arguments, +i.e. some fields in their struct, into the subdiagnostic when rendering the message, +so that the parameters in the main diagnostic can be used. +However, when a subdiagnostic is added to a main diagnostic by implementing `#[derive(Subdiagnostic)]`, +the following rules, introduced in [rust-lang/rust#142724](https://github.com/rust-lang/rust/pull/142724) +apply to the handling of arguments (i.e., variables used in Fluent messages): + +**Argument isolation between sub diagnostics**: +Arguments set by a subdiagnostic are only available during the rendering of that subdiagnostic. +After the subdiagnostic is rendered, all arguments it introduced are restore from the main diagnostic. +This ensures that multiple subdiagnostics do not pollute each other's argument scope. +For example, when using a `Vec`, it iteratively add the same arg over and over again. + +**Same argument override between sub and main diagnostics**: +If a subdiagnostic sets a argument with the same name as a arg already in the master diagnostic, +it will report an error at runtime unless both have exactly the same value. +This +- preserves the flexibility that can that *arguments is allowed to appear in the attributes of the subdiagnostic. +For example, There is a attribute `#[suggestion(code = "{new_vis}")]` in sub-diagnostic, but `new_vis` is the field in main diagnostic struct. +- prevents accidental overwriting or deletion of parameters required by the main diagnostic or other sub-diagnostics. + +These rules guarantee that arguments injected by subdiagnostics are strictly scoped to their own rendering. +The main diagnostic's arguments remain unaffected by subdiagnostic logic, even in the presence of name collisions. +Additionally, subdiagnostics can access parameters from the main diagnostic with the same name when needed. + +### Reference for `#[derive(Subdiagnostic)]` `#[derive(Subdiagnostic)]` supports the following attributes: - `#[label(slug)]`, `#[help(slug)]`, `#[warning(slug)]` or `#[note(slug)]` From e8ff13cd3306c1b234e322e6d4e40fa002d6abff Mon Sep 17 00:00:00 2001 From: xizheyin Date: Fri, 27 Jun 2025 17:44:15 +0800 Subject: [PATCH 04/62] Fix typo Signed-off-by: xizheyin --- .../src/diagnostics/diagnostic-structs.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md index ea6cdf024e1d..4e5c3413cb8a 100644 --- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md +++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md @@ -336,30 +336,30 @@ diagnostic struct. ### Argument sharing and isolation -Subdiagnostics will add their own arguments, -i.e. some fields in their struct, into the subdiagnostic when rendering the message, -so that the parameters in the main diagnostic can be used. +Subdiagnostics add their own arguments (i.e., certain fields in their structure) to the `Diag` structure before rendering the information. +`Diag` structure also stores the arguments from the main diagnostic, so the subdiagnostic can also use the arguments from the main diagnostic. + However, when a subdiagnostic is added to a main diagnostic by implementing `#[derive(Subdiagnostic)]`, the following rules, introduced in [rust-lang/rust#142724](https://github.com/rust-lang/rust/pull/142724) apply to the handling of arguments (i.e., variables used in Fluent messages): **Argument isolation between sub diagnostics**: Arguments set by a subdiagnostic are only available during the rendering of that subdiagnostic. -After the subdiagnostic is rendered, all arguments it introduced are restore from the main diagnostic. +After the subdiagnostic is rendered, all arguments it introduced are restored from the main diagnostic. This ensures that multiple subdiagnostics do not pollute each other's argument scope. -For example, when using a `Vec`, it iteratively add the same arg over and over again. +For example, when using a `Vec`, it iteratively adds the same argument over and over again. **Same argument override between sub and main diagnostics**: -If a subdiagnostic sets a argument with the same name as a arg already in the master diagnostic, +If a subdiagnostic sets a argument with the same name as a arguments already in the main diagnostic, it will report an error at runtime unless both have exactly the same value. -This -- preserves the flexibility that can that *arguments is allowed to appear in the attributes of the subdiagnostic. -For example, There is a attribute `#[suggestion(code = "{new_vis}")]` in sub-diagnostic, but `new_vis` is the field in main diagnostic struct. -- prevents accidental overwriting or deletion of parameters required by the main diagnostic or other sub-diagnostics. +It has two benefits: +- preserves the flexibility that arguments in the main diagnostic are allowed to appear in the attributes of the subdiagnostic. +For example, There is an attribute `#[suggestion(code = "{new_vis}")]` in the subdiagnostic, but `new_vis` is the field in the main diagnostic struct. +- prevents accidental overwriting or deletion of arguments required by the main diagnostic or other subdiagnostics. These rules guarantee that arguments injected by subdiagnostics are strictly scoped to their own rendering. The main diagnostic's arguments remain unaffected by subdiagnostic logic, even in the presence of name collisions. -Additionally, subdiagnostics can access parameters from the main diagnostic with the same name when needed. +Additionally, subdiagnostics can access arguments from the main diagnostic with the same name when needed. ### Reference for `#[derive(Subdiagnostic)]` `#[derive(Subdiagnostic)]` supports the following attributes: From 98c347049ec4d0d942740ddf462cc9c1bb64fd96 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Thu, 26 Jun 2025 22:50:31 +0800 Subject: [PATCH 05/62] Add a link to rust-forge to explain where rdg changes should be submitted Signed-off-by: xizheyin --- src/doc/rustc-dev-guide/src/contributing.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/contributing.md b/src/doc/rustc-dev-guide/src/contributing.md index 46d74b967342..b3fcd79ec818 100644 --- a/src/doc/rustc-dev-guide/src/contributing.md +++ b/src/doc/rustc-dev-guide/src/contributing.md @@ -434,6 +434,10 @@ Just a few things to keep in mind: it might benefit from having a Table of Contents at the beginning, which you can auto-generate by including the `` marker at the top. +#### ⚠️ Note: Where to contribute `rustc-dev-guide` changes + +For detailed information about where to contribute rustc-dev-guide changes and the benefits of doing so, see [the rustc-dev-guide working group documentation](https://forge.rust-lang.org/wg-rustc-dev-guide/index.html#where-to-contribute-rustc-dev-guide-changes). + ## Issue triage Please see . From e9721a69a7c39904d27d1d96f575eeb9c0f37fe3 Mon Sep 17 00:00:00 2001 From: Jieyou Xu Date: Sun, 29 Jun 2025 11:23:19 +0800 Subject: [PATCH 06/62] Add broken `./x test library/std` advisory --- .../src/building/how-to-build-and-run.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md index c4783002b85a..d29cd1448102 100644 --- a/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md +++ b/src/doc/rustc-dev-guide/src/building/how-to-build-and-run.md @@ -2,6 +2,24 @@ +
+ +For `profile = "library"` users, or users who use `download-rustc = true | "if-unchanged"`, please be advised that +the `./x test library/std` flow where `download-rustc` is active (i.e. no compiler changes) is currently broken. +This is tracked in . Only the `./x test` flow is affected in this +case, `./x {check,build} library/std` should still work. + +In the short-term, you may need to disable `download-rustc` for `./x test library/std`. This can be done either by: + +1. `./x test library/std --set rust.download-rustc=false` +2. Or set `rust.download-rustc=false` in `bootstrap.toml`. + +Unfortunately that will require building the stage 1 compiler. The bootstrap team is working on this, but +implementing a maintainable fix is taking some time. + +
+ + The compiler is built using a tool called `x.py`. You will need to have Python installed to run it. From 787a4cc90f540b979f31f3f24e103f35295bf036 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Mon, 30 Jun 2025 06:15:08 +0200 Subject: [PATCH 07/62] build-fail directive: make explanation more uniform The last part of the paragraph did not fit --- src/doc/rustc-dev-guide/src/tests/ui.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/tests/ui.md b/src/doc/rustc-dev-guide/src/tests/ui.md index 09dc476d68ee..65bd89bafe64 100644 --- a/src/doc/rustc-dev-guide/src/tests/ui.md +++ b/src/doc/rustc-dev-guide/src/tests/ui.md @@ -453,9 +453,9 @@ even run the resulting program. Just add one of the following - `//@ check-fail` — compilation should fail (the codegen phase is skipped). This is the default for UI tests. - `//@ build-fail` — compilation should fail during the codegen phase. - This will run `rustc` twice, once to verify that it compiles successfully - without the codegen phase, then a second time the full compile should - fail. + This will run `rustc` twice: + - First time is to ensure that the compile succeeds without the codegen phase + - Second time is to ensure that the full compile fails - `//@ run-fail` — compilation should succeed, but running the resulting binary should fail. From 390d1be1c7eb500672f9c982e7de13ed27506aea Mon Sep 17 00:00:00 2001 From: dianne Date: Sun, 29 Jun 2025 21:24:25 -0700 Subject: [PATCH 08/62] update AST-to-HIR lowering examples for conditionals and loops - `for` loops now use two `match`es for all of their bindings. I'm not sure this is the most helpful way of conveying that, but it's about as informative as before while staying brief. - `while let` and `if let` don't use `match`; they use `let` expressions in their conditions. Since `if let` no longer has significantly different desugaring and having a whole bullet point for `while` would feel redundant with `for`, I've removed those examples. --- src/doc/rustc-dev-guide/src/hir/lowering.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/hir/lowering.md b/src/doc/rustc-dev-guide/src/hir/lowering.md index 02c69b8609f1..c0057a69c10d 100644 --- a/src/doc/rustc-dev-guide/src/hir/lowering.md +++ b/src/doc/rustc-dev-guide/src/hir/lowering.md @@ -7,10 +7,8 @@ of such structures include but are not limited to * Parenthesis * Removed without replacement, the tree structure makes order explicit -* `for` loops and `while (let)` loops - * Converted to `loop` + `match` and some `let` bindings -* `if let` - * Converted to `match` +* `for` loops + * Converted to `match` + `loop` + `match` * Universal `impl Trait` * Converted to generic arguments (but with some flags, to know that the user didn't write them) From cda9bfef6f7ce3bc1744c0ed41e53523efdc5bba Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 1 Jul 2025 09:14:18 -0700 Subject: [PATCH 09/62] Fix `x clean` with a fifo `x clean` was failing when it encountered a special file like a fifo because it thought it was a directory. --- src/bootstrap/src/core/build_steps/clean.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/clean.rs b/src/bootstrap/src/core/build_steps/clean.rs index 882fcd087800..f67569d14860 100644 --- a/src/bootstrap/src/core/build_steps/clean.rs +++ b/src/bootstrap/src/core/build_steps/clean.rs @@ -181,7 +181,7 @@ fn rm_rf(path: &Path) { panic!("failed to get metadata for file {}: {}", path.display(), e); } Ok(metadata) => { - if metadata.file_type().is_file() || metadata.file_type().is_symlink() { + if !metadata.file_type().is_dir() { do_op(path, "remove file", |p| match fs::remove_file(p) { #[cfg(windows)] Err(e) From ae0bef778ab184636f06266fab5fbdec306e2ca1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Jul 2025 00:29:51 +0000 Subject: [PATCH 10/62] Remove fast path from codegen_select, since Sized has no methods --- compiler/rustc_traits/src/codegen.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 9d1440105618..7dd3c59edd05 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -6,11 +6,11 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::bug; use rustc_middle::traits::CodegenObligationError; -use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt, Upcast}; +use rustc_middle::ty::{self, PseudoCanonicalInput, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::error_reporting::InferCtxtErrorExt; use rustc_trait_selection::traits::{ ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext, - SelectionError, sizedness_fast_path, + SelectionError, }; use tracing::debug; @@ -34,13 +34,6 @@ pub(crate) fn codegen_select_candidate<'tcx>( let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env); let mut selcx = SelectionContext::new(&infcx); - if sizedness_fast_path(tcx, trait_ref.upcast(tcx)) { - return Ok(&*tcx.arena.alloc(ImplSource::Builtin( - ty::solve::BuiltinImplSource::Trivial, - Default::default(), - ))); - } - let obligation_cause = ObligationCause::dummy(); let obligation = Obligation::new(tcx, obligation_cause, param_env, trait_ref); From d3c0ef0c9fb000d09529e2ff71ed2e69e224a8d6 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Jul 2025 00:30:10 +0000 Subject: [PATCH 11/62] Use is_trivially_wf for ProvePredicate fast path --- .../src/traits/query/type_op/prove_predicate.rs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index 18971c47831a..22eeb285b376 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -21,19 +21,9 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { if let ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(term)) = key.value.predicate.kind().skip_binder() + && term.is_trivially_wf(tcx) { - match term.as_type()?.kind() { - ty::Param(_) - | ty::Bool - | ty::Char - | ty::Int(_) - | ty::Float(_) - | ty::Str - | ty::Uint(_) => { - return Some(()); - } - _ => {} - } + return Some(()); } None From 91c53c97a990e9d1ab87b2d932362a53236fba49 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Jul 2025 00:32:54 +0000 Subject: [PATCH 12/62] Consider polarity in sizedness fast path --- compiler/rustc_trait_selection/src/traits/util.rs | 7 ++++--- tests/ui/traits/negative-bounds/negative-sized.rs | 8 ++++++++ .../traits/negative-bounds/negative-sized.stderr | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 tests/ui/traits/negative-bounds/negative-sized.rs create mode 100644 tests/ui/traits/negative-bounds/negative-sized.stderr diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index a05bae535663..141454bfe375 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -368,16 +368,17 @@ pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc // Proving `Sized`/`MetaSized`, very often on "obviously sized" types like // `&T`, accounts for about 60% percentage of the predicates we have to prove. No need to // canonicalize and all that for such cases. - if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) = + if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = predicate.kind().skip_binder() + && trait_pred.polarity == ty::PredicatePolarity::Positive { - let sizedness = match tcx.as_lang_item(trait_ref.def_id()) { + let sizedness = match tcx.as_lang_item(trait_pred.def_id()) { Some(LangItem::Sized) => SizedTraitKind::Sized, Some(LangItem::MetaSized) => SizedTraitKind::MetaSized, _ => return false, }; - if trait_ref.self_ty().has_trivial_sizedness(tcx, sizedness) { + if trait_pred.self_ty().has_trivial_sizedness(tcx, sizedness) { debug!("fast path -- trivial sizedness"); return true; } diff --git a/tests/ui/traits/negative-bounds/negative-sized.rs b/tests/ui/traits/negative-bounds/negative-sized.rs new file mode 100644 index 000000000000..18369c784275 --- /dev/null +++ b/tests/ui/traits/negative-bounds/negative-sized.rs @@ -0,0 +1,8 @@ +#![feature(negative_bounds)] + +fn foo() {} + +fn main() { + foo::<()>(); + //~^ ERROR the trait bound `(): !Sized` is not satisfied +} diff --git a/tests/ui/traits/negative-bounds/negative-sized.stderr b/tests/ui/traits/negative-bounds/negative-sized.stderr new file mode 100644 index 000000000000..143933803b81 --- /dev/null +++ b/tests/ui/traits/negative-bounds/negative-sized.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): !Sized` is not satisfied + --> $DIR/negative-sized.rs:6:11 + | +LL | foo::<()>(); + | ^^ the trait bound `(): !Sized` is not satisfied + | +note: required by a bound in `foo` + --> $DIR/negative-sized.rs:3:11 + | +LL | fn foo() {} + | ^^^^^^ required by this bound in `foo` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From a0dc0b549db557245e3dc55490263fa264af5e69 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 12 Aug 2023 08:04:45 +0000 Subject: [PATCH 13/62] Do not depend on FOREVER_RED_NODE. --- compiler/rustc_middle/src/ty/context.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index c5f4b95cbbe6..3da888c11dba 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2082,9 +2082,8 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn iter_local_def_id(self) -> impl Iterator { - // Create a dependency to the red node to be sure we re-execute this when the amount of - // definitions change. - self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); + // Depend on the `analysis` query to ensure compilation if finished. + self.ensure_ok().analysis(()); let definitions = &self.untracked.definitions; gen { @@ -2104,9 +2103,8 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn def_path_table(self) -> &'tcx rustc_hir::definitions::DefPathTable { - // Create a dependency to the crate to be sure we re-execute this when the amount of - // definitions change. - self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); + // Depend on the `analysis` query to ensure compilation if finished. + self.ensure_ok().analysis(()); // Freeze definitions once we start iterating on them, to prevent adding new ones // while iterating. If some query needs to add definitions, it should be `ensure`d above. From 992fa62118d61c0df27cc0f8d5e22cb7d5bc51c0 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 9 Aug 2023 19:54:58 +0000 Subject: [PATCH 14/62] Hash resolutions. --- compiler/rustc_interface/src/passes.rs | 3 +-- compiler/rustc_middle/src/query/mod.rs | 1 - compiler/rustc_middle/src/ty/mod.rs | 12 ++++++------ compiler/rustc_resolve/src/lib.rs | 25 ++++++++++++------------- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 201b7e2b940c..8f9093e0f2b1 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -850,8 +850,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock = LazyLock::new(|| { providers.analysis = analysis; providers.hir_crate = rustc_ast_lowering::lower_to_hir; providers.resolver_for_lowering_raw = resolver_for_lowering_raw; - providers.stripped_cfg_items = - |tcx, _| tcx.arena.alloc_from_iter(tcx.resolutions(()).stripped_cfg_items.steal()); + providers.stripped_cfg_items = |tcx, _| &tcx.resolutions(()).stripped_cfg_items[..]; providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1; providers.early_lint_checks = early_lint_checks; providers.env_var_os = env_var_os; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3668f4e12f5d..030146a45852 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -194,7 +194,6 @@ rustc_queries! { } query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt { - no_hash desc { "getting the resolver outputs" } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 97408e31854a..1e827fd83273 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -33,7 +33,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; -use rustc_data_structures::unord::UnordMap; +use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{Diag, ErrorGuaranteed}; use rustc_hir::LangItem; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; @@ -176,11 +176,11 @@ pub struct ResolverOutputs { pub ast_lowering: ResolverAstLowering, } -#[derive(Debug)] +#[derive(Debug, HashStable)] pub struct ResolverGlobalCtxt { pub visibilities_for_hashing: Vec<(LocalDefId, Visibility)>, /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. - pub expn_that_defined: FxHashMap, + pub expn_that_defined: UnordMap, pub effective_visibilities: EffectiveVisibilities, pub extern_crate_map: UnordMap, pub maybe_unused_trait_imports: FxIndexSet, @@ -196,8 +196,8 @@ pub struct ResolverGlobalCtxt { pub confused_type_with_std_module: FxIndexMap, pub doc_link_resolutions: FxIndexMap, pub doc_link_traits_in_scope: FxIndexMap>, - pub all_macro_rules: FxHashSet, - pub stripped_cfg_items: Steal>, + pub all_macro_rules: UnordSet, + pub stripped_cfg_items: Vec, } /// Resolutions that should only be used for lowering. @@ -243,7 +243,7 @@ pub struct DelegationFnSig { pub target_feature: bool, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, HashStable)] pub struct MainDefinition { pub res: Res, pub is_import: bool, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index f0540725416c..0721fed1c0b1 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -46,7 +46,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::FreezeReadGuard; -use rustc_data_structures::unord::UnordMap; +use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::{Applicability, Diag, ErrCode, ErrorGuaranteed}; use rustc_expand::base::{DeriveResolution, SyntaxExtension, SyntaxExtensionKind}; use rustc_feature::BUILTIN_ATTRIBUTES; @@ -1031,7 +1031,7 @@ pub struct Resolver<'ra, 'tcx> { tcx: TyCtxt<'tcx>, /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. - expn_that_defined: FxHashMap, + expn_that_defined: UnordMap, graph_root: Module<'ra>, @@ -1208,7 +1208,7 @@ pub struct Resolver<'ra, 'tcx> { effective_visibilities: EffectiveVisibilities, doc_link_resolutions: FxIndexMap, doc_link_traits_in_scope: FxIndexMap>, - all_macro_rules: FxHashSet, + all_macro_rules: UnordSet, /// Invocation ids of all glob delegations. glob_delegation_invoc_ids: FxHashSet, @@ -1647,16 +1647,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let confused_type_with_std_module = self.confused_type_with_std_module; let effective_visibilities = self.effective_visibilities; - let stripped_cfg_items = Steal::new( - self.stripped_cfg_items - .into_iter() - .filter_map(|item| { - let parent_module = - self.node_id_to_def_id.get(&item.parent_module)?.key().to_def_id(); - Some(StrippedCfgItem { parent_module, ident: item.ident, cfg: item.cfg }) - }) - .collect(), - ); + let stripped_cfg_items = self + .stripped_cfg_items + .into_iter() + .filter_map(|item| { + let parent_module = + self.node_id_to_def_id.get(&item.parent_module)?.key().to_def_id(); + Some(StrippedCfgItem { parent_module, ident: item.ident, cfg: item.cfg }) + }) + .collect(); let global_ctxt = ResolverGlobalCtxt { expn_that_defined, From 9ce91f7a2884080a2231d08ed7bdeb04d91f002d Mon Sep 17 00:00:00 2001 From: Emmanuel Ferdman Date: Wed, 2 Jul 2025 16:16:33 -0700 Subject: [PATCH 15/62] update coherence example Signed-off-by: Emmanuel Ferdman --- src/doc/rustc-dev-guide/src/solve/opaque-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/src/solve/opaque-types.md b/src/doc/rustc-dev-guide/src/solve/opaque-types.md index 6898ef3aa780..8880962d621f 100644 --- a/src/doc/rustc-dev-guide/src/solve/opaque-types.md +++ b/src/doc/rustc-dev-guide/src/solve/opaque-types.md @@ -56,7 +56,7 @@ Finally, we check whether the item bounds of the opaque hold for the expected ty [source][item-bounds-ck]. [norm]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L13 -[coherence-example]: https://github.com/rust-lang/rust/blob/master/tests/ui/type-alias-impl-trait/coherence_different_hidden_ty.rs +[coherence-example]: https://github.com/rust-lang/rust/blob/master/tests/ui/type-alias-impl-trait/coherence/coherence_different_hidden_ty.rs [placeholder-ck]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L33 [check-storage]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L51-L52 [eq-prev]: https://github.com/rust-lang/rust/blob/384d26fc7e3bdd7687cc17b2662b091f6017ec2a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs#L51-L59 From d9505f0b321e85c47a6f12ee97cd86e0750d4174 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Thu, 3 Jul 2025 09:20:57 +0000 Subject: [PATCH 16/62] use unsigned_abs instead of `abs` on signed int to silence clippy --- library/core/src/num/uint_macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 079032f2f96d..9cadbd47ab6a 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2572,7 +2572,7 @@ macro_rules! uint_impl { if size_of::() == 1 { // Trick LLVM into generating the psadbw instruction when SSE2 // is available and this function is autovectorized for u8's. - (self as i32).wrapping_sub(other as i32).abs() as Self + (self as i32).wrapping_sub(other as i32).unsigned_abs() as Self } else { if self < other { other - self From 6bef238b6346911d29a1ee0b067dc003da15f828 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Mon, 2 Jun 2025 23:40:01 -0600 Subject: [PATCH 17/62] refactor: Make -Ztrack-diagnostics emit like a note --- compiler/rustc_errors/src/diagnostic.rs | 9 +++++++++ compiler/rustc_errors/src/emitter.rs | 17 ++++------------- compiler/rustc_errors/src/json.rs | 7 +++++-- .../tests/ui/track-diagnostics-clippy.stderr | 4 ++-- src/tools/clippy/tests/ui/track-diagnostics.rs | 1 + .../clippy/tests/ui/track-diagnostics.stderr | 3 ++- tests/rustdoc-ui/track-diagnostics.rs | 6 ++++-- tests/rustdoc-ui/track-diagnostics.stderr | 3 ++- tests/ui/track-diagnostics/track.rs | 5 ++++- tests/ui/track-diagnostics/track.stderr | 8 +++++--- tests/ui/track-diagnostics/track2.rs | 6 ++++-- tests/ui/track-diagnostics/track2.stderr | 2 +- tests/ui/track-diagnostics/track3.rs | 4 +++- tests/ui/track-diagnostics/track3.stderr | 6 ++++-- tests/ui/track-diagnostics/track4.rs | 6 ++++-- tests/ui/track-diagnostics/track4.stderr | 2 +- tests/ui/track-diagnostics/track5.rs | 6 ++++-- tests/ui/track-diagnostics/track5.stderr | 3 ++- tests/ui/track-diagnostics/track6.rs | 6 ++++-- tests/ui/track-diagnostics/track6.stderr | 2 +- 20 files changed, 66 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index fe9797026def..5746c28a2ab2 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -417,6 +417,15 @@ impl DiagInner { self.args = std::mem::take(&mut self.reserved_args); } + pub fn emitted_at_sub_diag(&self) -> Subdiag { + let track = format!("-Ztrack-diagnostics: created at {}", self.emitted_at); + Subdiag { + level: crate::Level::Note, + messages: vec![(DiagMessage::Str(Cow::Owned(track)), Style::NoStyle)], + span: MultiSpan::new(), + } + } + /// Fields used for Hash, and PartialEq trait. fn keys( &self, diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 3f5872f34a6f..2f398cea926c 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -28,7 +28,6 @@ use rustc_span::{FileLines, FileName, SourceFile, Span, char_width, str_width}; use termcolor::{Buffer, BufferWriter, Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use tracing::{debug, instrument, trace, warn}; -use crate::diagnostic::DiagLocation; use crate::registry::Registry; use crate::snippet::{ Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString, @@ -505,6 +504,10 @@ impl Emitter for HumanEmitter { fn emit_diagnostic(&mut self, mut diag: DiagInner, _registry: &Registry) { let fluent_args = to_fluent_args(diag.args.iter()); + if self.track_diagnostics && diag.span.has_primary_spans() && !diag.span.is_dummy() { + diag.children.insert(0, diag.emitted_at_sub_diag()); + } + let mut suggestions = diag.suggestions.unwrap_tag(); self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args); @@ -523,7 +526,6 @@ impl Emitter for HumanEmitter { &diag.span, &diag.children, &suggestions, - self.track_diagnostics.then_some(&diag.emitted_at), ); } @@ -1468,7 +1470,6 @@ impl HumanEmitter { level: &Level, max_line_num_len: usize, is_secondary: bool, - emitted_at: Option<&DiagLocation>, is_cont: bool, ) -> io::Result<()> { let mut buffer = StyledBuffer::new(); @@ -1978,12 +1979,6 @@ impl HumanEmitter { trace!("buffer: {:#?}", buffer.render()); } - if let Some(tracked) = emitted_at { - let track = format!("-Ztrack-diagnostics: created at {tracked}"); - let len = buffer.num_lines(); - buffer.append(len, &track, Style::NoStyle); - } - // final step: take our styled buffer, render it, then output it emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?; @@ -2478,7 +2473,6 @@ impl HumanEmitter { span: &MultiSpan, children: &[Subdiag], suggestions: &[CodeSuggestion], - emitted_at: Option<&DiagLocation>, ) { let max_line_num_len = if self.ui_testing { ANONYMIZED_LINE_NUM.len() @@ -2495,7 +2489,6 @@ impl HumanEmitter { level, max_line_num_len, false, - emitted_at, !children.is_empty() || suggestions.iter().any(|s| s.style != SuggestionStyle::CompletelyHidden), ) { @@ -2541,7 +2534,6 @@ impl HumanEmitter { &child.level, max_line_num_len, true, - None, !should_close, ) { panic!("failed to emit error: {err}"); @@ -2561,7 +2553,6 @@ impl HumanEmitter { &Level::Help, max_line_num_len, true, - None, // FIXME: this needs to account for the suggestion type, // some don't take any space. i + 1 != suggestions.len(), diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 4348610be0af..719d4ca625ae 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -372,13 +372,16 @@ impl Diagnostic { }; let level = diag.level.to_str(); let spans = DiagnosticSpan::from_multispan(&diag.span, &args, je); - let children = diag + let mut children: Vec = diag .children .iter() .map(|c| Diagnostic::from_sub_diagnostic(c, &args, je)) .chain(sugg) .collect(); - + if je.track_diagnostics && diag.span.has_primary_spans() && !diag.span.is_dummy() { + children + .insert(0, Diagnostic::from_sub_diagnostic(&diag.emitted_at_sub_diag(), &args, je)); + } let buf = BufWriter::default(); let mut dst: Destination = Box::new(buf.clone()); let short = je.json_rendered.short(); diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr index f3aca6854174..9d6538112bf0 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr +++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr @@ -3,8 +3,8 @@ error: casting to the same type is unnecessary (`u32` -> `u32`) | LL | let b = a as u32; | ^^^^^^^^ help: try: `a` --Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs:LL:CC | + = note: -Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs:LL:CC = note: `-D clippy::unnecessary-cast` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]` @@ -15,8 +15,8 @@ LL | let d = 42; | ----------- unnecessary `let` binding LL | d | ^ --Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/returns.rs:LL:CC | + = note: -Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/returns.rs:LL:CC = note: `-D clippy::let-and-return` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]` help: return the expression directly diff --git a/src/tools/clippy/tests/ui/track-diagnostics.rs b/src/tools/clippy/tests/ui/track-diagnostics.rs index 723ea23e9a63..0fbde867390d 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics.rs +++ b/src/tools/clippy/tests/ui/track-diagnostics.rs @@ -8,5 +8,6 @@ struct A; struct B; const S: A = B; //~^ ERROR: mismatched types +//~| NOTE: created at fn main() {} diff --git a/src/tools/clippy/tests/ui/track-diagnostics.stderr b/src/tools/clippy/tests/ui/track-diagnostics.stderr index 83451fb658d0..45262ba618f2 100644 --- a/src/tools/clippy/tests/ui/track-diagnostics.stderr +++ b/src/tools/clippy/tests/ui/track-diagnostics.stderr @@ -3,7 +3,8 @@ error[E0308]: mismatched types | LL | const S: A = B; | ^ expected `A`, found `B` --Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC + | + = note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC error: aborting due to 1 previous error diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs index d18d26bf7943..f8e710659a5c 100644 --- a/tests/rustdoc-ui/track-diagnostics.rs +++ b/tests/rustdoc-ui/track-diagnostics.rs @@ -1,5 +1,4 @@ //@ compile-flags: -Z track-diagnostics -//@ error-pattern: created at // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. @@ -8,4 +7,7 @@ struct A; struct B; -pub const S: A = B; //~ ERROR mismatched types +pub const S: A = B; +//~^ ERROR mismatched types +//~| NOTE created at +//~| NOTE expected `A`, found `B` diff --git a/tests/rustdoc-ui/track-diagnostics.stderr b/tests/rustdoc-ui/track-diagnostics.stderr index fb0d7b866449..a25fd2862aaf 100644 --- a/tests/rustdoc-ui/track-diagnostics.stderr +++ b/tests/rustdoc-ui/track-diagnostics.stderr @@ -3,7 +3,8 @@ error[E0308]: mismatched types | LL | pub const S: A = B; | ^ expected `A`, found `B` --Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC + | + = note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC error: aborting due to 1 previous error diff --git a/tests/ui/track-diagnostics/track.rs b/tests/ui/track-diagnostics/track.rs index 78ff85489bed..1b2558c724bb 100644 --- a/tests/ui/track-diagnostics/track.rs +++ b/tests/ui/track-diagnostics/track.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Z track-diagnostics -//@ error-pattern: created at +//@ dont-require-annotations: NOTE //@ rustc-env:RUST_BACKTRACE=0 //@ failure-status: 101 @@ -16,6 +16,9 @@ fn main() { break rust //~^ ERROR cannot find value `rust` in this scope + //~| NOTE created at //~| ERROR `break` outside of a loop or labeled block + //~| NOTE created at //~| ERROR It looks like you're trying to break rust; would you like some ICE? + //~| NOTE created at } diff --git a/tests/ui/track-diagnostics/track.stderr b/tests/ui/track-diagnostics/track.stderr index 527c0d1b8989..f82764958d46 100644 --- a/tests/ui/track-diagnostics/track.stderr +++ b/tests/ui/track-diagnostics/track.stderr @@ -3,22 +3,24 @@ error[E0425]: cannot find value `rust` in this scope | LL | break rust | ^^^^ not found in this scope --Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC + | + = note: -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC error[E0268]: `break` outside of a loop or labeled block --> $DIR/track.rs:LL:CC | LL | break rust | ^^^^^^^^^^ cannot `break` outside of a loop or labeled block --Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/loops.rs:LL:CC + | + = note: -Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/loops.rs:LL:CC error: internal compiler error: It looks like you're trying to break rust; would you like some ICE? --> $DIR/track.rs:LL:CC | LL | break rust | ^^^^^^^^^^ --Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/lib.rs:LL:CC | + = note: -Ztrack-diagnostics: created at compiler/rustc_hir_typeck/src/lib.rs:LL:CC = note: the compiler expectedly panicked. this is a feature. = note: we would appreciate a joke overview: https://github.com/rust-lang/rust/issues/43162#issuecomment-320764675 = note: rustc $VERSION running on $TARGET diff --git a/tests/ui/track-diagnostics/track2.rs b/tests/ui/track-diagnostics/track2.rs index f51a42cf86f9..591b84f330b7 100644 --- a/tests/ui/track-diagnostics/track2.rs +++ b/tests/ui/track-diagnostics/track2.rs @@ -1,10 +1,12 @@ //@ compile-flags: -Z track-diagnostics -//@ error-pattern: created at +//@ dont-require-annotations: NOTE // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" fn main() { - let _moved @ _from = String::from("foo"); //~ ERROR use of moved value + let _moved @ _from = String::from("foo"); + //~^ ERROR use of moved value + //~| NOTE created at } diff --git a/tests/ui/track-diagnostics/track2.stderr b/tests/ui/track-diagnostics/track2.stderr index dffa0b0c91c1..02010639c027 100644 --- a/tests/ui/track-diagnostics/track2.stderr +++ b/tests/ui/track-diagnostics/track2.stderr @@ -6,8 +6,8 @@ LL | let _moved @ _from = String::from("foo"); | | | | | value moved here | value used here after move --Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:LL:CC | + = note: -Ztrack-diagnostics: created at compiler/rustc_borrowck/src/borrowck_errors.rs:LL:CC help: borrow this binding in the pattern to avoid moving the value | LL | let ref _moved @ ref _from = String::from("foo"); diff --git a/tests/ui/track-diagnostics/track3.rs b/tests/ui/track-diagnostics/track3.rs index 428067572af7..a39e71915d90 100644 --- a/tests/ui/track-diagnostics/track3.rs +++ b/tests/ui/track-diagnostics/track3.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Z track-diagnostics -//@ error-pattern: created at +//@ dont-require-annotations: NOTE // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. @@ -8,5 +8,7 @@ fn main() { let _unimported = Blah { field: u8 }; //~^ ERROR cannot find struct, variant or union type `Blah` in this scope + //~| NOTE created at //~| ERROR expected value, found builtin type `u8` + //~| NOTE created at } diff --git a/tests/ui/track-diagnostics/track3.stderr b/tests/ui/track-diagnostics/track3.stderr index dc468d7e8eeb..3e99c8d5f33f 100644 --- a/tests/ui/track-diagnostics/track3.stderr +++ b/tests/ui/track-diagnostics/track3.stderr @@ -3,14 +3,16 @@ error[E0422]: cannot find struct, variant or union type `Blah` in this scope | LL | let _unimported = Blah { field: u8 }; | ^^^^ not found in this scope --Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC + | + = note: -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC error[E0423]: expected value, found builtin type `u8` --> $DIR/track3.rs:LL:CC | LL | let _unimported = Blah { field: u8 }; | ^^ not a value --Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC + | + = note: -Ztrack-diagnostics: created at compiler/rustc_resolve/src/late/diagnostics.rs:LL:CC error: aborting due to 2 previous errors diff --git a/tests/ui/track-diagnostics/track4.rs b/tests/ui/track-diagnostics/track4.rs index b6edfdba2596..0038c616aa55 100644 --- a/tests/ui/track-diagnostics/track4.rs +++ b/tests/ui/track-diagnostics/track4.rs @@ -1,11 +1,13 @@ //@ compile-flags: -Z track-diagnostics -//@ error-pattern: created at +//@ dont-require-annotations: NOTE // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" -pub onion { //~ ERROR missing `enum` for enum definition +pub onion { + //~^ ERROR missing `enum` for enum definition + //~| NOTE created at Owo(u8), Uwu(i8), } diff --git a/tests/ui/track-diagnostics/track4.stderr b/tests/ui/track-diagnostics/track4.stderr index 19499fa7abc5..2b6805849b52 100644 --- a/tests/ui/track-diagnostics/track4.stderr +++ b/tests/ui/track-diagnostics/track4.stderr @@ -3,8 +3,8 @@ error: missing `enum` for enum definition | LL | pub onion { | ^^^^^^^^^ --Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/item.rs:LL:CC | + = note: -Ztrack-diagnostics: created at compiler/rustc_parse/src/parser/item.rs:LL:CC help: add `enum` here to parse `onion` as an enum | LL | pub enum onion { diff --git a/tests/ui/track-diagnostics/track5.rs b/tests/ui/track-diagnostics/track5.rs index 800bb21b2b16..09fda4eb5273 100644 --- a/tests/ui/track-diagnostics/track5.rs +++ b/tests/ui/track-diagnostics/track5.rs @@ -1,8 +1,10 @@ //@ compile-flags: -Z track-diagnostics -//@ error-pattern: created at +//@ dont-require-annotations: NOTE // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. //@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" -} //~ ERROR unexpected closing delimiter: `}` +} +//~^ ERROR unexpected closing delimiter: `}` +//~| NOTE created at diff --git a/tests/ui/track-diagnostics/track5.stderr b/tests/ui/track-diagnostics/track5.stderr index ecc7d81b3c36..5de0550918eb 100644 --- a/tests/ui/track-diagnostics/track5.stderr +++ b/tests/ui/track-diagnostics/track5.stderr @@ -3,7 +3,8 @@ error: unexpected closing delimiter: `}` | LL | } | ^ unexpected closing delimiter --Ztrack-diagnostics: created at compiler/rustc_parse/src/lexer/tokentrees.rs:LL:CC + | + = note: -Ztrack-diagnostics: created at compiler/rustc_parse/src/lexer/tokentrees.rs:LL:CC error: aborting due to 1 previous error diff --git a/tests/ui/track-diagnostics/track6.rs b/tests/ui/track-diagnostics/track6.rs index 55db2ecf939d..11d3b7e9764b 100644 --- a/tests/ui/track-diagnostics/track6.rs +++ b/tests/ui/track-diagnostics/track6.rs @@ -1,5 +1,5 @@ //@ compile-flags: -Z track-diagnostics -//@ error-pattern: created at +//@ dont-require-annotations: NOTE // Normalize the emitted location so this doesn't need // updating everytime someone adds or removes a line. @@ -11,7 +11,9 @@ pub trait Foo { } impl Foo for T { - default fn bar() {} //~ ERROR specialization is unstable + default fn bar() {} + //~^ ERROR specialization is unstable + //~| NOTE created at } fn main() {} diff --git a/tests/ui/track-diagnostics/track6.stderr b/tests/ui/track-diagnostics/track6.stderr index 9ed8a19629df..a61f7855e323 100644 --- a/tests/ui/track-diagnostics/track6.stderr +++ b/tests/ui/track-diagnostics/track6.stderr @@ -3,8 +3,8 @@ error[E0658]: specialization is unstable | LL | default fn bar() {} | ^^^^^^^^^^^^^^^^^^^ --Ztrack-diagnostics: created at compiler/rustc_ast_passes/src/feature_gate.rs:LL:CC | + = note: -Ztrack-diagnostics: created at compiler/rustc_ast_passes/src/feature_gate.rs:LL:CC = note: see issue #31844 for more information = help: add `#![feature(specialization)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date From 1c3454af55316c11cef651a14e0cdf8b3bb0cb56 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Thu, 3 Jul 2025 13:44:35 +0000 Subject: [PATCH 18/62] remove redundant #[must_use] --- library/core/src/cmp.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 0aa8f47462db..b1ca3701fa5a 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -1449,7 +1449,6 @@ pub trait PartialOrd: PartialEq + PointeeSized { /// check `==` and `<` separately to do rather than needing to calculate /// (then optimize out) the three-way `Ordering` result. #[inline] - #[must_use] // Added to improve the behaviour of tuples; not necessarily stabilization-track. #[unstable(feature = "partial_ord_chaining_methods", issue = "none")] #[doc(hidden)] @@ -1459,7 +1458,6 @@ pub trait PartialOrd: PartialEq + PointeeSized { /// Same as `__chaining_lt`, but for `<=` instead of `<`. #[inline] - #[must_use] #[unstable(feature = "partial_ord_chaining_methods", issue = "none")] #[doc(hidden)] fn __chaining_le(&self, other: &Rhs) -> ControlFlow { @@ -1468,7 +1466,6 @@ pub trait PartialOrd: PartialEq + PointeeSized { /// Same as `__chaining_lt`, but for `>` instead of `<`. #[inline] - #[must_use] #[unstable(feature = "partial_ord_chaining_methods", issue = "none")] #[doc(hidden)] fn __chaining_gt(&self, other: &Rhs) -> ControlFlow { @@ -1477,7 +1474,6 @@ pub trait PartialOrd: PartialEq + PointeeSized { /// Same as `__chaining_lt`, but for `>=` instead of `<`. #[inline] - #[must_use] #[unstable(feature = "partial_ord_chaining_methods", issue = "none")] #[doc(hidden)] fn __chaining_ge(&self, other: &Rhs) -> ControlFlow { From 510e5d7e665400822a6495adb23e06df99cc339c Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 3 Jul 2025 23:16:46 +0800 Subject: [PATCH 19/62] rustdoc: don't treat methods under const impls or traits as const --- src/librustdoc/clean/types.rs | 15 +++++++- .../constant/const-trait-and-impl-methods.rs | 36 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc/constant/const-trait-and-impl-methods.rs diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 600c564d7141..2808339bb556 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -647,7 +647,20 @@ impl Item { ) -> hir::FnHeader { let sig = tcx.fn_sig(def_id).skip_binder(); let constness = if tcx.is_const_fn(def_id) { - hir::Constness::Const + // rustc's `is_const_fn` returns `true` for associated functions that have an `impl const` parent + // or that have a `#[const_trait]` parent. Do not display those as `const` in rustdoc because we + // won't be printing correct syntax plus the syntax is unstable. + match tcx.opt_associated_item(def_id) { + Some(ty::AssocItem { + container: ty::AssocItemContainer::Impl, + trait_item_def_id: Some(_), + .. + }) + | Some(ty::AssocItem { container: ty::AssocItemContainer::Trait, .. }) => { + hir::Constness::NotConst + } + None | Some(_) => hir::Constness::Const, + } } else { hir::Constness::NotConst }; diff --git a/tests/rustdoc/constant/const-trait-and-impl-methods.rs b/tests/rustdoc/constant/const-trait-and-impl-methods.rs new file mode 100644 index 000000000000..30fc539e5533 --- /dev/null +++ b/tests/rustdoc/constant/const-trait-and-impl-methods.rs @@ -0,0 +1,36 @@ +// check that we don't render `#[const_trait]` methods as `const` - even for +// const `trait`s and `impl`s. +#![crate_name = "foo"] +#![feature(const_trait_impl)] + +//@ has foo/trait.Tr.html +//@ has - '//*[@id="tymethod.required"]' 'fn required()' +//@ !has - '//*[@id="tymethod.required"]' 'const' +//@ has - '//*[@id="method.defaulted"]' 'fn defaulted()' +//@ !has - '//*[@id="method.defaulted"]' 'const' +#[const_trait] +pub trait Tr { + fn required(); + fn defaulted() {} +} + +pub struct ConstImpl {} +pub struct NonConstImpl {} + +//@ has foo/struct.ConstImpl.html +//@ has - '//*[@id="method.required"]' 'fn required()' +//@ !has - '//*[@id="method.required"]' 'const' +//@ has - '//*[@id="method.defaulted"]' 'fn defaulted()' +//@ !has - '//*[@id="method.defaulted"]' 'const' +impl const Tr for ConstImpl { + fn required() {} +} + +//@ has foo/struct.NonConstImpl.html +//@ has - '//*[@id="method.required"]' 'fn required()' +//@ !has - '//*[@id="method.required"]' 'const' +//@ has - '//*[@id="method.defaulted"]' 'fn defaulted()' +//@ !has - '//*[@id="method.defaulted"]' 'const' +impl Tr for NonConstImpl { + fn required() {} +} From 2b22d0f0d2b9d0d71025065db93058e34f846600 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Thu, 3 Jul 2025 09:17:48 -0700 Subject: [PATCH 20/62] Make __rust_alloc_error_handler_should_panic a function --- .../rustc_codegen_cranelift/src/allocator.rs | 41 +++++++++++------ compiler/rustc_codegen_gcc/src/allocator.rs | 44 +++++++++++++----- compiler/rustc_codegen_llvm/src/allocator.rs | 45 +++++++++++++++---- compiler/rustc_session/src/config.rs | 2 +- library/alloc/src/alloc.rs | 4 +- library/std/src/alloc.rs | 4 +- src/tools/miri/src/shims/extern_static.rs | 11 ----- src/tools/miri/src/shims/foreign_items.rs | 6 +++ .../miri/tests/pass/alloc-access-tracking.rs | 4 +- 9 files changed, 111 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index ffb932a3c38e..04f1129d87c1 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -84,19 +84,34 @@ fn codegen_inner( &mangle_internal_symbol(tcx, alloc_error_handler_name(alloc_error_handler_kind)), ); - let data_id = module - .declare_data( - &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), - Linkage::Export, - false, - false, - ) - .unwrap(); - let mut data = DataDescription::new(); - data.set_align(1); - let val = oom_strategy.should_panic(); - data.define(Box::new([val])); - module.define_data(data_id, &data).unwrap(); + { + let sig = Signature { + call_conv: module.target_config().default_call_conv, + params: vec![], + returns: vec![AbiParam::new(types::I8)], + }; + let func_id = module + .declare_function( + &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), + Linkage::Export, + &sig, + ) + .unwrap(); + let mut ctx = Context::new(); + ctx.func.signature = sig; + { + let mut func_ctx = FunctionBuilderContext::new(); + let mut bcx = FunctionBuilder::new(&mut ctx.func, &mut func_ctx); + + let block = bcx.create_block(); + bcx.switch_to_block(block); + let value = bcx.ins().iconst(types::I8, oom_strategy.should_panic() as i64); + bcx.ins().return_(&[value]); + bcx.seal_all_blocks(); + bcx.finalize(); + } + module.define_function(func_id, &mut ctx).unwrap(); + } { let sig = Signature { diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index cf8aa500c778..0d8dc93274f9 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -1,6 +1,6 @@ -use gccjit::{Context, FunctionType, GlobalKind, ToRValue, Type}; #[cfg(feature = "master")] -use gccjit::{FnAttribute, VarAttribute}; +use gccjit::FnAttribute; +use gccjit::{Context, FunctionType, RValue, ToRValue, Type}; use rustc_ast::expand::allocator::{ ALLOCATOR_METHODS, AllocatorKind, AllocatorTy, NO_ALLOC_SHIM_IS_UNSTABLE, alloc_error_handler_name, default_fn_name, global_fn_name, @@ -71,15 +71,13 @@ pub(crate) unsafe fn codegen( None, ); - let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL); - let global = context.new_global(None, GlobalKind::Exported, i8, name); - #[cfg(feature = "master")] - global.add_attribute(VarAttribute::Visibility(symbol_visibility_to_gcc( - tcx.sess.default_visibility(), - ))); - let value = tcx.sess.opts.unstable_opts.oom.should_panic(); - let value = context.new_rvalue_from_int(i8, value as i32); - global.global_set_initializer_rvalue(value); + create_const_value_function( + tcx, + context, + &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), + i8, + context.new_rvalue_from_int(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as i32), + ); create_wrapper_function( tcx, @@ -91,6 +89,30 @@ pub(crate) unsafe fn codegen( ); } +fn create_const_value_function( + tcx: TyCtxt<'_>, + context: &Context<'_>, + name: &str, + output: Type<'_>, + value: RValue<'_>, +) { + let func = context.new_function(None, FunctionType::Exported, output, &[], name, false); + + #[cfg(feature = "master")] + func.add_attribute(FnAttribute::Visibility(symbol_visibility_to_gcc( + tcx.sess.default_visibility(), + ))); + + func.add_attribute(FnAttribute::AlwaysInline); + + if tcx.sess.must_emit_unwind_tables() { + // TODO(antoyo): emit unwind tables. + } + + let block = func.new_block("entry"); + block.end_with_return(None, value); +} + fn create_wrapper_function( tcx: TyCtxt<'_>, context: &Context<'_>, diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 9dca63cfc8d4..2b5090ed6dba 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -11,7 +11,7 @@ use rustc_symbol_mangling::mangle_internal_symbol; use crate::builder::SBuilder; use crate::declare::declare_simple_fn; -use crate::llvm::{self, False, True, Type}; +use crate::llvm::{self, False, True, Type, Value}; use crate::{SimpleCx, attributes, debuginfo}; pub(crate) unsafe fn codegen( @@ -73,13 +73,14 @@ pub(crate) unsafe fn codegen( ); unsafe { - // __rust_alloc_error_handler_should_panic - let name = mangle_internal_symbol(tcx, OomStrategy::SYMBOL); - let ll_g = cx.declare_global(&name, i8); - llvm::set_visibility(ll_g, llvm::Visibility::from_generic(tcx.sess.default_visibility())); - let val = tcx.sess.opts.unstable_opts.oom.should_panic(); - let llval = llvm::LLVMConstInt(i8, val as u64, False); - llvm::set_initializer(ll_g, llval); + // __rust_alloc_error_handler_should_panic_v2 + create_const_value_function( + tcx, + &cx, + &mangle_internal_symbol(tcx, OomStrategy::SYMBOL), + &i8, + &llvm::LLVMConstInt(i8, tcx.sess.opts.unstable_opts.oom.should_panic() as u64, False), + ); // __rust_no_alloc_shim_is_unstable_v2 create_wrapper_function( @@ -100,6 +101,34 @@ pub(crate) unsafe fn codegen( } } +fn create_const_value_function( + tcx: TyCtxt<'_>, + cx: &SimpleCx<'_>, + name: &str, + output: &Type, + value: &Value, +) { + let ty = cx.type_func(&[], output); + let llfn = declare_simple_fn( + &cx, + name, + llvm::CallConv::CCallConv, + llvm::UnnamedAddr::Global, + llvm::Visibility::from_generic(tcx.sess.default_visibility()), + ty, + ); + + attributes::apply_to_llfn( + llfn, + llvm::AttributePlace::Function, + &[llvm::AttributeKind::AlwaysInline.create_attr(cx.llcx)], + ); + + let llbb = unsafe { llvm::LLVMAppendBasicBlockInContext(cx.llcx, llfn, c"entry".as_ptr()) }; + let mut bx = SBuilder::build(&cx, llbb); + bx.ret(value); +} + fn create_wrapper_function( tcx: TyCtxt<'_>, cx: &SimpleCx<'_>, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 73bb0471c222..0639363febb7 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3340,7 +3340,7 @@ pub enum OomStrategy { } impl OomStrategy { - pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic"; + pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic_v2"; pub fn should_panic(self) -> u8 { match self { diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index b4176e9c1f4d..c9b98fa4e5a9 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -429,10 +429,10 @@ pub mod __alloc_error_handler { // This symbol is emitted by rustc next to __rust_alloc_error_handler. // Its value depends on the -Zoom={panic,abort} compiler option. #[rustc_std_internal_symbol] - static __rust_alloc_error_handler_should_panic: u8; + fn __rust_alloc_error_handler_should_panic_v2() -> u8; } - if unsafe { __rust_alloc_error_handler_should_panic != 0 } { + if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } { panic!("memory allocation of {size} bytes failed") } else { core::panicking::panic_nounwind_fmt( diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index b574e9f3a25e..1d61630269ac 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -349,10 +349,10 @@ fn default_alloc_error_hook(layout: Layout) { // This symbol is emitted by rustc next to __rust_alloc_error_handler. // Its value depends on the -Zoom={panic,abort} compiler option. #[rustc_std_internal_symbol] - static __rust_alloc_error_handler_should_panic: u8; + fn __rust_alloc_error_handler_should_panic_v2() -> u8; } - if unsafe { __rust_alloc_error_handler_should_panic != 0 } { + if unsafe { __rust_alloc_error_handler_should_panic_v2() != 0 } { panic!("memory allocation of {} bytes failed", layout.size()); } else { // This is the default path taken on OOM, and the only path taken on stable with std. diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs index a2ea3dbd88b1..f02a3f425d1c 100644 --- a/src/tools/miri/src/shims/extern_static.rs +++ b/src/tools/miri/src/shims/extern_static.rs @@ -1,7 +1,5 @@ //! Provides the `extern static` that this platform expects. -use rustc_symbol_mangling::mangle_internal_symbol; - use crate::*; impl<'tcx> MiriMachine<'tcx> { @@ -45,15 +43,6 @@ impl<'tcx> MiriMachine<'tcx> { /// Sets up the "extern statics" for this machine. pub fn init_extern_statics(ecx: &mut MiriInterpCx<'tcx>) -> InterpResult<'tcx> { - // "__rust_alloc_error_handler_should_panic" - let val = ecx.tcx.sess.opts.unstable_opts.oom.should_panic(); - let val = ImmTy::from_int(val, ecx.machine.layouts.u8); - Self::alloc_extern_static( - ecx, - &mangle_internal_symbol(*ecx.tcx, "__rust_alloc_error_handler_should_panic"), - val, - )?; - if ecx.target_os_is_unix() { // "environ" is mandated by POSIX. let environ = ecx.machine.env_vars.unix().environ(); diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 97070eb742f3..1b66735ddb18 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -615,6 +615,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // This is a no-op shim that only exists to prevent making the allocator shims instantly stable. let [] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?; } + name if name == this.mangle_internal_symbol("__rust_alloc_error_handler_should_panic_v2") => { + // Gets the value of the `oom` option. + let [] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?; + let val = this.tcx.sess.opts.unstable_opts.oom.should_panic(); + this.write_int(val, dest)?; + } // C memory handling functions "memcmp" => { diff --git a/src/tools/miri/tests/pass/alloc-access-tracking.rs b/src/tools/miri/tests/pass/alloc-access-tracking.rs index 9eba0ca171bc..b285250c8abd 100644 --- a/src/tools/miri/tests/pass/alloc-access-tracking.rs +++ b/src/tools/miri/tests/pass/alloc-access-tracking.rs @@ -1,7 +1,7 @@ #![no_std] #![no_main] -//@compile-flags: -Zmiri-track-alloc-id=19 -Zmiri-track-alloc-accesses -Cpanic=abort -//@normalize-stderr-test: "id 19" -> "id $$ALLOC" +//@compile-flags: -Zmiri-track-alloc-id=18 -Zmiri-track-alloc-accesses -Cpanic=abort +//@normalize-stderr-test: "id 18" -> "id $$ALLOC" //@only-target: linux # alloc IDs differ between OSes (due to extern static allocations) extern "Rust" { From 35453a854c4e7eabbfcc4ac4f0095b26ee890dc1 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Thu, 3 Jul 2025 21:34:22 +0300 Subject: [PATCH 21/62] Add tidy-alphabetical for cross-crate attribute match --- .../src/encode_cross_crate.rs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index a1b1d670cfe0..34638ff55405 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -12,39 +12,41 @@ impl AttributeKind { use EncodeCrossCrate::*; match self { + // tidy-alphabetical-start Align { .. } => No, AllowConstFnUnstable(..) => No, AllowInternalUnstable(..) => Yes, AsPtr(..) => Yes, BodyStability { .. } => No, + Cold(..) => No, Confusables { .. } => Yes, + ConstContinue(..) => No, ConstStability { .. } => Yes, ConstStabilityIndirect => No, Deprecation { .. } => Yes, DocComment { .. } => Yes, ExportName { .. } => Yes, Inline(..) => No, - LinkSection { .. } => No, - MacroTransparency(..) => Yes, - Repr(..) => No, - Stability { .. } => Yes, - Cold(..) => No, - ConstContinue(..) => No, LinkName { .. } => Yes, + LinkSection { .. } => No, LoopMatch(..) => No, + MacroTransparency(..) => Yes, MayDangle(..) => No, MustUse { .. } => Yes, Naked(..) => No, NoMangle(..) => No, Optimize(..) => No, PubTransparent(..) => Yes, + Repr(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, RustcLayoutScalarValidRangeStart(..) => Yes, RustcObjectLifetimeDefault => No, SkipDuringMethodDispatch { .. } => No, + Stability { .. } => Yes, TargetFeature(..) => No, TrackCaller(..) => Yes, Used { .. } => No, + // tidy-alphabetical-end } } } From fee5e3c3aa643ab9d73b4b4c45f336c734688f60 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Mon, 30 Jun 2025 16:07:14 +0200 Subject: [PATCH 22/62] Port `#[no_implicit_prelude]` to the new attribute parsing infrastructure Signed-off-by: Jonathan Brouwer --- .../src/attributes.rs | 3 ++ .../src/encode_cross_crate.rs | 1 + .../rustc_attr_parsing/src/attributes/mod.rs | 1 + .../src/attributes/no_implicit_prelude.rs | 13 ++++++ compiler/rustc_attr_parsing/src/context.rs | 2 + compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 43 +++++++++++++++---- tests/ui/attributes/malformed-attrs.stderr | 15 ++++--- .../lint/unused/unused-attr-duplicate.stderr | 24 +++++------ 9 files changed, 77 insertions(+), 26 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 61ef31b8f9f4..1fafc97008e3 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -278,6 +278,9 @@ pub enum AttributeKind { /// Represents `#[naked]` Naked(Span), + /// Represents `#[no_implicit_prelude]` + NoImplicitPrelude(Span), + /// Represents `#[no_mangle]` NoMangle(Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index a1b1d670cfe0..a93ebbe97eed 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -35,6 +35,7 @@ impl AttributeKind { MayDangle(..) => No, MustUse { .. } => Yes, Naked(..) => No, + NoImplicitPrelude(..) => No, NoMangle(..) => No, Optimize(..) => No, PubTransparent(..) => Yes, diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 0215504b52b7..0898b44863a3 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -35,6 +35,7 @@ pub(crate) mod link_attrs; pub(crate) mod lint_helpers; pub(crate) mod loop_match; pub(crate) mod must_use; +pub(crate) mod no_implicit_prelude; pub(crate) mod repr; pub(crate) mod rustc_internal; pub(crate) mod semantics; diff --git a/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs b/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs new file mode 100644 index 000000000000..47cc925f7f6b --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/no_implicit_prelude.rs @@ -0,0 +1,13 @@ +use rustc_attr_data_structures::AttributeKind; +use rustc_span::{Span, sym}; + +use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; +use crate::context::Stage; + +pub(crate) struct NoImplicitPreludeParser; + +impl NoArgsAttributeParser for NoImplicitPreludeParser { + const PATH: &[rustc_span::Symbol] = &[sym::no_implicit_prelude]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoImplicitPrelude; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index bf8b1438df78..43b36b4c554e 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -26,6 +26,7 @@ use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser}; use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::must_use::MustUseParser; +use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; use crate::attributes::repr::{AlignParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, @@ -141,6 +142,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 4d64cdeb69ab..627e9aabd129 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -310,6 +310,7 @@ fn emit_malformed_attribute( | sym::link_section | sym::rustc_layout_scalar_valid_range_start | sym::rustc_layout_scalar_valid_range_end + | sym::no_implicit_prelude ) { return; } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 87d46e3e5069..7880e629e911 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -183,6 +183,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::Naked(attr_span)) => { self.check_naked(hir_id, *attr_span, span, target) } + Attribute::Parsed(AttributeKind::NoImplicitPrelude(attr_span)) => self + .check_generic_attr( + hir_id, + sym::no_implicit_prelude, + *attr_span, + target, + Target::Mod, + ), Attribute::Parsed(AttributeKind::TrackCaller(attr_span)) => { self.check_track_caller(hir_id, *attr_span, attrs, span, target) } @@ -289,16 +297,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::macro_use, ..] | [sym::macro_escape, ..] => { self.check_macro_use(hir_id, attr, target) } - [sym::path, ..] => self.check_generic_attr(hir_id, attr, target, Target::Mod), + [sym::path, ..] => self.check_generic_attr_unparsed(hir_id, attr, target, Target::Mod), [sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target), [sym::ignore, ..] | [sym::should_panic, ..] => { - self.check_generic_attr(hir_id, attr, target, Target::Fn) + self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn) } [sym::automatically_derived, ..] => { - self.check_generic_attr(hir_id, attr, target, Target::Impl) - } - [sym::no_implicit_prelude, ..] => { - self.check_generic_attr(hir_id, attr, target, Target::Mod) + self.check_generic_attr_unparsed(hir_id, attr, target, Target::Impl) } [sym::proc_macro, ..] => { self.check_proc_macro(hir_id, target, ProcMacroKind::FunctionLike) @@ -307,7 +312,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_proc_macro(hir_id, target, ProcMacroKind::Attribute); } [sym::proc_macro_derive, ..] => { - self.check_generic_attr(hir_id, attr, target, Target::Fn); + self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn); self.check_proc_macro(hir_id, target, ProcMacroKind::Derive) } [sym::autodiff_forward, ..] | [sym::autodiff_reverse, ..] => { @@ -616,7 +621,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_generic_attr( + /// FIXME: Remove when all attributes are ported to the new parser + fn check_generic_attr_unparsed( &self, hir_id: HirId, attr: &Attribute, @@ -639,6 +645,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } + fn check_generic_attr( + &self, + hir_id: HirId, + attr_name: Symbol, + attr_span: Span, + target: Target, + allowed_target: Target, + ) { + if target != allowed_target { + self.tcx.emit_node_span_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr_span, + errors::OnlyHasEffectOn { + attr_name: attr_name.to_string(), + target_name: allowed_target.name().replace(' ', "_"), + }, + ); + } + } + /// Checks if `#[naked]` is applied to a function definition. fn check_naked(&self, hir_id: HirId, attr_span: Span, span: Span, target: Target) { match target { diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index c65eff8a550e..bdebe155aba0 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -65,12 +65,6 @@ error: malformed `no_sanitize` attribute input LL | #[no_sanitize] | ^^^^^^^^^^^^^^ help: must be of the form: `#[no_sanitize(address, kcfi, memory, thread)]` -error: malformed `no_implicit_prelude` attribute input - --> $DIR/malformed-attrs.rs:96:1 - | -LL | #[no_implicit_prelude = 23] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[no_implicit_prelude]` - error: malformed `proc_macro` attribute input --> $DIR/malformed-attrs.rs:98:1 | @@ -514,6 +508,15 @@ error[E0539]: malformed `link_section` attribute input LL | #[link_section] | ^^^^^^^^^^^^^^^ help: must be of the form: `#[link_section = "name"]` +error[E0565]: malformed `no_implicit_prelude` attribute input + --> $DIR/malformed-attrs.rs:96:1 + | +LL | #[no_implicit_prelude = 23] + | ^^^^^^^^^^^^^^^^^^^^^^----^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[no_implicit_prelude]` + error[E0539]: malformed `must_use` attribute input --> $DIR/malformed-attrs.rs:118:1 | diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index feae8528cf7a..d9ceca2f29bd 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -140,18 +140,6 @@ note: attribute also specified here LL | #![no_std] | ^^^^^^^^^^ -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:25:1 - | -LL | #![no_implicit_prelude] - | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:24:1 - | -LL | #![no_implicit_prelude] - | ^^^^^^^^^^^^^^^^^^^^^^^ - error: unused attribute --> $DIR/unused-attr-duplicate.rs:27:1 | @@ -302,5 +290,17 @@ LL | #[link_section = ".bss"] | ^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:25:1 + | +LL | #![no_implicit_prelude] + | ^^^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:24:1 + | +LL | #![no_implicit_prelude] + | ^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 24 previous errors From 51857ade80c531c0ae0ee801dde5d425d13d38f8 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 3 Jul 2025 20:57:34 +0200 Subject: [PATCH 23/62] Always use the pure Rust fallback instead of `llvm.{maximum,minimum}` --- compiler/rustc_codegen_llvm/src/intrinsic.rs | 26 +++++++++++--------- library/core/src/num/f64.rs | 4 +-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 776658b9cca7..35922c100cd1 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -103,23 +103,25 @@ fn call_simple_intrinsic<'ll, 'tcx>( sym::minnumf64 => ("llvm.minnum", &[bx.type_f64()]), sym::minnumf128 => ("llvm.minnum", &[bx.type_f128()]), - sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]), - sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]), - sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]), - // There are issues on x86_64 and aarch64 with the f128 variant, - // let's instead use the intrinsic fallback body. - // sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]), + // FIXME: LLVM currently mis-compile those intrinsics, re-enable them + // when llvm/llvm-project#{139380,139381,140445} are fixed. + //sym::minimumf16 => ("llvm.minimum", &[bx.type_f16()]), + //sym::minimumf32 => ("llvm.minimum", &[bx.type_f32()]), + //sym::minimumf64 => ("llvm.minimum", &[bx.type_f64()]), + //sym::minimumf128 => ("llvm.minimum", &[cx.type_f128()]), + // sym::maxnumf16 => ("llvm.maxnum", &[bx.type_f16()]), sym::maxnumf32 => ("llvm.maxnum", &[bx.type_f32()]), sym::maxnumf64 => ("llvm.maxnum", &[bx.type_f64()]), sym::maxnumf128 => ("llvm.maxnum", &[bx.type_f128()]), - sym::maximumf16 => ("llvm.maximum", &[bx.type_f16()]), - sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]), - sym::maximumf64 => ("llvm.maximum", &[bx.type_f64()]), - // There are issues on x86_64 and aarch64 with the f128 variant, - // let's instead use the intrinsic fallback body. - // sym::maximumf128 => ("llvm.maximum", &[cx.type_f128()]), + // FIXME: LLVM currently mis-compile those intrinsics, re-enable them + // when llvm/llvm-project#{139380,139381,140445} are fixed. + //sym::maximumf16 => ("llvm.maximum", &[bx.type_f16()]), + //sym::maximumf32 => ("llvm.maximum", &[bx.type_f32()]), + //sym::maximumf64 => ("llvm.maximum", &[bx.type_f64()]), + //sym::maximumf128 => ("llvm.maximum", &[cx.type_f128()]), + // sym::copysignf16 => ("llvm.copysign", &[bx.type_f16()]), sym::copysignf32 => ("llvm.copysign", &[bx.type_f32()]), sym::copysignf64 => ("llvm.copysign", &[bx.type_f64()]), diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 93bfdbdd60b9..3cd079b84eb4 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -943,7 +943,7 @@ impl f64 { /// This returns NaN when *either* argument is NaN, as opposed to /// [`f64::max`] which only returns NaN when *both* arguments are NaN. /// - /// ```ignore-arm-unknown-linux-gnueabihf,ignore-i586 (see https://github.com/rust-lang/rust/issues/141087) + /// ``` /// #![feature(float_minimum_maximum)] /// let x = 1.0_f64; /// let y = 2.0_f64; @@ -970,7 +970,7 @@ impl f64 { /// This returns NaN when *either* argument is NaN, as opposed to /// [`f64::min`] which only returns NaN when *both* arguments are NaN. /// - /// ```ignore-arm-unknown-linux-gnueabihf,ignore-i586 (see https://github.com/rust-lang/rust/issues/141087) + /// ``` /// #![feature(float_minimum_maximum)] /// let x = 1.0_f64; /// let y = 2.0_f64; From e2e3f5809b079214c145afe74b2317e2cae720a9 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 3 Jul 2025 20:03:45 +0000 Subject: [PATCH 24/62] Remove PointerLike trait --- compiler/rustc_abi/src/layout/ty.rs | 12 +-- compiler/rustc_hir/src/lang_items.rs | 2 - .../src/coherence/builtin.rs | 99 ------------------- compiler/rustc_middle/src/ty/mod.rs | 14 ++- compiler/rustc_span/src/symbol.rs | 1 - .../src/traits/select/confirmation.rs | 79 +-------------- library/alloc/src/boxed.rs | 5 +- library/alloc/src/lib.rs | 1 - library/core/src/cell.rs | 11 +-- library/core/src/marker.rs | 31 ------ library/core/src/pin/unsafe_pinned.rs | 6 +- library/core/src/ptr/non_null.rs | 3 - tests/ui/traits/next-solver/pointer-like.rs | 14 --- .../ui/traits/next-solver/pointer-like.stderr | 24 ----- 14 files changed, 14 insertions(+), 288 deletions(-) delete mode 100644 tests/ui/traits/next-solver/pointer-like.rs delete mode 100644 tests/ui/traits/next-solver/pointer-like.stderr diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 18f0750aaa1f..8d3c10fd770a 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -6,7 +6,7 @@ use rustc_macros::HashStable_Generic; use crate::{ AbiAlign, Align, BackendRepr, FieldsShape, Float, HasDataLayout, LayoutData, Niche, - PointeeInfo, Primitive, Scalar, Size, TargetDataLayout, Variants, + PointeeInfo, Primitive, Size, Variants, }; // Explicitly import `Float` to avoid ambiguity with `Primitive::Float`. @@ -115,16 +115,6 @@ impl<'a> Layout<'a> { pub fn unadjusted_abi_align(self) -> Align { self.0.0.unadjusted_abi_align } - - /// Whether the layout is from a type that implements [`std::marker::PointerLike`]. - /// - /// Currently, that means that the type is pointer-sized, pointer-aligned, - /// and has a initialized (non-union), scalar ABI. - pub fn is_pointer_like(self, data_layout: &TargetDataLayout) -> bool { - self.size() == data_layout.pointer_size - && self.align().abi == data_layout.pointer_align.abi - && matches!(self.backend_repr(), BackendRepr::Scalar(Scalar::Initialized { .. })) - } } /// The layout of a type, alongside the type itself. diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 10dd5ff9aa76..c11db63ba11f 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -367,8 +367,6 @@ language_item_table! { TryTraitBranch, sym::branch, branch_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; TryTraitFromYeet, sym::from_yeet, from_yeet_fn, Target::Fn, GenericRequirement::None; - PointerLike, sym::pointer_like, pointer_like, Target::Trait, GenericRequirement::Exact(0); - CoercePointeeValidated, sym::coerce_pointee_validated, coerce_pointee_validated_trait, Target::Trait, GenericRequirement::Exact(0); ConstParamTy, sym::const_param_ty, const_param_ty_trait, Target::Trait, GenericRequirement::Exact(0); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 734c9c58c08a..65bc441a473e 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -47,7 +47,6 @@ pub(super) fn check_trait<'tcx>( checker.check(lang_items.coerce_unsized_trait(), visit_implementation_of_coerce_unsized)?; checker .check(lang_items.dispatch_from_dyn_trait(), visit_implementation_of_dispatch_from_dyn)?; - checker.check(lang_items.pointer_like(), visit_implementation_of_pointer_like)?; checker.check( lang_items.coerce_pointee_validated_trait(), visit_implementation_of_coerce_pointee_validity, @@ -707,104 +706,6 @@ fn infringing_fields_error<'tcx>( err.emit() } -fn visit_implementation_of_pointer_like(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> { - let tcx = checker.tcx; - let typing_env = ty::TypingEnv::non_body_analysis(tcx, checker.impl_def_id); - let impl_span = tcx.def_span(checker.impl_def_id); - let self_ty = tcx.impl_trait_ref(checker.impl_def_id).unwrap().instantiate_identity().self_ty(); - - let is_permitted_primitive = match *self_ty.kind() { - ty::Adt(def, _) => def.is_box(), - ty::Uint(..) | ty::Int(..) | ty::RawPtr(..) | ty::Ref(..) | ty::FnPtr(..) => true, - _ => false, - }; - - if is_permitted_primitive - && let Ok(layout) = tcx.layout_of(typing_env.as_query_input(self_ty)) - && layout.layout.is_pointer_like(&tcx.data_layout) - { - return Ok(()); - } - - let why_disqualified = match *self_ty.kind() { - // If an ADT is repr(transparent) - ty::Adt(self_ty_def, args) => { - if self_ty_def.repr().transparent() { - // FIXME(compiler-errors): This should and could be deduplicated into a query. - // Find the nontrivial field. - let adt_typing_env = ty::TypingEnv::non_body_analysis(tcx, self_ty_def.did()); - let nontrivial_field = self_ty_def.all_fields().find(|field_def| { - let field_ty = tcx.type_of(field_def.did).instantiate_identity(); - !tcx.layout_of(adt_typing_env.as_query_input(field_ty)) - .is_ok_and(|layout| layout.layout.is_1zst()) - }); - - if let Some(nontrivial_field) = nontrivial_field { - // Check that the nontrivial field implements `PointerLike`. - let nontrivial_field_ty = nontrivial_field.ty(tcx, args); - let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env); - let ocx = ObligationCtxt::new(&infcx); - ocx.register_bound( - ObligationCause::misc(impl_span, checker.impl_def_id), - param_env, - nontrivial_field_ty, - tcx.require_lang_item(LangItem::PointerLike, impl_span), - ); - // FIXME(dyn-star): We should regionck this implementation. - if ocx.select_all_or_error().is_empty() { - return Ok(()); - } else { - format!( - "the field `{field_name}` of {descr} `{self_ty}` \ - does not implement `PointerLike`", - field_name = nontrivial_field.name, - descr = self_ty_def.descr() - ) - } - } else { - format!( - "the {descr} `{self_ty}` is `repr(transparent)`, \ - but does not have a non-trivial field (it is zero-sized)", - descr = self_ty_def.descr() - ) - } - } else if self_ty_def.is_box() { - // If we got here, then the `layout.is_pointer_like()` check failed - // and this box is not a thin pointer. - - String::from("boxes of dynamically-sized types are too large to be `PointerLike`") - } else { - format!( - "the {descr} `{self_ty}` is not `repr(transparent)`", - descr = self_ty_def.descr() - ) - } - } - ty::Ref(..) => { - // If we got here, then the `layout.is_pointer_like()` check failed - // and this reference is not a thin pointer. - String::from("references to dynamically-sized types are too large to be `PointerLike`") - } - ty::Dynamic(..) | ty::Foreign(..) => { - String::from("types of dynamic or unknown size may not implement `PointerLike`") - } - _ => { - // This is a white lie; it is true everywhere outside the standard library. - format!("only user-defined sized types are eligible for `impl PointerLike`") - } - }; - - Err(tcx - .dcx() - .struct_span_err( - impl_span, - "implementation must be applied to type that has the same ABI as a pointer, \ - or is `repr(transparent)` and whose field is `PointerLike`", - ) - .with_note(why_disqualified) - .emit()) -} - fn visit_implementation_of_coerce_pointee_validity( checker: &Checker<'_>, ) -> Result<(), ErrorGuaranteed> { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 84b21fee92fe..3ba3bc1bbe68 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1149,12 +1149,16 @@ impl<'tcx> TypingEnv<'tcx> { { // FIXME(#132279): We should assert that the value does not contain any placeholders // as these placeholders are also local to the current inference context. However, we - // currently use pseudo-canonical queries in the trait solver which replaces params with - // placeholders. We should also simply not use pseudo-canonical queries in the trait - // solver, at which point we can readd this assert. As of writing this comment, this is - // only used by `fn layout_is_pointer_like` when calling `layout_of`. + // currently use pseudo-canonical queries in the trait solver, which replaces params + // with placeholders during canonicalization. We should also simply not use pseudo- + // canonical queries in the trait solver, at which point we can readd this assert. // - // debug_assert!(!value.has_placeholders()); + // As of writing this comment, this is only used when normalizing consts that mention + // params. + /* debug_assert!( + !value.has_placeholders(), + "{value:?} which has placeholder shouldn't be pseudo-canonicalized" + ); */ PseudoCanonicalInput { typing_env: self, value } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d6537d49be77..09f01d8704e2 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1623,7 +1623,6 @@ symbols! { pointee_sized, pointee_trait, pointer, - pointer_like, poll, poll_next, position, diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 3a369f13e790..a6b77583fdcd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -14,9 +14,7 @@ use rustc_hir::lang_items::LangItem; use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData}; -use rustc_middle::ty::{ - self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Upcast, elaborate, -}; +use rustc_middle::ty::{self, GenericArgsRef, Region, SizedTraitKind, Ty, TyCtxt, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; use thin_vec::thin_vec; @@ -1147,38 +1145,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::ClauseKind::TypeOutlives(outlives).upcast(tcx), )); - // Require that all AFIT will return something that can be coerced into `dyn*` - // -- a shim will be responsible for doing the actual coercion to `dyn*`. - if let Some(principal) = data.principal() { - for supertrait in - elaborate::supertraits(tcx, principal.with_self_ty(tcx, source)) - { - if tcx.is_trait_alias(supertrait.def_id()) { - continue; - } - - for &assoc_item in tcx.associated_item_def_ids(supertrait.def_id()) { - if !tcx.is_impl_trait_in_trait(assoc_item) { - continue; - } - - // RPITITs with `Self: Sized` don't need to be checked. - if tcx.generics_require_sized_self(assoc_item) { - continue; - } - - let pointer_like_goal = pointer_like_goal_for_rpitit( - tcx, - supertrait, - assoc_item, - &obligation.cause, - ); - - nested.push(predicate_to_obligation(pointer_like_goal.upcast(tcx))); - } - } - } - ImplSource::Builtin(BuiltinImplSource::Misc, nested) } @@ -1344,46 +1310,3 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ImplSource::Builtin(BuiltinImplSource::Misc, obligations) } } - -/// Compute a goal that some RPITIT (right now, only RPITITs corresponding to Futures) -/// implements the `PointerLike` trait, which is a requirement for the RPITIT to be -/// coercible to `dyn* Future`, which is itself a requirement for the RPITIT's parent -/// trait to be coercible to `dyn Trait`. -/// -/// We do this given a supertrait's substitutions, and then augment the substitutions -/// with bound variables to compute the goal universally. Given that `PointerLike` has -/// no region requirements (at least for the built-in pointer types), this shouldn't -/// *really* matter, but it is the best choice for soundness. -fn pointer_like_goal_for_rpitit<'tcx>( - tcx: TyCtxt<'tcx>, - supertrait: ty::PolyTraitRef<'tcx>, - rpitit_item: DefId, - cause: &ObligationCause<'tcx>, -) -> ty::PolyTraitRef<'tcx> { - let mut bound_vars = supertrait.bound_vars().to_vec(); - - let args = supertrait.skip_binder().args.extend_to(tcx, rpitit_item, |arg, _| match arg.kind { - ty::GenericParamDefKind::Lifetime => { - let kind = ty::BoundRegionKind::Named(arg.def_id, tcx.item_name(arg.def_id)); - bound_vars.push(ty::BoundVariableKind::Region(kind)); - ty::Region::new_bound( - tcx, - ty::INNERMOST, - ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind }, - ) - .into() - } - ty::GenericParamDefKind::Type { .. } | ty::GenericParamDefKind::Const { .. } => { - unreachable!() - } - }); - - ty::Binder::bind_with_vars( - ty::TraitRef::new( - tcx, - tcx.require_lang_item(LangItem::PointerLike, cause.span), - [Ty::new_projection_from_args(tcx, rpitit_item, args)], - ), - tcx.mk_bound_variable_kinds(&bound_vars), - ) -} diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 4e3f76de49e9..3db37f1d16f3 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -191,7 +191,7 @@ use core::error::{self, Error}; use core::fmt; use core::future::Future; use core::hash::{Hash, Hasher}; -use core::marker::{PointerLike, Tuple, Unsize}; +use core::marker::{Tuple, Unsize}; use core::mem::{self, SizedTypeProperties}; use core::ops::{ AsyncFn, AsyncFnMut, AsyncFnOnce, CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, @@ -2132,6 +2132,3 @@ impl Error for Box { Error::provide(&**self, request); } } - -#[unstable(feature = "pointer_like_trait", issue = "none")] -impl PointerLike for Box {} diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index f416732a8d63..4290bb7a8a93 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -134,7 +134,6 @@ #![feature(panic_internals)] #![feature(pattern)] #![feature(pin_coerce_unsized_trait)] -#![feature(pointer_like_trait)] #![feature(ptr_alignment_type)] #![feature(ptr_internals)] #![feature(ptr_metadata)] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 7ce03e3d8319..dfed8a00b7d7 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -252,7 +252,7 @@ use crate::cmp::Ordering; use crate::fmt::{self, Debug, Display}; -use crate::marker::{PhantomData, PointerLike, Unsize}; +use crate::marker::{PhantomData, Unsize}; use crate::mem; use crate::ops::{CoerceUnsized, Deref, DerefMut, DerefPure, DispatchFromDyn}; use crate::panic::const_panic; @@ -669,9 +669,6 @@ impl, U> CoerceUnsized> for Cell {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl, U> DispatchFromDyn> for Cell {} -#[unstable(feature = "pointer_like_trait", issue = "none")] -impl PointerLike for Cell {} - impl Cell<[T]> { /// Returns a `&[Cell]` from a `&Cell<[T]>` /// @@ -2361,9 +2358,6 @@ impl, U> CoerceUnsized> for UnsafeCell {} #[unstable(feature = "dispatch_from_dyn", issue = "none")] impl, U> DispatchFromDyn> for UnsafeCell {} -#[unstable(feature = "pointer_like_trait", issue = "none")] -impl PointerLike for UnsafeCell {} - /// [`UnsafeCell`], but [`Sync`]. /// /// This is just an `UnsafeCell`, except it implements `Sync` @@ -2470,9 +2464,6 @@ impl, U> CoerceUnsized> for SyncUnsafeCell //#[unstable(feature = "sync_unsafe_cell", issue = "95439")] impl, U> DispatchFromDyn> for SyncUnsafeCell {} -#[unstable(feature = "pointer_like_trait", issue = "none")] -impl PointerLike for SyncUnsafeCell {} - #[allow(unused)] fn assert_coerce_unsized( a: UnsafeCell<&i32>, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 67f95a02af3c..ccbd2b00cfd1 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -1066,37 +1066,6 @@ pub trait Destruct {} #[rustc_do_not_implement_via_object] pub trait Tuple {} -/// A marker for pointer-like types. -/// -/// This trait can only be implemented for types that are certain to have -/// the same size and alignment as a [`usize`] or [`*const ()`](pointer). -/// To ensure this, there are special requirements on implementations -/// of `PointerLike` (other than the already-provided implementations -/// for built-in types): -/// -/// * The type must have `#[repr(transparent)]`. -/// * The type’s sole non-zero-sized field must itself implement `PointerLike`. -#[unstable(feature = "pointer_like_trait", issue = "none")] -#[lang = "pointer_like"] -#[diagnostic::on_unimplemented( - message = "`{Self}` needs to have the same ABI as a pointer", - label = "`{Self}` needs to be a pointer-like type" -)] -#[rustc_do_not_implement_via_object] -pub trait PointerLike {} - -marker_impls! { - #[unstable(feature = "pointer_like_trait", issue = "none")] - PointerLike for - isize, - usize, - {T} &T, - {T} &mut T, - {T} *const T, - {T} *mut T, - {T: PointerLike} crate::pin::Pin, -} - /// A marker for types which can be used as types of `const` generic parameters. /// /// These types must have a proper equivalence relation (`Eq`) and it must be automatically diff --git a/library/core/src/pin/unsafe_pinned.rs b/library/core/src/pin/unsafe_pinned.rs index 17f7bcd306b0..b18b5d7c9ec0 100644 --- a/library/core/src/pin/unsafe_pinned.rs +++ b/library/core/src/pin/unsafe_pinned.rs @@ -1,5 +1,5 @@ use crate::cell::UnsafeCell; -use crate::marker::{PointerLike, Unpin}; +use crate::marker::Unpin; use crate::ops::{CoerceUnsized, DispatchFromDyn}; use crate::pin::Pin; use crate::{fmt, ptr}; @@ -178,8 +178,4 @@ impl, U> CoerceUnsized> for UnsafePinned // #[unstable(feature = "unsafe_pinned", issue = "125735")] impl, U> DispatchFromDyn> for UnsafePinned {} -#[unstable(feature = "pointer_like_trait", issue = "none")] -// #[unstable(feature = "unsafe_pinned", issue = "125735")] -impl PointerLike for UnsafePinned {} - // FIXME(unsafe_pinned): impl PinCoerceUnsized for UnsafePinned? diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index c26c3a32ef3a..c4ca29a36797 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1628,9 +1628,6 @@ impl DispatchFromDyn> for NonNull PinCoerceUnsized for NonNull {} -#[unstable(feature = "pointer_like_trait", issue = "none")] -impl core::marker::PointerLike for NonNull {} - #[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Debug for NonNull { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { diff --git a/tests/ui/traits/next-solver/pointer-like.rs b/tests/ui/traits/next-solver/pointer-like.rs deleted file mode 100644 index bdcad4d4c5eb..000000000000 --- a/tests/ui/traits/next-solver/pointer-like.rs +++ /dev/null @@ -1,14 +0,0 @@ -//@ compile-flags: -Znext-solver - -#![feature(pointer_like_trait)] - -use std::marker::PointerLike; - -fn require_(_: impl PointerLike) {} - -fn main() { - require_(1usize); - require_(1u16); - //~^ ERROR `u16` needs to have the same ABI as a pointer - require_(&1i16); -} diff --git a/tests/ui/traits/next-solver/pointer-like.stderr b/tests/ui/traits/next-solver/pointer-like.stderr deleted file mode 100644 index 4b624fd0d354..000000000000 --- a/tests/ui/traits/next-solver/pointer-like.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0277]: `u16` needs to have the same ABI as a pointer - --> $DIR/pointer-like.rs:11:14 - | -LL | require_(1u16); - | -------- ^^^^ the trait `PointerLike` is not implemented for `u16` - | | - | required by a bound introduced by this call - | - = note: the trait bound `u16: PointerLike` is not satisfied -note: required by a bound in `require_` - --> $DIR/pointer-like.rs:7:21 - | -LL | fn require_(_: impl PointerLike) {} - | ^^^^^^^^^^^ required by this bound in `require_` -help: consider borrowing here - | -LL | require_(&1u16); - | + -LL | require_(&mut 1u16); - | ++++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. From f5fbb2c0a5f2026453a3fa4c46afaaa2c0092e1f Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 3 Jul 2025 10:52:56 -0700 Subject: [PATCH 25/62] compiler: inline 1-2 query provide fn in hir_analysis and hir_typeck Many small indirections with 1-2 items actively hinders understanding. Inlines various tiny submodule provides into - hir_analysis::provide - hir_analysis::check::provide - hir_typeck::provide --- compiler/rustc_hir_analysis/src/check/mod.rs | 2 ++ compiler/rustc_hir_analysis/src/check/wfcheck.rs | 12 +++++------- compiler/rustc_hir_analysis/src/check_unused.rs | 7 +------ compiler/rustc_hir_analysis/src/hir_wf_check.rs | 7 +------ compiler/rustc_hir_analysis/src/lib.rs | 10 ++++++---- compiler/rustc_hir_analysis/src/outlives/mod.rs | 12 +++++------- compiler/rustc_hir_analysis/src/variance/mod.rs | 9 ++------- compiler/rustc_hir_typeck/src/lib.rs | 8 ++++++-- compiler/rustc_hir_typeck/src/method/mod.rs | 5 ----- compiler/rustc_hir_typeck/src/method/probe.rs | 7 +------ 10 files changed, 29 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index 5cec3331bb19..c9c218a79dbf 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -109,6 +109,8 @@ pub fn provide(providers: &mut Providers) { collect_return_position_impl_trait_in_trait_tys, compare_impl_item: compare_impl_item::compare_impl_item, check_coroutine_obligations: check::check_coroutine_obligations, + check_type_wf: wfcheck::check_type_wf, + check_well_formed: wfcheck::check_well_formed, ..*providers }; } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index ed8d25e9915c..4934136bc7af 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -15,7 +15,6 @@ use rustc_infer::infer::{self, InferCtxt, SubregionOrigin, TyCtxtInferExt}; use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION; use rustc_macros::LintDiagnostic; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::query::Providers; use rustc_middle::traits::solve::NoSolution; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ @@ -189,7 +188,10 @@ where } } -fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { +pub(super) fn check_well_formed( + tcx: TyCtxt<'_>, + def_id: LocalDefId, +) -> Result<(), ErrorGuaranteed> { let mut res = crate::check::check::check_item_type(tcx, def_id); for param in &tcx.generics_of(def_id).own_params { @@ -2249,7 +2251,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { } } -fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> { +pub(super) fn check_type_wf(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> { let items = tcx.hir_crate_items(()); let res = items .par_items(|item| tcx.ensure_ok().check_well_formed(item.owner_id.def_id)) @@ -2397,7 +2399,3 @@ struct RedundantLifetimeArgsLint<'tcx> { // The lifetime we can replace the victim with. candidate: ty::Region<'tcx>, } - -pub fn provide(providers: &mut Providers) { - *providers = Providers { check_type_wf, check_well_formed, ..*providers }; -} diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs index 464ffa8711a5..0133b1e8fcd3 100644 --- a/compiler/rustc_hir_analysis/src/check_unused.rs +++ b/compiler/rustc_hir_analysis/src/check_unused.rs @@ -1,16 +1,11 @@ use rustc_data_structures::unord::{ExtendUnord, UnordSet}; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_middle::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint; use tracing::debug; -pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { check_unused_traits, ..*providers }; -} - -fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { +pub(super) fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) { let mut used_trait_imports = UnordSet::::default(); // FIXME: Use `tcx.hir_par_body_owners()` when we implement creating `DefId`s diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index fef0dbf2ece9..bf539dfab42a 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -4,7 +4,6 @@ use rustc_hir::{self as hir, AmbigArg, ForeignItem, ForeignItemKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ObligationCause, ObligationCauseCode, WellFormedLoc}; use rustc_middle::bug; -use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode, fold_regions}; use rustc_span::def_id::LocalDefId; use rustc_trait_selection::traits::{self, ObligationCtxt}; @@ -12,13 +11,9 @@ use tracing::debug; use crate::collect::ItemCtxt; -pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { diagnostic_hir_wf_check, ..*providers }; -} - // Ideally, this would be in `rustc_trait_selection`, but we // need access to `ItemCtxt` -fn diagnostic_hir_wf_check<'tcx>( +pub(super) fn diagnostic_hir_wf_check<'tcx>( tcx: TyCtxt<'tcx>, (predicate, loc): (ty::Predicate<'tcx>, WellFormedLoc), ) -> Option> { diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 2ff7caef732a..19decfeff857 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -154,14 +154,16 @@ pub fn provide(providers: &mut Providers) { collect::provide(providers); coherence::provide(providers); check::provide(providers); - check_unused::provide(providers); - variance::provide(providers); - outlives::provide(providers); - hir_wf_check::provide(providers); *providers = Providers { + check_unused_traits: check_unused::check_unused_traits, + diagnostic_hir_wf_check: hir_wf_check::diagnostic_hir_wf_check, + inferred_outlives_crate: outlives::inferred_outlives_crate, + inferred_outlives_of: outlives::inferred_outlives_of, inherit_sig_for_delegation_item: delegation::inherit_sig_for_delegation_item, enforce_impl_non_lifetime_params_are_constrained: impl_wf_check::enforce_impl_non_lifetime_params_are_constrained, + crate_variances: variance::crate_variances, + variances_of: variance::variances_of, ..*providers }; } diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index 499f5572f470..d155f4f98ad7 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -1,6 +1,5 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; -use rustc_middle::query::Providers; use rustc_middle::ty::{self, CratePredicatesMap, GenericArgKind, TyCtxt, Upcast}; use rustc_span::Span; @@ -9,11 +8,10 @@ mod explicit; mod implicit_infer; mod utils; -pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { inferred_outlives_of, inferred_outlives_crate, ..*providers }; -} - -fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clause<'_>, Span)] { +pub(super) fn inferred_outlives_of( + tcx: TyCtxt<'_>, + item_def_id: LocalDefId, +) -> &[(ty::Clause<'_>, Span)] { match tcx.def_kind(item_def_id) { DefKind::Struct | DefKind::Enum | DefKind::Union => { let crate_map = tcx.inferred_outlives_crate(()); @@ -48,7 +46,7 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[(ty::Clau } } -fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { +pub(super) fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { // Compute a map from each ADT (struct/enum/union) and lazy type alias to // the **explicit** outlives predicates (`T: 'a`, `'a: 'b`) that the user wrote. // Typically there won't be many of these, except in older code where diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index dbba45dc7bb5..0666b335e093 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -8,7 +8,6 @@ use rustc_arena::DroplessArena; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_middle::query::Providers; use rustc_middle::span_bug; use rustc_middle::ty::{ self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, @@ -27,18 +26,14 @@ mod solve; pub(crate) mod dump; -pub(crate) fn provide(providers: &mut Providers) { - *providers = Providers { variances_of, crate_variances, ..*providers }; -} - -fn crate_variances(tcx: TyCtxt<'_>, (): ()) -> CrateVariancesMap<'_> { +pub(super) fn crate_variances(tcx: TyCtxt<'_>, (): ()) -> CrateVariancesMap<'_> { let arena = DroplessArena::default(); let terms_cx = terms::determine_parameters_to_be_inferred(tcx, &arena); let constraints_cx = constraints::add_constraints_from_crate(terms_cx); solve::solve_constraints(constraints_cx) } -fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] { +pub(super) fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] { // Skip items with no generics - there's nothing to infer in them. if tcx.generics_of(item_def_id).is_empty() { return &[]; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 1cc618e2aeec..eae6c2e8ed85 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -537,6 +537,10 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! { } pub fn provide(providers: &mut Providers) { - method::provide(providers); - *providers = Providers { typeck, used_trait_imports, ..*providers }; + *providers = Providers { + method_autoderef_steps: method::probe::method_autoderef_steps, + typeck, + used_trait_imports, + ..*providers + }; } diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 085e7a2f5df1..b6a57ba75891 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -13,7 +13,6 @@ use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def_id::DefId; use rustc_infer::infer::{BoundRegionConversionTime, InferOk}; use rustc_infer::traits::PredicateObligations; -use rustc_middle::query::Providers; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TypeVisitableExt, @@ -28,10 +27,6 @@ pub(crate) use self::MethodError::*; use self::probe::{IsSuggestion, ProbeScope}; use crate::FnCtxt; -pub(crate) fn provide(providers: &mut Providers) { - probe::provide(providers); -} - #[derive(Clone, Copy, Debug)] pub(crate) struct MethodCallee<'tcx> { /// Impl method ID, for inherent methods, or trait method ID, otherwise. diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index be0eb13cace6..94c93e736274 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -15,7 +15,6 @@ use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryRespons use rustc_infer::infer::{BoundRegionConversionTime, DefineOpaqueTypes, InferOk, TyCtxtInferExt}; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::middle::stability; -use rustc_middle::query::Providers; use rustc_middle::ty::elaborate::supertrait_def_ids; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, simplify_type}; use rustc_middle::ty::{ @@ -554,11 +553,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } -pub(crate) fn provide(providers: &mut Providers) { - providers.method_autoderef_steps = method_autoderef_steps; -} - -fn method_autoderef_steps<'tcx>( +pub(crate) fn method_autoderef_steps<'tcx>( tcx: TyCtxt<'tcx>, goal: CanonicalTyGoal<'tcx>, ) -> MethodAutoderefStepsResult<'tcx> { From 3b7f9f9d1b75cb98d8bd09cdedf2ded13283abf8 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 3 Jul 2025 10:59:14 -0700 Subject: [PATCH 26/62] compiler: document all provide fn in hir_analysis and hir_typeck --- compiler/rustc_hir_analysis/src/check/mod.rs | 4 ++-- compiler/rustc_hir_analysis/src/coherence/mod.rs | 1 + compiler/rustc_hir_analysis/src/collect.rs | 1 + compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs | 1 + compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_hir_typeck/src/lib.rs | 1 + 6 files changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs index c9c218a79dbf..b2cfab37c1f6 100644 --- a/compiler/rustc_hir_analysis/src/check/mod.rs +++ b/compiler/rustc_hir_analysis/src/check/mod.rs @@ -100,8 +100,8 @@ use self::compare_impl_item::collect_return_position_impl_trait_in_trait_tys; use self::region::region_scope_tree; use crate::{errors, require_c_abi_if_c_variadic}; -pub fn provide(providers: &mut Providers) { - wfcheck::provide(providers); +/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`] +pub(super) fn provide(providers: &mut Providers) { *providers = Providers { adt_destructor, adt_async_destructor, diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 16bac4304910..ed8f78216ff2 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -130,6 +130,7 @@ fn enforce_empty_impls_for_marker_traits( .emit()) } +/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`]. pub(crate) fn provide(providers: &mut Providers) { use self::builtin::coerce_unsized_info; use self::inherent_impls::{ diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index b10d5b55789b..aad9b08b2a3a 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -61,6 +61,7 @@ mod type_of; /////////////////////////////////////////////////////////////////////////// +/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`] pub(crate) fn provide(providers: &mut Providers) { resolve_bound_vars::provide(providers); *providers = Providers { 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 95743f9a63eb..0e775d374ab4 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -222,6 +222,7 @@ enum BinderScopeType { type ScopeRef<'a> = &'a Scope<'a>; +/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`] pub(crate) fn provide(providers: &mut Providers) { *providers = Providers { resolve_bound_vars, diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 19decfeff857..3a153ab089a4 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -150,6 +150,7 @@ fn require_c_abi_if_c_variadic( .emit(); } +/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`] pub fn provide(providers: &mut Providers) { collect::provide(providers); coherence::provide(providers); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index eae6c2e8ed85..ea8c2c6ce23a 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -536,6 +536,7 @@ fn fatally_break_rust(tcx: TyCtxt<'_>, span: Span) -> ! { diag.emit() } +/// Adds query implementations to the [Providers] vtable, see [`rustc_middle::query`] pub fn provide(providers: &mut Providers) { *providers = Providers { method_autoderef_steps: method::probe::method_autoderef_steps, From ef4dece2cb52dd14dc4f37a8484fa440a447da14 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sun, 15 Jun 2025 16:59:11 +0300 Subject: [PATCH 27/62] Port `#[rustc_pass_by_value]` to the new attribute system --- compiler/rustc_attr_data_structures/src/attributes.rs | 3 +++ .../rustc_attr_data_structures/src/encode_cross_crate.rs | 1 + .../rustc_attr_parsing/src/attributes/lint_helpers.rs | 7 +++++++ compiler/rustc_attr_parsing/src/context.rs | 3 ++- compiler/rustc_lint/src/pass_by_value.rs | 8 +++++--- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 8 +++++--- 7 files changed, 24 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 61ef31b8f9f4..1744d394b907 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -284,6 +284,9 @@ pub enum AttributeKind { /// Represents `#[optimize(size|speed)]` Optimize(OptimizeAttr, Span), + /// Represents `#[rustc_pass_by_value]` (used by the `rustc_pass_by_value` lint). + PassByValue(Span), + /// Represents `#[rustc_pub_transparent]` (used by the `repr_transparent_external_private_fields` lint). PubTransparent(Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 34638ff55405..af085bfc8ee4 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -36,6 +36,7 @@ impl AttributeKind { Naked(..) => No, NoMangle(..) => No, Optimize(..) => No, + PassByValue(..) => Yes, PubTransparent(..) => Yes, Repr(..) => No, RustcLayoutScalarValidRangeEnd(..) => Yes, diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs index 5437803d781d..8ad98c8d1d4a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -17,3 +17,10 @@ impl NoArgsAttributeParser for PubTransparentParser { const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; const CREATE: fn(Span) -> AttributeKind = AttributeKind::PubTransparent; } + +pub(crate) struct PassByValueParser; +impl NoArgsAttributeParser for PassByValueParser { + const PATH: &[Symbol] = &[sym::rustc_pass_by_value]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::PassByValue; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index bf8b1438df78..f060bef0ec59 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -23,7 +23,7 @@ use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; use crate::attributes::inline::{InlineParser, RustcForceInlineParser}; use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser}; -use crate::attributes::lint_helpers::{AsPtrParser, PubTransparentParser}; +use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::must_use::MustUseParser; use crate::attributes::repr::{AlignParser, ReprParser}; @@ -142,6 +142,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, // tidy-alphabetical-end diff --git a/compiler/rustc_lint/src/pass_by_value.rs b/compiler/rustc_lint/src/pass_by_value.rs index d85618f664d6..d3b3b55dd4c4 100644 --- a/compiler/rustc_lint/src/pass_by_value.rs +++ b/compiler/rustc_lint/src/pass_by_value.rs @@ -1,8 +1,8 @@ +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_hir::def::Res; use rustc_hir::{self as hir, AmbigArg, GenericArg, PathSegment, QPath, TyKind}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; -use rustc_span::sym; use crate::lints::PassByValueDiag; use crate::{LateContext, LateLintPass, LintContext}; @@ -45,14 +45,16 @@ impl<'tcx> LateLintPass<'tcx> for PassByValue { fn path_for_pass_by_value(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Option { if let TyKind::Path(QPath::Resolved(_, path)) = &ty.kind { match path.res { - Res::Def(_, def_id) if cx.tcx.has_attr(def_id, sym::rustc_pass_by_value) => { + Res::Def(_, def_id) + if find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::PassByValue(_)) => + { let name = cx.tcx.item_ident(def_id); let path_segment = path.segments.last().unwrap(); return Some(format!("{}{}", name, gen_args(cx, path_segment))); } Res::SelfTyAlias { alias_to: did, is_trait_impl: false, .. } => { if let ty::Adt(adt, args) = cx.tcx.type_of(did).instantiate_identity().kind() { - if cx.tcx.has_attr(adt.did(), sym::rustc_pass_by_value) { + if find_attr!(cx.tcx.get_all_attrs(adt.did()), AttributeKind::PassByValue(_)) { return Some(cx.tcx.def_path_str_with_args(adt.did(), args)); } } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 4d64cdeb69ab..1ca9ca842856 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -293,6 +293,7 @@ fn emit_malformed_attribute( | sym::rustc_force_inline | sym::rustc_confusables | sym::rustc_skip_during_method_dispatch + | sym::rustc_pass_by_value | sym::repr | sym::align | sym::deprecated diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 87d46e3e5069..7bcd893969e7 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -213,6 +213,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::Used { span: attr_span, .. }) => { self.check_used(*attr_span, target, span); } + &Attribute::Parsed(AttributeKind::PassByValue(attr_span)) => { + self.check_pass_by_value(attr_span, span, target) + } Attribute::Unparsed(attr_item) => { style = Some(attr_item.style); match attr.path().as_slice() { @@ -275,7 +278,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr.span(), span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), - [sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target), [sym::rustc_allow_incoherent_impl, ..] => { self.check_allow_incoherent_impl(attr, span, target) } @@ -1438,11 +1440,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Warns against some misuses of `#[pass_by_value]` - fn check_pass_by_value(&self, attr: &Attribute, span: Span, target: Target) { + fn check_pass_by_value(&self, attr_span: Span, span: Span, target: Target) { match target { Target::Struct | Target::Enum | Target::TyAlias => {} _ => { - self.dcx().emit_err(errors::PassByValue { attr_span: attr.span(), span }); + self.dcx().emit_err(errors::PassByValue { attr_span, span }); } } } From 90d54a1276e2061a3bbd547e0d422cf849a0511b Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Thu, 3 Jul 2025 15:30:30 -0700 Subject: [PATCH 28/62] adjust docs, after splitting up autodiff into two forward and reverse macros --- src/doc/rustc-dev-guide/src/autodiff/internals.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustc-dev-guide/src/autodiff/internals.md b/src/doc/rustc-dev-guide/src/autodiff/internals.md index 0093ef044c80..c1b31a0e4bd2 100644 --- a/src/doc/rustc-dev-guide/src/autodiff/internals.md +++ b/src/doc/rustc-dev-guide/src/autodiff/internals.md @@ -2,11 +2,11 @@ The `std::autodiff` module in Rust allows differentiable programming: ```rust #![feature(autodiff)] -use std::autodiff::autodiff; +use std::autodiff::*; // f(x) = x * x, f'(x) = 2.0 * x // bar therefore returns (x * x, 2.0 * x) -#[autodiff(bar, Reverse, Active, Active)] +#[autodiff_reverse(bar, Active, Active)] fn foo(x: f32) -> f32 { x * x } fn main() { From d0130ae186522d20e919e24ad43985428bf513e0 Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 5 May 2025 15:07:04 +0800 Subject: [PATCH 29/62] refactor: add `Tables<'tcx, B: Bridge>` and `SmirContainer` --- compiler/rustc_smir/src/rustc_internal/mod.rs | 155 +++--------------- compiler/rustc_smir/src/rustc_smir/mod.rs | 83 +++++++--- 2 files changed, 86 insertions(+), 152 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 2982a920b03d..871a6524f392 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -17,12 +17,12 @@ use rustc_span::Span; use rustc_span::def_id::{CrateNum, DefId}; use scoped_tls::scoped_thread_local; use stable_mir::Error; -use stable_mir::abi::Layout; use stable_mir::compiler_interface::SmirInterface; use stable_mir::ty::IndexedVal; use crate::rustc_smir::context::SmirCtxt; use crate::rustc_smir::{Stable, Tables}; +use crate::rustc_smir::{Bridge, SmirContainer, Tables}; use crate::stable_mir; mod internal; @@ -40,7 +40,7 @@ pub mod pretty; /// /// This function will panic if StableMIR has not been properly initialized. pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T { - with_tables(|tables| item.stable(tables)) + with_container(|tables, cx| item.stable(tables, cx)) } /// Convert a stable item into its internal Rust compiler counterpart, if one exists. @@ -54,137 +54,40 @@ pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T { /// # Panics /// /// This function will panic if StableMIR has not been properly initialized. -pub fn internal<'tcx, S>(tcx: TyCtxt<'tcx>, item: S) -> S::T<'tcx> +pub fn internal<'tcx, S>(item: S) -> S::T<'tcx> where S: RustcInternal, { - // The tcx argument ensures that the item won't outlive the type context. - with_tables(|tables| item.internal(tables, tcx)) + with_container(|tables, cx| item.internal(tables, cx)) } -impl<'tcx> Index for Tables<'tcx> { +impl<'tcx, B: Bridge> Index for Tables<'tcx, B> { type Output = DefId; #[inline(always)] - fn index(&self, index: stable_mir::DefId) -> &Self::Output { + fn index(&self, index: B::DefId) -> &Self::Output { &self.def_ids[index] } } -impl<'tcx> Index for Tables<'tcx> { - type Output = Span; - - #[inline(always)] - fn index(&self, index: stable_mir::ty::Span) -> &Self::Output { - &self.spans[index] - } -} - -impl<'tcx> Tables<'tcx> { - pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem { - stable_mir::CrateItem(self.create_def_id(did)) - } - - pub fn adt_def(&mut self, did: DefId) -> stable_mir::ty::AdtDef { - stable_mir::ty::AdtDef(self.create_def_id(did)) - } - - pub fn foreign_module_def(&mut self, did: DefId) -> stable_mir::ty::ForeignModuleDef { - stable_mir::ty::ForeignModuleDef(self.create_def_id(did)) - } - - pub fn foreign_def(&mut self, did: DefId) -> stable_mir::ty::ForeignDef { - stable_mir::ty::ForeignDef(self.create_def_id(did)) - } - - pub fn fn_def(&mut self, did: DefId) -> stable_mir::ty::FnDef { - stable_mir::ty::FnDef(self.create_def_id(did)) - } - - pub fn closure_def(&mut self, did: DefId) -> stable_mir::ty::ClosureDef { - stable_mir::ty::ClosureDef(self.create_def_id(did)) - } - - pub fn coroutine_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineDef { - stable_mir::ty::CoroutineDef(self.create_def_id(did)) - } - - pub fn coroutine_closure_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineClosureDef { - stable_mir::ty::CoroutineClosureDef(self.create_def_id(did)) - } - - pub fn alias_def(&mut self, did: DefId) -> stable_mir::ty::AliasDef { - stable_mir::ty::AliasDef(self.create_def_id(did)) - } - - pub fn param_def(&mut self, did: DefId) -> stable_mir::ty::ParamDef { - stable_mir::ty::ParamDef(self.create_def_id(did)) - } - - pub fn br_named_def(&mut self, did: DefId) -> stable_mir::ty::BrNamedDef { - stable_mir::ty::BrNamedDef(self.create_def_id(did)) - } - - pub fn trait_def(&mut self, did: DefId) -> stable_mir::ty::TraitDef { - stable_mir::ty::TraitDef(self.create_def_id(did)) - } - - pub fn generic_def(&mut self, did: DefId) -> stable_mir::ty::GenericDef { - stable_mir::ty::GenericDef(self.create_def_id(did)) - } - - pub fn const_def(&mut self, did: DefId) -> stable_mir::ty::ConstDef { - stable_mir::ty::ConstDef(self.create_def_id(did)) - } - - pub fn impl_def(&mut self, did: DefId) -> stable_mir::ty::ImplDef { - stable_mir::ty::ImplDef(self.create_def_id(did)) - } - - pub fn region_def(&mut self, did: DefId) -> stable_mir::ty::RegionDef { - stable_mir::ty::RegionDef(self.create_def_id(did)) - } - - pub fn coroutine_witness_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineWitnessDef { - stable_mir::ty::CoroutineWitnessDef(self.create_def_id(did)) - } - - pub fn assoc_def(&mut self, did: DefId) -> stable_mir::ty::AssocDef { - stable_mir::ty::AssocDef(self.create_def_id(did)) - } - - pub fn opaque_def(&mut self, did: DefId) -> stable_mir::ty::OpaqueDef { - stable_mir::ty::OpaqueDef(self.create_def_id(did)) - } - - pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov { - stable_mir::ty::Prov(self.create_alloc_id(aid)) - } - - pub(crate) fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId { +impl<'tcx, B: Bridge> Tables<'tcx, B> { + pub fn create_def_id(&mut self, did: DefId) -> B::DefId { self.def_ids.create_or_fetch(did) } - pub(crate) fn create_alloc_id(&mut self, aid: AllocId) -> stable_mir::mir::alloc::AllocId { + pub fn create_alloc_id(&mut self, aid: AllocId) -> B::AllocId { self.alloc_ids.create_or_fetch(aid) } - pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span { + pub fn create_span(&mut self, span: Span) -> B::Span { self.spans.create_or_fetch(span) } - pub(crate) fn instance_def( - &mut self, - instance: ty::Instance<'tcx>, - ) -> stable_mir::mir::mono::InstanceDef { + pub fn instance_def(&mut self, instance: ty::Instance<'tcx>) -> B::InstanceDef { self.instances.create_or_fetch(instance) } - pub(crate) fn static_def(&mut self, did: DefId) -> stable_mir::mir::mono::StaticDef { - stable_mir::mir::mono::StaticDef(self.create_def_id(did)) - } - - pub(crate) fn layout_id(&mut self, layout: rustc_abi::Layout<'tcx>) -> Layout { + pub fn layout_id(&mut self, layout: rustc_abi::Layout<'tcx>) -> B::Layout { self.layouts.create_or_fetch(layout) } } @@ -197,25 +100,28 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { // datastructures and stable MIR datastructures scoped_thread_local! (static TLV: Cell<*const ()>); -pub(crate) fn init<'tcx, F, T>(cx: &SmirCtxt<'tcx>, f: F) -> T +pub(crate) fn init<'tcx, F, T, B: Bridge>(container: &SmirContainer<'tcx, B>, f: F) -> T where F: FnOnce() -> T, { assert!(!TLV.is_set()); - let ptr = cx as *const _ as *const (); + let ptr = container as *const _ as *const (); TLV.set(&Cell::new(ptr), || f()) } /// Loads the current context and calls a function with it. /// Do not nest these, as that will ICE. -pub(crate) fn with_tables(f: impl for<'tcx> FnOnce(&mut Tables<'tcx>) -> R) -> R { +pub(crate) fn with_container<'tcx, R, B: Bridge>( + f: impl FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R, +) -> R { assert!(TLV.is_set()); TLV.with(|tlv| { let ptr = tlv.get(); assert!(!ptr.is_null()); - let context = ptr as *const SmirCtxt<'_>; - let mut tables = unsafe { (*context).0.borrow_mut() }; - f(&mut *tables) + let container = ptr as *const SmirContainer<'tcx, B>; + let mut tables = unsafe { (*container).tables.borrow_mut() }; + let cx = unsafe { (*container).cx.borrow() }; + f(&mut *tables, &*cx) }) } @@ -223,23 +129,10 @@ pub fn run(tcx: TyCtxt<'_>, f: F) -> Result where F: FnOnce() -> T, { - let tables = SmirCtxt(RefCell::new(Tables { - tcx, - def_ids: IndexMap::default(), - alloc_ids: IndexMap::default(), - spans: IndexMap::default(), - types: IndexMap::default(), - instances: IndexMap::default(), - ty_consts: IndexMap::default(), - mir_consts: IndexMap::default(), - layouts: IndexMap::default(), - })); + let smir_cx = RefCell::new(SmirCtxt::new(tcx)); + let container = SmirContainer { tables: RefCell::new(Tables::new(tcx)), cx: smir_cx }; - let interface = SmirInterface { cx: tables }; - - // Pass the `SmirInterface` to compiler_interface::run - // and initialize the rustc-specific TLS with tables. - stable_mir::compiler_interface::run(&interface, || init(&interface.cx, f)) + stable_mir::compiler_interface::run(&container, || init(&container, f)) } /// Instantiate and run the compiler with the provided arguments and callback. diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 26de9b0a4960..777e95a88d48 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,15 +9,15 @@ use std::marker::PointeeSized; use std::ops::RangeInclusive; +use std::cell::RefCell; +use std::fmt::Debug; +use context::SmirCtxt; use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::mir::interpret::AllocId; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use stable_mir::abi::Layout; -use stable_mir::mir::mono::{InstanceDef, StaticDef}; -use stable_mir::ty::{FnDef, MirConstId, Span, TyConstId}; use stable_mir::{CtorKind, ItemKind}; use tracing::debug; @@ -29,28 +29,50 @@ mod builder; pub mod context; mod convert; -pub struct Tables<'tcx> { - pub(crate) tcx: TyCtxt<'tcx>, - pub(crate) def_ids: IndexMap, - pub(crate) alloc_ids: IndexMap, - pub(crate) spans: IndexMap, - pub(crate) types: IndexMap, stable_mir::ty::Ty>, - pub(crate) instances: IndexMap, InstanceDef>, - pub(crate) ty_consts: IndexMap, TyConstId>, - pub(crate) mir_consts: IndexMap, MirConstId>, - pub(crate) layouts: IndexMap, Layout>, +/// A container which is used for TLS. +pub struct SmirContainer<'tcx, B: Bridge> { + pub tables: RefCell>, + pub cx: RefCell>, } -impl<'tcx> Tables<'tcx> { - pub(crate) fn intern_ty(&mut self, ty: Ty<'tcx>) -> stable_mir::ty::Ty { +pub struct Tables<'tcx, B: Bridge> { + tcx: TyCtxt<'tcx>, + pub(crate) def_ids: IndexMap, + pub(crate) alloc_ids: IndexMap, + pub(crate) spans: IndexMap, + pub(crate) types: IndexMap, B::Ty>, + pub(crate) instances: IndexMap, B::InstanceDef>, + pub(crate) ty_consts: IndexMap, B::TyConstId>, + pub(crate) mir_consts: IndexMap, B::MirConstId>, + pub(crate) layouts: IndexMap, B::Layout>, +} + +impl<'tcx, B: Bridge> Tables<'tcx, B> { + pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self { + Self { + tcx, + def_ids: IndexMap::default(), + alloc_ids: IndexMap::default(), + spans: IndexMap::default(), + types: IndexMap::default(), + instances: IndexMap::default(), + ty_consts: IndexMap::default(), + mir_consts: IndexMap::default(), + layouts: IndexMap::default(), + } + } +} + +impl<'tcx, B: Bridge> Tables<'tcx, B> { + pub(crate) fn intern_ty(&mut self, ty: Ty<'tcx>) -> B::Ty { self.types.create_or_fetch(ty) } - pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> TyConstId { + pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> B::TyConstId { self.ty_consts.create_or_fetch(ct) } - pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> MirConstId { + pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> B::MirConstId { self.mir_consts.create_or_fetch(constant) } @@ -82,19 +104,38 @@ impl<'tcx> Tables<'tcx> { !must_override && self.tcx.is_mir_available(def_id) } - fn to_fn_def(&mut self, def_id: DefId) -> Option { + fn filter_fn_def(&mut self, def_id: DefId) -> Option { if matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) { - Some(self.fn_def(def_id)) + Some(def_id) } else { None } } - fn to_static(&mut self, def_id: DefId) -> Option { - matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| self.static_def(def_id)) + fn filter_static_def(&mut self, def_id: DefId) -> Option { + matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| def_id) } } +/// A trait defining types that are used to emulate StableMIR components, which is really +/// useful when programming in stable_mir-agnostic settings. +pub trait Bridge { + type DefId: Copy + Debug + PartialEq + IndexedVal; + type AllocId: Copy + Debug + PartialEq + IndexedVal; + type Span: Copy + Debug + PartialEq + IndexedVal; + type Ty: Copy + Debug + PartialEq + IndexedVal; + type InstanceDef: Copy + Debug + PartialEq + IndexedVal; + type TyConstId: Copy + Debug + PartialEq + IndexedVal; + type MirConstId: Copy + Debug + PartialEq + IndexedVal; + type Layout: Copy + Debug + PartialEq + IndexedVal; + type Error: SmirError; +} + +pub trait SmirError { + fn new(msg: String) -> Self; + fn from_internal(err: T) -> Self; +} + /// Iterate over the definitions of the given crate. pub(crate) fn filter_def_ids(tcx: TyCtxt<'_>, krate: CrateNum, mut func: F) -> Vec where From 15286f220e54e39dc533e43a492679e957bf332b Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 3 Jul 2025 17:42:43 -0700 Subject: [PATCH 30/62] Remove some unnecessary `unsafe` in VecCache --- compiler/rustc_data_structures/src/vec_cache.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_data_structures/src/vec_cache.rs b/compiler/rustc_data_structures/src/vec_cache.rs index 3b448c056b74..df83d15b5f94 100644 --- a/compiler/rustc_data_structures/src/vec_cache.rs +++ b/compiler/rustc_data_structures/src/vec_cache.rs @@ -76,8 +76,8 @@ impl SlotIndex { index_in_bucket: idx as usize, }; } - // SAFETY: We already ruled out idx 0, so `checked_ilog2` can't return `None`. - let bucket = unsafe { idx.checked_ilog2().unwrap_unchecked() as usize }; + // We already ruled out idx 0, so this `ilog2` never panics (and the check optimizes away) + let bucket = idx.ilog2() as usize; let entries = 1 << bucket; SlotIndex { bucket_idx: bucket - FIRST_BUCKET_SHIFT + 1, From 7f5e382df4807577e3b2cb2b4c283bb37bc8e5c4 Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 5 May 2025 15:15:15 +0800 Subject: [PATCH 31/62] refactor: make `SmirInterface` a trait and impl it for `SmirContainer` - rewrite all `SmirInterface` apis. - add `BridgeTys` to impl those associated types in `Bridge`. - move `**_def()` stuffs living in `impl Tables` from `rustc_internal` to `stable_mir`. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 1 - compiler/rustc_smir/src/rustc_smir/mod.rs | 48 - .../src/stable_mir/compiler_interface.rs | 1052 ++++++++++++++--- compiler/rustc_smir/src/stable_mir/mod.rs | 38 + compiler/rustc_smir/src/stable_mir/ty.rs | 6 + 5 files changed, 901 insertions(+), 244 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 871a6524f392..3434c9fbf928 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -17,7 +17,6 @@ use rustc_span::Span; use rustc_span::def_id::{CrateNum, DefId}; use scoped_tls::scoped_thread_local; use stable_mir::Error; -use stable_mir::compiler_interface::SmirInterface; use stable_mir::ty::IndexedVal; use crate::rustc_smir::context::SmirCtxt; diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 777e95a88d48..95ae99bb7946 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -8,7 +8,6 @@ //! For now, we are developing everything inside `rustc`, thus, we keep this module private. use std::marker::PointeeSized; -use std::ops::RangeInclusive; use std::cell::RefCell; use std::fmt::Debug; @@ -18,8 +17,6 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::AllocId; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use stable_mir::{CtorKind, ItemKind}; -use tracing::debug; use crate::rustc_internal::IndexMap; use crate::stable_mir; @@ -154,51 +151,6 @@ where } } -/// Build a stable mir crate from a given crate number. -pub(crate) fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { - let crate_name = tcx.crate_name(crate_num).to_string(); - let is_local = crate_num == LOCAL_CRATE; - debug!(?crate_name, ?crate_num, "smir_crate"); - stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local } -} - -pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { - match kind { - DefKind::Mod - | DefKind::Struct - | DefKind::Union - | DefKind::Enum - | DefKind::Variant - | DefKind::Trait - | DefKind::TyAlias - | DefKind::ForeignTy - | DefKind::TraitAlias - | DefKind::AssocTy - | DefKind::TyParam - | DefKind::ConstParam - | DefKind::Macro(_) - | DefKind::ExternCrate - | DefKind::Use - | DefKind::ForeignMod - | DefKind::OpaqueTy - | DefKind::Field - | DefKind::LifetimeParam - | DefKind::Impl { .. } - | DefKind::GlobalAsm => { - unreachable!("Not a valid item kind: {kind:?}"); - } - DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => { - ItemKind::Fn - } - DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => { - ItemKind::Const - } - DefKind::Static { .. } => ItemKind::Static, - DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const), - DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn), - } -} - /// Trait used to convert between an internal MIR type to a Stable MIR type. pub trait Stable<'cx>: PointeeSized { /// The stable representation of the type implementing Stable. diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index 2668fba9f4f6..3be9d9db7539 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -5,13 +5,14 @@ use std::cell::Cell; -use rustc_smir::context::SmirCtxt; +use rustc_hir::def::DefKind; +use rustc_smir::{Bridge, SmirContainer, Tables}; use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions}; use stable_mir::crate_def::Attribute; use stable_mir::mir::alloc::{AllocId, GlobalAlloc}; use stable_mir::mir::mono::{Instance, InstanceDef, StaticDef}; use stable_mir::mir::{BinOp, Body, Place, UnOp}; -use stable_mir::target::MachineInfo; +use stable_mir::target::{MachineInfo, MachineSize}; use stable_mir::ty::{ AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, CoroutineDef, Discr, FieldDef, FnDef, ForeignDef, ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, @@ -19,119 +20,571 @@ use stable_mir::ty::{ TraitDecl, TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef, VariantIdx, }; use stable_mir::{ - AssocItems, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, - ItemKind, Symbol, TraitDecls, mir, + AssocItems, Crate, CrateDef, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, + ImplTraitDecls, ItemKind, Symbol, TraitDecls, alloc, mir, new_item_kind, }; +use tracing::debug; use crate::{rustc_smir, stable_mir}; +pub struct BridgeTys; + +impl Bridge for BridgeTys { + type DefId = stable_mir::DefId; + type AllocId = stable_mir::mir::alloc::AllocId; + type Span = stable_mir::ty::Span; + type Ty = stable_mir::ty::Ty; + type InstanceDef = stable_mir::mir::mono::InstanceDef; + type TyConstId = stable_mir::ty::TyConstId; + type MirConstId = stable_mir::ty::MirConstId; + type Layout = stable_mir::abi::Layout; + type Error = stable_mir::Error; +} + +impl<'tcx> Tables<'tcx, BridgeTys> { + pub(crate) fn crate_item(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::CrateItem { + stable_mir::CrateItem(self.create_def_id(did)) + } + + pub(crate) fn adt_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::AdtDef { + stable_mir::ty::AdtDef(self.create_def_id(did)) + } + + pub(crate) fn foreign_module_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::ForeignModuleDef { + stable_mir::ty::ForeignModuleDef(self.create_def_id(did)) + } + + pub(crate) fn foreign_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::ForeignDef { + stable_mir::ty::ForeignDef(self.create_def_id(did)) + } + + pub(crate) fn fn_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::FnDef { + stable_mir::ty::FnDef(self.create_def_id(did)) + } + + pub(crate) fn closure_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::ClosureDef { + stable_mir::ty::ClosureDef(self.create_def_id(did)) + } + + pub(crate) fn coroutine_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::CoroutineDef { + stable_mir::ty::CoroutineDef(self.create_def_id(did)) + } + + pub(crate) fn coroutine_closure_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::CoroutineClosureDef { + stable_mir::ty::CoroutineClosureDef(self.create_def_id(did)) + } + + pub(crate) fn alias_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::AliasDef { + stable_mir::ty::AliasDef(self.create_def_id(did)) + } + + pub(crate) fn param_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::ParamDef { + stable_mir::ty::ParamDef(self.create_def_id(did)) + } + + pub(crate) fn br_named_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::BrNamedDef { + stable_mir::ty::BrNamedDef(self.create_def_id(did)) + } + + pub(crate) fn trait_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::TraitDef { + stable_mir::ty::TraitDef(self.create_def_id(did)) + } + + pub(crate) fn generic_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::GenericDef { + stable_mir::ty::GenericDef(self.create_def_id(did)) + } + + pub(crate) fn const_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::ConstDef { + stable_mir::ty::ConstDef(self.create_def_id(did)) + } + + pub(crate) fn impl_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::ImplDef { + stable_mir::ty::ImplDef(self.create_def_id(did)) + } + + /* + pub(crate) fn region_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::RegionDef { + stable_mir::ty::RegionDef(self.create_def_id(did)) + } + */ + + pub(crate) fn coroutine_witness_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::CoroutineWitnessDef { + stable_mir::ty::CoroutineWitnessDef(self.create_def_id(did)) + } + + pub(crate) fn assoc_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::AssocDef { + stable_mir::ty::AssocDef(self.create_def_id(did)) + } + + pub(crate) fn opaque_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::ty::OpaqueDef { + stable_mir::ty::OpaqueDef(self.create_def_id(did)) + } + + pub(crate) fn prov( + &mut self, + aid: rustc_middle::mir::interpret::AllocId, + ) -> stable_mir::ty::Prov { + stable_mir::ty::Prov(self.create_alloc_id(aid)) + } + + pub(crate) fn static_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> stable_mir::mir::mono::StaticDef { + stable_mir::mir::mono::StaticDef(self.create_def_id(did)) + } +} + /// Stable public API for querying compiler information. /// -/// All queries are delegated to an internal [`SmirCtxt`] that provides +/// All queries are delegated to [`crate::rustc_smir::context::SmirCtxt`] that provides /// similar APIs but based on internal rustc constructs. /// /// Do not use this directly. This is currently used in the macro expansion. -pub(crate) struct SmirInterface<'tcx> { - pub(crate) cx: SmirCtxt<'tcx>, +pub(crate) trait SmirInterface { + fn entry_fn(&self) -> Option; + /// Retrieve all items of the local crate that have a MIR associated with them. + fn all_local_items(&self) -> CrateItems; + /// Retrieve the body of a function. + /// This function will panic if the body is not available. + fn mir_body(&self, item: DefId) -> mir::Body; + /// Check whether the body of a function is available. + fn has_body(&self, item: DefId) -> bool; + fn foreign_modules(&self, crate_num: CrateNum) -> Vec; + + /// Retrieve all functions defined in this crate. + fn crate_functions(&self, crate_num: CrateNum) -> Vec; + + /// Retrieve all static items defined in this crate. + fn crate_statics(&self, crate_num: CrateNum) -> Vec; + fn foreign_module(&self, mod_def: ForeignModuleDef) -> ForeignModule; + fn foreign_items(&self, mod_def: ForeignModuleDef) -> Vec; + fn all_trait_decls(&self) -> TraitDecls; + fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls; + fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl; + fn all_trait_impls(&self) -> ImplTraitDecls; + fn trait_impls(&self, crate_num: CrateNum) -> ImplTraitDecls; + fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait; + fn generics_of(&self, def_id: DefId) -> Generics; + fn predicates_of(&self, def_id: DefId) -> GenericPredicates; + fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates; + + /// Get information about the local crate. + fn local_crate(&self) -> Crate; + /// Retrieve a list of all external crates. + fn external_crates(&self) -> Vec; + + /// Find a crate with the given name. + fn find_crates(&self, name: &str) -> Vec; + + /// Returns the name of given `DefId` + fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol; + + /// Return registered tool attributes with the given attribute name. + /// + /// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool + /// attributes will simply return an empty list. + /// + /// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`. + /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`. + fn tool_attrs(&self, def_id: DefId, attr: &[Symbol]) -> Vec; + + /// Get all tool attributes of a definition. + fn all_tool_attrs(&self, def_id: DefId) -> Vec; + + /// Returns printable, human readable form of `Span` + fn span_to_string(&self, span: Span) -> String; + + /// Return filename from given `Span`, for diagnostic purposes + fn get_filename(&self, span: &Span) -> Filename; + + /// Return lines corresponding to this `Span` + fn get_lines(&self, span: &Span) -> LineInfo; + + /// Returns the `kind` of given `DefId` + fn item_kind(&self, item: CrateItem) -> ItemKind; + + /// Returns whether this is a foreign item. + fn is_foreign_item(&self, item: DefId) -> bool; + + /// Returns the kind of a given foreign item. + fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind; + + /// Returns the kind of a given algebraic data type + fn adt_kind(&self, def: AdtDef) -> AdtKind; + + /// Returns if the ADT is a box. + fn adt_is_box(&self, def: AdtDef) -> bool; + + /// Returns whether this ADT is simd. + fn adt_is_simd(&self, def: AdtDef) -> bool; + + /// Returns whether this definition is a C string. + fn adt_is_cstr(&self, def: AdtDef) -> bool; + + /// Retrieve the function signature for the given generic arguments. + fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig; + + /// Retrieve the intrinsic definition if the item corresponds one. + fn intrinsic(&self, item: DefId) -> Option; + + /// Retrieve the plain function name of an intrinsic. + fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol; + + /// Retrieve the closure signature for the given generic arguments. + fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig; + + /// The number of variants in this ADT. + fn adt_variants_len(&self, def: AdtDef) -> usize; + + /// The name of a variant. + fn variant_name(&self, def: VariantDef) -> Symbol; + fn variant_fields(&self, def: VariantDef) -> Vec; + + /// Evaluate constant as a target usize. + fn eval_target_usize(&self, cnst: &MirConst) -> Result; + fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result; + + /// Create a new zero-sized constant. + fn try_new_const_zst(&self, ty: Ty) -> Result; + + /// Create a new constant that represents the given string value. + fn new_const_str(&self, value: &str) -> MirConst; + + /// Create a new constant that represents the given boolean value. + fn new_const_bool(&self, value: bool) -> MirConst; + + /// Create a new constant that represents the given value. + fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; + fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; + + /// Create a new type from the given kind. + fn new_rigid_ty(&self, kind: RigidTy) -> Ty; + + /// Create a new box type, `Box`, for the given inner type `T`. + fn new_box_ty(&self, ty: Ty) -> Ty; + + /// Returns the type of given crate item. + fn def_ty(&self, item: DefId) -> Ty; + + /// Returns the type of given definition instantiated with the given arguments. + fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty; + + /// Returns literal value of a const as a string. + fn mir_const_pretty(&self, cnst: &MirConst) -> String; + + /// `Span` of an item + fn span_of_an_item(&self, def_id: DefId) -> Span; + + fn ty_const_pretty(&self, ct: TyConstId) -> String; + + /// Obtain the representation of a type. + fn ty_pretty(&self, ty: Ty) -> String; + + /// Obtain the kind of a type. + fn ty_kind(&self, ty: Ty) -> TyKind; + + // Get the discriminant Ty for this Ty if there's one. + fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> Ty; + + /// Get the body of an Instance which is already monomorphized. + fn instance_body(&self, instance: InstanceDef) -> Option; + + /// Get the instance type with generic instantiations applied and lifetimes erased. + fn instance_ty(&self, instance: InstanceDef) -> Ty; + + /// Get the instantiation types. + fn instance_args(&self, def: InstanceDef) -> GenericArgs; + + /// Get the instance. + fn instance_def_id(&self, instance: InstanceDef) -> DefId; + + /// Get the instance mangled name. + fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol; + + /// Check if this is an empty DropGlue shim. + fn is_empty_drop_shim(&self, def: InstanceDef) -> bool; + + /// Convert a non-generic crate item into an instance. + /// This function will panic if the item is generic. + fn mono_instance(&self, def_id: DefId) -> Instance; + + /// Item requires monomorphization. + fn requires_monomorphization(&self, def_id: DefId) -> bool; + + /// Resolve an instance from the given function definition and generic arguments. + fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option; + + /// Resolve an instance for drop_in_place for the given type. + fn resolve_drop_in_place(&self, ty: Ty) -> Instance; + + /// Resolve instance for a function pointer. + fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option; + + /// Resolve instance for a closure with the requested type. + fn resolve_closure( + &self, + def: ClosureDef, + args: &GenericArgs, + kind: ClosureKind, + ) -> Option; + + /// Evaluate a static's initializer. + fn eval_static_initializer(&self, def: StaticDef) -> Result; + + /// Try to evaluate an instance into a constant. + fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result; + + /// Retrieve global allocation for the given allocation ID. + fn global_alloc(&self, id: AllocId) -> GlobalAlloc; + + /// Retrieve the id for the virtual table. + fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option; + fn krate(&self, def_id: DefId) -> Crate; + fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol; + + /// Return information about the target machine. + fn target_info(&self) -> MachineInfo; + + /// Get an instance ABI. + fn instance_abi(&self, def: InstanceDef) -> Result; + + /// Get the ABI of a function pointer. + fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result; + + /// Get the layout of a type. + fn ty_layout(&self, ty: Ty) -> Result; + + /// Get the layout shape. + fn layout_shape(&self, id: Layout) -> LayoutShape; + + /// Get a debug string representation of a place. + fn place_pretty(&self, place: &Place) -> String; + + /// Get the resulting type of binary operation. + fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty; + + /// Get the resulting type of unary operation. + fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty; + + /// Get all associated items of a definition. + fn associated_items(&self, def_id: DefId) -> AssocItems; } -impl<'tcx> SmirInterface<'tcx> { - pub(crate) fn entry_fn(&self) -> Option { - self.cx.entry_fn() +impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { + fn entry_fn(&self) -> Option { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = cx.entry_fn(); + Some(tables.crate_item(did?)) } /// Retrieve all items of the local crate that have a MIR associated with them. - pub(crate) fn all_local_items(&self) -> CrateItems { - self.cx.all_local_items() + fn all_local_items(&self) -> CrateItems { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.all_local_items().iter().map(|did| tables.crate_item(*did)).collect() } /// Retrieve the body of a function. /// This function will panic if the body is not available. - pub(crate) fn mir_body(&self, item: DefId) -> mir::Body { - self.cx.mir_body(item) + fn mir_body(&self, item: DefId) -> mir::Body { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[item]; + cx.mir_body(did).stable(&mut *tables, cx) } /// Check whether the body of a function is available. - pub(crate) fn has_body(&self, item: DefId) -> bool { - self.cx.has_body(item) + fn has_body(&self, item: DefId) -> bool { + let mut tables = self.tables.borrow_mut(); + let tables_ref = &mut *tables; + let cx = &*self.cx.borrow(); + let def = item.internal(tables_ref, cx); + cx.has_body(def, tables_ref) } - pub(crate) fn foreign_modules(&self, crate_num: CrateNum) -> Vec { - self.cx.foreign_modules(crate_num) + fn foreign_modules(&self, crate_num: CrateNum) -> Vec { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.foreign_modules(crate_num.internal(&mut *tables, cx)) + .iter() + .map(|did| tables.foreign_module_def(*did)) + .collect() } /// Retrieve all functions defined in this crate. - pub(crate) fn crate_functions(&self, crate_num: CrateNum) -> Vec { - self.cx.crate_functions(crate_num) + fn crate_functions(&self, crate_num: CrateNum) -> Vec { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let tables_ref = &mut *tables; + let krate = crate_num.internal(tables_ref, cx); + cx.crate_functions(krate, tables_ref).iter().map(|did| tables.fn_def(*did)).collect() } /// Retrieve all static items defined in this crate. - pub(crate) fn crate_statics(&self, crate_num: CrateNum) -> Vec { - self.cx.crate_statics(crate_num) + fn crate_statics(&self, crate_num: CrateNum) -> Vec { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let tables_ref = &mut *tables; + let krate = crate_num.internal(tables_ref, cx); + cx.crate_statics(krate, tables_ref).iter().map(|did| tables.static_def(*did)).collect() } - pub(crate) fn foreign_module(&self, mod_def: ForeignModuleDef) -> ForeignModule { - self.cx.foreign_module(mod_def) + fn foreign_module(&self, mod_def: ForeignModuleDef) -> ForeignModule { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[mod_def.def_id()]; + cx.foreign_module(did).stable(&mut *tables, cx) } - pub(crate) fn foreign_items(&self, mod_def: ForeignModuleDef) -> Vec { - self.cx.foreign_items(mod_def) + fn foreign_items(&self, mod_def: ForeignModuleDef) -> Vec { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[mod_def.def_id()]; + cx.foreign_items(did).iter().map(|did| tables.foreign_def(*did)).collect() } - pub(crate) fn all_trait_decls(&self) -> TraitDecls { - self.cx.all_trait_decls() + fn all_trait_decls(&self) -> TraitDecls { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.all_trait_decls().map(|did| tables.trait_def(did)).collect() } - pub(crate) fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls { - self.cx.trait_decls(crate_num) + fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let krate = crate_num.internal(&mut *tables, cx); + cx.trait_decls(krate).iter().map(|did| tables.trait_def(*did)).collect() } - pub(crate) fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl { - self.cx.trait_decl(trait_def) + fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[trait_def.0]; + cx.trait_decl(did).stable(&mut *tables, cx) } - pub(crate) fn all_trait_impls(&self) -> ImplTraitDecls { - self.cx.all_trait_impls() + fn all_trait_impls(&self) -> ImplTraitDecls { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.all_trait_impls().iter().map(|did| tables.impl_def(*did)).collect() } - pub(crate) fn trait_impls(&self, crate_num: CrateNum) -> ImplTraitDecls { - self.cx.trait_impls(crate_num) + fn trait_impls(&self, crate_num: CrateNum) -> ImplTraitDecls { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let krate = crate_num.internal(&mut *tables, cx); + cx.trait_impls(krate).iter().map(|did| tables.impl_def(*did)).collect() } - pub(crate) fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait { - self.cx.trait_impl(trait_impl) + fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[trait_impl.0]; + cx.trait_impl(did).stable(&mut *tables, cx) } - pub(crate) fn generics_of(&self, def_id: DefId) -> Generics { - self.cx.generics_of(def_id) + fn generics_of(&self, def_id: DefId) -> Generics { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + cx.generics_of(did).stable(&mut *tables, cx) } - pub(crate) fn predicates_of(&self, def_id: DefId) -> GenericPredicates { - self.cx.predicates_of(def_id) + fn predicates_of(&self, def_id: DefId) -> GenericPredicates { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + let rustc_middle::ty::GenericPredicates { parent, predicates } = cx.predicates_of(did); + stable_mir::ty::GenericPredicates { + parent: parent.map(|did| tables.trait_def(did)), + predicates: predicates + .iter() + .map(|(clause, span)| { + ( + clause.as_predicate().kind().skip_binder().stable(&mut *tables, cx), + span.stable(&mut *tables, cx), + ) + }) + .collect(), + } } - pub(crate) fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates { - self.cx.explicit_predicates_of(def_id) + fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + let rustc_middle::ty::GenericPredicates { parent, predicates } = + cx.explicit_predicates_of(did); + stable_mir::ty::GenericPredicates { + parent: parent.map(|did| tables.trait_def(did)), + predicates: predicates + .iter() + .map(|(clause, span)| { + ( + clause.as_predicate().kind().skip_binder().stable(&mut *tables, cx), + span.stable(&mut *tables, cx), + ) + }) + .collect(), + } } /// Get information about the local crate. - pub(crate) fn local_crate(&self) -> Crate { - self.cx.local_crate() + fn local_crate(&self) -> Crate { + let cx = &*self.cx.borrow(); + self.smir_crate(cx.local_crate_num()) } /// Retrieve a list of all external crates. - pub(crate) fn external_crates(&self) -> Vec { - self.cx.external_crates() + fn external_crates(&self) -> Vec { + let cx = &*self.cx.borrow(); + cx.external_crates().iter().map(|crate_num| self.smir_crate(*crate_num)).collect() } /// Find a crate with the given name. - pub(crate) fn find_crates(&self, name: &str) -> Vec { - self.cx.find_crates(name) + fn find_crates(&self, name: &str) -> Vec { + let cx = &*self.cx.borrow(); + cx.find_crates(name).iter().map(|crate_num| self.smir_crate(*crate_num)).collect() } /// Returns the name of given `DefId`. - pub(crate) fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol { - self.cx.def_name(def_id, trimmed) + fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol { + let tables = self.tables.borrow(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + cx.def_name(did, trimmed) } /// Return registered tool attributes with the given attribute name. @@ -141,63 +594,111 @@ impl<'tcx> SmirInterface<'tcx> { /// /// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`. /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`. - pub(crate) fn tool_attrs(&self, def_id: DefId, attr: &[Symbol]) -> Vec { - self.cx.tool_attrs(def_id, attr) + fn tool_attrs(&self, def_id: DefId, attr: &[Symbol]) -> Vec { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + cx.tool_attrs(did, attr) + .into_iter() + .map(|(attr_str, span)| Attribute::new(attr_str, span.stable(&mut *tables, cx))) + .collect() } /// Get all tool attributes of a definition. - pub(crate) fn all_tool_attrs(&self, def_id: DefId) -> Vec { - self.cx.all_tool_attrs(def_id) + fn all_tool_attrs(&self, def_id: DefId) -> Vec { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + cx.all_tool_attrs(did) + .into_iter() + .map(|(attr_str, span)| Attribute::new(attr_str, span.stable(&mut *tables, cx))) + .collect() } /// Returns printable, human readable form of `Span`. - pub(crate) fn span_to_string(&self, span: Span) -> String { - self.cx.span_to_string(span) + fn span_to_string(&self, span: Span) -> String { + let tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let sp = tables.spans[span]; + cx.span_to_string(sp) } /// Return filename from given `Span`, for diagnostic purposes. - pub(crate) fn get_filename(&self, span: &Span) -> Filename { - self.cx.get_filename(span) + fn get_filename(&self, span: &Span) -> Filename { + let tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let sp = tables.spans[*span]; + cx.get_filename(sp) } /// Return lines corresponding to this `Span`. - pub(crate) fn get_lines(&self, span: &Span) -> LineInfo { - self.cx.get_lines(span) + fn get_lines(&self, span: &Span) -> LineInfo { + let tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let sp = tables.spans[*span]; + let lines = cx.get_lines(sp); + LineInfo::from(lines) } /// Returns the `kind` of given `DefId`. - pub(crate) fn item_kind(&self, item: CrateItem) -> ItemKind { - self.cx.item_kind(item) + fn item_kind(&self, item: CrateItem) -> ItemKind { + let tables = self.tables.borrow(); + let cx = &*self.cx.borrow(); + let did = tables[item.0]; + new_item_kind(cx.def_kind(did)) } /// Returns whether this is a foreign item. - pub(crate) fn is_foreign_item(&self, item: DefId) -> bool { - self.cx.is_foreign_item(item) + fn is_foreign_item(&self, item: DefId) -> bool { + let tables = self.tables.borrow(); + let cx = &*self.cx.borrow(); + let did = tables[item]; + cx.is_foreign_item(did) } /// Returns the kind of a given foreign item. - pub(crate) fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind { - self.cx.foreign_item_kind(def) + fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let def_id = tables[def.def_id()]; + let def_kind = cx.foreign_item_kind(def_id); + match def_kind { + DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)), + DefKind::Static { .. } => ForeignItemKind::Static(tables.static_def(def_id)), + DefKind::ForeignTy => { + use rustc_smir::context::SmirTy; + ForeignItemKind::Type(tables.intern_ty(cx.new_foreign(def_id))) + } + def_kind => unreachable!("Unexpected kind for a foreign item: {:?}", def_kind), + } } /// Returns the kind of a given algebraic data type. - pub(crate) fn adt_kind(&self, def: AdtDef) -> AdtKind { - self.cx.adt_kind(def) + fn adt_kind(&self, def: AdtDef) -> AdtKind { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.adt_kind(def.internal(&mut *tables, cx)).stable(&mut *tables, cx) } /// Returns if the ADT is a box. - pub(crate) fn adt_is_box(&self, def: AdtDef) -> bool { - self.cx.adt_is_box(def) + fn adt_is_box(&self, def: AdtDef) -> bool { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.adt_is_box(def.internal(&mut *tables, cx)) } /// Returns whether this ADT is simd. - pub(crate) fn adt_is_simd(&self, def: AdtDef) -> bool { - self.cx.adt_is_simd(def) + fn adt_is_simd(&self, def: AdtDef) -> bool { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.adt_is_simd(def.internal(&mut *tables, cx)) } /// Returns whether this definition is a C string. - pub(crate) fn adt_is_cstr(&self, def: AdtDef) -> bool { - self.cx.adt_is_cstr(def) + fn adt_is_cstr(&self, def: AdtDef) -> bool { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.adt_is_cstr(def.0.internal(&mut *tables, cx)) } /// Returns the representation options for this ADT @@ -206,28 +707,43 @@ impl<'tcx> SmirInterface<'tcx> { } /// Retrieve the function signature for the given generic arguments. - pub(crate) fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { - self.cx.fn_sig(def, args) + fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let def_id = def.0.internal(&mut *tables, cx); + let args_ref = args.internal(&mut *tables, cx); + cx.fn_sig(def_id, args_ref).stable(&mut *tables, cx) } /// Retrieve the intrinsic definition if the item corresponds one. - pub(crate) fn intrinsic(&self, item: DefId) -> Option { - self.cx.intrinsic(item) + fn intrinsic(&self, item: DefId) -> Option { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let def_id = item.internal(&mut *tables, cx); + cx.intrinsic(def_id).map(|_| IntrinsicDef(item)) } /// Retrieve the plain function name of an intrinsic. - pub(crate) fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol { - self.cx.intrinsic_name(def) + fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let def_id = def.0.internal(&mut *tables, cx); + cx.intrinsic_name(def_id) } /// Retrieve the closure signature for the given generic arguments. - pub(crate) fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig { - self.cx.closure_sig(args) + fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let args_ref = args.internal(&mut *tables, cx); + cx.closure_sig(args_ref).stable(&mut *tables, cx) } /// The number of variants in this ADT. - pub(crate) fn adt_variants_len(&self, def: AdtDef) -> usize { - self.cx.adt_variants_len(def) + fn adt_variants_len(&self, def: AdtDef) -> usize { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.adt_variants_len(def.internal(&mut *tables, cx)) } /// Discriminant for a given variant index of AdtDef @@ -246,259 +762,405 @@ impl<'tcx> SmirInterface<'tcx> { } /// The name of a variant. - pub(crate) fn variant_name(&self, def: VariantDef) -> Symbol { - self.cx.variant_name(def) + fn variant_name(&self, def: VariantDef) -> Symbol { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.variant_name(def.internal(&mut *tables, cx)) } - pub(crate) fn variant_fields(&self, def: VariantDef) -> Vec { - self.cx.variant_fields(def) + fn variant_fields(&self, def: VariantDef) -> Vec { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + def.internal(&mut *tables, cx).fields.iter().map(|f| f.stable(&mut *tables, cx)).collect() } /// Evaluate constant as a target usize. - pub(crate) fn eval_target_usize(&self, cnst: &MirConst) -> Result { - self.cx.eval_target_usize(cnst) + fn eval_target_usize(&self, mir_const: &MirConst) -> Result { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let cnst = mir_const.internal(&mut *tables, cx); + cx.eval_target_usize(cnst) } - pub(crate) fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result { - self.cx.eval_target_usize_ty(cnst) + fn eval_target_usize_ty(&self, ty_const: &TyConst) -> Result { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let cnst = ty_const.internal(&mut *tables, cx); + cx.eval_target_usize_ty(cnst) } /// Create a new zero-sized constant. - pub(crate) fn try_new_const_zst(&self, ty: Ty) -> Result { - self.cx.try_new_const_zst(ty) + fn try_new_const_zst(&self, ty: Ty) -> Result { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let ty_internal = ty.internal(&mut *tables, cx); + cx.try_new_const_zst(ty_internal).map(|cnst| cnst.stable(&mut *tables, cx)) } /// Create a new constant that represents the given string value. - pub(crate) fn new_const_str(&self, value: &str) -> MirConst { - self.cx.new_const_str(value) + fn new_const_str(&self, value: &str) -> MirConst { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.new_const_str(value).stable(&mut *tables, cx) } /// Create a new constant that represents the given boolean value. - pub(crate) fn new_const_bool(&self, value: bool) -> MirConst { - self.cx.new_const_bool(value) + fn new_const_bool(&self, value: bool) -> MirConst { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.new_const_bool(value).stable(&mut *tables, cx) } /// Create a new constant that represents the given value. - pub(crate) fn try_new_const_uint( - &self, - value: u128, - uint_ty: UintTy, - ) -> Result { - self.cx.try_new_const_uint(value, uint_ty) + fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx)); + cx.try_new_const_uint(value, ty).map(|cnst| cnst.stable(&mut *tables, cx)) } - pub(crate) fn try_new_ty_const_uint( - &self, - value: u128, - uint_ty: UintTy, - ) -> Result { - self.cx.try_new_ty_const_uint(value, uint_ty) + fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx)); + cx.try_new_ty_const_uint(value, ty).map(|cnst| cnst.stable(&mut *tables, cx)) } /// Create a new type from the given kind. - pub(crate) fn new_rigid_ty(&self, kind: RigidTy) -> Ty { - self.cx.new_rigid_ty(kind) + fn new_rigid_ty(&self, kind: RigidTy) -> Ty { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let internal_kind = kind.internal(&mut *tables, cx); + cx.new_rigid_ty(internal_kind).stable(&mut *tables, cx) } /// Create a new box type, `Box`, for the given inner type `T`. - pub(crate) fn new_box_ty(&self, ty: Ty) -> Ty { - self.cx.new_box_ty(ty) + fn new_box_ty(&self, ty: Ty) -> Ty { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let inner = ty.internal(&mut *tables, cx); + cx.new_box_ty(inner).stable(&mut *tables, cx) } /// Returns the type of given crate item. - pub(crate) fn def_ty(&self, item: DefId) -> Ty { - self.cx.def_ty(item) + fn def_ty(&self, item: DefId) -> Ty { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let inner = item.internal(&mut *tables, cx); + cx.def_ty(inner).stable(&mut *tables, cx) } /// Returns the type of given definition instantiated with the given arguments. - pub(crate) fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty { - self.cx.def_ty_with_args(item, args) + fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let inner = item.internal(&mut *tables, cx); + let args_ref = args.internal(&mut *tables, cx); + cx.def_ty_with_args(inner, args_ref).stable(&mut *tables, cx) } /// Returns literal value of a const as a string. - pub(crate) fn mir_const_pretty(&self, cnst: &MirConst) -> String { - self.cx.mir_const_pretty(cnst) + fn mir_const_pretty(&self, cnst: &MirConst) -> String { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cnst.internal(&mut *tables, cx).to_string() } /// `Span` of an item. - pub(crate) fn span_of_an_item(&self, def_id: DefId) -> Span { - self.cx.span_of_an_item(def_id) + fn span_of_an_item(&self, def_id: DefId) -> Span { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + cx.span_of_an_item(did).stable(&mut *tables, cx) } - pub(crate) fn ty_const_pretty(&self, ct: TyConstId) -> String { - self.cx.ty_const_pretty(ct) + fn ty_const_pretty(&self, ct: TyConstId) -> String { + let tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.ty_const_pretty(tables.ty_consts[ct]) } /// Obtain the representation of a type. - pub(crate) fn ty_pretty(&self, ty: Ty) -> String { - self.cx.ty_pretty(ty) + fn ty_pretty(&self, ty: Ty) -> String { + let tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.ty_pretty(tables.types[ty]) } - /// Obtain the representation of a type. - pub(crate) fn ty_kind(&self, ty: Ty) -> TyKind { - self.cx.ty_kind(ty) + /// Obtain the kind of a type. + fn ty_kind(&self, ty: Ty) -> TyKind { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.ty_kind(tables.types[ty]).stable(&mut *tables, cx) } /// Get the discriminant Ty for this Ty if there's one. - pub(crate) fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> Ty { - self.cx.rigid_ty_discriminant_ty(ty) + fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> Ty { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let internal_kind = ty.internal(&mut *tables, cx); + cx.rigid_ty_discriminant_ty(internal_kind).stable(&mut *tables, cx) } /// Get the body of an Instance which is already monomorphized. - pub(crate) fn instance_body(&self, instance: InstanceDef) -> Option { - self.cx.instance_body(instance) + fn instance_body(&self, instance: InstanceDef) -> Option { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let instance = tables.instances[instance]; + cx.instance_body(instance, &mut *tables).map(|body| body.stable(&mut *tables, cx)) } /// Get the instance type with generic instantiations applied and lifetimes erased. - pub(crate) fn instance_ty(&self, instance: InstanceDef) -> Ty { - self.cx.instance_ty(instance) + fn instance_ty(&self, instance: InstanceDef) -> Ty { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let instance = tables.instances[instance]; + cx.instance_ty(instance).stable(&mut *tables, cx) } /// Get the instantiation types. - pub(crate) fn instance_args(&self, def: InstanceDef) -> GenericArgs { - self.cx.instance_args(def) + fn instance_args(&self, def: InstanceDef) -> GenericArgs { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let instance = tables.instances[def]; + cx.instance_args(instance).stable(&mut *tables, cx) } /// Get the instance. - pub(crate) fn instance_def_id(&self, instance: InstanceDef) -> DefId { - self.cx.instance_def_id(instance) + fn instance_def_id(&self, instance: InstanceDef) -> DefId { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let instance = tables.instances[instance]; + cx.instance_def_id(instance, &mut *tables) } /// Get the instance mangled name. - pub(crate) fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol { - self.cx.instance_mangled_name(instance) + fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol { + let tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let instance = tables.instances[instance]; + cx.instance_mangled_name(instance) } /// Check if this is an empty DropGlue shim. - pub(crate) fn is_empty_drop_shim(&self, def: InstanceDef) -> bool { - self.cx.is_empty_drop_shim(def) + fn is_empty_drop_shim(&self, def: InstanceDef) -> bool { + let tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let instance = tables.instances[def]; + cx.is_empty_drop_shim(instance) } /// Convert a non-generic crate item into an instance. /// This function will panic if the item is generic. - pub(crate) fn mono_instance(&self, def_id: DefId) -> Instance { - self.cx.mono_instance(def_id) + fn mono_instance(&self, def_id: DefId) -> Instance { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + cx.mono_instance(did).stable(&mut *tables, cx) } /// Item requires monomorphization. - pub(crate) fn requires_monomorphization(&self, def_id: DefId) -> bool { - self.cx.requires_monomorphization(def_id) + fn requires_monomorphization(&self, def_id: DefId) -> bool { + let tables = self.tables.borrow(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + cx.requires_monomorphization(did) } /// Resolve an instance from the given function definition and generic arguments. - pub(crate) fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option { - self.cx.resolve_instance(def, args) + fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let def_id = def.0.internal(&mut *tables, cx); + let args_ref = args.internal(&mut *tables, cx); + cx.resolve_instance(def_id, args_ref).map(|inst| inst.stable(&mut *tables, cx)) } /// Resolve an instance for drop_in_place for the given type. - pub(crate) fn resolve_drop_in_place(&self, ty: Ty) -> Instance { - self.cx.resolve_drop_in_place(ty) + fn resolve_drop_in_place(&self, ty: Ty) -> Instance { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let internal_ty = ty.internal(&mut *tables, cx); + + cx.resolve_drop_in_place(internal_ty).stable(&mut *tables, cx) } /// Resolve instance for a function pointer. - pub(crate) fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option { - self.cx.resolve_for_fn_ptr(def, args) + fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let def_id = def.0.internal(&mut *tables, cx); + let args_ref = args.internal(&mut *tables, cx); + cx.resolve_for_fn_ptr(def_id, args_ref).stable(&mut *tables, cx) } /// Resolve instance for a closure with the requested type. - pub(crate) fn resolve_closure( + fn resolve_closure( &self, def: ClosureDef, args: &GenericArgs, kind: ClosureKind, ) -> Option { - self.cx.resolve_closure(def, args, kind) + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let def_id = def.0.internal(&mut *tables, cx); + let args_ref = args.internal(&mut *tables, cx); + let closure_kind = kind.internal(&mut *tables, cx); + cx.resolve_closure(def_id, args_ref, closure_kind).map(|inst| inst.stable(&mut *tables, cx)) } /// Evaluate a static's initializer. - pub(crate) fn eval_static_initializer(&self, def: StaticDef) -> Result { - self.cx.eval_static_initializer(def) + fn eval_static_initializer(&self, def: StaticDef) -> Result { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let def_id = def.0.internal(&mut *tables, cx); + + cx.eval_static_initializer(def_id).stable(&mut *tables, cx) } /// Try to evaluate an instance into a constant. - pub(crate) fn eval_instance( - &self, - def: InstanceDef, - const_ty: Ty, - ) -> Result { - self.cx.eval_instance(def, const_ty) + fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result { + let mut tables = self.tables.borrow_mut(); + let instance = tables.instances[def]; + let cx = &*self.cx.borrow(); + let const_ty = const_ty.internal(&mut *tables, cx); + cx.eval_instance(instance) + .map(|const_val| alloc::try_new_allocation(const_ty, const_val, &mut *tables, cx)) + .map_err(|e| e.stable(&mut *tables, cx))? } /// Retrieve global allocation for the given allocation ID. - pub(crate) fn global_alloc(&self, id: AllocId) -> GlobalAlloc { - self.cx.global_alloc(id) + fn global_alloc(&self, id: AllocId) -> GlobalAlloc { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let alloc_id = id.internal(&mut *tables, cx); + cx.global_alloc(alloc_id).stable(&mut *tables, cx) } /// Retrieve the id for the virtual table. - pub(crate) fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option { - self.cx.vtable_allocation(global_alloc) + fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option { + let mut tables = self.tables.borrow_mut(); + let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else { + return None; + }; + let cx = &*self.cx.borrow(); + let ty = ty.internal(&mut *tables, cx); + let trait_ref = trait_ref.internal(&mut *tables, cx); + let alloc_id = cx.vtable_allocation(ty, trait_ref); + Some(alloc_id.stable(&mut *tables, cx)) } - pub(crate) fn krate(&self, def_id: DefId) -> Crate { - self.cx.krate(def_id) + fn krate(&self, def_id: DefId) -> Crate { + let tables = self.tables.borrow(); + self.smir_crate(tables[def_id].krate) } - pub(crate) fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol { - self.cx.instance_name(def, trimmed) + fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol { + let tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let instance = tables.instances[def]; + cx.instance_name(instance, trimmed) } /// Return information about the target machine. - pub(crate) fn target_info(&self) -> MachineInfo { - self.cx.target_info() + fn target_info(&self) -> MachineInfo { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + MachineInfo { + endian: cx.target_endian().stable(&mut *tables, cx), + pointer_width: MachineSize::from_bits(cx.target_pointer_size()), + } } /// Get an instance ABI. - pub(crate) fn instance_abi(&self, def: InstanceDef) -> Result { - self.cx.instance_abi(def) + fn instance_abi(&self, def: InstanceDef) -> Result { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let instance = tables.instances[def]; + cx.instance_abi(instance, &mut *tables).map(|fn_abi| fn_abi.stable(&mut *tables, cx)) } /// Get the ABI of a function pointer. - pub(crate) fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result { - self.cx.fn_ptr_abi(fn_ptr) + fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let sig = fn_ptr.internal(&mut *tables, cx); + cx.fn_ptr_abi(sig, &mut *tables).map(|fn_abi| fn_abi.stable(&mut *tables, cx)) } /// Get the layout of a type. - pub(crate) fn ty_layout(&self, ty: Ty) -> Result { - self.cx.ty_layout(ty) + fn ty_layout(&self, ty: Ty) -> Result { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let internal_ty = ty.internal(&mut *tables, cx); + cx.ty_layout(internal_ty, &mut *tables).map(|layout| layout.stable(&mut *tables, cx)) } /// Get the layout shape. - pub(crate) fn layout_shape(&self, id: Layout) -> LayoutShape { - self.cx.layout_shape(id) + fn layout_shape(&self, id: Layout) -> LayoutShape { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + id.internal(&mut *tables, cx).0.stable(&mut *tables, cx) } /// Get a debug string representation of a place. - pub(crate) fn place_pretty(&self, place: &Place) -> String { - self.cx.place_pretty(place) + fn place_pretty(&self, place: &Place) -> String { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + + format!("{:?}", place.internal(&mut *tables, cx)) } /// Get the resulting type of binary operation. - pub(crate) fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty { - self.cx.binop_ty(bin_op, rhs, lhs) + fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let rhs_internal = rhs.internal(&mut *tables, cx); + let lhs_internal = lhs.internal(&mut *tables, cx); + let bin_op_internal = bin_op.internal(&mut *tables, cx); + cx.binop_ty(bin_op_internal, rhs_internal, lhs_internal).stable(&mut *tables, cx) } /// Get the resulting type of unary operation. - pub(crate) fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty { - self.cx.unop_ty(un_op, arg) + fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let un_op = un_op.internal(&mut *tables, cx); + let arg = arg.internal(&mut *tables, cx); + cx.unop_ty(un_op, arg).stable(&mut *tables, cx) } /// Get all associated items of a definition. - pub(crate) fn associated_items(&self, def_id: DefId) -> AssocItems { - self.cx.associated_items(def_id) + fn associated_items(&self, def_id: DefId) -> AssocItems { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let did = tables[def_id]; + cx.associated_items(did).iter().map(|assoc| assoc.stable(&mut *tables, cx)).collect() + } +} + +impl<'tcx> SmirContainer<'tcx, BridgeTys> { + fn smir_crate(&self, crate_num: rustc_span::def_id::CrateNum) -> Crate { + let cx = &*self.cx.borrow(); + let name = cx.crate_name(crate_num); + let is_local = cx.crate_is_local(crate_num); + let id = cx.crate_num_id(crate_num); + debug!(?name, ?crate_num, "smir_crate"); + Crate { id, name, is_local } } } // A thread local variable that stores a pointer to [`SmirInterface`]. scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>); -pub(crate) fn run<'tcx, T, F>(interface: &SmirInterface<'tcx>, f: F) -> Result +pub(crate) fn run(interface: &dyn SmirInterface, f: F) -> Result where F: FnOnce() -> T, { if TLV.is_set() { Err(Error::from("StableMIR already running")) } else { - let ptr: *const () = (interface as *const SmirInterface<'tcx>) as *const (); + let ptr: *const () = (&raw const interface) as _; TLV.set(&Cell::new(ptr), || Ok(f())) } } @@ -507,11 +1169,11 @@ where /// /// I.e., This function will load the current interface and calls a function with it. /// Do not nest these, as that will ICE. -pub(crate) fn with(f: impl FnOnce(&SmirInterface<'_>) -> R) -> R { +pub(crate) fn with(f: impl FnOnce(&dyn SmirInterface) -> R) -> R { assert!(TLV.is_set()); TLV.with(|tlv| { let ptr = tlv.get(); assert!(!ptr.is_null()); - f(unsafe { &*(ptr as *const SmirInterface<'_>) }) + f(unsafe { *(ptr as *const &dyn SmirInterface) }) }) } diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index c59758d4ad3f..0ced493b9ab5 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -27,6 +27,7 @@ use std::fmt::Debug; use std::{fmt, io}; +use rustc_hir::def::DefKind; use serde::Serialize; use stable_mir::compiler_interface::with; pub use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId}; @@ -218,6 +219,43 @@ pub fn all_trait_impls() -> ImplTraitDecls { with(|cx| cx.all_trait_impls()) } +pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { + match kind { + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::TyParam + | DefKind::ConstParam + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::OpaqueTy + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::Impl { .. } + | DefKind::GlobalAsm => { + unreachable!("Not a valid item kind: {kind:?}"); + } + DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => { + ItemKind::Fn + } + DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => { + ItemKind::Const + } + DefKind::Static { .. } => ItemKind::Static, + DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const), + DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn), + } +} + /// A type that provides internal information but that can still be used for debug purpose. #[derive(Clone, PartialEq, Eq, Hash, Serialize)] pub struct Opaque(String); diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 398738d1c389..9a30b231e0c1 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -298,6 +298,12 @@ pub struct LineInfo { pub end_col: usize, } +impl LineInfo { + pub fn from(lines: (usize, usize, usize, usize)) -> Self { + LineInfo { start_line: lines.0, start_col: lines.1, end_line: lines.2, end_col: lines.3 } + } +} + #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum TyKind { RigidTy(RigidTy), From 3a43ed2f377cb449856d53b564f4a464792ffdfe Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 5 May 2025 15:20:40 +0800 Subject: [PATCH 32/62] refactor: move `IndexedVal` from `stable_mir` to `rustc_smir` --- compiler/rustc_smir/src/rustc_internal/mod.rs | 3 +-- compiler/rustc_smir/src/rustc_smir/mod.rs | 7 ++++++- compiler/rustc_smir/src/stable_mir/abi.rs | 4 ++-- compiler/rustc_smir/src/stable_mir/mir/alloc.rs | 5 +++-- compiler/rustc_smir/src/stable_mir/mir/pretty.rs | 5 +++-- compiler/rustc_smir/src/stable_mir/mod.rs | 5 +++-- compiler/rustc_smir/src/stable_mir/ty.rs | 11 +++-------- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 3434c9fbf928..c343242ddfc5 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -17,11 +17,10 @@ use rustc_span::Span; use rustc_span::def_id::{CrateNum, DefId}; use scoped_tls::scoped_thread_local; use stable_mir::Error; -use stable_mir::ty::IndexedVal; use crate::rustc_smir::context::SmirCtxt; use crate::rustc_smir::{Stable, Tables}; -use crate::rustc_smir::{Bridge, SmirContainer, Tables}; +use crate::rustc_smir::{Bridge, IndexedVal, SmirContainer, Tables}; use crate::stable_mir; mod internal; diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 95ae99bb7946..edaec47fe7d7 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -19,7 +19,6 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use crate::rustc_internal::IndexMap; -use crate::stable_mir; mod alloc; mod builder; @@ -133,6 +132,12 @@ pub trait SmirError { fn from_internal(err: T) -> Self; } +pub trait IndexedVal { + fn to_val(index: usize) -> Self; + + fn to_index(&self) -> usize; +} + /// Iterate over the definitions of the given crate. pub(crate) fn filter_def_ids(tcx: TyCtxt<'_>, krate: CrateNum, mut func: F) -> Vec where diff --git a/compiler/rustc_smir/src/stable_mir/abi.rs b/compiler/rustc_smir/src/stable_mir/abi.rs index d8a2b97662c4..3c8bdb243d4c 100644 --- a/compiler/rustc_smir/src/stable_mir/abi.rs +++ b/compiler/rustc_smir/src/stable_mir/abi.rs @@ -6,7 +6,7 @@ use serde::Serialize; use stable_mir::compiler_interface::with; use stable_mir::mir::FieldIdx; use stable_mir::target::{MachineInfo, MachineSize as Size}; -use stable_mir::ty::{Align, IndexedVal, Ty, VariantIdx}; +use stable_mir::ty::{Align, Ty, VariantIdx}; use stable_mir::{Error, Opaque, error}; use crate::stable_mir; @@ -119,7 +119,7 @@ impl Layout { } } -impl IndexedVal for Layout { +impl crate::rustc_smir::IndexedVal for Layout { fn to_val(index: usize) -> Self { Layout(index) } diff --git a/compiler/rustc_smir/src/stable_mir/mir/alloc.rs b/compiler/rustc_smir/src/stable_mir/mir/alloc.rs index 782f52888b73..325f26da8bbf 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/alloc.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/alloc.rs @@ -2,13 +2,14 @@ use std::io::Read; +use rustc_smir::IndexedVal; use serde::Serialize; use stable_mir::mir::mono::{Instance, StaticDef}; use stable_mir::target::{Endian, MachineInfo}; -use stable_mir::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty}; +use stable_mir::ty::{Allocation, Binder, ExistentialTraitRef, Ty}; use stable_mir::{Error, with}; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; /// An allocation in the SMIR global memory can be either a function pointer, /// a static, or a "real" allocation with some data in it. diff --git a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs index b068a9a1081f..6fe455e17ec1 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs @@ -4,14 +4,15 @@ use std::io::Write; use std::{fmt, io, iter}; use fmt::{Display, Formatter}; +use rustc_smir::IndexedVal; use stable_mir::mir::{ Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents, }; -use stable_mir::ty::{AdtKind, AssocKind, IndexedVal, MirConst, Ty, TyConst}; +use stable_mir::ty::{AdtKind, AssocKind, MirConst, Ty, TyConst}; use stable_mir::{Body, CrateDef, Mutability, with}; use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind}; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; impl Display for Ty { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 0ced493b9ab5..1c992ec5dbb7 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -28,15 +28,16 @@ use std::fmt::Debug; use std::{fmt, io}; use rustc_hir::def::DefKind; +use rustc_smir::IndexedVal; use serde::Serialize; use stable_mir::compiler_interface::with; pub use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId}; pub use stable_mir::error::*; use stable_mir::mir::mono::StaticDef; use stable_mir::mir::{Body, Mutability}; -use stable_mir::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty}; +use stable_mir::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, Span, TraitDef, Ty}; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; pub mod abi; #[macro_use] diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 9a30b231e0c1..9933a8e9f7f7 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1,6 +1,7 @@ use std::fmt::{self, Debug, Display, Formatter}; use std::ops::Range; +use rustc_smir::IndexedVal; use serde::Serialize; use stable_mir::abi::{FnAbi, Layout}; use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType}; @@ -12,7 +13,7 @@ use stable_mir::{Filename, Opaque}; use super::abi::ReprOptions; use super::mir::{Body, Mutability, Safety}; use super::{DefId, Error, Symbol, with}; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)] pub struct Ty(usize); @@ -1563,15 +1564,9 @@ pub enum PredicatePolarity { Negative, } -pub trait IndexedVal { - fn to_val(index: usize) -> Self; - - fn to_index(&self) -> usize; -} - macro_rules! index_impl { ($name:ident) => { - impl IndexedVal for $name { + impl crate::rustc_smir::IndexedVal for $name { fn to_val(index: usize) -> Self { $name(index) } From 96ad3882324199305495ce03f6c94fa3bfebf34c Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 5 May 2025 15:22:48 +0800 Subject: [PATCH 33/62] refactor: impl `SmirError` for `stable_mir::Error` --- compiler/rustc_smir/src/stable_mir/error.rs | 12 ++++++++++-- compiler/rustc_smir/src/stable_mir/mir/mono.rs | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_smir/src/stable_mir/error.rs b/compiler/rustc_smir/src/stable_mir/error.rs index 050752e41eb9..c6bf96ebd176 100644 --- a/compiler/rustc_smir/src/stable_mir/error.rs +++ b/compiler/rustc_smir/src/stable_mir/error.rs @@ -7,6 +7,10 @@ use std::fmt::{Debug, Display, Formatter}; use std::{fmt, io}; +use rustc_smir::SmirError; + +use crate::rustc_smir; + macro_rules! error { ($fmt: literal $(,)?) => { Error(format!($fmt)) }; ($fmt: literal, $($arg:tt)*) => { Error(format!($fmt, $($arg)*)) }; @@ -30,10 +34,14 @@ pub enum CompilerError { #[derive(Clone, Debug, Eq, PartialEq)] pub struct Error(pub(crate) String); -impl Error { - pub fn new(msg: String) -> Self { +impl SmirError for Error { + fn new(msg: String) -> Self { Self(msg) } + + fn from_internal(err: T) -> Self { + Self(format!("{err:?}")) + } } impl From<&str> for Error { diff --git a/compiler/rustc_smir/src/stable_mir/mir/mono.rs b/compiler/rustc_smir/src/stable_mir/mir/mono.rs index f5239cccae1e..4d16b3bef519 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/mono.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/mono.rs @@ -1,14 +1,15 @@ use std::fmt::{Debug, Formatter}; use std::io; +use rustc_smir::{IndexedVal, SmirError}; use serde::Serialize; use stable_mir::abi::FnAbi; use stable_mir::crate_def::CrateDef; use stable_mir::mir::Body; -use stable_mir::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty}; +use stable_mir::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, Ty}; use stable_mir::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, with}; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum MonoItem { From 3b328e111a8b4fc67e7c4e7b39f45b89231d1487 Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 5 May 2025 15:25:54 +0800 Subject: [PATCH 34/62] refactor: split `rustc_smir::alloc` into two parts The previous `rustc_smir::alloc` had many direct calls to rustc queries. This commit splits it into two parts: `rustc_smir::alloc` and `stable_mir::alloc`. Following the same pattern as `SmirCtxt` and `SmirInterface`, the `rustc_smir::alloc` handles all direct interactions with rustc queries and performs the actual memory allocations, while the `stable_mir::alloc` is responsible for constructing stable components. --- compiler/rustc_smir/src/rustc_smir/alloc.rs | 161 ++++++++------------ compiler/rustc_smir/src/rustc_smir/mod.rs | 2 +- compiler/rustc_smir/src/stable_mir/alloc.rs | 86 +++++++++++ compiler/rustc_smir/src/stable_mir/mod.rs | 1 + 4 files changed, 151 insertions(+), 99 deletions(-) create mode 100644 compiler/rustc_smir/src/stable_mir/alloc.rs diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index a6d31ac4e13d..34692962de70 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -1,102 +1,74 @@ -use rustc_abi::{Align, Size}; -use rustc_middle::mir::ConstValue; -use rustc_middle::mir::interpret::{AllocInit, AllocRange, Pointer, alloc_range}; -use stable_mir::Error; -use stable_mir::mir::Mutability; -use stable_mir::ty::{Allocation, ProvenanceMap}; +//! Internal memory allocator implementation for StableMIR. +//! +//! This module handles all direct interactions with rustc queries and performs +//! the actual memory allocations. The stable interface in `stable_mir::alloc` +//! delegates all query-related operations to this implementation. -use crate::rustc_smir::{Stable, Tables}; -use crate::stable_mir; +use rustc_abi::{Size, TyAndLayout}; +use rustc_middle::mir::interpret::{ + AllocId, AllocInit, AllocRange, Allocation, ConstAllocation, Pointer, Scalar, alloc_range, +}; +use rustc_middle::ty::Ty; -/// Creates new empty `Allocation` from given `Align`. -fn new_empty_allocation(align: Align) -> Allocation { - Allocation { - bytes: Vec::new(), - provenance: ProvenanceMap { ptrs: Vec::new() }, - align: align.bytes(), - mutability: Mutability::Not, - } +use crate::rustc_smir::{Bridge, SmirError, Tables}; + +pub fn try_new_scalar<'tcx, B: Bridge>( + layout: TyAndLayout<'tcx, Ty<'tcx>>, + scalar: Scalar, + tables: &mut Tables<'tcx, B>, +) -> Result { + let size = scalar.size(); + let mut allocation = Allocation::new(size, layout.align.abi, AllocInit::Uninit, ()); + allocation + .write_scalar(&tables.tcx, alloc_range(Size::ZERO, size), scalar) + .map_err(|e| B::Error::from_internal(e))?; + + Ok(allocation) } -// We need this method instead of a Stable implementation -// because we need to get `Ty` of the const we are trying to create, to do that -// we need to have access to `ConstantKind` but we can't access that inside Stable impl. -#[allow(rustc::usage_of_qualified_ty)] -pub(crate) fn new_allocation<'tcx>( - ty: rustc_middle::ty::Ty<'tcx>, - const_value: ConstValue<'tcx>, - tables: &mut Tables<'tcx>, -) -> Allocation { - try_new_allocation(ty, const_value, tables) - .unwrap_or_else(|_| panic!("Failed to convert: {const_value:?} to {ty:?}")) +pub fn try_new_slice<'tcx, B: Bridge>( + layout: TyAndLayout<'tcx, Ty<'tcx>>, + data: ConstAllocation<'tcx>, + meta: u64, + tables: &mut Tables<'tcx, B>, +) -> Result { + let alloc_id = tables.tcx.reserve_and_set_memory_alloc(data); + let ptr = Pointer::new(alloc_id.into(), Size::ZERO); + let scalar_ptr = Scalar::from_pointer(ptr, &tables.tcx); + let scalar_meta: Scalar = Scalar::from_target_usize(meta, &tables.tcx); + let mut allocation = Allocation::new(layout.size, layout.align.abi, AllocInit::Uninit, ()); + allocation + .write_scalar( + &tables.tcx, + alloc_range(Size::ZERO, tables.tcx.data_layout.pointer_size), + scalar_ptr, + ) + .map_err(|e| B::Error::from_internal(e))?; + allocation + .write_scalar( + &tables.tcx, + alloc_range(tables.tcx.data_layout.pointer_size, scalar_meta.size()), + scalar_meta, + ) + .map_err(|e| B::Error::from_internal(e))?; + + Ok(allocation) } -#[allow(rustc::usage_of_qualified_ty)] -pub(crate) fn try_new_allocation<'tcx>( - ty: rustc_middle::ty::Ty<'tcx>, - const_value: ConstValue<'tcx>, - tables: &mut Tables<'tcx>, -) -> Result { - let layout = tables - .tcx - .layout_of(rustc_middle::ty::TypingEnv::fully_monomorphized().as_query_input(ty)) - .map_err(|e| e.stable(tables))?; - Ok(match const_value { - ConstValue::Scalar(scalar) => { - let size = scalar.size(); - let mut allocation = rustc_middle::mir::interpret::Allocation::new( - size, - layout.align.abi, - AllocInit::Uninit, - (), - ); - allocation - .write_scalar(&tables.tcx, alloc_range(Size::ZERO, size), scalar) - .map_err(|e| e.stable(tables))?; - allocation.stable(tables) - } - ConstValue::ZeroSized => new_empty_allocation(layout.align.abi), - ConstValue::Slice { data, meta } => { - let alloc_id = tables.tcx.reserve_and_set_memory_alloc(data); - let ptr = Pointer::new(alloc_id.into(), Size::ZERO); - let scalar_ptr = rustc_middle::mir::interpret::Scalar::from_pointer(ptr, &tables.tcx); - let scalar_meta = - rustc_middle::mir::interpret::Scalar::from_target_usize(meta, &tables.tcx); - let mut allocation = rustc_middle::mir::interpret::Allocation::new( - layout.size, - layout.align.abi, - AllocInit::Uninit, - (), - ); - allocation - .write_scalar( - &tables.tcx, - alloc_range(Size::ZERO, tables.tcx.data_layout.pointer_size), - scalar_ptr, - ) - .map_err(|e| e.stable(tables))?; - allocation - .write_scalar( - &tables.tcx, - alloc_range(tables.tcx.data_layout.pointer_size, scalar_meta.size()), - scalar_meta, - ) - .map_err(|e| e.stable(tables))?; - allocation.stable(tables) - } - ConstValue::Indirect { alloc_id, offset } => { - let alloc = tables.tcx.global_alloc(alloc_id).unwrap_memory(); - allocation_filter(&alloc.0, alloc_range(offset, layout.size), tables) - } - }) +pub fn try_new_indirect<'tcx, B: Bridge>( + alloc_id: AllocId, + tables: &mut Tables<'tcx, B>, +) -> ConstAllocation<'tcx> { + let alloc = tables.tcx.global_alloc(alloc_id).unwrap_memory(); + + alloc } /// Creates an `Allocation` only from information within the `AllocRange`. -pub(super) fn allocation_filter<'tcx>( +pub fn allocation_filter( alloc: &rustc_middle::mir::interpret::Allocation, alloc_range: AllocRange, - tables: &mut Tables<'tcx>, -) -> Allocation { +) -> (Vec>, Vec<(usize, AllocId)>) { let mut bytes: Vec> = alloc .inspect_with_uninit_and_ptr_outside_interpreter( alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(), @@ -117,15 +89,8 @@ pub(super) fn allocation_filter<'tcx>( .iter() .filter(|a| a.0 >= alloc_range.start && a.0 <= alloc_range.end()) { - ptrs.push(( - offset.bytes_usize() - alloc_range.start.bytes_usize(), - tables.prov(prov.alloc_id()), - )); - } - Allocation { - bytes, - provenance: ProvenanceMap { ptrs }, - align: alloc.align.bytes(), - mutability: alloc.mutability.stable(tables), + ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), prov.alloc_id())); } + + (bytes, ptrs) } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index edaec47fe7d7..4f6919d27241 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -20,7 +20,7 @@ use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use crate::rustc_internal::IndexMap; -mod alloc; +pub mod alloc; mod builder; pub mod context; mod convert; diff --git a/compiler/rustc_smir/src/stable_mir/alloc.rs b/compiler/rustc_smir/src/stable_mir/alloc.rs new file mode 100644 index 000000000000..4e6facac705e --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/alloc.rs @@ -0,0 +1,86 @@ +//! Memory allocation implementation for StableMIR. +//! +//! This module is responsible for constructing stable components. +//! All operations requiring rustc queries must be delegated +//! to `rustc_smir::alloc` to maintain stability guarantees. + +use rustc_abi::Align; +use rustc_middle::mir::ConstValue; +use rustc_middle::mir::interpret::AllocRange; +use rustc_smir::context::SmirCtxt; +use rustc_smir::{SmirError, Tables, alloc}; + +use super::Error; +use super::compiler_interface::BridgeTys; +use super::convert::Stable; +use super::mir::Mutability; +use super::ty::{Allocation, ProvenanceMap}; +use crate::rustc_smir; + +/// Creates new empty `Allocation` from given `Align`. +fn new_empty_allocation(align: Align) -> Allocation { + Allocation { + bytes: Vec::new(), + provenance: ProvenanceMap { ptrs: Vec::new() }, + align: align.bytes(), + mutability: Mutability::Not, + } +} + +// We need this method instead of a Stable implementation +// because we need to get `Ty` of the const we are trying to create, to do that +// we need to have access to `ConstantKind` but we can't access that inside Stable impl. +#[allow(rustc::usage_of_qualified_ty)] +pub(crate) fn new_allocation<'tcx>( + ty: rustc_middle::ty::Ty<'tcx>, + const_value: ConstValue<'tcx>, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, +) -> Allocation { + try_new_allocation(ty, const_value, tables, cx) + .unwrap_or_else(|_| panic!("Failed to convert: {const_value:?} to {ty:?}")) +} + +#[allow(rustc::usage_of_qualified_ty)] +pub(crate) fn try_new_allocation<'tcx>( + ty: rustc_middle::ty::Ty<'tcx>, + const_value: ConstValue<'tcx>, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, +) -> Result { + use rustc_smir::context::SmirTypingEnv; + let layout = cx + .layout_of(cx.fully_monomorphized().as_query_input(ty)) + .map_err(|e| Error::from_internal(e))?; + match const_value { + ConstValue::Scalar(scalar) => { + alloc::try_new_scalar(layout, scalar, tables).map(|alloc| alloc.stable(tables, cx)) + } + ConstValue::ZeroSized => Ok(new_empty_allocation(layout.align.abi)), + ConstValue::Slice { data, meta } => { + alloc::try_new_slice(layout, data, meta, tables).map(|alloc| alloc.stable(tables, cx)) + } + ConstValue::Indirect { alloc_id, offset } => { + let alloc = alloc::try_new_indirect(alloc_id, tables); + use rustc_smir::context::SmirAllocRange; + Ok(allocation_filter(&alloc.0, cx.alloc_range(offset, layout.size), tables, cx)) + } + } +} + +/// Creates an `Allocation` only from information within the `AllocRange`. +pub(super) fn allocation_filter<'tcx>( + alloc: &rustc_middle::mir::interpret::Allocation, + alloc_range: AllocRange, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, +) -> Allocation { + let (bytes, ptrs) = alloc::allocation_filter(alloc, alloc_range); + let ptrs = ptrs.iter().map(|(i, aid)| (*i, tables.prov(*aid))).collect(); + Allocation { + bytes, + provenance: ProvenanceMap { ptrs }, + align: alloc.align.bytes(), + mutability: alloc.mutability.stable(tables, cx), + } +} diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 1c992ec5dbb7..d3ef5f4001dc 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -40,6 +40,7 @@ use stable_mir::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, Span, TraitDef use crate::{rustc_smir, stable_mir}; pub mod abi; +mod alloc; #[macro_use] pub mod crate_def; pub mod compiler_interface; From 0f6f68313d6d1b503c695bddd2f41dc09f6c1058 Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 5 May 2025 15:31:34 +0800 Subject: [PATCH 35/62] refactor: rewrite the whole `rustc_smir::context` This commit removes the `Tables` field from `SmirCtxt`, since borrows of `tables` should only be managed by `SmirInterface`. This change prevents `SmirCtxt` from holding separate borrows and requires passing `tables` explicitly when needed. We use the `traits.rs` file to define traits that are used for encapsulating the associated functions in the rustc's internals. This is much easier to use and maintain than directly cramming everything into `SmirCtxt`. --- compiler/rustc_smir/src/rustc_smir/context.rs | 1000 ----------------- .../src/rustc_smir/context/impls.rs | 772 +++++++++++++ .../rustc_smir/src/rustc_smir/context/mod.rs | 79 ++ .../src/rustc_smir/context/traits.rs | 50 + 4 files changed, 901 insertions(+), 1000 deletions(-) delete mode 100644 compiler/rustc_smir/src/rustc_smir/context.rs create mode 100644 compiler/rustc_smir/src/rustc_smir/context/impls.rs create mode 100644 compiler/rustc_smir/src/rustc_smir/context/mod.rs create mode 100644 compiler/rustc_smir/src/rustc_smir/context/traits.rs diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs deleted file mode 100644 index 3fa83cfc6a08..000000000000 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ /dev/null @@ -1,1000 +0,0 @@ -//! Implementation of StableMIR Context. - -#![allow(rustc::usage_of_qualified_ty)] - -use std::cell::RefCell; -use std::iter; - -use rustc_abi::HasDataLayout; -use rustc_hir::{Attribute, LangItem}; -use rustc_middle::ty::layout::{ - FnAbiOf, FnAbiOfHelpers, HasTyCtxt, HasTypingEnv, LayoutOf, LayoutOfHelpers, -}; -use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; -use rustc_middle::ty::{ - CoroutineArgsExt, GenericPredicates, Instance, List, ScalarInt, TyCtxt, TypeVisitableExt, - ValTree, -}; -use rustc_middle::{mir, ty}; -use rustc_span::def_id::LOCAL_CRATE; -use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions}; -use stable_mir::mir::alloc::GlobalAlloc; -use stable_mir::mir::mono::{InstanceDef, StaticDef}; -use stable_mir::mir::{BinOp, Body, Place, UnOp}; -use stable_mir::target::{MachineInfo, MachineSize}; -use stable_mir::ty::{ - AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, CoroutineDef, Discr, FieldDef, FnDef, - ForeignDef, ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, - Span, Ty, TyConst, TyKind, UintTy, VariantDef, VariantIdx, -}; -use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol}; - -use crate::rustc_internal::RustcInternal; -use crate::rustc_smir::builder::BodyBuilder; -use crate::rustc_smir::{Stable, Tables, alloc, filter_def_ids, new_item_kind, smir_crate}; -use crate::stable_mir; - -/// Provides direct access to rustc's internal queries. -/// -/// The [`crate::stable_mir::compiler_interface::SmirInterface`] must go through -/// this context to obtain rustc-level information. -pub struct SmirCtxt<'tcx>(pub RefCell>); - -impl<'tcx> SmirCtxt<'tcx> { - pub fn target_info(&self) -> MachineInfo { - let mut tables = self.0.borrow_mut(); - MachineInfo { - endian: tables.tcx.data_layout.endian.stable(&mut *tables), - pointer_width: MachineSize::from_bits( - tables.tcx.data_layout.pointer_size.bits().try_into().unwrap(), - ), - } - } - - pub fn entry_fn(&self) -> Option { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - Some(tables.crate_item(tcx.entry_fn(())?.0)) - } - - /// Retrieve all items of the local crate that have a MIR associated with them. - pub fn all_local_items(&self) -> stable_mir::CrateItems { - let mut tables = self.0.borrow_mut(); - tables.tcx.mir_keys(()).iter().map(|item| tables.crate_item(item.to_def_id())).collect() - } - - /// Retrieve the body of a function. - /// This function will panic if the body is not available. - pub fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body { - let mut tables = self.0.borrow_mut(); - let def_id = tables[item]; - tables.tcx.instance_mir(rustc_middle::ty::InstanceKind::Item(def_id)).stable(&mut tables) - } - - /// Check whether the body of a function is available. - pub fn has_body(&self, def: DefId) -> bool { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = def.internal(&mut *tables, tcx); - tables.item_has_body(def_id) - } - - pub fn foreign_modules(&self, crate_num: CrateNum) -> Vec { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - tcx.foreign_modules(crate_num.internal(&mut *tables, tcx)) - .keys() - .map(|mod_def_id| tables.foreign_module_def(*mod_def_id)) - .collect() - } - - /// Retrieve all functions defined in this crate. - pub fn crate_functions(&self, crate_num: CrateNum) -> Vec { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let krate = crate_num.internal(&mut *tables, tcx); - filter_def_ids(tcx, krate, |def_id| tables.to_fn_def(def_id)) - } - - /// Retrieve all static items defined in this crate. - pub fn crate_statics(&self, crate_num: CrateNum) -> Vec { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let krate = crate_num.internal(&mut *tables, tcx); - filter_def_ids(tcx, krate, |def_id| tables.to_static(def_id)) - } - - pub fn foreign_module( - &self, - mod_def: stable_mir::ty::ForeignModuleDef, - ) -> stable_mir::ty::ForeignModule { - let mut tables = self.0.borrow_mut(); - let def_id = tables[mod_def.def_id()]; - let mod_def = tables.tcx.foreign_modules(def_id.krate).get(&def_id).unwrap(); - mod_def.stable(&mut *tables) - } - - pub fn foreign_items(&self, mod_def: stable_mir::ty::ForeignModuleDef) -> Vec { - let mut tables = self.0.borrow_mut(); - let def_id = tables[mod_def.def_id()]; - tables - .tcx - .foreign_modules(def_id.krate) - .get(&def_id) - .unwrap() - .foreign_items - .iter() - .map(|item_def| tables.foreign_def(*item_def)) - .collect() - } - - pub fn all_trait_decls(&self) -> stable_mir::TraitDecls { - let mut tables = self.0.borrow_mut(); - tables - .tcx - .all_traits_including_private() - .map(|trait_def_id| tables.trait_def(trait_def_id)) - .collect() - } - - pub fn trait_decls(&self, crate_num: CrateNum) -> stable_mir::TraitDecls { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - tcx.traits(crate_num.internal(&mut *tables, tcx)) - .iter() - .map(|trait_def_id| tables.trait_def(*trait_def_id)) - .collect() - } - - pub fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl { - let mut tables = self.0.borrow_mut(); - let def_id = tables[trait_def.0]; - let trait_def = tables.tcx.trait_def(def_id); - trait_def.stable(&mut *tables) - } - - pub fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - iter::once(LOCAL_CRATE) - .chain(tables.tcx.crates(()).iter().copied()) - .flat_map(|cnum| tcx.trait_impls_in_crate(cnum).iter()) - .map(|impl_def_id| tables.impl_def(*impl_def_id)) - .collect() - } - - pub fn trait_impls(&self, crate_num: CrateNum) -> stable_mir::ImplTraitDecls { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - tcx.trait_impls_in_crate(crate_num.internal(&mut *tables, tcx)) - .iter() - .map(|impl_def_id| tables.impl_def(*impl_def_id)) - .collect() - } - - pub fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait { - let mut tables = self.0.borrow_mut(); - let def_id = tables[impl_def.0]; - let impl_trait = tables.tcx.impl_trait_ref(def_id).unwrap(); - impl_trait.stable(&mut *tables) - } - - pub fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics { - let mut tables = self.0.borrow_mut(); - let def_id = tables[def_id]; - let generics = tables.tcx.generics_of(def_id); - generics.stable(&mut *tables) - } - - pub fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates { - let mut tables = self.0.borrow_mut(); - let def_id = tables[def_id]; - let GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id); - stable_mir::ty::GenericPredicates { - parent: parent.map(|did| tables.trait_def(did)), - predicates: predicates - .iter() - .map(|(clause, span)| { - ( - clause.as_predicate().kind().skip_binder().stable(&mut *tables), - span.stable(&mut *tables), - ) - }) - .collect(), - } - } - - pub fn explicit_predicates_of( - &self, - def_id: stable_mir::DefId, - ) -> stable_mir::ty::GenericPredicates { - let mut tables = self.0.borrow_mut(); - let def_id = tables[def_id]; - let GenericPredicates { parent, predicates } = tables.tcx.explicit_predicates_of(def_id); - stable_mir::ty::GenericPredicates { - parent: parent.map(|did| tables.trait_def(did)), - predicates: predicates - .iter() - .map(|(clause, span)| { - ( - clause.as_predicate().kind().skip_binder().stable(&mut *tables), - span.stable(&mut *tables), - ) - }) - .collect(), - } - } - - /// Get information about the local crate. - pub fn local_crate(&self) -> stable_mir::Crate { - let tables = self.0.borrow(); - smir_crate(tables.tcx, LOCAL_CRATE) - } - - /// Retrieve a list of all external crates. - pub fn external_crates(&self) -> Vec { - let tables = self.0.borrow(); - tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect() - } - - /// Find a crate with the given name. - pub fn find_crates(&self, name: &str) -> Vec { - let tables = self.0.borrow(); - let crates: Vec = [LOCAL_CRATE] - .iter() - .chain(tables.tcx.crates(()).iter()) - .filter_map(|crate_num| { - let crate_name = tables.tcx.crate_name(*crate_num).to_string(); - (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num)) - }) - .collect(); - crates - } - - /// Returns the name of given `DefId`. - pub fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol { - let tables = self.0.borrow(); - if trimmed { - with_forced_trimmed_paths!(tables.tcx.def_path_str(tables[def_id])) - } else { - with_no_trimmed_paths!(tables.tcx.def_path_str(tables[def_id])) - } - } - - /// Return registered tool attributes with the given attribute name. - /// - /// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool - /// attributes will simply return an empty list. - /// - /// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`. - /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`. - pub fn tool_attrs( - &self, - def_id: stable_mir::DefId, - attr: &[stable_mir::Symbol], - ) -> Vec { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let did = tables[def_id]; - let attr_name: Vec<_> = attr.iter().map(|seg| rustc_span::Symbol::intern(&seg)).collect(); - tcx.get_attrs_by_path(did, &attr_name) - .filter_map(|attribute| { - if let Attribute::Unparsed(u) = attribute { - let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute); - Some(stable_mir::crate_def::Attribute::new( - attr_str, - u.span.stable(&mut *tables), - )) - } else { - None - } - }) - .collect() - } - - /// Get all tool attributes of a definition. - pub fn all_tool_attrs( - &self, - def_id: stable_mir::DefId, - ) -> Vec { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let did = tables[def_id]; - let attrs_iter = if let Some(did) = did.as_local() { - tcx.hir_attrs(tcx.local_def_id_to_hir_id(did)).iter() - } else { - tcx.attrs_for_def(did).iter() - }; - attrs_iter - .filter_map(|attribute| { - if let Attribute::Unparsed(u) = attribute { - let attr_str = rustc_hir_pretty::attribute_to_string(&tcx, attribute); - Some(stable_mir::crate_def::Attribute::new( - attr_str, - u.span.stable(&mut *tables), - )) - } else { - None - } - }) - .collect() - } - - /// Returns printable, human readable form of `Span`. - pub fn span_to_string(&self, span: stable_mir::ty::Span) -> String { - let tables = self.0.borrow(); - tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span]) - } - - /// Return filename from given `Span`, for diagnostic purposes. - pub fn get_filename(&self, span: &Span) -> Filename { - let tables = self.0.borrow(); - tables - .tcx - .sess - .source_map() - .span_to_filename(tables[*span]) - .display(rustc_span::FileNameDisplayPreference::Local) - .to_string() - } - - /// Return lines corresponding to this `Span`. - pub fn get_lines(&self, span: &Span) -> LineInfo { - let tables = self.0.borrow(); - let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]); - LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 } - } - - /// Returns the `kind` of given `DefId`. - pub fn item_kind(&self, item: CrateItem) -> ItemKind { - let tables = self.0.borrow(); - new_item_kind(tables.tcx.def_kind(tables[item.0])) - } - - /// Returns whether this is a foreign item. - pub fn is_foreign_item(&self, item: DefId) -> bool { - let tables = self.0.borrow(); - tables.tcx.is_foreign_item(tables[item]) - } - - /// Returns the kind of a given foreign item. - pub fn foreign_item_kind(&self, def: ForeignDef) -> ForeignItemKind { - let mut tables = self.0.borrow_mut(); - let def_id = tables[def.def_id()]; - let tcx = tables.tcx; - use rustc_hir::def::DefKind; - match tcx.def_kind(def_id) { - DefKind::Fn => ForeignItemKind::Fn(tables.fn_def(def_id)), - DefKind::Static { .. } => ForeignItemKind::Static(tables.static_def(def_id)), - DefKind::ForeignTy => ForeignItemKind::Type( - tables.intern_ty(rustc_middle::ty::Ty::new_foreign(tcx, def_id)), - ), - def_kind => unreachable!("Unexpected kind for a foreign item: {:?}", def_kind), - } - } - - /// Returns the kind of a given algebraic data type. - pub fn adt_kind(&self, def: AdtDef) -> AdtKind { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - def.internal(&mut *tables, tcx).adt_kind().stable(&mut *tables) - } - - /// Returns if the ADT is a box. - pub fn adt_is_box(&self, def: AdtDef) -> bool { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - def.internal(&mut *tables, tcx).is_box() - } - - /// Returns whether this ADT is simd. - pub fn adt_is_simd(&self, def: AdtDef) -> bool { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - def.internal(&mut *tables, tcx).repr().simd() - } - - /// Returns whether this definition is a C string. - pub fn adt_is_cstr(&self, def: AdtDef) -> bool { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = def.0.internal(&mut *tables, tcx); - tables.tcx.is_lang_item(def_id, LangItem::CStr) - } - - /// Returns the representation options for this ADT - pub fn adt_repr(&self, def: AdtDef) -> ReprOptions { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - def.internal(&mut *tables, tcx).repr().stable(&mut *tables) - } - - /// Retrieve the function signature for the given generic arguments. - pub fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = def.0.internal(&mut *tables, tcx); - let sig = - tables.tcx.fn_sig(def_id).instantiate(tables.tcx, args.internal(&mut *tables, tcx)); - sig.stable(&mut *tables) - } - - /// Retrieve the intrinsic definition if the item corresponds one. - pub fn intrinsic(&self, def: DefId) -> Option { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = def.internal(&mut *tables, tcx); - let intrinsic = tcx.intrinsic_raw(def_id); - intrinsic.map(|_| IntrinsicDef(def)) - } - - /// Retrieve the plain function name of an intrinsic. - pub fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = def.0.internal(&mut *tables, tcx); - tcx.intrinsic(def_id).unwrap().name.to_string() - } - - /// Retrieve the closure signature for the given generic arguments. - pub fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let args_ref = args.internal(&mut *tables, tcx); - let sig = args_ref.as_closure().sig(); - sig.stable(&mut *tables) - } - - /// The number of variants in this ADT. - pub fn adt_variants_len(&self, def: AdtDef) -> usize { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - def.internal(&mut *tables, tcx).variants().len() - } - - /// Discriminant for a given variant index of AdtDef - pub fn adt_discr_for_variant(&self, adt: AdtDef, variant: VariantIdx) -> Discr { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let adt = adt.internal(&mut *tables, tcx); - let variant = variant.internal(&mut *tables, tcx); - adt.discriminant_for_variant(tcx, variant).stable(&mut *tables) - } - - /// Discriminant for a given variand index and args of a coroutine - pub fn coroutine_discr_for_variant( - &self, - coroutine: CoroutineDef, - args: &GenericArgs, - variant: VariantIdx, - ) -> Discr { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let coroutine = coroutine.def_id().internal(&mut *tables, tcx); - let args = args.internal(&mut *tables, tcx); - let variant = variant.internal(&mut *tables, tcx); - args.as_coroutine().discriminant_for_variant(coroutine, tcx, variant).stable(&mut *tables) - } - - /// The name of a variant. - pub fn variant_name(&self, def: VariantDef) -> Symbol { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - def.internal(&mut *tables, tcx).name.to_string() - } - - pub fn variant_fields(&self, def: VariantDef) -> Vec { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - def.internal(&mut *tables, tcx).fields.iter().map(|f| f.stable(&mut *tables)).collect() - } - - /// Evaluate constant as a target usize. - pub fn eval_target_usize(&self, cnst: &MirConst) -> Result { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let mir_const = cnst.internal(&mut *tables, tcx); - mir_const - .try_eval_target_usize(tables.tcx, ty::TypingEnv::fully_monomorphized()) - .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) - } - pub fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let mir_const = cnst.internal(&mut *tables, tcx); - mir_const - .try_to_target_usize(tables.tcx) - .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) - } - - /// Create a new zero-sized constant. - pub fn try_new_const_zst(&self, ty: Ty) -> Result { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let ty_internal = ty.internal(&mut *tables, tcx); - let size = tables - .tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty_internal)) - .map_err(|err| { - Error::new(format!( - "Cannot create a zero-sized constant for type `{ty_internal}`: {err}" - )) - })? - .size; - if size.bytes() != 0 { - return Err(Error::new(format!( - "Cannot create a zero-sized constant for type `{ty_internal}`: \ - Type `{ty_internal}` has {} bytes", - size.bytes() - ))); - } - - Ok(mir::Const::Ty(ty_internal, ty::Const::zero_sized(tables.tcx, ty_internal)) - .stable(&mut *tables)) - } - - /// Create a new constant that represents the given string value. - pub fn new_const_str(&self, value: &str) -> MirConst { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let ty = ty::Ty::new_static_str(tcx); - let bytes = value.as_bytes(); - let valtree = ty::ValTree::from_raw_bytes(tcx, bytes); - let cv = ty::Value { ty, valtree }; - let val = tcx.valtree_to_const_val(cv); - mir::Const::from_value(val, ty).stable(&mut tables) - } - - /// Create a new constant that represents the given boolean value. - pub fn new_const_bool(&self, value: bool) -> MirConst { - let mut tables = self.0.borrow_mut(); - mir::Const::from_bool(tables.tcx, value).stable(&mut tables) - } - - /// Create a new constant that represents the given value. - pub fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); - let size = tables - .tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) - .unwrap() - .size; - let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { - Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`.")) - })?; - Ok(mir::Const::from_scalar(tcx, mir::interpret::Scalar::Int(scalar), ty) - .stable(&mut tables)) - } - pub fn try_new_ty_const_uint( - &self, - value: u128, - uint_ty: UintTy, - ) -> Result { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); - let size = tables - .tcx - .layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) - .unwrap() - .size; - - // We don't use Const::from_bits since it doesn't have any error checking. - let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { - Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`.")) - })?; - Ok(ty::Const::new_value(tcx, ValTree::from_scalar_int(tcx, scalar), ty) - .stable(&mut *tables)) - } - - /// Create a new type from the given kind. - pub fn new_rigid_ty(&self, kind: RigidTy) -> stable_mir::ty::Ty { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let internal_kind = kind.internal(&mut *tables, tcx); - tables.tcx.mk_ty_from_kind(internal_kind).stable(&mut *tables) - } - - /// Create a new box type, `Box`, for the given inner type `T`. - pub fn new_box_ty(&self, ty: stable_mir::ty::Ty) -> stable_mir::ty::Ty { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let inner = ty.internal(&mut *tables, tcx); - ty::Ty::new_box(tables.tcx, inner).stable(&mut *tables) - } - - /// Returns the type of given crate item. - pub fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - tcx.type_of(item.internal(&mut *tables, tcx)).instantiate_identity().stable(&mut *tables) - } - - /// Returns the type of given definition instantiated with the given arguments. - pub fn def_ty_with_args( - &self, - item: stable_mir::DefId, - args: &GenericArgs, - ) -> stable_mir::ty::Ty { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let args = args.internal(&mut *tables, tcx); - let def_ty = tables.tcx.type_of(item.internal(&mut *tables, tcx)); - tables - .tcx - .instantiate_and_normalize_erasing_regions( - args, - ty::TypingEnv::fully_monomorphized(), - def_ty, - ) - .stable(&mut *tables) - } - - /// Returns literal value of a const as a string. - pub fn mir_const_pretty(&self, cnst: &stable_mir::ty::MirConst) -> String { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - cnst.internal(&mut *tables, tcx).to_string() - } - - /// `Span` of an item. - pub fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span { - let mut tables = self.0.borrow_mut(); - tables.tcx.def_span(tables[def_id]).stable(&mut *tables) - } - - /// Obtain the representation of a type. - pub fn ty_pretty(&self, ty: stable_mir::ty::Ty) -> String { - let tables = self.0.borrow_mut(); - tables.types[ty].to_string() - } - - /// Obtain the representation of a type. - pub fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind { - let mut tables = self.0.borrow_mut(); - tables.types[ty].kind().stable(&mut *tables) - } - - pub fn ty_const_pretty(&self, ct: stable_mir::ty::TyConstId) -> String { - let tables = self.0.borrow_mut(); - tables.ty_consts[ct].to_string() - } - - /// Get the discriminant Ty for this Ty if there's one. - pub fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let internal_kind = ty.internal(&mut *tables, tcx); - let internal_ty = tables.tcx.mk_ty_from_kind(internal_kind); - internal_ty.discriminant_ty(tables.tcx).stable(&mut *tables) - } - - /// Get the body of an Instance which is already monomorphized. - pub fn instance_body(&self, def: InstanceDef) -> Option { - let mut tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - tables - .instance_has_body(instance) - .then(|| BodyBuilder::new(tables.tcx, instance).build(&mut *tables)) - } - - /// Get the instance type with generic instantiations applied and lifetimes erased. - pub fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty { - let mut tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation"); - instance.ty(tables.tcx, ty::TypingEnv::fully_monomorphized()).stable(&mut *tables) - } - - /// Get the instantiation types. - pub fn instance_args(&self, def: InstanceDef) -> GenericArgs { - let mut tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - instance.args.stable(&mut *tables) - } - - /// Get an instance ABI. - pub fn instance_abi(&self, def: InstanceDef) -> Result { - let mut tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - Ok(tables.fn_abi_of_instance(instance, List::empty())?.stable(&mut *tables)) - } - - /// Get the ABI of a function pointer. - pub fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let sig = fn_ptr.internal(&mut *tables, tcx); - Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?.stable(&mut *tables)) - } - - /// Get the instance. - pub fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId { - let mut tables = self.0.borrow_mut(); - let def_id = tables.instances[def].def_id(); - tables.create_def_id(def_id) - } - - /// Get the instance mangled name. - pub fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol { - let tables = self.0.borrow_mut(); - let instance = tables.instances[instance]; - tables.tcx.symbol_name(instance).name.to_string() - } - - /// Check if this is an empty DropGlue shim. - pub fn is_empty_drop_shim(&self, def: InstanceDef) -> bool { - let tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - matches!(instance.def, ty::InstanceKind::DropGlue(_, None)) - } - - /// Convert a non-generic crate item into an instance. - /// This function will panic if the item is generic. - pub fn mono_instance(&self, def_id: stable_mir::DefId) -> stable_mir::mir::mono::Instance { - let mut tables = self.0.borrow_mut(); - let def_id = tables[def_id]; - Instance::mono(tables.tcx, def_id).stable(&mut *tables) - } - - /// Item requires monomorphization. - pub fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool { - let tables = self.0.borrow(); - let def_id = tables[def_id]; - let generics = tables.tcx.generics_of(def_id); - let result = generics.requires_monomorphization(tables.tcx); - result - } - - /// Resolve an instance from the given function definition and generic arguments. - pub fn resolve_instance( - &self, - def: stable_mir::ty::FnDef, - args: &stable_mir::ty::GenericArgs, - ) -> Option { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = def.0.internal(&mut *tables, tcx); - let args_ref = args.internal(&mut *tables, tcx); - match Instance::try_resolve( - tables.tcx, - ty::TypingEnv::fully_monomorphized(), - def_id, - args_ref, - ) { - Ok(Some(instance)) => Some(instance.stable(&mut *tables)), - Ok(None) | Err(_) => None, - } - } - - /// Resolve an instance for drop_in_place for the given type. - pub fn resolve_drop_in_place(&self, ty: stable_mir::ty::Ty) -> stable_mir::mir::mono::Instance { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let internal_ty = ty.internal(&mut *tables, tcx); - let instance = Instance::resolve_drop_in_place(tables.tcx, internal_ty); - instance.stable(&mut *tables) - } - - /// Resolve instance for a function pointer. - pub fn resolve_for_fn_ptr( - &self, - def: FnDef, - args: &GenericArgs, - ) -> Option { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = def.0.internal(&mut *tables, tcx); - let args_ref = args.internal(&mut *tables, tcx); - Instance::resolve_for_fn_ptr( - tables.tcx, - ty::TypingEnv::fully_monomorphized(), - def_id, - args_ref, - ) - .stable(&mut *tables) - } - - /// Resolve instance for a closure with the requested type. - pub fn resolve_closure( - &self, - def: ClosureDef, - args: &GenericArgs, - kind: ClosureKind, - ) -> Option { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = def.0.internal(&mut *tables, tcx); - let args_ref = args.internal(&mut *tables, tcx); - let closure_kind = kind.internal(&mut *tables, tcx); - Some( - Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind) - .stable(&mut *tables), - ) - } - - /// Try to evaluate an instance into a constant. - pub fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result { - let mut tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - let tcx = tables.tcx; - let result = tcx.const_eval_instance( - ty::TypingEnv::fully_monomorphized(), - instance, - tcx.def_span(instance.def_id()), - ); - result - .map(|const_val| { - alloc::try_new_allocation( - const_ty.internal(&mut *tables, tcx), - const_val, - &mut *tables, - ) - }) - .map_err(|e| e.stable(&mut *tables))? - } - - /// Evaluate a static's initializer. - pub fn eval_static_initializer(&self, def: StaticDef) -> Result { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = def.0.internal(&mut *tables, tcx); - tables.tcx.eval_static_initializer(def_id).stable(&mut *tables) - } - - /// Retrieve global allocation for the given allocation ID. - pub fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let alloc_id = alloc.internal(&mut *tables, tcx); - tables.tcx.global_alloc(alloc_id).stable(&mut *tables) - } - - /// Retrieve the id for the virtual table. - pub fn vtable_allocation( - &self, - global_alloc: &GlobalAlloc, - ) -> Option { - let mut tables = self.0.borrow_mut(); - let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else { - return None; - }; - let tcx = tables.tcx; - let alloc_id = tables.tcx.vtable_allocation(( - ty.internal(&mut *tables, tcx), - trait_ref - .internal(&mut *tables, tcx) - .map(|principal| tcx.instantiate_bound_regions_with_erased(principal)), - )); - Some(alloc_id.stable(&mut *tables)) - } - - pub fn krate(&self, def_id: stable_mir::DefId) -> Crate { - let tables = self.0.borrow(); - smir_crate(tables.tcx, tables[def_id].krate) - } - - /// Retrieve the instance name for diagnostic messages. - /// - /// This will return the specialized name, e.g., `Vec::new`. - pub fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol { - let tables = self.0.borrow_mut(); - let instance = tables.instances[def]; - if trimmed { - with_forced_trimmed_paths!( - tables.tcx.def_path_str_with_args(instance.def_id(), instance.args) - ) - } else { - with_no_trimmed_paths!( - tables.tcx.def_path_str_with_args(instance.def_id(), instance.args) - ) - } - } - - /// Get the layout of a type. - pub fn ty_layout(&self, ty: Ty) -> Result { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let ty = ty.internal(&mut *tables, tcx); - let layout = tables.layout_of(ty)?.layout; - Ok(layout.stable(&mut *tables)) - } - - /// Get the layout shape. - pub fn layout_shape(&self, id: Layout) -> LayoutShape { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - id.internal(&mut *tables, tcx).0.stable(&mut *tables) - } - - /// Get a debug string representation of a place. - pub fn place_pretty(&self, place: &Place) -> String { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - format!("{:?}", place.internal(&mut *tables, tcx)) - } - - /// Get the resulting type of binary operation. - pub fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let rhs_internal = rhs.internal(&mut *tables, tcx); - let lhs_internal = lhs.internal(&mut *tables, tcx); - let ty = bin_op.internal(&mut *tables, tcx).ty(tcx, rhs_internal, lhs_internal); - ty.stable(&mut *tables) - } - - /// Get the resulting type of unary operation. - pub fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let arg_internal = arg.internal(&mut *tables, tcx); - let ty = un_op.internal(&mut *tables, tcx).ty(tcx, arg_internal); - ty.stable(&mut *tables) - } - - /// Get all associated items of a definition. - pub fn associated_items(&self, def_id: stable_mir::DefId) -> stable_mir::AssocItems { - let mut tables = self.0.borrow_mut(); - let tcx = tables.tcx; - let def_id = tables[def_id]; - let assoc_items = if tcx.is_trait_alias(def_id) { - Vec::new() - } else { - tcx.associated_item_def_ids(def_id) - .iter() - .map(|did| tcx.associated_item(*did).stable(&mut *tables)) - .collect() - }; - assoc_items - } -} - -/// Implement error handling for extracting function ABI information. -impl<'tcx> FnAbiOfHelpers<'tcx> for Tables<'tcx> { - type FnAbiOfResult = Result<&'tcx rustc_target::callconv::FnAbi<'tcx, ty::Ty<'tcx>>, Error>; - - #[inline] - fn handle_fn_abi_err( - &self, - err: ty::layout::FnAbiError<'tcx>, - _span: rustc_span::Span, - fn_abi_request: ty::layout::FnAbiRequest<'tcx>, - ) -> Error { - Error::new(format!("Failed to get ABI for `{fn_abi_request:?}`: {err:?}")) - } -} - -impl<'tcx> LayoutOfHelpers<'tcx> for Tables<'tcx> { - type LayoutOfResult = Result, Error>; - - #[inline] - fn handle_layout_err( - &self, - err: ty::layout::LayoutError<'tcx>, - _span: rustc_span::Span, - ty: ty::Ty<'tcx>, - ) -> Error { - Error::new(format!("Failed to get layout for `{ty}`: {err}")) - } -} - -impl<'tcx> HasTypingEnv<'tcx> for Tables<'tcx> { - fn typing_env(&self) -> ty::TypingEnv<'tcx> { - ty::TypingEnv::fully_monomorphized() - } -} - -impl<'tcx> HasTyCtxt<'tcx> for Tables<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } -} - -impl<'tcx> HasDataLayout for Tables<'tcx> { - fn data_layout(&self) -> &rustc_abi::TargetDataLayout { - self.tcx.data_layout() - } -} diff --git a/compiler/rustc_smir/src/rustc_smir/context/impls.rs b/compiler/rustc_smir/src/rustc_smir/context/impls.rs new file mode 100644 index 000000000000..77a2f879d6a7 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/context/impls.rs @@ -0,0 +1,772 @@ +//! Implementation of StableMIR Context. + +#![allow(rustc::usage_of_qualified_ty)] + +use std::iter; + +use rustc_abi::{Endian, Layout}; +use rustc_hir::def::DefKind; +use rustc_hir::{Attribute, LangItem}; +use rustc_middle::infer::canonical::ir::{ + Binder, EarlyBinder, ExistentialTraitRef, FnSig, TraitRef, +}; +use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar}; +use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp}; +use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; +use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; +use rustc_middle::ty::{ + AdtDef, AdtKind, AssocItem, ClosureKind, GenericArgsRef, GenericPredicates, Instance, + InstanceKind, IntrinsicDef, List, PolyFnSig, ScalarInt, TraitDef, Ty, TyCtxt, TyKind, + TypeVisitableExt, UintTy, ValTree, VariantDef, +}; +use rustc_middle::{mir, ty}; +use rustc_session::cstore::ForeignModule; +use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use rustc_span::{FileNameDisplayPreference, Span, Symbol}; +use rustc_target::callconv::FnAbi; + +use super::{ + SmirAllocRange, SmirCtxt, SmirExistentialProjection, SmirExistentialTraitRef, SmirRegion, + SmirTraitRef, SmirTy, SmirTypingEnv, +}; +use crate::rustc_smir::builder::BodyBuilder; +use crate::rustc_smir::{Bridge, SmirError, Tables, filter_def_ids}; + +impl<'tcx, B: Bridge> SmirExistentialProjection<'tcx> for SmirCtxt<'tcx, B> { + fn new_from_args( + &self, + def_id: rustc_span::def_id::DefId, + args: ty::GenericArgsRef<'tcx>, + term: ty::Term<'tcx>, + ) -> ty::ExistentialProjection<'tcx> { + ty::ExistentialProjection::new_from_args(self.tcx, def_id, args, term) + } +} + +impl<'tcx, B: Bridge> SmirExistentialTraitRef<'tcx> for SmirCtxt<'tcx, B> { + fn new_from_args( + &self, + trait_def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> ty::ExistentialTraitRef<'tcx> { + ty::ExistentialTraitRef::new_from_args(self.tcx, trait_def_id, args) + } +} + +impl<'tcx, B: Bridge> SmirTraitRef<'tcx> for SmirCtxt<'tcx, B> { + fn new_from_args( + &self, + trait_def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> ty::TraitRef<'tcx> { + ty::TraitRef::new_from_args(self.tcx, trait_def_id, args) + } +} + +impl<'tcx, B: Bridge> SmirTy<'tcx> for SmirCtxt<'tcx, B> { + fn new_foreign(&self, def_id: DefId) -> ty::Ty<'tcx> { + ty::Ty::new_foreign(self.tcx, def_id) + } +} + +impl<'tcx, B: Bridge> SmirTypingEnv<'tcx> for SmirCtxt<'tcx, B> { + fn fully_monomorphized(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv::fully_monomorphized() + } +} + +impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> { + fn alloc_range( + &self, + offset: rustc_abi::Size, + size: rustc_abi::Size, + ) -> mir::interpret::AllocRange { + rustc_middle::mir::interpret::alloc_range(offset, size) + } +} + +impl<'tcx, B: Bridge> SmirRegion<'tcx> for SmirCtxt<'tcx, B> { + fn lifetimes_re_erased(&self) -> ty::Region<'tcx> { + self.tcx.lifetimes.re_erased + } +} + +impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { + pub fn lift>>(&self, value: T) -> Option { + self.tcx.lift(value) + } + + pub fn mk_args_from_iter(&self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply, ty::GenericArgsRef<'tcx>>, + { + self.tcx.mk_args_from_iter(iter) + } + + pub fn mk_pat(&self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx> { + self.tcx.mk_pat(v) + } + + pub fn mk_poly_existential_predicates( + &self, + eps: &[ty::PolyExistentialPredicate<'tcx>], + ) -> &'tcx List> { + self.tcx.mk_poly_existential_predicates(eps) + } + + pub fn mk_type_list(&self, v: &[Ty<'tcx>]) -> &'tcx List> { + self.tcx.mk_type_list(v) + } + + pub fn mk_bound_variable_kinds_from_iter(&self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply>, + { + self.tcx.mk_bound_variable_kinds_from_iter(iter) + } + + pub fn mk_place_elems(&self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List> { + self.tcx.mk_place_elems(v) + } + + pub fn adt_def(&self, def_id: DefId) -> AdtDef<'tcx> { + self.tcx.adt_def(def_id) + } + + pub fn coroutine_movability(&self, def_id: DefId) -> ty::Movability { + self.tcx.coroutine_movability(def_id) + } + + pub fn valtree_to_const_val(&self, key: ty::Value<'tcx>) -> ConstValue<'tcx> { + self.tcx.valtree_to_const_val(key) + } + + pub fn target_endian(&self) -> Endian { + self.tcx.data_layout.endian + } + + pub fn target_pointer_size(&self) -> usize { + self.tcx.data_layout.pointer_size.bits().try_into().unwrap() + } + + pub fn entry_fn(&self) -> Option { + Some(self.tcx.entry_fn(())?.0) + } + + /// Retrieve all items of the local crate that have a MIR associated with them. + pub fn all_local_items(&self) -> Vec { + self.tcx.mir_keys(()).iter().map(|item| item.to_def_id()).collect() + } + + /// Retrieve the body of a function. + /// This function will panic if the body is not available. + pub fn mir_body(&self, item: DefId) -> &'tcx Body<'tcx> { + self.tcx.instance_mir(InstanceKind::Item(item)) + } + + /// Check whether the body of a function is available. + pub fn has_body(&self, def: DefId, tables: &mut Tables<'_, B>) -> bool { + tables.item_has_body(def) + } + + pub fn foreign_modules(&self, crate_num: CrateNum) -> Vec { + self.tcx.foreign_modules(crate_num).keys().map(|mod_def_id| *mod_def_id).collect() + } + + /// Retrieve all functions defined in this crate. + pub fn crate_functions(&self, crate_num: CrateNum, tables: &mut Tables<'_, B>) -> Vec { + filter_def_ids(self.tcx, crate_num, |def_id| tables.filter_fn_def(def_id)) + } + + /// Retrieve all static items defined in this crate. + pub fn crate_statics(&self, crate_num: CrateNum, tables: &mut Tables<'_, B>) -> Vec { + filter_def_ids(self.tcx, crate_num, |def_id| tables.filter_static_def(def_id)) + } + + pub fn foreign_module(&self, mod_def: DefId) -> &ForeignModule { + self.tcx.foreign_modules(mod_def.krate).get(&mod_def).unwrap() + } + + pub fn foreign_items(&self, mod_def: DefId) -> Vec { + self.tcx + .foreign_modules(mod_def.krate) + .get(&mod_def) + .unwrap() + .foreign_items + .iter() + .map(|item_def| *item_def) + .collect() + } + + pub fn all_trait_decls(&self) -> impl Iterator { + self.tcx.all_traits_including_private() + } + + pub fn trait_decls(&self, crate_num: CrateNum) -> Vec { + self.tcx.traits(crate_num).iter().map(|trait_def_id| *trait_def_id).collect() + } + + pub fn trait_decl(&self, trait_def: DefId) -> &'tcx TraitDef { + self.tcx.trait_def(trait_def) + } + + pub fn all_trait_impls(&self) -> Vec { + iter::once(LOCAL_CRATE) + .chain(self.tcx.crates(()).iter().copied()) + .flat_map(|cnum| self.tcx.trait_impls_in_crate(cnum).iter()) + .map(|impl_def_id| *impl_def_id) + .collect() + } + + pub fn trait_impls(&self, crate_num: CrateNum) -> Vec { + self.tcx.trait_impls_in_crate(crate_num).iter().map(|impl_def_id| *impl_def_id).collect() + } + + pub fn trait_impl(&self, impl_def: DefId) -> EarlyBinder, TraitRef>> { + self.tcx.impl_trait_ref(impl_def).unwrap() + } + + pub fn generics_of(&self, def_id: DefId) -> &'tcx ty::Generics { + self.tcx.generics_of(def_id) + } + + pub fn predicates_of(&self, def_id: DefId) -> GenericPredicates<'tcx> { + self.tcx.predicates_of(def_id) + } + + pub fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates<'tcx> { + self.tcx.explicit_predicates_of(def_id) + } + + pub fn crate_name(&self, crate_num: CrateNum) -> String { + self.tcx.crate_name(crate_num).to_string() + } + + pub fn crate_is_local(&self, crate_num: CrateNum) -> bool { + crate_num == LOCAL_CRATE + } + + pub fn crate_num_id(&self, crate_num: CrateNum) -> usize { + crate_num.into() + } + + pub fn local_crate_num(&self) -> CrateNum { + LOCAL_CRATE + } + + /// Retrieve a list of all external crates. + pub fn external_crates(&self) -> Vec { + self.tcx.crates(()).iter().map(|crate_num| *crate_num).collect() + } + + /// Find a crate with the given name. + pub fn find_crates(&self, name: &str) -> Vec { + let crates: Vec = [LOCAL_CRATE] + .iter() + .chain(self.tcx.crates(()).iter()) + .filter_map(|crate_num| { + let crate_name = self.tcx.crate_name(*crate_num).to_string(); + (name == crate_name).then(|| *crate_num) + }) + .collect(); + crates + } + + /// Returns the name of given `DefId`. + pub fn def_name(&self, def_id: DefId, trimmed: bool) -> String { + if trimmed { + with_forced_trimmed_paths!(self.tcx.def_path_str(def_id)) + } else { + with_no_trimmed_paths!(self.tcx.def_path_str(def_id)) + } + } + + /// Return registered tool attributes with the given attribute name. + /// + /// FIXME(jdonszelmann): may panic on non-tool attributes. After more attribute work, non-tool + /// attributes will simply return an empty list. + /// + /// Single segmented name like `#[clippy]` is specified as `&["clippy".to_string()]`. + /// Multi-segmented name like `#[rustfmt::skip]` is specified as `&["rustfmt".to_string(), "skip".to_string()]`. + pub fn tool_attrs(&self, def_id: DefId, attr: &[String]) -> Vec<(String, Span)> { + let attr_name: Vec<_> = attr.iter().map(|seg| Symbol::intern(&seg)).collect(); + self.tcx + .get_attrs_by_path(def_id, &attr_name) + .filter_map(|attribute| { + if let Attribute::Unparsed(u) = attribute { + let attr_str = rustc_hir_pretty::attribute_to_string(&self.tcx, attribute); + Some((attr_str, u.span)) + } else { + None + } + }) + .collect() + } + + /// Get all tool attributes of a definition. + pub fn all_tool_attrs(&self, did: DefId) -> Vec<(String, Span)> { + let attrs_iter = if let Some(did) = did.as_local() { + self.tcx.hir_attrs(self.tcx.local_def_id_to_hir_id(did)).iter() + } else { + self.tcx.attrs_for_def(did).iter() + }; + attrs_iter + .filter_map(|attribute| { + if let Attribute::Unparsed(u) = attribute { + let attr_str = rustc_hir_pretty::attribute_to_string(&self.tcx, attribute); + Some((attr_str, u.span)) + } else { + None + } + }) + .collect() + } + + /// Returns printable, human readable form of `Span`. + pub fn span_to_string(&self, span: Span) -> String { + self.tcx.sess.source_map().span_to_diagnostic_string(span) + } + + /// Return filename from given `Span`, for diagnostic purposes. + pub fn get_filename(&self, span: Span) -> String { + self.tcx + .sess + .source_map() + .span_to_filename(span) + .display(FileNameDisplayPreference::Local) + .to_string() + } + + /// Return lines corresponding to this `Span`. + pub fn get_lines(&self, span: Span) -> (usize, usize, usize, usize) { + let lines = &self.tcx.sess.source_map().span_to_location_info(span); + (lines.1, lines.2, lines.3, lines.4) + } + + /// Returns the `kind` of given `DefId`. + pub fn def_kind(&self, item: DefId) -> DefKind { + self.tcx.def_kind(item) + } + + /// Returns whether this is a foreign item. + pub fn is_foreign_item(&self, item: DefId) -> bool { + self.tcx.is_foreign_item(item) + } + + /// Returns the kind of a given foreign item. + pub fn foreign_item_kind(&self, def_id: DefId) -> DefKind { + self.tcx.def_kind(def_id) + } + + /// Returns the kind of a given algebraic data type. + pub fn adt_kind(&self, def: AdtDef<'tcx>) -> AdtKind { + def.adt_kind() + } + + /// Returns if the ADT is a box. + pub fn adt_is_box(&self, def: AdtDef<'tcx>) -> bool { + def.is_box() + } + + /// Returns whether this ADT is simd. + pub fn adt_is_simd(&self, def: AdtDef<'tcx>) -> bool { + def.repr().simd() + } + + /// Returns whether this definition is a C string. + pub fn adt_is_cstr(&self, def_id: DefId) -> bool { + self.tcx.is_lang_item(def_id, LangItem::CStr) + } + + /// Retrieve the function signature for the given generic arguments. + pub fn fn_sig( + &self, + def_id: DefId, + args_ref: GenericArgsRef<'tcx>, + ) -> Binder, FnSig>> { + let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args_ref); + sig + } + + /// Retrieve the intrinsic definition if the item corresponds one. + pub fn intrinsic(&self, def_id: DefId) -> Option { + let intrinsic = self.tcx.intrinsic_raw(def_id); + intrinsic + } + + /// Retrieve the plain function name of an intrinsic. + pub fn intrinsic_name(&self, def_id: DefId) -> String { + self.tcx.intrinsic(def_id).unwrap().name.to_string() + } + + /// Retrieve the closure signature for the given generic arguments. + pub fn closure_sig( + &self, + args_ref: GenericArgsRef<'tcx>, + ) -> Binder, FnSig>> { + args_ref.as_closure().sig() + } + + /// The number of variants in this ADT. + pub fn adt_variants_len(&self, def: AdtDef<'tcx>) -> usize { + def.variants().len() + } + + /// The name of a variant. + pub fn variant_name(&self, def: &'tcx VariantDef) -> String { + def.name.to_string() + } + + /// Evaluate constant as a target usize. + pub fn eval_target_usize(&self, cnst: MirConst<'tcx>) -> Result { + use crate::rustc_smir::context::SmirTypingEnv; + cnst.try_eval_target_usize(self.tcx, self.fully_monomorphized()) + .ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) + } + + pub fn eval_target_usize_ty(&self, cnst: ty::Const<'tcx>) -> Result { + cnst.try_to_target_usize(self.tcx) + .ok_or_else(|| B::Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) + } + + pub(crate) fn try_new_const_zst( + &self, + ty_internal: Ty<'tcx>, + ) -> Result, B::Error> { + let size = self + .tcx + .layout_of(self.fully_monomorphized().as_query_input(ty_internal)) + .map_err(|err| { + B::Error::new(format!( + "Cannot create a zero-sized constant for type `{ty_internal}`: {err}" + )) + })? + .size; + if size.bytes() != 0 { + return Err(B::Error::new(format!( + "Cannot create a zero-sized constant for type `{ty_internal}`: \ + Type `{ty_internal}` has {} bytes", + size.bytes() + ))); + } + + Ok(MirConst::Ty(ty_internal, self.const_zero_sized(ty_internal))) + } + + pub fn const_zero_sized(&self, ty_internal: Ty<'tcx>) -> ty::Const<'tcx> { + ty::Const::zero_sized(self.tcx, ty_internal) + } + + /// Create a new constant that represents the given string value. + pub fn new_const_str(&self, value: &str) -> MirConst<'tcx> { + let ty = Ty::new_static_str(self.tcx); + let bytes = value.as_bytes(); + let valtree = ValTree::from_raw_bytes(self.tcx, bytes); + let cv = ty::Value { ty, valtree }; + let val = self.tcx.valtree_to_const_val(cv); + MirConst::from_value(val, ty) + } + + /// Create a new constant that represents the given boolean value. + pub fn new_const_bool(&self, value: bool) -> MirConst<'tcx> { + MirConst::from_bool(self.tcx, value) + } + + pub fn try_new_const_uint( + &self, + value: u128, + ty_internal: Ty<'tcx>, + ) -> Result, B::Error> { + let size = self + .tcx + .layout_of(self.fully_monomorphized().as_query_input(ty_internal)) + .unwrap() + .size; + let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { + B::Error::new(format!("Value overflow: cannot convert `{value}` to `{ty_internal}`.")) + })?; + Ok(self.mir_const_from_scalar(Scalar::Int(scalar), ty_internal)) + } + + pub fn try_new_ty_const_uint( + &self, + value: u128, + ty_internal: Ty<'tcx>, + ) -> Result, B::Error> { + let size = self + .tcx + .layout_of(self.fully_monomorphized().as_query_input(ty_internal)) + .unwrap() + .size; + let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { + B::Error::new(format!("Value overflow: cannot convert `{value}` to `{ty_internal}`.")) + })?; + + Ok(self.ty_const_new_value(ValTree::from_scalar_int(self.tcx, scalar), ty_internal)) + } + + pub fn ty_new_uint(&self, ty: UintTy) -> Ty<'tcx> { + Ty::new_uint(self.tcx, ty) + } + + pub fn mir_const_from_scalar(&self, s: Scalar, ty: Ty<'tcx>) -> MirConst<'tcx> { + MirConst::from_scalar(self.tcx, s, ty) + } + + pub fn ty_const_new_value(&self, valtree: ValTree<'tcx>, ty: Ty<'tcx>) -> ty::Const<'tcx> { + ty::Const::new_value(self.tcx, valtree, ty) + } + + pub fn ty_valtree_from_scalar_int(&self, i: ScalarInt) -> ValTree<'tcx> { + ValTree::from_scalar_int(self.tcx, i) + } + + /// Create a new type from the given kind. + pub fn new_rigid_ty(&self, internal_kind: TyKind<'tcx>) -> Ty<'tcx> { + self.tcx.mk_ty_from_kind(internal_kind) + } + + /// Create a new box type, `Box`, for the given inner type `T`. + pub fn new_box_ty(&self, ty: Ty<'tcx>) -> Ty<'tcx> { + ty::Ty::new_box(self.tcx, ty) + } + + /// Returns the type of given crate item. + pub fn def_ty(&self, item: DefId) -> Ty<'tcx> { + self.tcx.type_of(item).instantiate_identity() + } + + /// Returns the type of given definition instantiated with the given arguments. + pub fn def_ty_with_args(&self, item: DefId, args_ref: GenericArgsRef<'tcx>) -> Ty<'tcx> { + let def_ty = self.tcx.type_of(item); + self.tcx.instantiate_and_normalize_erasing_regions( + args_ref, + self.fully_monomorphized(), + def_ty, + ) + } + + /// `Span` of an item. + pub fn span_of_an_item(&self, def_id: DefId) -> Span { + self.tcx.def_span(def_id) + } + + pub fn ty_const_pretty(&self, ct: ty::Const<'tcx>) -> String { + ct.to_string() + } + + /// Obtain the representation of a type. + pub fn ty_pretty(&self, ty: Ty<'tcx>) -> String { + ty.to_string() + } + + /// Obtain the kind of a type. + pub fn ty_kind(&self, ty: Ty<'tcx>) -> &'tcx TyKind<'tcx> { + ty.kind() + } + + /// Get the discriminant Ty for this Ty if there's one. + pub fn rigid_ty_discriminant_ty(&self, internal_kind: TyKind<'tcx>) -> Ty<'tcx> { + let internal_ty = self.tcx.mk_ty_from_kind(internal_kind); + internal_ty.discriminant_ty(self.tcx) + } + + /// Get the body of an Instance which is already monomorphized. + pub fn instance_body( + &self, + instance: ty::Instance<'tcx>, + tables: &mut Tables<'tcx, B>, + ) -> Option> { + tables + .instance_has_body(instance) + .then(|| BodyBuilder::new(self.tcx, instance).build(tables)) + } + + /// Get the instance type with generic instantiations applied and lifetimes erased. + pub fn instance_ty(&self, instance: ty::Instance<'tcx>) -> Ty<'tcx> { + assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation"); + instance.ty(self.tcx, self.fully_monomorphized()) + } + + /// Get the instantiation types. + pub fn instance_args(&self, instance: ty::Instance<'tcx>) -> GenericArgsRef<'tcx> { + instance.args + } + + /// Get an instance ABI. + pub fn instance_abi( + &self, + instance: ty::Instance<'tcx>, + tables: &mut Tables<'tcx, B>, + ) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> { + Ok(tables.fn_abi_of_instance(instance, List::empty())?) + } + + /// Get the ABI of a function pointer. + pub fn fn_ptr_abi( + &self, + sig: PolyFnSig<'tcx>, + tables: &mut Tables<'tcx, B>, + ) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> { + Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?) + } + + /// Get the instance. + pub fn instance_def_id( + &self, + instances: ty::Instance<'tcx>, + tables: &mut Tables<'_, B>, + ) -> B::DefId { + let def_id = instances.def_id(); + tables.create_def_id(def_id) + } + + /// Get the instance mangled name. + pub fn instance_mangled_name(&self, instance: ty::Instance<'tcx>) -> String { + self.tcx.symbol_name(instance).name.to_string() + } + + /// Check if this is an empty DropGlue shim. + pub fn is_empty_drop_shim(&self, instance: ty::Instance<'tcx>) -> bool { + matches!(instance.def, ty::InstanceKind::DropGlue(_, None)) + } + + /// Convert a non-generic crate item into an instance. + /// This function will panic if the item is generic. + pub fn mono_instance(&self, def_id: DefId) -> Instance<'tcx> { + Instance::mono(self.tcx, def_id) + } + + /// Item requires monomorphization. + pub fn requires_monomorphization(&self, def_id: DefId) -> bool { + let generics = self.tcx.generics_of(def_id); + let result = generics.requires_monomorphization(self.tcx); + result + } + + /// Resolve an instance from the given function definition and generic arguments. + pub fn resolve_instance( + &self, + def_id: DefId, + args_ref: GenericArgsRef<'tcx>, + ) -> Option> { + match Instance::try_resolve(self.tcx, self.fully_monomorphized(), def_id, args_ref) { + Ok(Some(instance)) => Some(instance), + Ok(None) | Err(_) => None, + } + } + + /// Resolve an instance for drop_in_place for the given type. + pub fn resolve_drop_in_place(&self, internal_ty: Ty<'tcx>) -> Instance<'tcx> { + let instance = Instance::resolve_drop_in_place(self.tcx, internal_ty); + instance + } + + /// Resolve instance for a function pointer. + pub fn resolve_for_fn_ptr( + &self, + def_id: DefId, + args_ref: GenericArgsRef<'tcx>, + ) -> Option> { + Instance::resolve_for_fn_ptr(self.tcx, self.fully_monomorphized(), def_id, args_ref) + } + + /// Resolve instance for a closure with the requested type. + pub fn resolve_closure( + &self, + def_id: DefId, + args_ref: GenericArgsRef<'tcx>, + closure_kind: ClosureKind, + ) -> Option> { + Some(Instance::resolve_closure(self.tcx, def_id, args_ref, closure_kind)) + } + + /// Try to evaluate an instance into a constant. + pub fn eval_instance( + &self, + instance: ty::Instance<'tcx>, + ) -> Result, ErrorHandled> { + self.tcx.const_eval_instance( + self.fully_monomorphized(), + instance, + self.tcx.def_span(instance.def_id()), + ) + } + + /// Evaluate a static's initializer. + pub fn eval_static_initializer( + &self, + def_id: DefId, + ) -> Result, ErrorHandled> { + self.tcx.eval_static_initializer(def_id) + } + + /// Retrieve global allocation for the given allocation ID. + pub fn global_alloc(&self, alloc_id: AllocId) -> GlobalAlloc<'tcx> { + self.tcx.global_alloc(alloc_id) + } + + /// Retrieve the id for the virtual table. + pub fn vtable_allocation( + &self, + ty: Ty<'tcx>, + trait_ref: Option, ExistentialTraitRef>>>, + ) -> AllocId { + let alloc_id = self.tcx.vtable_allocation(( + ty, + trait_ref.map(|principal| self.tcx.instantiate_bound_regions_with_erased(principal)), + )); + alloc_id + } + + /// Retrieve the instance name for diagnostic messages. + /// + /// This will return the specialized name, e.g., `Vec::new`. + pub fn instance_name(&self, instance: ty::Instance<'tcx>, trimmed: bool) -> String { + if trimmed { + with_forced_trimmed_paths!( + self.tcx.def_path_str_with_args(instance.def_id(), instance.args) + ) + } else { + with_no_trimmed_paths!( + self.tcx.def_path_str_with_args(instance.def_id(), instance.args) + ) + } + } + + /// Get the layout of a type. + pub fn ty_layout( + &self, + ty: Ty<'tcx>, + tables: &mut Tables<'tcx, B>, + ) -> Result, B::Error> { + let layout = tables.layout_of(ty)?.layout; + Ok(layout) + } + + /// Get the resulting type of binary operation. + pub fn binop_ty(&self, bin_op: BinOp, rhs: Ty<'tcx>, lhs: Ty<'tcx>) -> Ty<'tcx> { + bin_op.ty(self.tcx, rhs, lhs) + } + + /// Get the resulting type of unary operation. + pub fn unop_ty(&self, un_op: UnOp, arg: Ty<'tcx>) -> Ty<'tcx> { + un_op.ty(self.tcx, arg) + } + + /// Get all associated items of a definition. + pub fn associated_items(&self, def_id: DefId) -> Vec { + let assoc_items = if self.tcx.is_trait_alias(def_id) { + Vec::new() + } else { + self.tcx + .associated_item_def_ids(def_id) + .iter() + .map(|did| self.tcx.associated_item(*did)) + .collect() + }; + assoc_items + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/context/mod.rs b/compiler/rustc_smir/src/rustc_smir/context/mod.rs new file mode 100644 index 000000000000..75acede8d345 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/context/mod.rs @@ -0,0 +1,79 @@ +//! Implementation of StableMIR Context. + +#![allow(rustc::usage_of_qualified_ty)] + +use std::marker::PhantomData; + +use rustc_abi::HasDataLayout; +use rustc_middle::ty; +use rustc_middle::ty::layout::{FnAbiOfHelpers, HasTyCtxt, HasTypingEnv, LayoutOfHelpers}; +use rustc_middle::ty::{Ty, TyCtxt}; + +use crate::rustc_smir::{Bridge, SmirError, Tables}; + +mod impls; +mod traits; + +pub use traits::*; + +/// Provides direct access to rustc's internal queries. +/// +/// The [`crate::stable_mir::compiler_interface::SmirInterface`] must go through +/// this context to obtain rustc-level information. +pub struct SmirCtxt<'tcx, B: Bridge> { + tcx: TyCtxt<'tcx>, + _marker: PhantomData, +} + +impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { + pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self { + Self { tcx, _marker: Default::default() } + } +} + +/// Implement error handling for extracting function ABI information. +impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for Tables<'tcx, B> { + type FnAbiOfResult = Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, B::Error>; + + #[inline] + fn handle_fn_abi_err( + &self, + err: ty::layout::FnAbiError<'tcx>, + _span: rustc_span::Span, + fn_abi_request: ty::layout::FnAbiRequest<'tcx>, + ) -> B::Error { + B::Error::new(format!("Failed to get ABI for `{fn_abi_request:?}`: {err:?}")) + } +} + +impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for Tables<'tcx, B> { + type LayoutOfResult = Result, B::Error>; + + #[inline] + fn handle_layout_err( + &self, + err: ty::layout::LayoutError<'tcx>, + _span: rustc_span::Span, + ty: Ty<'tcx>, + ) -> B::Error { + B::Error::new(format!("Failed to get layout for `{ty}`: {err}")) + } +} + +impl<'tcx, B: Bridge> HasTypingEnv<'tcx> for Tables<'tcx, B> { + fn typing_env(&self) -> ty::TypingEnv<'tcx> { + ty::TypingEnv::fully_monomorphized() + } +} + +impl<'tcx, B: Bridge> HasTyCtxt<'tcx> for Tables<'tcx, B> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } +} + +impl<'tcx, B: Bridge> HasDataLayout for Tables<'tcx, B> { + fn data_layout(&self) -> &rustc_abi::TargetDataLayout { + self.tcx.data_layout() + } +} diff --git a/compiler/rustc_smir/src/rustc_smir/context/traits.rs b/compiler/rustc_smir/src/rustc_smir/context/traits.rs new file mode 100644 index 000000000000..f5cd7c330b8f --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/context/traits.rs @@ -0,0 +1,50 @@ +//! A set of traits that define a stable interface to rustc's internals. +//! +//! These traits abstract rustc's internal APIs, allowing StableMIR to maintain a stable +//! interface regardless of internal compiler changes. + +use rustc_middle::mir::interpret::AllocRange; +use rustc_middle::ty; +use rustc_middle::ty::Ty; +use rustc_span::def_id::DefId; + +pub trait SmirExistentialProjection<'tcx> { + fn new_from_args( + &self, + def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + term: ty::Term<'tcx>, + ) -> ty::ExistentialProjection<'tcx>; +} + +pub trait SmirExistentialTraitRef<'tcx> { + fn new_from_args( + &self, + trait_def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> ty::ExistentialTraitRef<'tcx>; +} + +pub trait SmirTraitRef<'tcx> { + fn new_from_args( + &self, + trait_def_id: DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> ty::TraitRef<'tcx>; +} + +pub trait SmirTy<'tcx> { + fn new_foreign(&self, def_id: DefId) -> Ty<'tcx>; +} + +pub trait SmirTypingEnv<'tcx> { + fn fully_monomorphized(&self) -> ty::TypingEnv<'tcx>; +} + +pub trait SmirAllocRange<'tcx> { + fn alloc_range(&self, offset: rustc_abi::Size, size: rustc_abi::Size) -> AllocRange; +} + +pub trait SmirRegion<'tcx> { + fn lifetimes_re_erased(&self) -> ty::Region<'tcx>; +} From 663e2b7e2904d68fda6d5c23fd1b8ad9fbd7ee03 Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 5 May 2025 15:35:54 +0800 Subject: [PATCH 36/62] refactor: move `convert` module to `stable_mir` note that this commit delete `convert/error.rs`, we would use `SmirError::from_internal` instead. **Unresolved questions:** - There are still a few direct calls to rustc's internals scattered across `impl Stable`s, but most of them appear to be relatively stable, e.g., `mir::interpret::ConstAllocation::inner(self)` and `mir::syntax::SwitchTargets::otherwise(self)`. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 11 +- .../src/rustc_smir/convert/error.rs | 25 - compiler/rustc_smir/src/rustc_smir/mod.rs | 78 --- .../src/stable_mir/compiler_interface.rs | 1 + .../convert}/internal.rs | 458 +++++++++++----- .../rustc_smir/src/stable_mir/convert/mod.rs | 126 +++++ .../convert/stable}/abi.rs | 157 ++++-- .../convert/stable}/mir.rs | 502 +++++++++++------- .../convert/stable}/mod.rs | 36 +- .../convert/stable}/ty.rs | 498 +++++++++++------ compiler/rustc_smir/src/stable_mir/mod.rs | 1 + 11 files changed, 1225 insertions(+), 668 deletions(-) delete mode 100644 compiler/rustc_smir/src/rustc_smir/convert/error.rs rename compiler/rustc_smir/src/{rustc_internal => stable_mir/convert}/internal.rs (59%) create mode 100644 compiler/rustc_smir/src/stable_mir/convert/mod.rs rename compiler/rustc_smir/src/{rustc_smir/convert => stable_mir/convert/stable}/abi.rs (69%) rename compiler/rustc_smir/src/{rustc_smir/convert => stable_mir/convert/stable}/mir.rs (68%) rename compiler/rustc_smir/src/{rustc_smir/convert => stable_mir/convert/stable}/mod.rs (68%) rename compiler/rustc_smir/src/{rustc_smir/convert => stable_mir/convert/stable}/ty.rs (69%) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index c343242ddfc5..5947a7a84405 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -17,13 +17,12 @@ use rustc_span::Span; use rustc_span::def_id::{CrateNum, DefId}; use scoped_tls::scoped_thread_local; use stable_mir::Error; +use stable_mir::convert::{RustcInternal, Stable}; use crate::rustc_smir::context::SmirCtxt; -use crate::rustc_smir::{Stable, Tables}; use crate::rustc_smir::{Bridge, IndexedVal, SmirContainer, Tables}; use crate::stable_mir; -mod internal; pub mod pretty; /// Convert an internal Rust compiler item into its stable counterpart, if one exists. @@ -340,11 +339,3 @@ impl Index; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx>; -} diff --git a/compiler/rustc_smir/src/rustc_smir/convert/error.rs b/compiler/rustc_smir/src/rustc_smir/convert/error.rs deleted file mode 100644 index 2cde5542483d..000000000000 --- a/compiler/rustc_smir/src/rustc_smir/convert/error.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! Handle the conversion of different internal errors into a stable version. -//! -//! Currently we encode everything as [stable_mir::Error], which is represented as a string. - -use rustc_middle::mir::interpret::AllocError; -use rustc_middle::ty::layout::LayoutError; - -use crate::rustc_smir::{Stable, Tables}; -use crate::stable_mir; - -impl<'tcx> Stable<'tcx> for LayoutError<'tcx> { - type T = stable_mir::Error; - - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { - stable_mir::Error::new(format!("{self:?}")) - } -} - -impl<'tcx> Stable<'tcx> for AllocError { - type T = stable_mir::Error; - - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { - stable_mir::Error::new(format!("{self:?}")) - } -} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 4f6919d27241..b597189585b3 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,7 +7,6 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use std::marker::PointeeSized; use std::cell::RefCell; use std::fmt::Debug; @@ -23,7 +22,6 @@ use crate::rustc_internal::IndexMap; pub mod alloc; mod builder; pub mod context; -mod convert; /// A container which is used for TLS. pub struct SmirContainer<'tcx, B: Bridge> { @@ -155,79 +153,3 @@ where .collect() } } - -/// Trait used to convert between an internal MIR type to a Stable MIR type. -pub trait Stable<'cx>: PointeeSized { - /// The stable representation of the type implementing Stable. - type T; - /// Converts an object to the equivalent Stable MIR representation. - fn stable(&self, tables: &mut Tables<'_>) -> Self::T; -} - -impl<'tcx, T> Stable<'tcx> for &T -where - T: Stable<'tcx>, -{ - type T = T::T; - - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - (*self).stable(tables) - } -} - -impl<'tcx, T> Stable<'tcx> for Option -where - T: Stable<'tcx>, -{ - type T = Option; - - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - self.as_ref().map(|value| value.stable(tables)) - } -} - -impl<'tcx, T, E> Stable<'tcx> for Result -where - T: Stable<'tcx>, - E: Stable<'tcx>, -{ - type T = Result; - - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - match self { - Ok(val) => Ok(val.stable(tables)), - Err(error) => Err(error.stable(tables)), - } - } -} - -impl<'tcx, T> Stable<'tcx> for &[T] -where - T: Stable<'tcx>, -{ - type T = Vec; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - self.iter().map(|e| e.stable(tables)).collect() - } -} - -impl<'tcx, T, U> Stable<'tcx> for (T, U) -where - T: Stable<'tcx>, - U: Stable<'tcx>, -{ - type T = (T::T, U::T); - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - (self.0.stable(tables), self.1.stable(tables)) - } -} - -impl<'tcx, T> Stable<'tcx> for RangeInclusive -where - T: Stable<'tcx>, -{ - type T = RangeInclusive; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - RangeInclusive::new(self.start().stable(tables), self.end().stable(tables)) - } -} diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index 3be9d9db7539..9d75f3664169 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -8,6 +8,7 @@ use std::cell::Cell; use rustc_hir::def::DefKind; use rustc_smir::{Bridge, SmirContainer, Tables}; use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions}; +use stable_mir::convert::{RustcInternal, Stable}; use stable_mir::crate_def::Attribute; use stable_mir::mir::alloc::{AllocId, GlobalAlloc}; use stable_mir::mir::mono::{Instance, InstanceDef, StaticDef}; diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/stable_mir/convert/internal.rs similarity index 59% rename from compiler/rustc_smir/src/rustc_internal/internal.rs rename to compiler/rustc_smir/src/stable_mir/convert/internal.rs index f878b6e6b717..a8c5f1085285 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/stable_mir/convert/internal.rs @@ -5,93 +5,132 @@ // Prefer importing stable_mir over internal rustc constructs to make this file more readable. -use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt}; +use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy}; +use rustc_smir::context::SmirCtxt; +use rustc_smir::{IndexedVal, Tables}; use rustc_span::Symbol; use stable_mir::abi::Layout; +use stable_mir::compiler_interface::BridgeTys; +use stable_mir::convert::RustcInternal; use stable_mir::mir::alloc::AllocId; use stable_mir::mir::mono::{Instance, MonoItem, StaticDef}; use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, RawPtrKind, Safety, UnOp}; use stable_mir::ty::{ Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig, - GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy, - Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx, + GenericArgKind, GenericArgs, IntTy, MirConst, Movability, Pattern, Region, RigidTy, Span, + TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx, }; use stable_mir::{CrateItem, CrateNum, DefId}; -use super::RustcInternal; -use crate::rustc_smir::Tables; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; impl RustcInternal for CrateItem { type T<'tcx> = rustc_span::def_id::DefId; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - self.0.internal(tables, tcx) + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + self.0.internal(tables, cx) } } impl RustcInternal for CrateNum { type T<'tcx> = rustc_span::def_id::CrateNum; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { rustc_span::def_id::CrateNum::from_usize(*self) } } impl RustcInternal for DefId { type T<'tcx> = rustc_span::def_id::DefId; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.def_ids[*self]).unwrap() + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.lift(tables.def_ids[*self]).unwrap() } } impl RustcInternal for GenericArgs { type T<'tcx> = rustc_ty::GenericArgsRef<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables, tcx))) + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables, cx))) } } impl RustcInternal for GenericArgKind { type T<'tcx> = rustc_ty::GenericArg<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { let arg: rustc_ty::GenericArg<'tcx> = match self { - GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(), - GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(), - GenericArgKind::Const(cnst) => cnst.internal(tables, tcx).into(), + GenericArgKind::Lifetime(reg) => reg.internal(tables, cx).into(), + GenericArgKind::Type(ty) => ty.internal(tables, cx).into(), + GenericArgKind::Const(cnst) => cnst.internal(tables, cx).into(), }; - tcx.lift(arg).unwrap() + cx.lift(arg).unwrap() } } impl RustcInternal for Region { type T<'tcx> = rustc_ty::Region<'tcx>; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { // Cannot recover region. Use erased for now. - tcx.lifetimes.re_erased + use rustc_smir::context::SmirRegion; + cx.lifetimes_re_erased() } } impl RustcInternal for Ty { type T<'tcx> = InternalTy<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.types[*self]).unwrap() + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.lift(tables.types[*self]).unwrap() } } impl RustcInternal for TyConst { type T<'tcx> = InternalConst<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.ty_consts[self.id]).unwrap() + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.lift(tables.ty_consts[self.id]).unwrap() } } impl RustcInternal for Pattern { type T<'tcx> = rustc_ty::Pattern<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.mk_pat(match self { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.mk_pat(match self { Pattern::Range { start, end, include_end: _ } => rustc_ty::PatternKind::Range { - start: start.as_ref().unwrap().internal(tables, tcx), - end: end.as_ref().unwrap().internal(tables, tcx), + start: start.as_ref().unwrap().internal(tables, cx), + end: end.as_ref().unwrap().internal(tables, cx), }, }) } @@ -100,62 +139,66 @@ impl RustcInternal for Pattern { impl RustcInternal for RigidTy { type T<'tcx> = rustc_ty::TyKind<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { RigidTy::Bool => rustc_ty::TyKind::Bool, RigidTy::Char => rustc_ty::TyKind::Char, - RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables, tcx)), - RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables, tcx)), - RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, tcx)), + RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables, cx)), + RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables, cx)), + RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, cx)), RigidTy::Never => rustc_ty::TyKind::Never, RigidTy::Array(ty, cnst) => { - rustc_ty::TyKind::Array(ty.internal(tables, tcx), cnst.internal(tables, tcx)) + rustc_ty::TyKind::Array(ty.internal(tables, cx), cnst.internal(tables, cx)) } RigidTy::Pat(ty, pat) => { - rustc_ty::TyKind::Pat(ty.internal(tables, tcx), pat.internal(tables, tcx)) + rustc_ty::TyKind::Pat(ty.internal(tables, cx), pat.internal(tables, cx)) } RigidTy::Adt(def, args) => { - rustc_ty::TyKind::Adt(def.internal(tables, tcx), args.internal(tables, tcx)) + rustc_ty::TyKind::Adt(def.internal(tables, cx), args.internal(tables, cx)) } RigidTy::Str => rustc_ty::TyKind::Str, - RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, tcx)), + RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, cx)), RigidTy::RawPtr(ty, mutability) => { - rustc_ty::TyKind::RawPtr(ty.internal(tables, tcx), mutability.internal(tables, tcx)) + rustc_ty::TyKind::RawPtr(ty.internal(tables, cx), mutability.internal(tables, cx)) } RigidTy::Ref(region, ty, mutability) => rustc_ty::TyKind::Ref( - region.internal(tables, tcx), - ty.internal(tables, tcx), - mutability.internal(tables, tcx), + region.internal(tables, cx), + ty.internal(tables, cx), + mutability.internal(tables, cx), ), - RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, tcx)), + RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, cx)), RigidTy::FnDef(def, args) => { - rustc_ty::TyKind::FnDef(def.0.internal(tables, tcx), args.internal(tables, tcx)) + rustc_ty::TyKind::FnDef(def.0.internal(tables, cx), args.internal(tables, cx)) } RigidTy::FnPtr(sig) => { - let (sig_tys, hdr) = sig.internal(tables, tcx).split(); + let (sig_tys, hdr) = sig.internal(tables, cx).split(); rustc_ty::TyKind::FnPtr(sig_tys, hdr) } RigidTy::Closure(def, args) => { - rustc_ty::TyKind::Closure(def.0.internal(tables, tcx), args.internal(tables, tcx)) + rustc_ty::TyKind::Closure(def.0.internal(tables, cx), args.internal(tables, cx)) } RigidTy::Coroutine(def, args, _mov) => { - rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx)) + rustc_ty::TyKind::Coroutine(def.0.internal(tables, cx), args.internal(tables, cx)) } RigidTy::CoroutineClosure(def, args) => rustc_ty::TyKind::CoroutineClosure( - def.0.internal(tables, tcx), - args.internal(tables, tcx), + def.0.internal(tables, cx), + args.internal(tables, cx), ), RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness( - def.0.internal(tables, tcx), - args.internal(tables, tcx), + def.0.internal(tables, cx), + args.internal(tables, cx), ), RigidTy::Dynamic(predicate, region, dyn_kind) => rustc_ty::TyKind::Dynamic( - tcx.mk_poly_existential_predicates(&predicate.internal(tables, tcx)), - region.internal(tables, tcx), - dyn_kind.internal(tables, tcx), + cx.mk_poly_existential_predicates(&predicate.internal(tables, cx)), + region.internal(tables, cx), + dyn_kind.internal(tables, cx), ), RigidTy::Tuple(tys) => { - rustc_ty::TyKind::Tuple(tcx.mk_type_list(&tys.internal(tables, tcx))) + rustc_ty::TyKind::Tuple(cx.mk_type_list(&tys.internal(tables, cx))) } } } @@ -164,7 +207,11 @@ impl RustcInternal for RigidTy { impl RustcInternal for IntTy { type T<'tcx> = rustc_ty::IntTy; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { IntTy::Isize => rustc_ty::IntTy::Isize, IntTy::I8 => rustc_ty::IntTy::I8, @@ -179,7 +226,11 @@ impl RustcInternal for IntTy { impl RustcInternal for UintTy { type T<'tcx> = rustc_ty::UintTy; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { UintTy::Usize => rustc_ty::UintTy::Usize, UintTy::U8 => rustc_ty::UintTy::U8, @@ -194,7 +245,11 @@ impl RustcInternal for UintTy { impl RustcInternal for FloatTy { type T<'tcx> = rustc_ty::FloatTy; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { FloatTy::F16 => rustc_ty::FloatTy::F16, FloatTy::F32 => rustc_ty::FloatTy::F32, @@ -207,7 +262,11 @@ impl RustcInternal for FloatTy { impl RustcInternal for Mutability { type T<'tcx> = rustc_ty::Mutability; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { Mutability::Not => rustc_ty::Mutability::Not, Mutability::Mut => rustc_ty::Mutability::Mut, @@ -218,7 +277,11 @@ impl RustcInternal for Mutability { impl RustcInternal for Movability { type T<'tcx> = rustc_ty::Movability; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { Movability::Static => rustc_ty::Movability::Static, Movability::Movable => rustc_ty::Movability::Movable, @@ -229,7 +292,11 @@ impl RustcInternal for Movability { impl RustcInternal for RawPtrKind { type T<'tcx> = rustc_middle::mir::RawPtrKind; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { RawPtrKind::Mut => rustc_middle::mir::RawPtrKind::Mut, RawPtrKind::Const => rustc_middle::mir::RawPtrKind::Const, @@ -241,12 +308,16 @@ impl RustcInternal for RawPtrKind { impl RustcInternal for FnSig { type T<'tcx> = rustc_ty::FnSig<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(rustc_ty::FnSig { - inputs_and_output: tcx.mk_type_list(&self.inputs_and_output.internal(tables, tcx)), + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.lift(rustc_ty::FnSig { + inputs_and_output: cx.mk_type_list(&self.inputs_and_output.internal(tables, cx)), c_variadic: self.c_variadic, - safety: self.safety.internal(tables, tcx), - abi: self.abi.internal(tables, tcx), + safety: self.safety.internal(tables, cx), + abi: self.abi.internal(tables, cx), }) .unwrap() } @@ -255,7 +326,11 @@ impl RustcInternal for FnSig { impl RustcInternal for VariantIdx { type T<'tcx> = rustc_abi::VariantIdx; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { rustc_abi::VariantIdx::from(self.to_index()) } } @@ -263,27 +338,35 @@ impl RustcInternal for VariantIdx { impl RustcInternal for VariantDef { type T<'tcx> = &'tcx rustc_ty::VariantDef; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - self.adt_def.internal(tables, tcx).variant(self.idx.internal(tables, tcx)) + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + self.adt_def.internal(tables, cx).variant(self.idx.internal(tables, cx)) } } impl RustcInternal for MirConst { type T<'tcx> = rustc_middle::mir::Const<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { let constant = tables.mir_consts[self.id]; match constant { rustc_middle::mir::Const::Ty(ty, ct) => { - rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap(), tcx.lift(ct).unwrap()) + rustc_middle::mir::Const::Ty(cx.lift(ty).unwrap(), cx.lift(ct).unwrap()) } rustc_middle::mir::Const::Unevaluated(uneval, ty) => { rustc_middle::mir::Const::Unevaluated( - tcx.lift(uneval).unwrap(), - tcx.lift(ty).unwrap(), + cx.lift(uneval).unwrap(), + cx.lift(ty).unwrap(), ) } rustc_middle::mir::Const::Val(const_val, ty) => { - rustc_middle::mir::Const::Val(tcx.lift(const_val).unwrap(), tcx.lift(ty).unwrap()) + rustc_middle::mir::Const::Val(cx.lift(const_val).unwrap(), cx.lift(ty).unwrap()) } } } @@ -292,11 +375,15 @@ impl RustcInternal for MirConst { impl RustcInternal for MonoItem { type T<'tcx> = rustc_middle::mir::mono::MonoItem<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { use rustc_middle::mir::mono as rustc_mono; match self { - MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables, tcx)), - MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables, tcx)), + MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables, cx)), + MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables, cx)), MonoItem::GlobalAsm(_) => { unimplemented!() } @@ -307,16 +394,24 @@ impl RustcInternal for MonoItem { impl RustcInternal for Instance { type T<'tcx> = rustc_ty::Instance<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.instances[self.def]).unwrap() + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.lift(tables.instances[self.def]).unwrap() } } impl RustcInternal for StaticDef { type T<'tcx> = rustc_span::def_id::DefId; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - self.0.internal(tables, tcx) + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + self.0.internal(tables, cx) } } @@ -328,11 +423,15 @@ where { type T<'tcx> = rustc_ty::Binder<'tcx, T::T<'tcx>>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { rustc_ty::Binder::bind_with_vars( - self.value.internal(tables, tcx), - tcx.mk_bound_variable_kinds_from_iter( - self.bound_vars.iter().map(|bound| bound.internal(tables, tcx)), + self.value.internal(tables, cx), + cx.mk_bound_variable_kinds_from_iter( + self.bound_vars.iter().map(|bound| bound.internal(tables, cx)), ), ) } @@ -341,19 +440,22 @@ where impl RustcInternal for BoundVariableKind { type T<'tcx> = rustc_ty::BoundVariableKind; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind { BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon, - BoundTyKind::Param(def, symbol) => rustc_ty::BoundTyKind::Param( - def.0.internal(tables, tcx), - Symbol::intern(symbol), - ), + BoundTyKind::Param(def, symbol) => { + rustc_ty::BoundTyKind::Param(def.0.internal(tables, cx), Symbol::intern(symbol)) + } }), BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind { BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::Anon, BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::Named( - def.0.internal(tables, tcx), + def.0.internal(tables, cx), Symbol::intern(symbol), ), BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::ClosureEnv, @@ -366,7 +468,11 @@ impl RustcInternal for BoundVariableKind { impl RustcInternal for DynKind { type T<'tcx> = rustc_ty::DynKind; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { DynKind::Dyn => rustc_ty::DynKind::Dyn, } @@ -376,16 +482,20 @@ impl RustcInternal for DynKind { impl RustcInternal for ExistentialPredicate { type T<'tcx> = rustc_ty::ExistentialPredicate<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { ExistentialPredicate::Trait(trait_ref) => { - rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, tcx)) + rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, cx)) } ExistentialPredicate::Projection(proj) => { - rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, tcx)) + rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, cx)) } ExistentialPredicate::AutoTrait(trait_def) => { - rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, tcx)) + rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, cx)) } } } @@ -394,12 +504,16 @@ impl RustcInternal for ExistentialPredicate { impl RustcInternal for ExistentialProjection { type T<'tcx> = rustc_ty::ExistentialProjection<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_ty::ExistentialProjection::new_from_args( - tcx, - self.def_id.0.internal(tables, tcx), - self.generic_args.internal(tables, tcx), - self.term.internal(tables, tcx), + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + use rustc_smir::context::SmirExistentialProjection; + cx.new_from_args( + self.def_id.0.internal(tables, cx), + self.generic_args.internal(tables, cx), + self.term.internal(tables, cx), ) } } @@ -407,10 +521,14 @@ impl RustcInternal for ExistentialProjection { impl RustcInternal for TermKind { type T<'tcx> = rustc_ty::Term<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { - TermKind::Type(ty) => ty.internal(tables, tcx).into(), - TermKind::Const(cnst) => cnst.internal(tables, tcx).into(), + TermKind::Type(ty) => ty.internal(tables, cx).into(), + TermKind::Const(cnst) => cnst.internal(tables, cx).into(), } } } @@ -418,38 +536,48 @@ impl RustcInternal for TermKind { impl RustcInternal for ExistentialTraitRef { type T<'tcx> = rustc_ty::ExistentialTraitRef<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_ty::ExistentialTraitRef::new_from_args( - tcx, - self.def_id.0.internal(tables, tcx), - self.generic_args.internal(tables, tcx), - ) + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + use rustc_smir::context::SmirExistentialTraitRef; + cx.new_from_args(self.def_id.0.internal(tables, cx), self.generic_args.internal(tables, cx)) } } impl RustcInternal for TraitRef { type T<'tcx> = rustc_ty::TraitRef<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - rustc_ty::TraitRef::new_from_args( - tcx, - self.def_id.0.internal(tables, tcx), - self.args().internal(tables, tcx), - ) + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + use rustc_smir::context::SmirTraitRef; + cx.new_from_args(self.def_id.0.internal(tables, cx), self.args().internal(tables, cx)) } } impl RustcInternal for AllocId { type T<'tcx> = rustc_middle::mir::interpret::AllocId; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.alloc_ids[*self]).unwrap() + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.lift(tables.alloc_ids[*self]).unwrap() } } impl RustcInternal for ClosureKind { type T<'tcx> = rustc_ty::ClosureKind; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { ClosureKind::Fn => rustc_ty::ClosureKind::Fn, ClosureKind::FnMut => rustc_ty::ClosureKind::FnMut, @@ -460,15 +588,23 @@ impl RustcInternal for ClosureKind { impl RustcInternal for AdtDef { type T<'tcx> = rustc_ty::AdtDef<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.adt_def(self.0.internal(tables, tcx)) + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.adt_def(self.0.internal(tables, cx)) } } impl RustcInternal for Abi { type T<'tcx> = rustc_abi::ExternAbi; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match *self { Abi::Rust => rustc_abi::ExternAbi::Rust, Abi::C { unwind } => rustc_abi::ExternAbi::C { unwind }, @@ -504,7 +640,11 @@ impl RustcInternal for Abi { impl RustcInternal for Safety { type T<'tcx> = rustc_hir::Safety; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { Safety::Unsafe => rustc_hir::Safety::Unsafe, Safety::Safe => rustc_hir::Safety::Safe, @@ -514,26 +654,38 @@ impl RustcInternal for Safety { impl RustcInternal for Span { type T<'tcx> = rustc_span::Span; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tables[*self] + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + tables.spans[*self] } } impl RustcInternal for Layout { type T<'tcx> = rustc_abi::Layout<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - tcx.lift(tables.layouts[*self]).unwrap() + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + cx.lift(tables.layouts[*self]).unwrap() } } impl RustcInternal for Place { type T<'tcx> = rustc_middle::mir::Place<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { rustc_middle::mir::Place { local: rustc_middle::mir::Local::from_usize(self.local), - projection: tcx.mk_place_elems(&self.projection.internal(tables, tcx)), + projection: cx.mk_place_elems(&self.projection.internal(tables, cx)), } } } @@ -541,11 +693,15 @@ impl RustcInternal for Place { impl RustcInternal for ProjectionElem { type T<'tcx> = rustc_middle::mir::PlaceElem<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { ProjectionElem::Deref => rustc_middle::mir::PlaceElem::Deref, ProjectionElem::Field(idx, ty) => { - rustc_middle::mir::PlaceElem::Field((*idx).into(), ty.internal(tables, tcx)) + rustc_middle::mir::PlaceElem::Field((*idx).into(), ty.internal(tables, cx)) } ProjectionElem::Index(idx) => rustc_middle::mir::PlaceElem::Index((*idx).into()), ProjectionElem::ConstantIndex { offset, min_length, from_end } => { @@ -559,13 +715,13 @@ impl RustcInternal for ProjectionElem { rustc_middle::mir::PlaceElem::Subslice { from: *from, to: *to, from_end: *from_end } } ProjectionElem::Downcast(idx) => { - rustc_middle::mir::PlaceElem::Downcast(None, idx.internal(tables, tcx)) + rustc_middle::mir::PlaceElem::Downcast(None, idx.internal(tables, cx)) } ProjectionElem::OpaqueCast(ty) => { - rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, tcx)) + rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, cx)) } ProjectionElem::Subtype(ty) => { - rustc_middle::mir::PlaceElem::Subtype(ty.internal(tables, tcx)) + rustc_middle::mir::PlaceElem::Subtype(ty.internal(tables, cx)) } } } @@ -574,7 +730,11 @@ impl RustcInternal for ProjectionElem { impl RustcInternal for BinOp { type T<'tcx> = rustc_middle::mir::BinOp; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { BinOp::Add => rustc_middle::mir::BinOp::Add, BinOp::AddUnchecked => rustc_middle::mir::BinOp::AddUnchecked, @@ -606,7 +766,11 @@ impl RustcInternal for BinOp { impl RustcInternal for UnOp { type T<'tcx> = rustc_middle::mir::UnOp; - fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + fn internal<'tcx>( + &self, + _tables: &mut Tables<'_, BridgeTys>, + _cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { match self { UnOp::Not => rustc_middle::mir::UnOp::Not, UnOp::Neg => rustc_middle::mir::UnOp::Neg, @@ -621,8 +785,12 @@ where { type T<'tcx> = T::T<'tcx>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - (*self).internal(tables, tcx) + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + (*self).internal(tables, cx) } } @@ -632,8 +800,12 @@ where { type T<'tcx> = Option>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - self.as_ref().map(|inner| inner.internal(tables, tcx)) + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + self.as_ref().map(|inner| inner.internal(tables, cx)) } } @@ -643,7 +815,11 @@ where { type T<'tcx> = Vec>; - fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - self.iter().map(|e| e.internal(tables, tcx)).collect() + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx> { + self.iter().map(|e| e.internal(tables, cx)).collect() } } diff --git a/compiler/rustc_smir/src/stable_mir/convert/mod.rs b/compiler/rustc_smir/src/stable_mir/convert/mod.rs new file mode 100644 index 000000000000..90ed67ed972b --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/convert/mod.rs @@ -0,0 +1,126 @@ +use std::ops::RangeInclusive; + +use rustc_smir::Tables; +use rustc_smir::context::SmirCtxt; + +use super::compiler_interface::BridgeTys; +use crate::rustc_smir; + +mod internal; +mod stable; + +impl<'tcx, T> Stable<'tcx> for &T +where + T: Stable<'tcx>, +{ + type T = T::T; + + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + (*self).stable(tables, cx) + } +} + +impl<'tcx, T> Stable<'tcx> for Option +where + T: Stable<'tcx>, +{ + type T = Option; + + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + self.as_ref().map(|value| value.stable(tables, cx)) + } +} + +impl<'tcx, T, E> Stable<'tcx> for Result +where + T: Stable<'tcx>, + E: Stable<'tcx>, +{ + type T = Result; + + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + match self { + Ok(val) => Ok(val.stable(tables, cx)), + Err(error) => Err(error.stable(tables, cx)), + } + } +} + +impl<'tcx, T> Stable<'tcx> for &[T] +where + T: Stable<'tcx>, +{ + type T = Vec; + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + self.iter().map(|e| e.stable(tables, cx)).collect() + } +} + +impl<'tcx, T, U> Stable<'tcx> for (T, U) +where + T: Stable<'tcx>, + U: Stable<'tcx>, +{ + type T = (T::T, U::T); + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + (self.0.stable(tables, cx), self.1.stable(tables, cx)) + } +} + +impl<'tcx, T> Stable<'tcx> for RangeInclusive +where + T: Stable<'tcx>, +{ + type T = RangeInclusive; + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + RangeInclusive::new(self.start().stable(tables, cx), self.end().stable(tables, cx)) + } +} + +/// Trait used to convert between an internal MIR type to a Stable MIR type. +pub trait Stable<'tcx> { + /// The stable representation of the type implementing Stable. + type T; + /// Converts an object to the equivalent Stable MIR representation. + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T; +} + +/// Trait used to translate a stable construct to its rustc counterpart. +/// +/// This is basically a mirror of [Stable]. +pub trait RustcInternal { + type T<'tcx>; + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T<'tcx>; +} diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/stable_mir/convert/stable/abi.rs similarity index 69% rename from compiler/rustc_smir/src/rustc_smir/convert/abi.rs rename to compiler/rustc_smir/src/stable_mir/convert/stable/abi.rs index 35d5b7fb89af..b6f02e1bc8f6 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs +++ b/compiler/rustc_smir/src/stable_mir/convert/stable/abi.rs @@ -4,22 +4,25 @@ use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call}; use rustc_middle::ty; +use rustc_smir::context::SmirCtxt; +use rustc_smir::{IndexedVal, Tables}; use rustc_target::callconv; use stable_mir::abi::{ AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength, IntegerType, Layout, LayoutShape, PassMode, Primitive, ReprFlags, ReprOptions, Scalar, TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange, }; +use stable_mir::compiler_interface::BridgeTys; +use stable_mir::convert::Stable; use stable_mir::opaque; use stable_mir::target::MachineSize as Size; -use stable_mir::ty::{Align, IndexedVal, VariantIdx}; +use stable_mir::ty::{Align, VariantIdx}; -use crate::rustc_smir::{Stable, Tables}; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx { type T = VariantIdx; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { VariantIdx::to_val(self.as_usize()) } } @@ -27,7 +30,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx { impl<'tcx> Stable<'tcx> for rustc_abi::Endian { type T = stable_mir::target::Endian; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { rustc_abi::Endian::Little => stable_mir::target::Endian::Little, rustc_abi::Endian::Big => stable_mir::target::Endian::Big, @@ -38,29 +41,41 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Endian { impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> { type T = TyAndLayout; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - TyAndLayout { ty: self.ty.stable(tables), layout: self.layout.stable(tables) } + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + TyAndLayout { ty: self.ty.stable(tables, cx), layout: self.layout.stable(tables, cx) } } } impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> { type T = Layout; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - tables.layout_id(tables.tcx.lift(*self).unwrap()) + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + tables.layout_id(cx.lift(*self).unwrap()) } } impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData { type T = LayoutShape; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { LayoutShape { - fields: self.fields.stable(tables), - variants: self.variants.stable(tables), - abi: self.backend_repr.stable(tables), - abi_align: self.align.abi.stable(tables), - size: self.size.stable(tables), + fields: self.fields.stable(tables, cx), + variants: self.variants.stable(tables, cx), + abi: self.backend_repr.stable(tables, cx), + abi_align: self.align.abi.stable(tables, cx), + size: self.size.stable(tables, cx), } } } @@ -68,14 +83,18 @@ impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> { type T = FnAbi; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { assert!(self.args.len() >= self.fixed_count as usize); assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C)); FnAbi { - args: self.args.as_ref().stable(tables), - ret: self.ret.stable(tables), + args: self.args.as_ref().stable(tables, cx), + ret: self.ret.stable(tables, cx), fixed_count: self.fixed_count, - conv: self.conv.stable(tables), + conv: self.conv.stable(tables, cx), c_variadic: self.c_variadic, } } @@ -84,11 +103,15 @@ impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> { impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> { type T = ArgAbi; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { ArgAbi { - ty: self.layout.ty.stable(tables), - layout: self.layout.layout.stable(tables), - mode: self.mode.stable(tables), + ty: self.layout.ty.stable(tables, cx), + layout: self.layout.layout.stable(tables, cx), + mode: self.mode.stable(tables, cx), } } } @@ -96,7 +119,7 @@ impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> { impl<'tcx> Stable<'tcx> for CanonAbi { type T = CallConvention; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { CanonAbi::C => CallConvention::C, CanonAbi::Rust => CallConvention::Rust, @@ -132,7 +155,7 @@ impl<'tcx> Stable<'tcx> for CanonAbi { impl<'tcx> Stable<'tcx> for callconv::PassMode { type T = PassMode; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { callconv::PassMode::Ignore => PassMode::Ignore, callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)), @@ -154,15 +177,19 @@ impl<'tcx> Stable<'tcx> for callconv::PassMode { impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape { type T = FieldsShape; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive, rustc_abi::FieldsShape::Union(count) => FieldsShape::Union(*count), rustc_abi::FieldsShape::Array { stride, count } => { - FieldsShape::Array { stride: stride.stable(tables), count: *count } + FieldsShape::Array { stride: stride.stable(tables, cx), count: *count } } rustc_abi::FieldsShape::Arbitrary { offsets, .. } => { - FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables) } + FieldsShape::Arbitrary { offsets: offsets.iter().as_slice().stable(tables, cx) } } } } @@ -171,18 +198,22 @@ impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape { impl<'tcx> Stable<'tcx> for rustc_abi::Variants { type T = VariantsShape; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { rustc_abi::Variants::Single { index } => { - VariantsShape::Single { index: index.stable(tables) } + VariantsShape::Single { index: index.stable(tables, cx) } } rustc_abi::Variants::Empty => VariantsShape::Empty, rustc_abi::Variants::Multiple { tag, tag_encoding, tag_field, variants } => { VariantsShape::Multiple { - tag: tag.stable(tables), - tag_encoding: tag_encoding.stable(tables), - tag_field: tag_field.stable(tables), - variants: variants.iter().as_slice().stable(tables), + tag: tag.stable(tables, cx), + tag_encoding: tag_encoding.stable(tables, cx), + tag_field: *tag_field, + variants: variants.iter().as_slice().stable(tables, cx), } } } @@ -192,13 +223,17 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants Stable<'tcx> for rustc_abi::TagEncoding { type T = TagEncoding; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { rustc_abi::TagEncoding::Direct => TagEncoding::Direct, rustc_abi::TagEncoding::Niche { untagged_variant, niche_variants, niche_start } => { TagEncoding::Niche { - untagged_variant: untagged_variant.stable(tables), - niche_variants: niche_variants.stable(tables), + untagged_variant: untagged_variant.stable(tables, cx), + niche_variants: niche_variants.stable(tables, cx), niche_start: *niche_start, } } @@ -209,14 +244,18 @@ impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding { impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { type T = ValueAbi; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match *self { - rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables)), + rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables, cx)), rustc_abi::BackendRepr::ScalarPair(first, second) => { - ValueAbi::ScalarPair(first.stable(tables), second.stable(tables)) + ValueAbi::ScalarPair(first.stable(tables, cx), second.stable(tables, cx)) } rustc_abi::BackendRepr::SimdVector { element, count } => { - ValueAbi::Vector { element: element.stable(tables), count } + ValueAbi::Vector { element: element.stable(tables, cx), count } } rustc_abi::BackendRepr::Memory { sized } => ValueAbi::Aggregate { sized }, } @@ -226,7 +265,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { impl<'tcx> Stable<'tcx> for rustc_abi::Size { type T = Size; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { Size::from_bits(self.bits_usize()) } } @@ -234,7 +273,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Size { impl<'tcx> Stable<'tcx> for rustc_abi::Align { type T = Align; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { self.bytes() } } @@ -242,13 +281,17 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Align { impl<'tcx> Stable<'tcx> for rustc_abi::Scalar { type T = Scalar; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized { - value: value.stable(tables), - valid_range: valid_range.stable(tables), + value: value.stable(tables, cx), + valid_range: valid_range.stable(tables, cx), }, - rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables) }, + rustc_abi::Scalar::Union { value } => Scalar::Union { value: value.stable(tables, cx) }, } } } @@ -256,15 +299,19 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Scalar { impl<'tcx> Stable<'tcx> for rustc_abi::Primitive { type T = Primitive; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { rustc_abi::Primitive::Int(length, signed) => { - Primitive::Int { length: length.stable(tables), signed: *signed } + Primitive::Int { length: length.stable(tables, cx), signed: *signed } } rustc_abi::Primitive::Float(length) => { - Primitive::Float { length: length.stable(tables) } + Primitive::Float { length: length.stable(tables, cx) } } - rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables)), + rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables, cx)), } } } @@ -272,7 +319,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Primitive { impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace { type T = AddressSpace; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { AddressSpace(self.0) } } @@ -280,7 +327,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace { impl<'tcx> Stable<'tcx> for rustc_abi::Integer { type T = IntegerLength; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { rustc_abi::Integer::I8 => IntegerLength::I8, rustc_abi::Integer::I16 => IntegerLength::I16, @@ -294,7 +341,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Integer { impl<'tcx> Stable<'tcx> for rustc_abi::Float { type T = FloatLength; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { rustc_abi::Float::F16 => FloatLength::F16, rustc_abi::Float::F32 => FloatLength::F32, @@ -307,7 +354,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Float { impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange { type T = WrappingRange; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { WrappingRange { start: self.start, end: self.end } } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs similarity index 68% rename from compiler/rustc_smir/src/rustc_smir/convert/mir.rs rename to compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs index daea4acc36c0..f5ea17d1e55c 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs @@ -1,56 +1,66 @@ //! Conversion of internal Rust compiler `mir` items to stable ones. -use rustc_middle::mir::interpret::alloc_range; use rustc_middle::mir::mono::MonoItem; use rustc_middle::{bug, mir}; +use rustc_smir::context::SmirCtxt; +use rustc_smir::{SmirError, Tables}; +use stable_mir::compiler_interface::BridgeTys; +use stable_mir::convert::Stable; use stable_mir::mir::alloc::GlobalAlloc; use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment}; use stable_mir::ty::{Allocation, ConstantKind, MirConst}; -use stable_mir::{Error, opaque}; +use stable_mir::{Error, alloc, opaque}; -use crate::rustc_smir::{Stable, Tables, alloc}; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; impl<'tcx> Stable<'tcx> for mir::Body<'tcx> { type T = stable_mir::mir::Body; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { stable_mir::mir::Body::new( self.basic_blocks .iter() .map(|block| stable_mir::mir::BasicBlock { - terminator: block.terminator().stable(tables), + terminator: block.terminator().stable(tables, cx), statements: block .statements .iter() - .map(|statement| statement.stable(tables)) + .map(|statement| statement.stable(tables, cx)) .collect(), }) .collect(), self.local_decls .iter() .map(|decl| stable_mir::mir::LocalDecl { - ty: decl.ty.stable(tables), - span: decl.source_info.span.stable(tables), - mutability: decl.mutability.stable(tables), + ty: decl.ty.stable(tables, cx), + span: decl.source_info.span.stable(tables, cx), + mutability: decl.mutability.stable(tables, cx), }) .collect(), self.arg_count, - self.var_debug_info.iter().map(|info| info.stable(tables)).collect(), - self.spread_arg.stable(tables), - self.span.stable(tables), + self.var_debug_info.iter().map(|info| info.stable(tables, cx)).collect(), + self.spread_arg.stable(tables, cx), + self.span.stable(tables, cx), ) } } impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> { type T = stable_mir::mir::VarDebugInfo; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { stable_mir::mir::VarDebugInfo { name: self.name.to_string(), - source_info: self.source_info.stable(tables), - composite: self.composite.as_ref().map(|composite| composite.stable(tables)), - value: self.value.stable(tables), + source_info: self.source_info.stable(tables, cx), + composite: self.composite.as_ref().map(|composite| composite.stable(tables, cx)), + value: self.value.stable(tables, cx), argument_index: self.argument_index, } } @@ -58,40 +68,59 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> { impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { type T = stable_mir::mir::Statement; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - Statement { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) } + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + Statement { + kind: self.kind.stable(tables, cx), + span: self.source_info.span.stable(tables, cx), + } } } impl<'tcx> Stable<'tcx> for mir::SourceInfo { type T = stable_mir::mir::SourceInfo; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - stable_mir::mir::SourceInfo { span: self.span.stable(tables), scope: self.scope.into() } + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + stable_mir::mir::SourceInfo { span: self.span.stable(tables, cx), scope: self.scope.into() } } } impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> { type T = stable_mir::mir::VarDebugInfoFragment; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { VarDebugInfoFragment { - ty: self.ty.stable(tables), - projection: self.projection.iter().map(|e| e.stable(tables)).collect(), + ty: self.ty.stable(tables, cx), + projection: self.projection.iter().map(|e| e.stable(tables, cx)).collect(), } } } impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> { type T = stable_mir::mir::VarDebugInfoContents; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { mir::VarDebugInfoContents::Place(place) => { - stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables)) + stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables, cx)) } mir::VarDebugInfoContents::Const(const_operand) => { let op = ConstOperand { - span: const_operand.span.stable(tables), + span: const_operand.span.stable(tables, cx), user_ty: const_operand.user_ty.map(|index| index.as_usize()), - const_: const_operand.const_.stable(tables), + const_: const_operand.const_.stable(tables, cx), }; stable_mir::mir::VarDebugInfoContents::Const(op) } @@ -101,53 +130,58 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> { impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> { type T = stable_mir::mir::StatementKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { mir::StatementKind::Assign(assign) => stable_mir::mir::StatementKind::Assign( - assign.0.stable(tables), - assign.1.stable(tables), + assign.0.stable(tables, cx), + assign.1.stable(tables, cx), ), mir::StatementKind::FakeRead(fake_read_place) => { stable_mir::mir::StatementKind::FakeRead( - fake_read_place.0.stable(tables), - fake_read_place.1.stable(tables), + fake_read_place.0.stable(tables, cx), + fake_read_place.1.stable(tables, cx), ) } mir::StatementKind::SetDiscriminant { place, variant_index } => { stable_mir::mir::StatementKind::SetDiscriminant { - place: place.as_ref().stable(tables), - variant_index: variant_index.stable(tables), + place: place.as_ref().stable(tables, cx), + variant_index: variant_index.stable(tables, cx), } } mir::StatementKind::Deinit(place) => { - stable_mir::mir::StatementKind::Deinit(place.stable(tables)) + stable_mir::mir::StatementKind::Deinit(place.stable(tables, cx)) } mir::StatementKind::StorageLive(place) => { - stable_mir::mir::StatementKind::StorageLive(place.stable(tables)) + stable_mir::mir::StatementKind::StorageLive(place.stable(tables, cx)) } mir::StatementKind::StorageDead(place) => { - stable_mir::mir::StatementKind::StorageDead(place.stable(tables)) - } - mir::StatementKind::Retag(retag, place) => { - stable_mir::mir::StatementKind::Retag(retag.stable(tables), place.stable(tables)) + stable_mir::mir::StatementKind::StorageDead(place.stable(tables, cx)) } + mir::StatementKind::Retag(retag, place) => stable_mir::mir::StatementKind::Retag( + retag.stable(tables, cx), + place.stable(tables, cx), + ), mir::StatementKind::PlaceMention(place) => { - stable_mir::mir::StatementKind::PlaceMention(place.stable(tables)) + stable_mir::mir::StatementKind::PlaceMention(place.stable(tables, cx)) } mir::StatementKind::AscribeUserType(place_projection, variance) => { stable_mir::mir::StatementKind::AscribeUserType { - place: place_projection.as_ref().0.stable(tables), - projections: place_projection.as_ref().1.stable(tables), - variance: variance.stable(tables), + place: place_projection.as_ref().0.stable(tables, cx), + projections: place_projection.as_ref().1.stable(tables, cx), + variance: variance.stable(tables, cx), } } mir::StatementKind::Coverage(coverage) => { stable_mir::mir::StatementKind::Coverage(opaque(coverage)) } mir::StatementKind::Intrinsic(intrinstic) => { - stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables)) + stable_mir::mir::StatementKind::Intrinsic(intrinstic.stable(tables, cx)) } mir::StatementKind::ConstEvalCounter => { stable_mir::mir::StatementKind::ConstEvalCounter @@ -163,61 +197,68 @@ impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> { impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { type T = stable_mir::mir::Rvalue; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::mir::Rvalue::*; match self { - Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)), + Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables, cx)), Repeat(op, len) => { - let len = len.stable(tables); - stable_mir::mir::Rvalue::Repeat(op.stable(tables), len) + let len = len.stable(tables, cx); + stable_mir::mir::Rvalue::Repeat(op.stable(tables, cx), len) } Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref( - region.stable(tables), - kind.stable(tables), - place.stable(tables), + region.stable(tables, cx), + kind.stable(tables, cx), + place.stable(tables, cx), ), ThreadLocalRef(def_id) => { stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id)) } - RawPtr(mutability, place) => { - stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables)) - } - Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)), + RawPtr(mutability, place) => stable_mir::mir::Rvalue::AddressOf( + mutability.stable(tables, cx), + place.stable(tables, cx), + ), + Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables, cx)), Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast( - cast_kind.stable(tables), - op.stable(tables), - ty.stable(tables), + cast_kind.stable(tables, cx), + op.stable(tables, cx), + ty.stable(tables, cx), ), BinaryOp(bin_op, ops) => { if let Some(bin_op) = bin_op.overflowing_to_wrapping() { stable_mir::mir::Rvalue::CheckedBinaryOp( - bin_op.stable(tables), - ops.0.stable(tables), - ops.1.stable(tables), + bin_op.stable(tables, cx), + ops.0.stable(tables, cx), + ops.1.stable(tables, cx), ) } else { stable_mir::mir::Rvalue::BinaryOp( - bin_op.stable(tables), - ops.0.stable(tables), - ops.1.stable(tables), + bin_op.stable(tables, cx), + ops.0.stable(tables, cx), + ops.1.stable(tables, cx), ) } } - NullaryOp(null_op, ty) => { - stable_mir::mir::Rvalue::NullaryOp(null_op.stable(tables), ty.stable(tables)) - } + NullaryOp(null_op, ty) => stable_mir::mir::Rvalue::NullaryOp( + null_op.stable(tables, cx), + ty.stable(tables, cx), + ), UnaryOp(un_op, op) => { - stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables)) + stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables, cx), op.stable(tables, cx)) } - Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables)), + Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables, cx)), Aggregate(agg_kind, operands) => { - let operands = operands.iter().map(|op| op.stable(tables)).collect(); - stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands) + let operands = operands.iter().map(|op| op.stable(tables, cx)).collect(); + stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables, cx), operands) } - ShallowInitBox(op, ty) => { - stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), ty.stable(tables)) - } - CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)), + ShallowInitBox(op, ty) => stable_mir::mir::Rvalue::ShallowInitBox( + op.stable(tables, cx), + ty.stable(tables, cx), + ), + CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables, cx)), WrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"), } } @@ -225,7 +266,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { impl<'tcx> Stable<'tcx> for mir::Mutability { type T = stable_mir::mir::Mutability; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_hir::Mutability::*; match *self { Not => stable_mir::mir::Mutability::Not, @@ -236,7 +277,7 @@ impl<'tcx> Stable<'tcx> for mir::Mutability { impl<'tcx> Stable<'tcx> for mir::RawPtrKind { type T = stable_mir::mir::RawPtrKind; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use mir::RawPtrKind::*; match *self { Const => stable_mir::mir::RawPtrKind::Const, @@ -248,19 +289,23 @@ impl<'tcx> Stable<'tcx> for mir::RawPtrKind { impl<'tcx> Stable<'tcx> for mir::BorrowKind { type T = stable_mir::mir::BorrowKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::mir::BorrowKind::*; match *self { Shared => stable_mir::mir::BorrowKind::Shared, - Fake(kind) => stable_mir::mir::BorrowKind::Fake(kind.stable(tables)), - Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables) }, + Fake(kind) => stable_mir::mir::BorrowKind::Fake(kind.stable(tables, cx)), + Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable(tables, cx) }, } } } impl<'tcx> Stable<'tcx> for mir::MutBorrowKind { type T = stable_mir::mir::MutBorrowKind; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::mir::MutBorrowKind::*; match *self { Default => stable_mir::mir::MutBorrowKind::Default, @@ -272,7 +317,7 @@ impl<'tcx> Stable<'tcx> for mir::MutBorrowKind { impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind { type T = stable_mir::mir::FakeBorrowKind; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::mir::FakeBorrowKind::*; match *self { Deep => stable_mir::mir::FakeBorrowKind::Deep, @@ -283,13 +328,17 @@ impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind { impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> { type T = stable_mir::mir::NullOp; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::mir::NullOp::*; match self { SizeOf => stable_mir::mir::NullOp::SizeOf, AlignOf => stable_mir::mir::NullOp::AlignOf, OffsetOf(indices) => stable_mir::mir::NullOp::OffsetOf( - indices.iter().map(|idx| idx.stable(tables)).collect(), + indices.iter().map(|idx| idx.stable(tables, cx)).collect(), ), UbChecks => stable_mir::mir::NullOp::UbChecks, ContractChecks => stable_mir::mir::NullOp::ContractChecks, @@ -299,12 +348,16 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> { impl<'tcx> Stable<'tcx> for mir::CastKind { type T = stable_mir::mir::CastKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::mir::CastKind::*; match self { PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress, PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance, - PointerCoercion(c, _) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)), + PointerCoercion(c, _) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables, cx)), IntToInt => stable_mir::mir::CastKind::IntToInt, FloatToInt => stable_mir::mir::CastKind::FloatToInt, FloatToFloat => stable_mir::mir::CastKind::FloatToFloat, @@ -318,7 +371,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind { impl<'tcx> Stable<'tcx> for mir::FakeReadCause { type T = stable_mir::mir::FakeReadCause; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::mir::FakeReadCause::*; match self { ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard, @@ -334,12 +387,16 @@ impl<'tcx> Stable<'tcx> for mir::FakeReadCause { impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> { type T = stable_mir::mir::Operand; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::mir::Operand::*; match self { - Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables)), - Move(place) => stable_mir::mir::Operand::Move(place.stable(tables)), - Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables)), + Copy(place) => stable_mir::mir::Operand::Copy(place.stable(tables, cx)), + Move(place) => stable_mir::mir::Operand::Move(place.stable(tables, cx)), + Constant(c) => stable_mir::mir::Operand::Constant(c.stable(tables, cx)), } } } @@ -347,35 +404,48 @@ impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> { impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> { type T = stable_mir::mir::ConstOperand; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { stable_mir::mir::ConstOperand { - span: self.span.stable(tables), + span: self.span.stable(tables, cx), user_ty: self.user_ty.map(|u| u.as_usize()).or(None), - const_: self.const_.stable(tables), + const_: self.const_.stable(tables, cx), } } } impl<'tcx> Stable<'tcx> for mir::Place<'tcx> { type T = stable_mir::mir::Place; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { stable_mir::mir::Place { local: self.local.as_usize(), - projection: self.projection.iter().map(|e| e.stable(tables)).collect(), + projection: self.projection.iter().map(|e| e.stable(tables, cx)).collect(), } } } impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { type T = stable_mir::mir::ProjectionElem; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::mir::ProjectionElem::*; match self { Deref => stable_mir::mir::ProjectionElem::Deref, - Field(idx, ty) => { - stable_mir::mir::ProjectionElem::Field(idx.stable(tables), ty.stable(tables)) - } - Index(local) => stable_mir::mir::ProjectionElem::Index(local.stable(tables)), + Field(idx, ty) => stable_mir::mir::ProjectionElem::Field( + idx.stable(tables, cx), + ty.stable(tables, cx), + ), + Index(local) => stable_mir::mir::ProjectionElem::Index(local.stable(tables, cx)), ConstantIndex { offset, min_length, from_end } => { stable_mir::mir::ProjectionElem::ConstantIndex { offset: *offset, @@ -393,9 +463,9 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { // via a lookup using the `VariantIdx`. The `Option` argument is therefore // dropped when converting to Stable MIR. A brief justification for this decision can be // found at https://github.com/rust-lang/rust/pull/117517#issuecomment-1811683486 - Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables)), - OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables)), - Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables)), + Downcast(_, idx) => stable_mir::mir::ProjectionElem::Downcast(idx.stable(tables, cx)), + OpaqueCast(ty) => stable_mir::mir::ProjectionElem::OpaqueCast(ty.stable(tables, cx)), + Subtype(ty) => stable_mir::mir::ProjectionElem::Subtype(ty.stable(tables, cx)), UnwrapUnsafeBinder(..) => todo!("FIXME(unsafe_binders):"), } } @@ -404,21 +474,21 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { impl<'tcx> Stable<'tcx> for mir::UserTypeProjection { type T = stable_mir::mir::UserTypeProjection; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) } } } impl<'tcx> Stable<'tcx> for mir::Local { type T = stable_mir::mir::Local; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { self.as_usize() } } impl<'tcx> Stable<'tcx> for mir::RetagKind { type T = stable_mir::mir::RetagKind; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::mir::RetagKind; match self { RetagKind::FnEntry => stable_mir::mir::RetagKind::FnEntry, @@ -431,7 +501,7 @@ impl<'tcx> Stable<'tcx> for mir::RetagKind { impl<'tcx> Stable<'tcx> for mir::UnwindAction { type T = stable_mir::mir::UnwindAction; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::mir::UnwindAction; match self { UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, @@ -445,18 +515,22 @@ impl<'tcx> Stable<'tcx> for mir::UnwindAction { impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> { type T = stable_mir::mir::NonDivergingIntrinsic; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::mir::NonDivergingIntrinsic; use stable_mir::mir::CopyNonOverlapping; match self { NonDivergingIntrinsic::Assume(op) => { - stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables)) + stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables, cx)) } NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => { stable_mir::mir::NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { - src: copy_non_overlapping.src.stable(tables), - dst: copy_non_overlapping.dst.stable(tables), - count: copy_non_overlapping.count.stable(tables), + src: copy_non_overlapping.src.stable(tables, cx), + dst: copy_non_overlapping.dst.stable(tables, cx), + count: copy_non_overlapping.count.stable(tables, cx), }) } } @@ -465,47 +539,51 @@ impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> { impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { type T = stable_mir::mir::AssertMessage; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::mir::AssertKind; match self { AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck { - len: len.stable(tables), - index: index.stable(tables), + len: len.stable(tables, cx), + index: index.stable(tables, cx), }, AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow( - bin_op.stable(tables), - op1.stable(tables), - op2.stable(tables), + bin_op.stable(tables, cx), + op1.stable(tables, cx), + op2.stable(tables, cx), ), AssertKind::OverflowNeg(op) => { - stable_mir::mir::AssertMessage::OverflowNeg(op.stable(tables)) + stable_mir::mir::AssertMessage::OverflowNeg(op.stable(tables, cx)) } AssertKind::DivisionByZero(op) => { - stable_mir::mir::AssertMessage::DivisionByZero(op.stable(tables)) + stable_mir::mir::AssertMessage::DivisionByZero(op.stable(tables, cx)) } AssertKind::RemainderByZero(op) => { - stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables)) + stable_mir::mir::AssertMessage::RemainderByZero(op.stable(tables, cx)) } AssertKind::ResumedAfterReturn(coroutine) => { - stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables)) + stable_mir::mir::AssertMessage::ResumedAfterReturn(coroutine.stable(tables, cx)) } AssertKind::ResumedAfterPanic(coroutine) => { - stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables)) + stable_mir::mir::AssertMessage::ResumedAfterPanic(coroutine.stable(tables, cx)) } AssertKind::ResumedAfterDrop(coroutine) => { - stable_mir::mir::AssertMessage::ResumedAfterDrop(coroutine.stable(tables)) + stable_mir::mir::AssertMessage::ResumedAfterDrop(coroutine.stable(tables, cx)) } AssertKind::MisalignedPointerDereference { required, found } => { stable_mir::mir::AssertMessage::MisalignedPointerDereference { - required: required.stable(tables), - found: found.stable(tables), + required: required.stable(tables, cx), + found: found.stable(tables, cx), } } AssertKind::NullPointerDereference => { stable_mir::mir::AssertMessage::NullPointerDereference } AssertKind::InvalidEnumConstruction(source) => { - stable_mir::mir::AssertMessage::InvalidEnumConstruction(source.stable(tables)) + stable_mir::mir::AssertMessage::InvalidEnumConstruction(source.stable(tables, cx)) } } } @@ -513,7 +591,7 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { impl<'tcx> Stable<'tcx> for mir::BinOp { type T = stable_mir::mir::BinOp; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::mir::BinOp; match self { BinOp::Add => stable_mir::mir::BinOp::Add, @@ -548,7 +626,7 @@ impl<'tcx> Stable<'tcx> for mir::BinOp { impl<'tcx> Stable<'tcx> for mir::UnOp { type T = stable_mir::mir::UnOp; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::mir::UnOp; match self { UnOp::Not => stable_mir::mir::UnOp::Not, @@ -560,17 +638,21 @@ impl<'tcx> Stable<'tcx> for mir::UnOp { impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { type T = stable_mir::mir::AggregateKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { mir::AggregateKind::Array(ty) => { - stable_mir::mir::AggregateKind::Array(ty.stable(tables)) + stable_mir::mir::AggregateKind::Array(ty.stable(tables, cx)) } mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple, mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => { stable_mir::mir::AggregateKind::Adt( tables.adt_def(*def_id), - var_idx.stable(tables), - generic_arg.stable(tables), + var_idx.stable(tables, cx), + generic_arg.stable(tables, cx), user_ty_index.map(|idx| idx.index()), field_idx.map(|idx| idx.index()), ) @@ -578,39 +660,46 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { mir::AggregateKind::Closure(def_id, generic_arg) => { stable_mir::mir::AggregateKind::Closure( tables.closure_def(*def_id), - generic_arg.stable(tables), + generic_arg.stable(tables, cx), ) } mir::AggregateKind::Coroutine(def_id, generic_arg) => { stable_mir::mir::AggregateKind::Coroutine( tables.coroutine_def(*def_id), - generic_arg.stable(tables), - tables.tcx.coroutine_movability(*def_id).stable(tables), + generic_arg.stable(tables, cx), + cx.coroutine_movability(*def_id).stable(tables, cx), ) } mir::AggregateKind::CoroutineClosure(def_id, generic_args) => { stable_mir::mir::AggregateKind::CoroutineClosure( tables.coroutine_closure_def(*def_id), - generic_args.stable(tables), + generic_args.stable(tables, cx), ) } - mir::AggregateKind::RawPtr(ty, mutability) => { - stable_mir::mir::AggregateKind::RawPtr(ty.stable(tables), mutability.stable(tables)) - } + mir::AggregateKind::RawPtr(ty, mutability) => stable_mir::mir::AggregateKind::RawPtr( + ty.stable(tables, cx), + mutability.stable(tables, cx), + ), } } } impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> { type T = stable_mir::mir::InlineAsmOperand; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::mir::InlineAsmOperand; let (in_value, out_place) = match self { - InlineAsmOperand::In { value, .. } => (Some(value.stable(tables)), None), - InlineAsmOperand::Out { place, .. } => (None, place.map(|place| place.stable(tables))), + InlineAsmOperand::In { value, .. } => (Some(value.stable(tables, cx)), None), + InlineAsmOperand::Out { place, .. } => { + (None, place.map(|place| place.stable(tables, cx))) + } InlineAsmOperand::InOut { in_value, out_place, .. } => { - (Some(in_value.stable(tables)), out_place.map(|place| place.stable(tables))) + (Some(in_value.stable(tables, cx)), out_place.map(|place| place.stable(tables, cx))) } InlineAsmOperand::Const { .. } | InlineAsmOperand::SymFn { .. } @@ -624,22 +713,33 @@ impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> { impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> { type T = stable_mir::mir::Terminator; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::mir::Terminator; - Terminator { kind: self.kind.stable(tables), span: self.source_info.span.stable(tables) } + Terminator { + kind: self.kind.stable(tables, cx), + span: self.source_info.span.stable(tables, cx), + } } } impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { type T = stable_mir::mir::TerminatorKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::mir::TerminatorKind; match self { mir::TerminatorKind::Goto { target } => { TerminatorKind::Goto { target: target.as_usize() } } mir::TerminatorKind::SwitchInt { discr, targets } => TerminatorKind::SwitchInt { - discr: discr.stable(tables), + discr: discr.stable(tables, cx), targets: { let branches = targets.iter().map(|(val, target)| (val, target.as_usize())); stable_mir::mir::SwitchTargets::new( @@ -660,9 +760,9 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { drop: _, async_fut: _, } => TerminatorKind::Drop { - place: place.stable(tables), + place: place.stable(tables, cx), target: target.as_usize(), - unwind: unwind.stable(tables), + unwind: unwind.stable(tables, cx), }, mir::TerminatorKind::Call { func, @@ -673,20 +773,20 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { call_source: _, fn_span: _, } => TerminatorKind::Call { - func: func.stable(tables), - args: args.iter().map(|arg| arg.node.stable(tables)).collect(), - destination: destination.stable(tables), + func: func.stable(tables, cx), + args: args.iter().map(|arg| arg.node.stable(tables, cx)).collect(), + destination: destination.stable(tables, cx), target: target.map(|t| t.as_usize()), - unwind: unwind.stable(tables), + unwind: unwind.stable(tables, cx), }, mir::TerminatorKind::TailCall { func: _, args: _, fn_span: _ } => todo!(), mir::TerminatorKind::Assert { cond, expected, msg, target, unwind } => { TerminatorKind::Assert { - cond: cond.stable(tables), + cond: cond.stable(tables, cx), expected: *expected, - msg: msg.stable(tables), + msg: msg.stable(tables, cx), target: target.as_usize(), - unwind: unwind.stable(tables), + unwind: unwind.stable(tables, cx), } } mir::TerminatorKind::InlineAsm { @@ -699,12 +799,12 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { unwind, } => TerminatorKind::InlineAsm { template: format!("{template:?}"), - operands: operands.iter().map(|operand| operand.stable(tables)).collect(), + operands: operands.iter().map(|operand| operand.stable(tables, cx)).collect(), options: format!("{options:?}"), line_spans: format!("{line_spans:?}"), // FIXME: Figure out how to do labels in SMIR destination: targets.first().map(|d| d.as_usize()), - unwind: unwind.stable(tables), + unwind: unwind.stable(tables, cx), }, mir::TerminatorKind::Yield { .. } | mir::TerminatorKind::CoroutineDrop @@ -717,22 +817,40 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> { type T = Allocation; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - self.inner().stable(tables) + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + self.inner().stable(tables, cx) } } impl<'tcx> Stable<'tcx> for mir::interpret::Allocation { type T = stable_mir::ty::Allocation; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - alloc::allocation_filter(self, alloc_range(rustc_abi::Size::ZERO, self.size()), tables) + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + use rustc_smir::context::SmirAllocRange; + alloc::allocation_filter( + self, + cx.alloc_range(rustc_abi::Size::ZERO, self.size()), + tables, + cx, + ) } } impl<'tcx> Stable<'tcx> for mir::interpret::AllocId { type T = stable_mir::mir::alloc::AllocId; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + _: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { tables.create_alloc_id(*self) } } @@ -740,19 +858,25 @@ impl<'tcx> Stable<'tcx> for mir::interpret::AllocId { impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> { type T = GlobalAlloc; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { mir::interpret::GlobalAlloc::Function { instance, .. } => { - GlobalAlloc::Function(instance.stable(tables)) + GlobalAlloc::Function(instance.stable(tables, cx)) } mir::interpret::GlobalAlloc::VTable(ty, dyn_ty) => { // FIXME: Should we record the whole vtable? - GlobalAlloc::VTable(ty.stable(tables), dyn_ty.principal().stable(tables)) + GlobalAlloc::VTable(ty.stable(tables, cx), dyn_ty.principal().stable(tables, cx)) } mir::interpret::GlobalAlloc::Static(def) => { GlobalAlloc::Static(tables.static_def(*def)) } - mir::interpret::GlobalAlloc::Memory(alloc) => GlobalAlloc::Memory(alloc.stable(tables)), + mir::interpret::GlobalAlloc::Memory(alloc) => { + GlobalAlloc::Memory(alloc.stable(tables, cx)) + } } } } @@ -760,33 +884,37 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> { impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { type T = stable_mir::ty::MirConst; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - let id = tables.intern_mir_const(tables.tcx.lift(*self).unwrap()); + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + let id = tables.intern_mir_const(cx.lift(*self).unwrap()); match *self { mir::Const::Ty(ty, c) => MirConst::new( - stable_mir::ty::ConstantKind::Ty(c.stable(tables)), - ty.stable(tables), + stable_mir::ty::ConstantKind::Ty(c.stable(tables, cx)), + ty.stable(tables, cx), id, ), mir::Const::Unevaluated(unev_const, ty) => { let kind = stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { def: tables.const_def(unev_const.def), - args: unev_const.args.stable(tables), + args: unev_const.args.stable(tables, cx), promoted: unev_const.promoted.map(|u| u.as_u32()), }); - let ty = ty.stable(tables); + let ty = ty.stable(tables, cx); MirConst::new(kind, ty, id) } mir::Const::Val(mir::ConstValue::ZeroSized, ty) => { - let ty = ty.stable(tables); + let ty = ty.stable(tables, cx); MirConst::new(ConstantKind::ZeroSized, ty, id) } mir::Const::Val(val, ty) => { - let ty = tables.tcx.lift(ty).unwrap(); - let val = tables.tcx.lift(val).unwrap(); - let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables)); - let ty = ty.stable(tables); + let ty = cx.lift(ty).unwrap(); + let val = cx.lift(val).unwrap(); + let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables, cx)); + let ty = ty.stable(tables, cx); MirConst::new(kind, ty, id) } } @@ -796,7 +924,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled { type T = Error; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { Error::new(format!("{self:?}")) } } @@ -804,10 +932,14 @@ impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled { impl<'tcx> Stable<'tcx> for MonoItem<'tcx> { type T = stable_mir::mir::mono::MonoItem; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::mir::mono::MonoItem as StableMonoItem; match self { - MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables)), + MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables, cx)), MonoItem::Static(def_id) => StableMonoItem::Static(tables.static_def(*def_id)), MonoItem::GlobalAsm(item_id) => StableMonoItem::GlobalAsm(opaque(item_id)), } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/stable_mir/convert/stable/mod.rs similarity index 68% rename from compiler/rustc_smir/src/rustc_smir/convert/mod.rs rename to compiler/rustc_smir/src/stable_mir/convert/stable/mod.rs index 3494de62d835..1cead1c3c37b 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/convert/stable/mod.rs @@ -1,18 +1,20 @@ //! Conversion of internal Rust compiler items to stable ones. use rustc_abi::FieldIdx; +use rustc_smir::Tables; +use rustc_smir::context::SmirCtxt; +use stable_mir::compiler_interface::BridgeTys; -use crate::rustc_smir::{Stable, Tables}; -use crate::stable_mir; +use super::Stable; +use crate::{rustc_smir, stable_mir}; mod abi; -mod error; mod mir; mod ty; impl<'tcx> Stable<'tcx> for rustc_hir::Safety { type T = stable_mir::mir::Safety; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { rustc_hir::Safety::Unsafe => stable_mir::mir::Safety::Unsafe, rustc_hir::Safety::Safe => stable_mir::mir::Safety::Safe, @@ -22,14 +24,14 @@ impl<'tcx> Stable<'tcx> for rustc_hir::Safety { impl<'tcx> Stable<'tcx> for FieldIdx { type T = usize; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { self.as_usize() } } impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource { type T = stable_mir::mir::CoroutineSource; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_hir::CoroutineSource; match self { CoroutineSource::Block => stable_mir::mir::CoroutineSource::Block, @@ -41,28 +43,32 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource { impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind { type T = stable_mir::mir::CoroutineKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_hir::{CoroutineDesugaring, CoroutineKind}; match *self { CoroutineKind::Desugared(CoroutineDesugaring::Async, source) => { stable_mir::mir::CoroutineKind::Desugared( stable_mir::mir::CoroutineDesugaring::Async, - source.stable(tables), + source.stable(tables, cx), ) } CoroutineKind::Desugared(CoroutineDesugaring::Gen, source) => { stable_mir::mir::CoroutineKind::Desugared( stable_mir::mir::CoroutineDesugaring::Gen, - source.stable(tables), + source.stable(tables, cx), ) } CoroutineKind::Coroutine(movability) => { - stable_mir::mir::CoroutineKind::Coroutine(movability.stable(tables)) + stable_mir::mir::CoroutineKind::Coroutine(movability.stable(tables, cx)) } CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, source) => { stable_mir::mir::CoroutineKind::Desugared( stable_mir::mir::CoroutineDesugaring::AsyncGen, - source.stable(tables), + source.stable(tables, cx), ) } } @@ -72,7 +78,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind { impl<'tcx> Stable<'tcx> for rustc_span::Symbol { type T = stable_mir::Symbol; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { self.to_string() } } @@ -80,7 +86,11 @@ impl<'tcx> Stable<'tcx> for rustc_span::Symbol { impl<'tcx> Stable<'tcx> for rustc_span::Span { type T = stable_mir::ty::Span; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + _: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { tables.create_span(*self) } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/stable_mir/convert/stable/ty.rs similarity index 69% rename from compiler/rustc_smir/src/rustc_smir/convert/ty.rs rename to compiler/rustc_smir/src/stable_mir/convert/stable/ty.rs index ff0b8e833dcc..d84bc119ecc0 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/convert/stable/ty.rs @@ -2,16 +2,20 @@ use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; +use rustc_smir::Tables; +use rustc_smir::context::SmirCtxt; +use stable_mir::alloc; +use stable_mir::compiler_interface::BridgeTys; +use stable_mir::convert::Stable; use stable_mir::ty::{ AdtKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, TyKind, UintTy, }; -use crate::rustc_smir::{Stable, Tables, alloc}; -use crate::stable_mir; +use crate::{rustc_smir, stable_mir}; impl<'tcx> Stable<'tcx> for ty::AliasTyKind { type T = stable_mir::ty::AliasKind; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { ty::Projection => stable_mir::ty::AliasKind::Projection, ty::Inherent => stable_mir::ty::AliasKind::Inherent, @@ -23,24 +27,35 @@ impl<'tcx> Stable<'tcx> for ty::AliasTyKind { impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> { type T = stable_mir::ty::AliasTy; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { let ty::AliasTy { args, def_id, .. } = self; - stable_mir::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables) } + stable_mir::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables, cx) } } } impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> { type T = stable_mir::ty::AliasTerm; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { let ty::AliasTerm { args, def_id, .. } = self; - stable_mir::ty::AliasTerm { def_id: tables.alias_def(*def_id), args: args.stable(tables) } + stable_mir::ty::AliasTerm { + def_id: tables.alias_def(*def_id), + args: args.stable(tables, cx), + } } } impl<'tcx> Stable<'tcx> for ty::DynKind { type T = stable_mir::ty::DynKind; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { ty::Dyn => stable_mir::ty::DynKind::Dyn, } @@ -50,14 +65,18 @@ impl<'tcx> Stable<'tcx> for ty::DynKind { impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> { type T = stable_mir::ty::ExistentialPredicate; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::ExistentialPredicate::*; match self { ty::ExistentialPredicate::Trait(existential_trait_ref) => { - Trait(existential_trait_ref.stable(tables)) + Trait(existential_trait_ref.stable(tables, cx)) } ty::ExistentialPredicate::Projection(existential_projection) => { - Projection(existential_projection.stable(tables)) + Projection(existential_projection.stable(tables, cx)) } ty::ExistentialPredicate::AutoTrait(def_id) => AutoTrait(tables.trait_def(*def_id)), } @@ -67,11 +86,15 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> { impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> { type T = stable_mir::ty::ExistentialTraitRef; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { let ty::ExistentialTraitRef { def_id, args, .. } = self; stable_mir::ty::ExistentialTraitRef { def_id: tables.trait_def(*def_id), - generic_args: args.stable(tables), + generic_args: args.stable(tables, cx), } } } @@ -79,12 +102,16 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> { impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> { type T = stable_mir::ty::TermKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::TermKind; match self { - ty::TermKind::Ty(ty) => TermKind::Type(ty.stable(tables)), + ty::TermKind::Ty(ty) => TermKind::Type(ty.stable(tables, cx)), ty::TermKind::Const(cnst) => { - let cnst = cnst.stable(tables); + let cnst = cnst.stable(tables, cx); TermKind::Const(cnst) } } @@ -94,25 +121,33 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> { type T = stable_mir::ty::ExistentialProjection; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { let ty::ExistentialProjection { def_id, args, term, .. } = self; stable_mir::ty::ExistentialProjection { def_id: tables.trait_def(*def_id), - generic_args: args.stable(tables), - term: term.kind().stable(tables), + generic_args: args.stable(tables, cx), + term: term.kind().stable(tables, cx), } } } impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion { type T = stable_mir::mir::PointerCoercion; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::ty::adjustment::PointerCoercion; match self { PointerCoercion::ReifyFnPointer => stable_mir::mir::PointerCoercion::ReifyFnPointer, PointerCoercion::UnsafeFnPointer => stable_mir::mir::PointerCoercion::UnsafeFnPointer, PointerCoercion::ClosureFnPointer(safety) => { - stable_mir::mir::PointerCoercion::ClosureFnPointer(safety.stable(tables)) + stable_mir::mir::PointerCoercion::ClosureFnPointer(safety.stable(tables, cx)) } PointerCoercion::MutToConstPointer => { stable_mir::mir::PointerCoercion::MutToConstPointer @@ -125,7 +160,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion { impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex { type T = usize; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { self.as_usize() } } @@ -133,7 +168,7 @@ impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex { impl<'tcx> Stable<'tcx> for ty::AdtKind { type T = AdtKind; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { ty::AdtKind::Struct => AdtKind::Struct, ty::AdtKind::Union => AdtKind::Union, @@ -145,30 +180,44 @@ impl<'tcx> Stable<'tcx> for ty::AdtKind { impl<'tcx> Stable<'tcx> for ty::FieldDef { type T = stable_mir::ty::FieldDef; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { stable_mir::ty::FieldDef { def: tables.create_def_id(self.did), - name: self.name.stable(tables), + name: self.name.stable(tables, cx), } } } impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> { type T = stable_mir::ty::GenericArgs; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - GenericArgs(self.iter().map(|arg| arg.kind().stable(tables)).collect()) + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + GenericArgs(self.iter().map(|arg| arg.kind().stable(tables, cx)).collect()) } } impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> { type T = stable_mir::ty::GenericArgKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::GenericArgKind; match self { - ty::GenericArgKind::Lifetime(region) => GenericArgKind::Lifetime(region.stable(tables)), - ty::GenericArgKind::Type(ty) => GenericArgKind::Type(ty.stable(tables)), - ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables)), + ty::GenericArgKind::Lifetime(region) => { + GenericArgKind::Lifetime(region.stable(tables, cx)) + } + ty::GenericArgKind::Type(ty) => GenericArgKind::Type(ty.stable(tables, cx)), + ty::GenericArgKind::Const(cnst) => GenericArgKind::Const(cnst.stable(tables, cx)), } } } @@ -179,15 +228,19 @@ where { type T = stable_mir::ty::Binder; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::Binder; Binder { - value: self.as_ref().skip_binder().stable(tables), + value: self.as_ref().skip_binder().stable(tables, cx), bound_vars: self .bound_vars() .iter() - .map(|bound_var| bound_var.stable(tables)) + .map(|bound_var| bound_var.stable(tables, cx)) .collect(), } } @@ -199,23 +252,35 @@ where { type T = stable_mir::ty::EarlyBinder; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::EarlyBinder; - EarlyBinder { value: self.as_ref().skip_binder().stable(tables) } + EarlyBinder { value: self.as_ref().skip_binder().stable(tables, cx) } } } impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { type T = stable_mir::ty::FnSig; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::FnSig; FnSig { - inputs_and_output: self.inputs_and_output.iter().map(|ty| ty.stable(tables)).collect(), + inputs_and_output: self + .inputs_and_output + .iter() + .map(|ty| ty.stable(tables, cx)) + .collect(), c_variadic: self.c_variadic, - safety: self.safety.stable(tables), - abi: self.abi.stable(tables), + safety: self.safety.stable(tables, cx), + abi: self.abi.stable(tables, cx), } } } @@ -223,7 +288,11 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { impl<'tcx> Stable<'tcx> for ty::BoundTyKind { type T = stable_mir::ty::BoundTyKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + _: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::BoundTyKind; match self { @@ -238,7 +307,11 @@ impl<'tcx> Stable<'tcx> for ty::BoundTyKind { impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { type T = stable_mir::ty::BoundRegionKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + _: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::BoundRegionKind; match self { @@ -254,15 +327,19 @@ impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { impl<'tcx> Stable<'tcx> for ty::BoundVariableKind { type T = stable_mir::ty::BoundVariableKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::BoundVariableKind; match self { ty::BoundVariableKind::Ty(bound_ty_kind) => { - BoundVariableKind::Ty(bound_ty_kind.stable(tables)) + BoundVariableKind::Ty(bound_ty_kind.stable(tables, cx)) } ty::BoundVariableKind::Region(bound_region_kind) => { - BoundVariableKind::Region(bound_region_kind.stable(tables)) + BoundVariableKind::Region(bound_region_kind.stable(tables, cx)) } ty::BoundVariableKind::Const => BoundVariableKind::Const, } @@ -272,7 +349,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundVariableKind { impl<'tcx> Stable<'tcx> for ty::IntTy { type T = IntTy; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { ty::IntTy::Isize => IntTy::Isize, ty::IntTy::I8 => IntTy::I8, @@ -287,7 +364,7 @@ impl<'tcx> Stable<'tcx> for ty::IntTy { impl<'tcx> Stable<'tcx> for ty::UintTy { type T = UintTy; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { ty::UintTy::Usize => UintTy::Usize, ty::UintTy::U8 => UintTy::U8, @@ -302,7 +379,7 @@ impl<'tcx> Stable<'tcx> for ty::UintTy { impl<'tcx> Stable<'tcx> for ty::FloatTy { type T = FloatTy; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { ty::FloatTy::F16 => FloatTy::F16, ty::FloatTy::F32 => FloatTy::F32, @@ -314,46 +391,55 @@ impl<'tcx> Stable<'tcx> for ty::FloatTy { impl<'tcx> Stable<'tcx> for Ty<'tcx> { type T = stable_mir::ty::Ty; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - tables.intern_ty(tables.tcx.lift(*self).unwrap()) + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + tables.intern_ty(cx.lift(*self).unwrap()) } } impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { type T = stable_mir::ty::TyKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match self { ty::Bool => TyKind::RigidTy(RigidTy::Bool), ty::Char => TyKind::RigidTy(RigidTy::Char), - ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables))), - ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))), - ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))), + ty::Int(int_ty) => TyKind::RigidTy(RigidTy::Int(int_ty.stable(tables, cx))), + ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables, cx))), + ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables, cx))), ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt( tables.adt_def(adt_def.did()), - generic_args.stable(tables), + generic_args.stable(tables, cx), )), ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))), ty::Str => TyKind::RigidTy(RigidTy::Str), ty::Array(ty, constant) => { - TyKind::RigidTy(RigidTy::Array(ty.stable(tables), constant.stable(tables))) + TyKind::RigidTy(RigidTy::Array(ty.stable(tables, cx), constant.stable(tables, cx))) } ty::Pat(ty, pat) => { - TyKind::RigidTy(RigidTy::Pat(ty.stable(tables), pat.stable(tables))) + TyKind::RigidTy(RigidTy::Pat(ty.stable(tables, cx), pat.stable(tables, cx))) } - ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(ty.stable(tables))), + ty::Slice(ty) => TyKind::RigidTy(RigidTy::Slice(ty.stable(tables, cx))), ty::RawPtr(ty, mutbl) => { - TyKind::RigidTy(RigidTy::RawPtr(ty.stable(tables), mutbl.stable(tables))) + TyKind::RigidTy(RigidTy::RawPtr(ty.stable(tables, cx), mutbl.stable(tables, cx))) } ty::Ref(region, ty, mutbl) => TyKind::RigidTy(RigidTy::Ref( - region.stable(tables), - ty.stable(tables), - mutbl.stable(tables), + region.stable(tables, cx), + ty.stable(tables, cx), + mutbl.stable(tables, cx), + )), + ty::FnDef(def_id, generic_args) => TyKind::RigidTy(RigidTy::FnDef( + tables.fn_def(*def_id), + generic_args.stable(tables, cx), )), - ty::FnDef(def_id, generic_args) => { - TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables))) - } ty::FnPtr(sig_tys, hdr) => { - TyKind::RigidTy(RigidTy::FnPtr(sig_tys.with(*hdr).stable(tables))) + TyKind::RigidTy(RigidTy::FnPtr(sig_tys.with(*hdr).stable(tables, cx))) } // FIXME(unsafe_binders): ty::UnsafeBinder(_) => todo!(), @@ -361,36 +447,36 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { TyKind::RigidTy(RigidTy::Dynamic( existential_predicates .iter() - .map(|existential_predicate| existential_predicate.stable(tables)) + .map(|existential_predicate| existential_predicate.stable(tables, cx)) .collect(), - region.stable(tables), - dyn_kind.stable(tables), + region.stable(tables, cx), + dyn_kind.stable(tables, cx), )) } ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure( tables.closure_def(*def_id), - generic_args.stable(tables), + generic_args.stable(tables, cx), )), ty::CoroutineClosure(..) => todo!("FIXME(async_closures): Lower these to SMIR"), ty::Coroutine(def_id, generic_args) => TyKind::RigidTy(RigidTy::Coroutine( tables.coroutine_def(*def_id), - generic_args.stable(tables), - tables.tcx.coroutine_movability(*def_id).stable(tables), + generic_args.stable(tables, cx), + cx.coroutine_movability(*def_id).stable(tables, cx), )), ty::Never => TyKind::RigidTy(RigidTy::Never), - ty::Tuple(fields) => { - TyKind::RigidTy(RigidTy::Tuple(fields.iter().map(|ty| ty.stable(tables)).collect())) - } + ty::Tuple(fields) => TyKind::RigidTy(RigidTy::Tuple( + fields.iter().map(|ty| ty.stable(tables, cx)).collect(), + )), ty::Alias(alias_kind, alias_ty) => { - TyKind::Alias(alias_kind.stable(tables), alias_ty.stable(tables)) + TyKind::Alias(alias_kind.stable(tables, cx), alias_ty.stable(tables, cx)) } - ty::Param(param_ty) => TyKind::Param(param_ty.stable(tables)), + ty::Param(param_ty) => TyKind::Param(param_ty.stable(tables, cx)), ty::Bound(debruijn_idx, bound_ty) => { - TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables)) + TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables, cx)) } ty::CoroutineWitness(def_id, args) => TyKind::RigidTy(RigidTy::CoroutineWitness( tables.coroutine_witness_def(*def_id), - args.stable(tables), + args.stable(tables, cx), )), ty::Placeholder(..) | ty::Infer(_) | ty::Error(_) => { unreachable!(); @@ -402,12 +488,16 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { type T = stable_mir::ty::Pattern; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { match **self { ty::PatternKind::Range { start, end } => stable_mir::ty::Pattern::Range { // FIXME(SMIR): update data structures to not have an Option here anymore - start: Some(start.stable(tables)), - end: Some(end.stable(tables)), + start: Some(start.stable(tables, cx)), + end: Some(end.stable(tables, cx)), include_end: true, }, ty::PatternKind::Or(_) => todo!(), @@ -418,24 +508,30 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { type T = stable_mir::ty::TyConst; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - let ct = tables.tcx.lift(*self).unwrap(); + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + let ct = cx.lift(*self).unwrap(); let kind = match ct.kind() { ty::ConstKind::Value(cv) => { - let const_val = tables.tcx.valtree_to_const_val(cv); + let const_val = cx.valtree_to_const_val(cv); if matches!(const_val, mir::ConstValue::ZeroSized) { - stable_mir::ty::TyConstKind::ZSTValue(cv.ty.stable(tables)) + stable_mir::ty::TyConstKind::ZSTValue(cv.ty.stable(tables, cx)) } else { stable_mir::ty::TyConstKind::Value( - cv.ty.stable(tables), - alloc::new_allocation(cv.ty, const_val, tables), + cv.ty.stable(tables, cx), + alloc::new_allocation(cv.ty, const_val, tables, cx), ) } } - ty::ConstKind::Param(param) => stable_mir::ty::TyConstKind::Param(param.stable(tables)), + ty::ConstKind::Param(param) => { + stable_mir::ty::TyConstKind::Param(param.stable(tables, cx)) + } ty::ConstKind::Unevaluated(uv) => stable_mir::ty::TyConstKind::Unevaluated( tables.const_def(uv.def), - uv.args.stable(tables), + uv.args.stable(tables, cx), ), ty::ConstKind::Error(_) => unreachable!(), ty::ConstKind::Infer(_) => unreachable!(), @@ -450,7 +546,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { impl<'tcx> Stable<'tcx> for ty::ParamConst { type T = stable_mir::ty::ParamConst; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use stable_mir::ty::ParamConst; ParamConst { index: self.index, name: self.name.to_string() } } @@ -458,7 +554,7 @@ impl<'tcx> Stable<'tcx> for ty::ParamConst { impl<'tcx> Stable<'tcx> for ty::ParamTy { type T = stable_mir::ty::ParamTy; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use stable_mir::ty::ParamTy; ParamTy { index: self.index, name: self.name.to_string() } } @@ -466,15 +562,19 @@ impl<'tcx> Stable<'tcx> for ty::ParamTy { impl<'tcx> Stable<'tcx> for ty::BoundTy { type T = stable_mir::ty::BoundTy; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::BoundTy; - BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables) } + BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables, cx) } } } impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind { type T = stable_mir::ty::TraitSpecializationKind; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use stable_mir::ty::TraitSpecializationKind; match self { @@ -489,20 +589,24 @@ impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind { impl<'tcx> Stable<'tcx> for ty::TraitDef { type T = stable_mir::ty::TraitDecl; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::opaque; use stable_mir::ty::TraitDecl; TraitDecl { def_id: tables.trait_def(self.def_id), - safety: self.safety.stable(tables), + safety: self.safety.stable(tables, cx), paren_sugar: self.paren_sugar, has_auto_impl: self.has_auto_impl, is_marker: self.is_marker, is_coinductive: self.is_coinductive, skip_array_during_method_dispatch: self.skip_array_during_method_dispatch, skip_boxed_slice_during_method_dispatch: self.skip_boxed_slice_during_method_dispatch, - specialization_kind: self.specialization_kind.stable(tables), + specialization_kind: self.specialization_kind.stable(tables, cx), must_implement_one_of: self .must_implement_one_of .as_ref() @@ -515,20 +619,28 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef { impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> { type T = stable_mir::ty::TraitRef; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::TraitRef; - TraitRef::try_new(tables.trait_def(self.def_id), self.args.stable(tables)).unwrap() + TraitRef::try_new(tables.trait_def(self.def_id), self.args.stable(tables, cx)).unwrap() } } impl<'tcx> Stable<'tcx> for ty::Generics { type T = stable_mir::ty::Generics; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::Generics; - let params: Vec<_> = self.own_params.iter().map(|param| param.stable(tables)).collect(); + let params: Vec<_> = self.own_params.iter().map(|param| param.stable(tables, cx)).collect(); let param_def_id_to_index = params.iter().map(|param| (param.def_id, param.index)).collect(); @@ -541,7 +653,7 @@ impl<'tcx> Stable<'tcx> for ty::Generics { has_late_bound_regions: self .has_late_bound_regions .as_ref() - .map(|late_bound_regions| late_bound_regions.stable(tables)), + .map(|late_bound_regions| late_bound_regions.stable(tables, cx)), } } } @@ -549,7 +661,7 @@ impl<'tcx> Stable<'tcx> for ty::Generics { impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { type T = stable_mir::ty::GenericParamDefKind; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use stable_mir::ty::GenericParamDefKind; match self { ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime, @@ -566,13 +678,17 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef { type T = stable_mir::ty::GenericParamDef; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { GenericParamDef { name: self.name.to_string(), def_id: tables.generic_def(self.def_id), index: self.index, pure_wrt_drop: self.pure_wrt_drop, - kind: self.kind.stable(tables), + kind: self.kind.stable(tables, cx), } } } @@ -580,31 +696,36 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef { impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> { type T = stable_mir::ty::PredicateKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::ty::PredicateKind; match self { PredicateKind::Clause(clause_kind) => { - stable_mir::ty::PredicateKind::Clause(clause_kind.stable(tables)) + stable_mir::ty::PredicateKind::Clause(clause_kind.stable(tables, cx)) } PredicateKind::DynCompatible(did) => { stable_mir::ty::PredicateKind::DynCompatible(tables.trait_def(*did)) } PredicateKind::Subtype(subtype_predicate) => { - stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables)) + stable_mir::ty::PredicateKind::SubType(subtype_predicate.stable(tables, cx)) } PredicateKind::Coerce(coerce_predicate) => { - stable_mir::ty::PredicateKind::Coerce(coerce_predicate.stable(tables)) - } - PredicateKind::ConstEquate(a, b) => { - stable_mir::ty::PredicateKind::ConstEquate(a.stable(tables), b.stable(tables)) + stable_mir::ty::PredicateKind::Coerce(coerce_predicate.stable(tables, cx)) } + PredicateKind::ConstEquate(a, b) => stable_mir::ty::PredicateKind::ConstEquate( + a.stable(tables, cx), + b.stable(tables, cx), + ), PredicateKind::Ambiguous => stable_mir::ty::PredicateKind::Ambiguous, PredicateKind::NormalizesTo(_pred) => unimplemented!(), PredicateKind::AliasRelate(a, b, alias_relation_direction) => { stable_mir::ty::PredicateKind::AliasRelate( - a.kind().stable(tables), - b.kind().stable(tables), - alias_relation_direction.stable(tables), + a.kind().stable(tables, cx), + b.kind().stable(tables, cx), + alias_relation_direction.stable(tables, cx), ) } } @@ -614,34 +735,38 @@ impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { type T = stable_mir::ty::ClauseKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use rustc_middle::ty::ClauseKind; match *self { ClauseKind::Trait(trait_object) => { - stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables)) + stable_mir::ty::ClauseKind::Trait(trait_object.stable(tables, cx)) } ClauseKind::RegionOutlives(region_outlives) => { - stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables)) + stable_mir::ty::ClauseKind::RegionOutlives(region_outlives.stable(tables, cx)) } ClauseKind::TypeOutlives(type_outlives) => { let ty::OutlivesPredicate::<_, _>(a, b) = type_outlives; stable_mir::ty::ClauseKind::TypeOutlives(stable_mir::ty::OutlivesPredicate( - a.stable(tables), - b.stable(tables), + a.stable(tables, cx), + b.stable(tables, cx), )) } ClauseKind::Projection(projection_predicate) => { - stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables)) + stable_mir::ty::ClauseKind::Projection(projection_predicate.stable(tables, cx)) } ClauseKind::ConstArgHasType(const_, ty) => stable_mir::ty::ClauseKind::ConstArgHasType( - const_.stable(tables), - ty.stable(tables), + const_.stable(tables, cx), + ty.stable(tables, cx), ), ClauseKind::WellFormed(term) => { - stable_mir::ty::ClauseKind::WellFormed(term.kind().stable(tables)) + stable_mir::ty::ClauseKind::WellFormed(term.kind().stable(tables, cx)) } ClauseKind::ConstEvaluatable(const_) => { - stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables)) + stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables, cx)) } ClauseKind::HostEffect(..) => { todo!() @@ -653,7 +778,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::ClosureKind { type T = stable_mir::ty::ClosureKind; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::ty::ClosureKind::*; match self { Fn => stable_mir::ty::ClosureKind::Fn, @@ -666,25 +791,33 @@ impl<'tcx> Stable<'tcx> for ty::ClosureKind { impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> { type T = stable_mir::ty::SubtypePredicate; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { let ty::SubtypePredicate { a, b, a_is_expected: _ } = self; - stable_mir::ty::SubtypePredicate { a: a.stable(tables), b: b.stable(tables) } + stable_mir::ty::SubtypePredicate { a: a.stable(tables, cx), b: b.stable(tables, cx) } } } impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> { type T = stable_mir::ty::CoercePredicate; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { let ty::CoercePredicate { a, b } = self; - stable_mir::ty::CoercePredicate { a: a.stable(tables), b: b.stable(tables) } + stable_mir::ty::CoercePredicate { a: a.stable(tables, cx), b: b.stable(tables, cx) } } } impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection { type T = stable_mir::ty::AliasRelationDirection; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::ty::AliasRelationDirection::*; match self { Equate => stable_mir::ty::AliasRelationDirection::Equate, @@ -696,11 +829,15 @@ impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection { impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> { type T = stable_mir::ty::TraitPredicate; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { let ty::TraitPredicate { trait_ref, polarity } = self; stable_mir::ty::TraitPredicate { - trait_ref: trait_ref.stable(tables), - polarity: polarity.stable(tables), + trait_ref: trait_ref.stable(tables, cx), + polarity: polarity.stable(tables, cx), } } } @@ -711,20 +848,28 @@ where { type T = stable_mir::ty::OutlivesPredicate; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { let ty::OutlivesPredicate(a, b) = self; - stable_mir::ty::OutlivesPredicate(a.stable(tables), b.stable(tables)) + stable_mir::ty::OutlivesPredicate(a.stable(tables, cx), b.stable(tables, cx)) } } impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { type T = stable_mir::ty::ProjectionPredicate; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { let ty::ProjectionPredicate { projection_term, term } = self; stable_mir::ty::ProjectionPredicate { - projection_term: projection_term.stable(tables), - term: term.kind().stable(tables), + projection_term: projection_term.stable(tables, cx), + term: term.kind().stable(tables, cx), } } } @@ -732,7 +877,7 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { impl<'tcx> Stable<'tcx> for ty::ImplPolarity { type T = stable_mir::ty::ImplPolarity; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::ty::ImplPolarity::*; match self { Positive => stable_mir::ty::ImplPolarity::Positive, @@ -745,7 +890,7 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity { impl<'tcx> Stable<'tcx> for ty::PredicatePolarity { type T = stable_mir::ty::PredicatePolarity; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_middle::ty::PredicatePolarity::*; match self { Positive => stable_mir::ty::PredicatePolarity::Positive, @@ -757,15 +902,23 @@ impl<'tcx> Stable<'tcx> for ty::PredicatePolarity { impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { type T = stable_mir::ty::Region; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - Region { kind: self.kind().stable(tables) } + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + Region { kind: self.kind().stable(tables, cx) } } } impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { type T = stable_mir::ty::RegionKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind}; match self { ty::ReEarlyParam(early_reg) => RegionKind::ReEarlyParam(EarlyParamRegion { @@ -774,7 +927,10 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { }), ty::ReBound(db_index, bound_reg) => RegionKind::ReBound( db_index.as_u32(), - BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) }, + BoundRegion { + var: bound_reg.var.as_u32(), + kind: bound_reg.kind.stable(tables, cx), + }, ), ty::ReStatic => RegionKind::ReStatic, ty::RePlaceholder(place_holder) => { @@ -782,7 +938,7 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { universe: place_holder.universe.as_u32(), bound: BoundRegion { var: place_holder.bound.var.as_u32(), - kind: place_holder.bound.kind.stable(tables), + kind: place_holder.bound.kind.stable(tables, cx), }, }) } @@ -795,8 +951,12 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { type T = stable_mir::mir::mono::Instance; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - let def = tables.instance_def(tables.tcx.lift(*self).unwrap()); + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { + let def = tables.instance_def(cx.lift(*self).unwrap()); let kind = match self.def { ty::InstanceKind::Item(..) => stable_mir::mir::mono::InstanceKind::Item, ty::InstanceKind::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic, @@ -824,7 +984,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { impl<'tcx> Stable<'tcx> for ty::Variance { type T = stable_mir::mir::Variance; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { ty::Bivariant => stable_mir::mir::Variance::Bivariant, ty::Contravariant => stable_mir::mir::Variance::Contravariant, @@ -837,7 +997,7 @@ impl<'tcx> Stable<'tcx> for ty::Variance { impl<'tcx> Stable<'tcx> for ty::Movability { type T = stable_mir::ty::Movability; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { match self { ty::Movability::Static => stable_mir::ty::Movability::Static, ty::Movability::Movable => stable_mir::ty::Movability::Movable, @@ -848,7 +1008,7 @@ impl<'tcx> Stable<'tcx> for ty::Movability { impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi { type T = stable_mir::ty::Abi; - fn stable(&self, _: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use rustc_abi::ExternAbi; use stable_mir::ty::Abi; match *self { @@ -886,10 +1046,14 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi { impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule { type T = stable_mir::ty::ForeignModule; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { stable_mir::ty::ForeignModule { def_id: tables.foreign_module_def(self.def_id), - abi: self.abi.stable(tables), + abi: self.abi.stable(tables, cx), } } } @@ -897,7 +1061,11 @@ impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule { impl<'tcx> Stable<'tcx> for ty::AssocKind { type T = stable_mir::ty::AssocKind; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::{AssocKind, AssocTypeData}; match *self { ty::AssocKind::Const { name } => AssocKind::Const { name: name.to_string() }, @@ -908,7 +1076,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind { data: match data { ty::AssocTypeData::Normal(name) => AssocTypeData::Normal(name.to_string()), ty::AssocTypeData::Rpitit(rpitit) => { - AssocTypeData::Rpitit(rpitit.stable(tables)) + AssocTypeData::Rpitit(rpitit.stable(tables, cx)) } }, }, @@ -919,7 +1087,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind { impl<'tcx> Stable<'tcx> for ty::AssocItemContainer { type T = stable_mir::ty::AssocItemContainer; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { use stable_mir::ty::AssocItemContainer; match self { ty::AssocItemContainer::Trait => AssocItemContainer::Trait, @@ -931,11 +1099,15 @@ impl<'tcx> Stable<'tcx> for ty::AssocItemContainer { impl<'tcx> Stable<'tcx> for ty::AssocItem { type T = stable_mir::ty::AssocItem; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + cx: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { stable_mir::ty::AssocItem { def_id: tables.assoc_def(self.def_id), - kind: self.kind.stable(tables), - container: self.container.stable(tables), + kind: self.kind.stable(tables, cx), + container: self.container.stable(tables, cx), trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)), } } @@ -944,7 +1116,11 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem { impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData { type T = stable_mir::ty::ImplTraitInTraitData; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable( + &self, + tables: &mut Tables<'tcx, BridgeTys>, + _: &SmirCtxt<'tcx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::ImplTraitInTraitData; match self { ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => { diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index d3ef5f4001dc..33213fcbe08e 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -41,6 +41,7 @@ use crate::{rustc_smir, stable_mir}; pub mod abi; mod alloc; +pub(crate) mod convert; #[macro_use] pub mod crate_def; pub mod compiler_interface; From 6916089d7c4cefc2c2bb10398547535e0250fb60 Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 5 May 2025 15:40:42 +0800 Subject: [PATCH 37/62] fix: rewrite some parts of `rustc_smir::builder.rs` --- compiler/rustc_smir/src/rustc_smir/builder.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs index 40e6d21c0637..b8a1d240e3f8 100644 --- a/compiler/rustc_smir/src/rustc_smir/builder.rs +++ b/compiler/rustc_smir/src/rustc_smir/builder.rs @@ -9,8 +9,7 @@ use rustc_middle::mir; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::ty::{self, TyCtxt}; -use crate::rustc_smir::{Stable, Tables}; -use crate::stable_mir; +use crate::rustc_smir::{Bridge, Tables}; /// Builds a monomorphic body for a given instance. pub(crate) struct BodyBuilder<'tcx> { @@ -31,7 +30,7 @@ impl<'tcx> BodyBuilder<'tcx> { /// Build a stable monomorphic body for a given instance based on the MIR body. /// /// All constants are also evaluated. - pub(crate) fn build(mut self, tables: &mut Tables<'tcx>) -> stable_mir::mir::Body { + pub(crate) fn build(mut self, tables: &mut Tables<'tcx, B>) -> mir::Body<'tcx> { let body = tables.tcx.instance_mir(self.instance.def).clone(); let mono_body = if !self.instance.args.is_empty() // Without the `generic_const_exprs` feature gate, anon consts in signatures do not @@ -50,7 +49,8 @@ impl<'tcx> BodyBuilder<'tcx> { // Already monomorphic. body }; - mono_body.stable(tables) + + mono_body } } From 45cf29d65160ca30c1878fa516bb93e0f0dc9619 Mon Sep 17 00:00:00 2001 From: Makai Date: Tue, 6 May 2025 12:41:34 +0800 Subject: [PATCH 38/62] refactor: remove the `tcx` field in `Tables` the only functionality of `Tables` is caching results. this commit moves calls to rustc queries from `Tables` to `SmirCtxt`. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 2 +- compiler/rustc_smir/src/rustc_smir/alloc.rs | 35 ++++---- compiler/rustc_smir/src/rustc_smir/builder.rs | 8 +- .../src/rustc_smir/context/impls.rs | 81 ++++++++++++------- .../rustc_smir/src/rustc_smir/context/mod.rs | 14 ++-- compiler/rustc_smir/src/rustc_smir/mod.rs | 48 +---------- compiler/rustc_smir/src/stable_mir/alloc.rs | 11 +-- .../src/stable_mir/compiler_interface.rs | 20 +++-- 8 files changed, 100 insertions(+), 119 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 5947a7a84405..db232a1b83a9 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -127,7 +127,7 @@ where F: FnOnce() -> T, { let smir_cx = RefCell::new(SmirCtxt::new(tcx)); - let container = SmirContainer { tables: RefCell::new(Tables::new(tcx)), cx: smir_cx }; + let container = SmirContainer { tables: RefCell::new(Tables::default()), cx: smir_cx }; stable_mir::compiler_interface::run(&container, || init(&container, f)) } diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 34692962de70..6b32b5b07d87 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -8,19 +8,28 @@ use rustc_abi::{Size, TyAndLayout}; use rustc_middle::mir::interpret::{ AllocId, AllocInit, AllocRange, Allocation, ConstAllocation, Pointer, Scalar, alloc_range, }; -use rustc_middle::ty::Ty; +use rustc_middle::ty::{Ty, layout}; -use crate::rustc_smir::{Bridge, SmirError, Tables}; +use super::SmirCtxt; +use crate::rustc_smir::{Bridge, SmirError}; + +pub fn create_ty_and_layout<'tcx, B: Bridge>( + cx: &SmirCtxt<'tcx, B>, + ty: Ty<'tcx>, +) -> Result>, &'tcx layout::LayoutError<'tcx>> { + use crate::rustc_smir::context::SmirTypingEnv; + cx.tcx.layout_of(cx.fully_monomorphized().as_query_input(ty)) +} pub fn try_new_scalar<'tcx, B: Bridge>( layout: TyAndLayout<'tcx, Ty<'tcx>>, scalar: Scalar, - tables: &mut Tables<'tcx, B>, + cx: &SmirCtxt<'tcx, B>, ) -> Result { let size = scalar.size(); let mut allocation = Allocation::new(size, layout.align.abi, AllocInit::Uninit, ()); allocation - .write_scalar(&tables.tcx, alloc_range(Size::ZERO, size), scalar) + .write_scalar(&cx.tcx, alloc_range(Size::ZERO, size), scalar) .map_err(|e| B::Error::from_internal(e))?; Ok(allocation) @@ -30,24 +39,20 @@ pub fn try_new_slice<'tcx, B: Bridge>( layout: TyAndLayout<'tcx, Ty<'tcx>>, data: ConstAllocation<'tcx>, meta: u64, - tables: &mut Tables<'tcx, B>, + cx: &SmirCtxt<'tcx, B>, ) -> Result { - let alloc_id = tables.tcx.reserve_and_set_memory_alloc(data); + let alloc_id = cx.tcx.reserve_and_set_memory_alloc(data); let ptr = Pointer::new(alloc_id.into(), Size::ZERO); let scalar_ptr = Scalar::from_pointer(ptr, &tables.tcx); let scalar_meta: Scalar = Scalar::from_target_usize(meta, &tables.tcx); let mut allocation = Allocation::new(layout.size, layout.align.abi, AllocInit::Uninit, ()); allocation - .write_scalar( - &tables.tcx, - alloc_range(Size::ZERO, tables.tcx.data_layout.pointer_size), - scalar_ptr, - ) + .write_scalar(&cx.tcx, alloc_range(Size::ZERO, cx.tcx.data_layout.pointer_size), scalar_ptr) .map_err(|e| B::Error::from_internal(e))?; allocation .write_scalar( - &tables.tcx, - alloc_range(tables.tcx.data_layout.pointer_size, scalar_meta.size()), + &cx.tcx, + alloc_range(cx.tcx.data_layout.pointer_size, scalar_meta.size()), scalar_meta, ) .map_err(|e| B::Error::from_internal(e))?; @@ -57,9 +62,9 @@ pub fn try_new_slice<'tcx, B: Bridge>( pub fn try_new_indirect<'tcx, B: Bridge>( alloc_id: AllocId, - tables: &mut Tables<'tcx, B>, + cx: &SmirCtxt<'tcx, B>, ) -> ConstAllocation<'tcx> { - let alloc = tables.tcx.global_alloc(alloc_id).unwrap_memory(); + let alloc = cx.tcx.global_alloc(alloc_id).unwrap_memory(); alloc } diff --git a/compiler/rustc_smir/src/rustc_smir/builder.rs b/compiler/rustc_smir/src/rustc_smir/builder.rs index b8a1d240e3f8..2141053d09af 100644 --- a/compiler/rustc_smir/src/rustc_smir/builder.rs +++ b/compiler/rustc_smir/src/rustc_smir/builder.rs @@ -9,8 +9,6 @@ use rustc_middle::mir; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::ty::{self, TyCtxt}; -use crate::rustc_smir::{Bridge, Tables}; - /// Builds a monomorphic body for a given instance. pub(crate) struct BodyBuilder<'tcx> { tcx: TyCtxt<'tcx>, @@ -30,8 +28,8 @@ impl<'tcx> BodyBuilder<'tcx> { /// Build a stable monomorphic body for a given instance based on the MIR body. /// /// All constants are also evaluated. - pub(crate) fn build(mut self, tables: &mut Tables<'tcx, B>) -> mir::Body<'tcx> { - let body = tables.tcx.instance_mir(self.instance.def).clone(); + pub(crate) fn build(mut self) -> mir::Body<'tcx> { + let body = self.tcx.instance_mir(self.instance.def).clone(); let mono_body = if !self.instance.args.is_empty() // Without the `generic_const_exprs` feature gate, anon consts in signatures do not // get generic parameters. Which is wrong, but also not a problem without @@ -39,7 +37,7 @@ impl<'tcx> BodyBuilder<'tcx> { || self.tcx.def_kind(self.instance.def_id()) != DefKind::AnonConst { let mut mono_body = self.instance.instantiate_mir_and_normalize_erasing_regions( - tables.tcx, + self.tcx, ty::TypingEnv::fully_monomorphized(), ty::EarlyBinder::bind(body), ); diff --git a/compiler/rustc_smir/src/rustc_smir/context/impls.rs b/compiler/rustc_smir/src/rustc_smir/context/impls.rs index 77a2f879d6a7..bf86d4ac41dd 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/impls.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/impls.rs @@ -143,6 +143,46 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { self.tcx.valtree_to_const_val(key) } + /// Return whether the instance as a body available. + /// + /// Items and intrinsics may have a body available from its definition. + /// Shims body may be generated depending on their type. + pub(crate) fn instance_has_body(&self, instance: Instance<'tcx>) -> bool { + let def_id = instance.def_id(); + self.item_has_body(def_id) + || !matches!( + instance.def, + ty::InstanceKind::Virtual(..) + | ty::InstanceKind::Intrinsic(..) + | ty::InstanceKind::Item(..) + ) + } + + /// Return whether the item has a body defined by the user. + /// + /// Note that intrinsics may have a placeholder body that shouldn't be used in practice. + /// In StableMIR, we handle this case as if the body is not available. + pub(crate) fn item_has_body(&self, def_id: DefId) -> bool { + let must_override = if let Some(intrinsic) = self.tcx.intrinsic(def_id) { + intrinsic.must_be_overridden + } else { + false + }; + !must_override && self.tcx.is_mir_available(def_id) + } + + fn filter_fn_def(&self, def_id: DefId) -> Option { + if matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) { + Some(def_id) + } else { + None + } + } + + fn filter_static_def(&self, def_id: DefId) -> Option { + matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| def_id) + } + pub fn target_endian(&self) -> Endian { self.tcx.data_layout.endian } @@ -167,8 +207,8 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { } /// Check whether the body of a function is available. - pub fn has_body(&self, def: DefId, tables: &mut Tables<'_, B>) -> bool { - tables.item_has_body(def) + pub fn has_body(&self, def: DefId) -> bool { + self.item_has_body(def) } pub fn foreign_modules(&self, crate_num: CrateNum) -> Vec { @@ -176,13 +216,13 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { } /// Retrieve all functions defined in this crate. - pub fn crate_functions(&self, crate_num: CrateNum, tables: &mut Tables<'_, B>) -> Vec { - filter_def_ids(self.tcx, crate_num, |def_id| tables.filter_fn_def(def_id)) + pub fn crate_functions(&self, crate_num: CrateNum) -> Vec { + filter_def_ids(self.tcx, crate_num, |def_id| self.filter_fn_def(def_id)) } /// Retrieve all static items defined in this crate. - pub fn crate_statics(&self, crate_num: CrateNum, tables: &mut Tables<'_, B>) -> Vec { - filter_def_ids(self.tcx, crate_num, |def_id| tables.filter_static_def(def_id)) + pub fn crate_statics(&self, crate_num: CrateNum) -> Vec { + filter_def_ids(self.tcx, crate_num, |def_id| self.filter_static_def(def_id)) } pub fn foreign_module(&self, mod_def: DefId) -> &ForeignModule { @@ -574,14 +614,8 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { } /// Get the body of an Instance which is already monomorphized. - pub fn instance_body( - &self, - instance: ty::Instance<'tcx>, - tables: &mut Tables<'tcx, B>, - ) -> Option> { - tables - .instance_has_body(instance) - .then(|| BodyBuilder::new(self.tcx, instance).build(tables)) + pub fn instance_body(&self, instance: ty::Instance<'tcx>) -> Option> { + self.instance_has_body(instance).then(|| BodyBuilder::new(self.tcx, instance).build()) } /// Get the instance type with generic instantiations applied and lifetimes erased. @@ -599,18 +633,13 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { pub fn instance_abi( &self, instance: ty::Instance<'tcx>, - tables: &mut Tables<'tcx, B>, ) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> { - Ok(tables.fn_abi_of_instance(instance, List::empty())?) + Ok(self.fn_abi_of_instance(instance, List::empty())?) } /// Get the ABI of a function pointer. - pub fn fn_ptr_abi( - &self, - sig: PolyFnSig<'tcx>, - tables: &mut Tables<'tcx, B>, - ) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> { - Ok(tables.fn_abi_of_fn_ptr(sig, List::empty())?) + pub fn fn_ptr_abi(&self, sig: PolyFnSig<'tcx>) -> Result<&FnAbi<'tcx, Ty<'tcx>>, B::Error> { + Ok(self.fn_abi_of_fn_ptr(sig, List::empty())?) } /// Get the instance. @@ -737,12 +766,8 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { } /// Get the layout of a type. - pub fn ty_layout( - &self, - ty: Ty<'tcx>, - tables: &mut Tables<'tcx, B>, - ) -> Result, B::Error> { - let layout = tables.layout_of(ty)?.layout; + pub fn ty_layout(&self, ty: Ty<'tcx>) -> Result, B::Error> { + let layout = self.layout_of(ty)?.layout; Ok(layout) } diff --git a/compiler/rustc_smir/src/rustc_smir/context/mod.rs b/compiler/rustc_smir/src/rustc_smir/context/mod.rs index 75acede8d345..b31d92cdfca6 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/mod.rs @@ -9,7 +9,7 @@ use rustc_middle::ty; use rustc_middle::ty::layout::{FnAbiOfHelpers, HasTyCtxt, HasTypingEnv, LayoutOfHelpers}; use rustc_middle::ty::{Ty, TyCtxt}; -use crate::rustc_smir::{Bridge, SmirError, Tables}; +use crate::rustc_smir::{Bridge, SmirError}; mod impls; mod traits; @@ -21,7 +21,7 @@ pub use traits::*; /// The [`crate::stable_mir::compiler_interface::SmirInterface`] must go through /// this context to obtain rustc-level information. pub struct SmirCtxt<'tcx, B: Bridge> { - tcx: TyCtxt<'tcx>, + pub(crate) tcx: TyCtxt<'tcx>, _marker: PhantomData, } @@ -32,7 +32,7 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { } /// Implement error handling for extracting function ABI information. -impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for Tables<'tcx, B> { +impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for SmirCtxt<'tcx, B> { type FnAbiOfResult = Result<&'tcx rustc_target::callconv::FnAbi<'tcx, Ty<'tcx>>, B::Error>; #[inline] @@ -46,7 +46,7 @@ impl<'tcx, B: Bridge> FnAbiOfHelpers<'tcx> for Tables<'tcx, B> { } } -impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for Tables<'tcx, B> { +impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for SmirCtxt<'tcx, B> { type LayoutOfResult = Result, B::Error>; #[inline] @@ -60,19 +60,19 @@ impl<'tcx, B: Bridge> LayoutOfHelpers<'tcx> for Tables<'tcx, B> { } } -impl<'tcx, B: Bridge> HasTypingEnv<'tcx> for Tables<'tcx, B> { +impl<'tcx, B: Bridge> HasTypingEnv<'tcx> for SmirCtxt<'tcx, B> { fn typing_env(&self) -> ty::TypingEnv<'tcx> { ty::TypingEnv::fully_monomorphized() } } -impl<'tcx, B: Bridge> HasTyCtxt<'tcx> for Tables<'tcx, B> { +impl<'tcx, B: Bridge> HasTyCtxt<'tcx> for SmirCtxt<'tcx, B> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } } -impl<'tcx, B: Bridge> HasDataLayout for Tables<'tcx, B> { +impl<'tcx, B: Bridge> HasDataLayout for SmirCtxt<'tcx, B> { fn data_layout(&self) -> &rustc_abi::TargetDataLayout { self.tcx.data_layout() } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index b597189585b3..e82e6e20b491 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -14,7 +14,7 @@ use context::SmirCtxt; use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::mir::interpret::AllocId; -use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use crate::rustc_internal::IndexMap; @@ -30,7 +30,6 @@ pub struct SmirContainer<'tcx, B: Bridge> { } pub struct Tables<'tcx, B: Bridge> { - tcx: TyCtxt<'tcx>, pub(crate) def_ids: IndexMap, pub(crate) alloc_ids: IndexMap, pub(crate) spans: IndexMap, @@ -41,10 +40,9 @@ pub struct Tables<'tcx, B: Bridge> { pub(crate) layouts: IndexMap, B::Layout>, } -impl<'tcx, B: Bridge> Tables<'tcx, B> { - pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self { +impl<'tcx, B: Bridge> Default for Tables<'tcx, B> { + fn default() -> Self { Self { - tcx, def_ids: IndexMap::default(), alloc_ids: IndexMap::default(), spans: IndexMap::default(), @@ -69,46 +67,6 @@ impl<'tcx, B: Bridge> Tables<'tcx, B> { pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> B::MirConstId { self.mir_consts.create_or_fetch(constant) } - - /// Return whether the instance as a body available. - /// - /// Items and intrinsics may have a body available from its definition. - /// Shims body may be generated depending on their type. - pub(crate) fn instance_has_body(&self, instance: Instance<'tcx>) -> bool { - let def_id = instance.def_id(); - self.item_has_body(def_id) - || !matches!( - instance.def, - ty::InstanceKind::Virtual(..) - | ty::InstanceKind::Intrinsic(..) - | ty::InstanceKind::Item(..) - ) - } - - /// Return whether the item has a body defined by the user. - /// - /// Note that intrinsics may have a placeholder body that shouldn't be used in practice. - /// In StableMIR, we handle this case as if the body is not available. - pub(crate) fn item_has_body(&self, def_id: DefId) -> bool { - let must_override = if let Some(intrinsic) = self.tcx.intrinsic(def_id) { - intrinsic.must_be_overridden - } else { - false - }; - !must_override && self.tcx.is_mir_available(def_id) - } - - fn filter_fn_def(&mut self, def_id: DefId) -> Option { - if matches!(self.tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) { - Some(def_id) - } else { - None - } - } - - fn filter_static_def(&mut self, def_id: DefId) -> Option { - matches!(self.tcx.def_kind(def_id), DefKind::Static { .. }).then(|| def_id) - } } /// A trait defining types that are used to emulate StableMIR components, which is really diff --git a/compiler/rustc_smir/src/stable_mir/alloc.rs b/compiler/rustc_smir/src/stable_mir/alloc.rs index 4e6facac705e..5f85d8d34299 100644 --- a/compiler/rustc_smir/src/stable_mir/alloc.rs +++ b/compiler/rustc_smir/src/stable_mir/alloc.rs @@ -48,20 +48,17 @@ pub(crate) fn try_new_allocation<'tcx>( tables: &mut Tables<'tcx, BridgeTys>, cx: &SmirCtxt<'tcx, BridgeTys>, ) -> Result { - use rustc_smir::context::SmirTypingEnv; - let layout = cx - .layout_of(cx.fully_monomorphized().as_query_input(ty)) - .map_err(|e| Error::from_internal(e))?; + let layout = alloc::create_ty_and_layout(cx, ty).map_err(|e| Error::from_internal(e))?; match const_value { ConstValue::Scalar(scalar) => { - alloc::try_new_scalar(layout, scalar, tables).map(|alloc| alloc.stable(tables, cx)) + alloc::try_new_scalar(layout, scalar, cx).map(|alloc| alloc.stable(tables, cx)) } ConstValue::ZeroSized => Ok(new_empty_allocation(layout.align.abi)), ConstValue::Slice { data, meta } => { - alloc::try_new_slice(layout, data, meta, tables).map(|alloc| alloc.stable(tables, cx)) + alloc::try_new_slice(layout, data, meta, cx).map(|alloc| alloc.stable(tables, cx)) } ConstValue::Indirect { alloc_id, offset } => { - let alloc = alloc::try_new_indirect(alloc_id, tables); + let alloc = alloc::try_new_indirect(alloc_id, cx); use rustc_smir::context::SmirAllocRange; Ok(allocation_filter(&alloc.0, cx.alloc_range(offset, layout.size), tables, cx)) } diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index 9d75f3664169..c621ace82565 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -432,7 +432,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { let tables_ref = &mut *tables; let cx = &*self.cx.borrow(); let def = item.internal(tables_ref, cx); - cx.has_body(def, tables_ref) + cx.has_body(def) } fn foreign_modules(&self, crate_num: CrateNum) -> Vec { @@ -448,18 +448,16 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn crate_functions(&self, crate_num: CrateNum) -> Vec { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let tables_ref = &mut *tables; - let krate = crate_num.internal(tables_ref, cx); - cx.crate_functions(krate, tables_ref).iter().map(|did| tables.fn_def(*did)).collect() + let krate = crate_num.internal(&mut *tables, cx); + cx.crate_functions(krate).iter().map(|did| tables.fn_def(*did)).collect() } /// Retrieve all static items defined in this crate. fn crate_statics(&self, crate_num: CrateNum) -> Vec { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let tables_ref = &mut *tables; - let krate = crate_num.internal(tables_ref, cx); - cx.crate_statics(krate, tables_ref).iter().map(|did| tables.static_def(*did)).collect() + let krate = crate_num.internal(&mut *tables, cx); + cx.crate_statics(krate).iter().map(|did| tables.static_def(*did)).collect() } fn foreign_module(&self, mod_def: ForeignModuleDef) -> ForeignModule { @@ -908,7 +906,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); let instance = tables.instances[instance]; - cx.instance_body(instance, &mut *tables).map(|body| body.stable(&mut *tables, cx)) + cx.instance_body(instance).map(|body| body.stable(&mut *tables, cx)) } /// Get the instance type with generic instantiations applied and lifetimes erased. @@ -1078,7 +1076,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); let instance = tables.instances[def]; - cx.instance_abi(instance, &mut *tables).map(|fn_abi| fn_abi.stable(&mut *tables, cx)) + cx.instance_abi(instance).map(|fn_abi| fn_abi.stable(&mut *tables, cx)) } /// Get the ABI of a function pointer. @@ -1086,7 +1084,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); let sig = fn_ptr.internal(&mut *tables, cx); - cx.fn_ptr_abi(sig, &mut *tables).map(|fn_abi| fn_abi.stable(&mut *tables, cx)) + cx.fn_ptr_abi(sig).map(|fn_abi| fn_abi.stable(&mut *tables, cx)) } /// Get the layout of a type. @@ -1094,7 +1092,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); let internal_ty = ty.internal(&mut *tables, cx); - cx.ty_layout(internal_ty, &mut *tables).map(|layout| layout.stable(&mut *tables, cx)) + cx.ty_layout(internal_ty).map(|layout| layout.stable(&mut *tables, cx)) } /// Get the layout shape. From 62d60319d67ddbd4ebceaf349e7b6abb12ecc0e8 Mon Sep 17 00:00:00 2001 From: Makai Date: Sun, 11 May 2025 09:03:51 +0000 Subject: [PATCH 39/62] refactor: unify `Tables` implementation with bridge types and re-export `IndexedVal` define bridge types for `***Def`s. consolidate scattered `Tables` implementations into single inherent impl. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 36 +--- compiler/rustc_smir/src/rustc_smir/bridge.rs | 47 +++++ compiler/rustc_smir/src/rustc_smir/mod.rs | 174 ++++++++++++++++-- compiler/rustc_smir/src/stable_mir/abi.rs | 2 +- compiler/rustc_smir/src/stable_mir/alloc.rs | 3 +- .../src/stable_mir/compiler_interface.rs | 154 +++------------- .../src/stable_mir/convert/stable/mir.rs | 3 +- compiler/rustc_smir/src/stable_mir/error.rs | 2 +- .../rustc_smir/src/stable_mir/mir/alloc.rs | 5 +- .../rustc_smir/src/stable_mir/mir/mono.rs | 4 +- .../rustc_smir/src/stable_mir/mir/pretty.rs | 5 +- compiler/rustc_smir/src/stable_mir/mod.rs | 37 ++++ compiler/rustc_smir/src/stable_mir/ty.rs | 7 +- 13 files changed, 285 insertions(+), 194 deletions(-) create mode 100644 compiler/rustc_smir/src/rustc_smir/bridge.rs diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index db232a1b83a9..7701d7e5bd1a 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -10,11 +10,8 @@ use std::ops::Index; use rustc_data_structures::fx; use rustc_data_structures::fx::FxIndexMap; -use rustc_middle::mir::interpret::AllocId; -use rustc_middle::ty; use rustc_middle::ty::TyCtxt; -use rustc_span::Span; -use rustc_span::def_id::{CrateNum, DefId}; +use rustc_span::def_id::CrateNum; use scoped_tls::scoped_thread_local; use stable_mir::Error; use stable_mir::convert::{RustcInternal, Stable}; @@ -58,37 +55,6 @@ where with_container(|tables, cx| item.internal(tables, cx)) } -impl<'tcx, B: Bridge> Index for Tables<'tcx, B> { - type Output = DefId; - - #[inline(always)] - fn index(&self, index: B::DefId) -> &Self::Output { - &self.def_ids[index] - } -} - -impl<'tcx, B: Bridge> Tables<'tcx, B> { - pub fn create_def_id(&mut self, did: DefId) -> B::DefId { - self.def_ids.create_or_fetch(did) - } - - pub fn create_alloc_id(&mut self, aid: AllocId) -> B::AllocId { - self.alloc_ids.create_or_fetch(aid) - } - - pub fn create_span(&mut self, span: Span) -> B::Span { - self.spans.create_or_fetch(span) - } - - pub fn instance_def(&mut self, instance: ty::Instance<'tcx>) -> B::InstanceDef { - self.instances.create_or_fetch(instance) - } - - pub fn layout_id(&mut self, layout: rustc_abi::Layout<'tcx>) -> B::Layout { - self.layouts.create_or_fetch(layout) - } -} - pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { item.id.into() } diff --git a/compiler/rustc_smir/src/rustc_smir/bridge.rs b/compiler/rustc_smir/src/rustc_smir/bridge.rs new file mode 100644 index 000000000000..0a1c09043ea1 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/bridge.rs @@ -0,0 +1,47 @@ +//! Defines a set of traits that is used for abstracting +//! stable_mir's components that are needed in rustc_smir. +//! +//! These traits are really useful when programming +//! in stable_mir-agnostic settings. + +use std::fmt::Debug; + +use super::Bridge; + +pub trait SmirError { + fn new(msg: String) -> Self; + fn from_internal(err: T) -> Self; +} + +pub trait Prov { + fn new(aid: B::AllocId) -> Self; +} + +macro_rules! make_bridge_trait { + ($name:ident) => { + pub trait $name { + fn new(did: B::DefId) -> Self; + } + }; +} + +make_bridge_trait!(CrateItem); +make_bridge_trait!(AdtDef); +make_bridge_trait!(ForeignModuleDef); +make_bridge_trait!(ForeignDef); +make_bridge_trait!(FnDef); +make_bridge_trait!(ClosureDef); +make_bridge_trait!(CoroutineDef); +make_bridge_trait!(CoroutineClosureDef); +make_bridge_trait!(AliasDef); +make_bridge_trait!(ParamDef); +make_bridge_trait!(BrNamedDef); +make_bridge_trait!(TraitDef); +make_bridge_trait!(GenericDef); +make_bridge_trait!(ConstDef); +make_bridge_trait!(ImplDef); +make_bridge_trait!(RegionDef); +make_bridge_trait!(CoroutineWitnessDef); +make_bridge_trait!(AssocDef); +make_bridge_trait!(OpaqueDef); +make_bridge_trait!(StaticDef); diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index e82e6e20b491..833064ef0c00 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,17 +9,21 @@ use std::cell::RefCell; use std::fmt::Debug; +use std::ops::Index; +use bridge::*; use context::SmirCtxt; use rustc_hir::def::DefKind; use rustc_middle::mir; use rustc_middle::mir::interpret::AllocId; use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_span::Span; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use crate::rustc_internal::IndexMap; pub mod alloc; +pub mod bridge; mod builder; pub mod context; @@ -30,14 +34,14 @@ pub struct SmirContainer<'tcx, B: Bridge> { } pub struct Tables<'tcx, B: Bridge> { - pub(crate) def_ids: IndexMap, - pub(crate) alloc_ids: IndexMap, - pub(crate) spans: IndexMap, - pub(crate) types: IndexMap, B::Ty>, - pub(crate) instances: IndexMap, B::InstanceDef>, - pub(crate) ty_consts: IndexMap, B::TyConstId>, - pub(crate) mir_consts: IndexMap, B::MirConstId>, - pub(crate) layouts: IndexMap, B::Layout>, + pub def_ids: IndexMap, + pub alloc_ids: IndexMap, + pub spans: IndexMap, + pub types: IndexMap, B::Ty>, + pub instances: IndexMap, B::InstanceDef>, + pub ty_consts: IndexMap, B::TyConstId>, + pub mir_consts: IndexMap, B::MirConstId>, + pub layouts: IndexMap, B::Layout>, } impl<'tcx, B: Bridge> Default for Tables<'tcx, B> { @@ -55,23 +59,142 @@ impl<'tcx, B: Bridge> Default for Tables<'tcx, B> { } } +impl<'tcx, B: Bridge> Index for Tables<'tcx, B> { + type Output = DefId; + + #[inline(always)] + fn index(&self, index: B::DefId) -> &Self::Output { + &self.def_ids[index] + } +} + impl<'tcx, B: Bridge> Tables<'tcx, B> { - pub(crate) fn intern_ty(&mut self, ty: Ty<'tcx>) -> B::Ty { + pub fn intern_ty(&mut self, ty: Ty<'tcx>) -> B::Ty { self.types.create_or_fetch(ty) } - pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> B::TyConstId { + pub fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> B::TyConstId { self.ty_consts.create_or_fetch(ct) } - pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> B::MirConstId { + pub fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> B::MirConstId { self.mir_consts.create_or_fetch(constant) } + + pub fn create_def_id(&mut self, did: DefId) -> B::DefId { + self.def_ids.create_or_fetch(did) + } + + pub fn create_alloc_id(&mut self, aid: AllocId) -> B::AllocId { + self.alloc_ids.create_or_fetch(aid) + } + + pub fn create_span(&mut self, span: Span) -> B::Span { + self.spans.create_or_fetch(span) + } + + pub fn instance_def(&mut self, instance: ty::Instance<'tcx>) -> B::InstanceDef { + self.instances.create_or_fetch(instance) + } + + pub fn layout_id(&mut self, layout: rustc_abi::Layout<'tcx>) -> B::Layout { + self.layouts.create_or_fetch(layout) + } + + pub fn crate_item(&mut self, did: rustc_span::def_id::DefId) -> B::CrateItem { + B::CrateItem::new(self.create_def_id(did)) + } + + pub fn adt_def(&mut self, did: rustc_span::def_id::DefId) -> B::AdtDef { + B::AdtDef::new(self.create_def_id(did)) + } + + pub fn foreign_module_def(&mut self, did: rustc_span::def_id::DefId) -> B::ForeignModuleDef { + B::ForeignModuleDef::new(self.create_def_id(did)) + } + + pub fn foreign_def(&mut self, did: rustc_span::def_id::DefId) -> B::ForeignDef { + B::ForeignDef::new(self.create_def_id(did)) + } + + pub fn fn_def(&mut self, did: rustc_span::def_id::DefId) -> B::FnDef { + B::FnDef::new(self.create_def_id(did)) + } + + pub fn closure_def(&mut self, did: rustc_span::def_id::DefId) -> B::ClosureDef { + B::ClosureDef::new(self.create_def_id(did)) + } + + pub fn coroutine_def(&mut self, did: rustc_span::def_id::DefId) -> B::CoroutineDef { + B::CoroutineDef::new(self.create_def_id(did)) + } + + pub fn coroutine_closure_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> B::CoroutineClosureDef { + B::CoroutineClosureDef::new(self.create_def_id(did)) + } + + pub fn alias_def(&mut self, did: rustc_span::def_id::DefId) -> B::AliasDef { + B::AliasDef::new(self.create_def_id(did)) + } + + pub fn param_def(&mut self, did: rustc_span::def_id::DefId) -> B::ParamDef { + B::ParamDef::new(self.create_def_id(did)) + } + + pub fn br_named_def(&mut self, did: rustc_span::def_id::DefId) -> B::BrNamedDef { + B::BrNamedDef::new(self.create_def_id(did)) + } + + pub fn trait_def(&mut self, did: rustc_span::def_id::DefId) -> B::TraitDef { + B::TraitDef::new(self.create_def_id(did)) + } + + pub fn generic_def(&mut self, did: rustc_span::def_id::DefId) -> B::GenericDef { + B::GenericDef::new(self.create_def_id(did)) + } + + pub fn const_def(&mut self, did: rustc_span::def_id::DefId) -> B::ConstDef { + B::ConstDef::new(self.create_def_id(did)) + } + + pub fn impl_def(&mut self, did: rustc_span::def_id::DefId) -> B::ImplDef { + B::ImplDef::new(self.create_def_id(did)) + } + + pub fn region_def(&mut self, did: rustc_span::def_id::DefId) -> B::RegionDef { + B::RegionDef::new(self.create_def_id(did)) + } + + pub fn coroutine_witness_def( + &mut self, + did: rustc_span::def_id::DefId, + ) -> B::CoroutineWitnessDef { + B::CoroutineWitnessDef::new(self.create_def_id(did)) + } + + pub fn assoc_def(&mut self, did: rustc_span::def_id::DefId) -> B::AssocDef { + B::AssocDef::new(self.create_def_id(did)) + } + + pub fn opaque_def(&mut self, did: rustc_span::def_id::DefId) -> B::OpaqueDef { + B::OpaqueDef::new(self.create_def_id(did)) + } + + pub fn prov(&mut self, aid: rustc_middle::mir::interpret::AllocId) -> B::Prov { + B::Prov::new(self.create_alloc_id(aid)) + } + + pub fn static_def(&mut self, did: rustc_span::def_id::DefId) -> B::StaticDef { + B::StaticDef::new(self.create_def_id(did)) + } } /// A trait defining types that are used to emulate StableMIR components, which is really /// useful when programming in stable_mir-agnostic settings. -pub trait Bridge { +pub trait Bridge: Sized { type DefId: Copy + Debug + PartialEq + IndexedVal; type AllocId: Copy + Debug + PartialEq + IndexedVal; type Span: Copy + Debug + PartialEq + IndexedVal; @@ -80,12 +203,29 @@ pub trait Bridge { type TyConstId: Copy + Debug + PartialEq + IndexedVal; type MirConstId: Copy + Debug + PartialEq + IndexedVal; type Layout: Copy + Debug + PartialEq + IndexedVal; - type Error: SmirError; -} -pub trait SmirError { - fn new(msg: String) -> Self; - fn from_internal(err: T) -> Self; + type Error: SmirError; + type CrateItem: CrateItem; + type AdtDef: AdtDef; + type ForeignModuleDef: ForeignModuleDef; + type ForeignDef: ForeignDef; + type FnDef: FnDef; + type ClosureDef: ClosureDef; + type CoroutineDef: CoroutineDef; + type CoroutineClosureDef: CoroutineClosureDef; + type AliasDef: AliasDef; + type ParamDef: ParamDef; + type BrNamedDef: BrNamedDef; + type TraitDef: TraitDef; + type GenericDef: GenericDef; + type ConstDef: ConstDef; + type ImplDef: ImplDef; + type RegionDef: RegionDef; + type CoroutineWitnessDef: CoroutineWitnessDef; + type AssocDef: AssocDef; + type OpaqueDef: OpaqueDef; + type Prov: Prov; + type StaticDef: StaticDef; } pub trait IndexedVal { diff --git a/compiler/rustc_smir/src/stable_mir/abi.rs b/compiler/rustc_smir/src/stable_mir/abi.rs index 3c8bdb243d4c..369d08e444ec 100644 --- a/compiler/rustc_smir/src/stable_mir/abi.rs +++ b/compiler/rustc_smir/src/stable_mir/abi.rs @@ -119,7 +119,7 @@ impl Layout { } } -impl crate::rustc_smir::IndexedVal for Layout { +impl stable_mir::IndexedVal for Layout { fn to_val(index: usize) -> Self { Layout(index) } diff --git a/compiler/rustc_smir/src/stable_mir/alloc.rs b/compiler/rustc_smir/src/stable_mir/alloc.rs index 5f85d8d34299..43c1ca49e19d 100644 --- a/compiler/rustc_smir/src/stable_mir/alloc.rs +++ b/compiler/rustc_smir/src/stable_mir/alloc.rs @@ -7,8 +7,9 @@ use rustc_abi::Align; use rustc_middle::mir::ConstValue; use rustc_middle::mir::interpret::AllocRange; +use rustc_smir::bridge::SmirError; use rustc_smir::context::SmirCtxt; -use rustc_smir::{SmirError, Tables, alloc}; +use rustc_smir::{Tables, alloc}; use super::Error; use super::compiler_interface::BridgeTys; diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index c621ace82565..54d88ddf1979 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -6,7 +6,7 @@ use std::cell::Cell; use rustc_hir::def::DefKind; -use rustc_smir::{Bridge, SmirContainer, Tables}; +use rustc_smir::{Bridge, SmirContainer}; use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions}; use stable_mir::convert::{RustcInternal, Stable}; use stable_mir::crate_def::Attribute; @@ -39,131 +39,29 @@ impl Bridge for BridgeTys { type TyConstId = stable_mir::ty::TyConstId; type MirConstId = stable_mir::ty::MirConstId; type Layout = stable_mir::abi::Layout; + type Error = stable_mir::Error; -} - -impl<'tcx> Tables<'tcx, BridgeTys> { - pub(crate) fn crate_item(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::CrateItem { - stable_mir::CrateItem(self.create_def_id(did)) - } - - pub(crate) fn adt_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::AdtDef { - stable_mir::ty::AdtDef(self.create_def_id(did)) - } - - pub(crate) fn foreign_module_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::ForeignModuleDef { - stable_mir::ty::ForeignModuleDef(self.create_def_id(did)) - } - - pub(crate) fn foreign_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::ForeignDef { - stable_mir::ty::ForeignDef(self.create_def_id(did)) - } - - pub(crate) fn fn_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::FnDef { - stable_mir::ty::FnDef(self.create_def_id(did)) - } - - pub(crate) fn closure_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::ClosureDef { - stable_mir::ty::ClosureDef(self.create_def_id(did)) - } - - pub(crate) fn coroutine_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::CoroutineDef { - stable_mir::ty::CoroutineDef(self.create_def_id(did)) - } - - pub(crate) fn coroutine_closure_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::CoroutineClosureDef { - stable_mir::ty::CoroutineClosureDef(self.create_def_id(did)) - } - - pub(crate) fn alias_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::AliasDef { - stable_mir::ty::AliasDef(self.create_def_id(did)) - } - - pub(crate) fn param_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::ParamDef { - stable_mir::ty::ParamDef(self.create_def_id(did)) - } - - pub(crate) fn br_named_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::BrNamedDef { - stable_mir::ty::BrNamedDef(self.create_def_id(did)) - } - - pub(crate) fn trait_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::TraitDef { - stable_mir::ty::TraitDef(self.create_def_id(did)) - } - - pub(crate) fn generic_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::GenericDef { - stable_mir::ty::GenericDef(self.create_def_id(did)) - } - - pub(crate) fn const_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::ConstDef { - stable_mir::ty::ConstDef(self.create_def_id(did)) - } - - pub(crate) fn impl_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::ImplDef { - stable_mir::ty::ImplDef(self.create_def_id(did)) - } - - /* - pub(crate) fn region_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::RegionDef { - stable_mir::ty::RegionDef(self.create_def_id(did)) - } - */ - - pub(crate) fn coroutine_witness_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::CoroutineWitnessDef { - stable_mir::ty::CoroutineWitnessDef(self.create_def_id(did)) - } - - pub(crate) fn assoc_def(&mut self, did: rustc_span::def_id::DefId) -> stable_mir::ty::AssocDef { - stable_mir::ty::AssocDef(self.create_def_id(did)) - } - - pub(crate) fn opaque_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::ty::OpaqueDef { - stable_mir::ty::OpaqueDef(self.create_def_id(did)) - } - - pub(crate) fn prov( - &mut self, - aid: rustc_middle::mir::interpret::AllocId, - ) -> stable_mir::ty::Prov { - stable_mir::ty::Prov(self.create_alloc_id(aid)) - } - - pub(crate) fn static_def( - &mut self, - did: rustc_span::def_id::DefId, - ) -> stable_mir::mir::mono::StaticDef { - stable_mir::mir::mono::StaticDef(self.create_def_id(did)) - } + type CrateItem = stable_mir::CrateItem; + type AdtDef = stable_mir::ty::AdtDef; + type ForeignModuleDef = stable_mir::ty::ForeignModuleDef; + type ForeignDef = stable_mir::ty::ForeignDef; + type FnDef = stable_mir::ty::FnDef; + type ClosureDef = stable_mir::ty::ClosureDef; + type CoroutineDef = stable_mir::ty::CoroutineDef; + type CoroutineClosureDef = stable_mir::ty::CoroutineClosureDef; + type AliasDef = stable_mir::ty::AliasDef; + type ParamDef = stable_mir::ty::ParamDef; + type BrNamedDef = stable_mir::ty::BrNamedDef; + type TraitDef = stable_mir::ty::TraitDef; + type GenericDef = stable_mir::ty::GenericDef; + type ConstDef = stable_mir::ty::ConstDef; + type ImplDef = stable_mir::ty::ImplDef; + type RegionDef = stable_mir::ty::RegionDef; + type CoroutineWitnessDef = stable_mir::ty::CoroutineWitnessDef; + type AssocDef = stable_mir::ty::AssocDef; + type OpaqueDef = stable_mir::ty::OpaqueDef; + type Prov = stable_mir::ty::Prov; + type StaticDef = stable_mir::mir::mono::StaticDef; } /// Stable public API for querying compiler information. @@ -1138,7 +1036,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { } } -impl<'tcx> SmirContainer<'tcx, BridgeTys> { +impl<'tcx> Helper for SmirContainer<'tcx, BridgeTys> { fn smir_crate(&self, crate_num: rustc_span::def_id::CrateNum) -> Crate { let cx = &*self.cx.borrow(); let name = cx.crate_name(crate_num); @@ -1149,6 +1047,10 @@ impl<'tcx> SmirContainer<'tcx, BridgeTys> { } } +trait Helper { + fn smir_crate(&self, crate_num: rustc_span::def_id::CrateNum) -> Crate; +} + // A thread local variable that stores a pointer to [`SmirInterface`]. scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>); diff --git a/compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs b/compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs index f5ea17d1e55c..aa983ddd38d9 100644 --- a/compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs +++ b/compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs @@ -2,8 +2,9 @@ use rustc_middle::mir::mono::MonoItem; use rustc_middle::{bug, mir}; +use rustc_smir::Tables; +use rustc_smir::bridge::SmirError; use rustc_smir::context::SmirCtxt; -use rustc_smir::{SmirError, Tables}; use stable_mir::compiler_interface::BridgeTys; use stable_mir::convert::Stable; use stable_mir::mir::alloc::GlobalAlloc; diff --git a/compiler/rustc_smir/src/stable_mir/error.rs b/compiler/rustc_smir/src/stable_mir/error.rs index c6bf96ebd176..3f9d67954b9d 100644 --- a/compiler/rustc_smir/src/stable_mir/error.rs +++ b/compiler/rustc_smir/src/stable_mir/error.rs @@ -7,7 +7,7 @@ use std::fmt::{Debug, Display, Formatter}; use std::{fmt, io}; -use rustc_smir::SmirError; +use rustc_smir::bridge::SmirError; use crate::rustc_smir; diff --git a/compiler/rustc_smir/src/stable_mir/mir/alloc.rs b/compiler/rustc_smir/src/stable_mir/mir/alloc.rs index 325f26da8bbf..26f30898a9cc 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/alloc.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/alloc.rs @@ -2,14 +2,13 @@ use std::io::Read; -use rustc_smir::IndexedVal; use serde::Serialize; use stable_mir::mir::mono::{Instance, StaticDef}; use stable_mir::target::{Endian, MachineInfo}; use stable_mir::ty::{Allocation, Binder, ExistentialTraitRef, Ty}; -use stable_mir::{Error, with}; +use stable_mir::{Error, IndexedVal, with}; -use crate::{rustc_smir, stable_mir}; +use crate::stable_mir; /// An allocation in the SMIR global memory can be either a function pointer, /// a static, or a "real" allocation with some data in it. diff --git a/compiler/rustc_smir/src/stable_mir/mir/mono.rs b/compiler/rustc_smir/src/stable_mir/mir/mono.rs index 4d16b3bef519..5f177416714e 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/mono.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/mono.rs @@ -1,13 +1,13 @@ use std::fmt::{Debug, Formatter}; use std::io; -use rustc_smir::{IndexedVal, SmirError}; +use rustc_smir::bridge::SmirError; use serde::Serialize; use stable_mir::abi::FnAbi; use stable_mir::crate_def::CrateDef; use stable_mir::mir::Body; use stable_mir::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, Ty}; -use stable_mir::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, with}; +use stable_mir::{CrateItem, DefId, Error, IndexedVal, ItemKind, Opaque, Symbol, with}; use crate::{rustc_smir, stable_mir}; diff --git a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs index 6fe455e17ec1..a7347e9b0216 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/pretty.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/pretty.rs @@ -4,15 +4,14 @@ use std::io::Write; use std::{fmt, io, iter}; use fmt::{Display, Formatter}; -use rustc_smir::IndexedVal; use stable_mir::mir::{ Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents, }; use stable_mir::ty::{AdtKind, AssocKind, MirConst, Ty, TyConst}; -use stable_mir::{Body, CrateDef, Mutability, with}; +use stable_mir::{Body, CrateDef, IndexedVal, Mutability, with}; use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind}; -use crate::{rustc_smir, stable_mir}; +use crate::stable_mir; impl Display for Ty { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 33213fcbe08e..4726611c46df 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -278,3 +278,40 @@ impl std::fmt::Debug for Opaque { pub fn opaque(value: &T) -> Opaque { Opaque(format!("{value:?}")) } + +macro_rules! bridge_impl { + ($name: ident, $ty: ty) => { + impl rustc_smir::bridge::$name for $ty { + fn new(def: stable_mir::DefId) -> Self { + Self(def) + } + } + }; +} + +bridge_impl!(CrateItem, stable_mir::CrateItem); +bridge_impl!(AdtDef, stable_mir::ty::AdtDef); +bridge_impl!(ForeignModuleDef, stable_mir::ty::ForeignModuleDef); +bridge_impl!(ForeignDef, stable_mir::ty::ForeignDef); +bridge_impl!(FnDef, stable_mir::ty::FnDef); +bridge_impl!(ClosureDef, stable_mir::ty::ClosureDef); +bridge_impl!(CoroutineDef, stable_mir::ty::CoroutineDef); +bridge_impl!(CoroutineClosureDef, stable_mir::ty::CoroutineClosureDef); +bridge_impl!(AliasDef, stable_mir::ty::AliasDef); +bridge_impl!(ParamDef, stable_mir::ty::ParamDef); +bridge_impl!(BrNamedDef, stable_mir::ty::BrNamedDef); +bridge_impl!(TraitDef, stable_mir::ty::TraitDef); +bridge_impl!(GenericDef, stable_mir::ty::GenericDef); +bridge_impl!(ConstDef, stable_mir::ty::ConstDef); +bridge_impl!(ImplDef, stable_mir::ty::ImplDef); +bridge_impl!(RegionDef, stable_mir::ty::RegionDef); +bridge_impl!(CoroutineWitnessDef, stable_mir::ty::CoroutineWitnessDef); +bridge_impl!(AssocDef, stable_mir::ty::AssocDef); +bridge_impl!(OpaqueDef, stable_mir::ty::OpaqueDef); +bridge_impl!(StaticDef, stable_mir::mir::mono::StaticDef); + +impl rustc_smir::bridge::Prov for stable_mir::ty::Prov { + fn new(aid: stable_mir::mir::alloc::AllocId) -> Self { + Self(aid) + } +} diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs index 9933a8e9f7f7..004a7c022346 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/ty.rs @@ -1,19 +1,18 @@ use std::fmt::{self, Debug, Display, Formatter}; use std::ops::Range; -use rustc_smir::IndexedVal; use serde::Serialize; use stable_mir::abi::{FnAbi, Layout}; use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType}; use stable_mir::mir::alloc::{AllocId, read_target_int, read_target_uint}; use stable_mir::mir::mono::StaticDef; use stable_mir::target::MachineInfo; -use stable_mir::{Filename, Opaque}; +use stable_mir::{Filename, IndexedVal, Opaque}; use super::abi::ReprOptions; use super::mir::{Body, Mutability, Safety}; use super::{DefId, Error, Symbol, with}; -use crate::{rustc_smir, stable_mir}; +use crate::stable_mir; #[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)] pub struct Ty(usize); @@ -1566,7 +1565,7 @@ pub enum PredicatePolarity { macro_rules! index_impl { ($name:ident) => { - impl crate::rustc_smir::IndexedVal for $name { + impl stable_mir::IndexedVal for $name { fn to_val(index: usize) -> Self { $name(index) } From b5a2e7d08057bc04c823ab1611e60cccb2d2cce4 Mon Sep 17 00:00:00 2001 From: Makai Date: Sun, 11 May 2025 09:29:44 +0000 Subject: [PATCH 40/62] refactor: move `IndexMap` to `rustc_smir` we should no longer keep `IndexMap` in `rustc_internal`, as we've decided to migrate `rustc_internal` to `stable_mir` under a feature. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 39 +------------------ compiler/rustc_smir/src/rustc_smir/mod.rs | 37 ++++++++++++++++-- 2 files changed, 35 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 7701d7e5bd1a..b99514a3b730 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -4,12 +4,7 @@ //! until stable MIR is complete. use std::cell::{Cell, RefCell}; -use std::fmt::Debug; -use std::hash::Hash; -use std::ops::Index; -use rustc_data_structures::fx; -use rustc_data_structures::fx::FxIndexMap; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::CrateNum; use scoped_tls::scoped_thread_local; @@ -17,7 +12,7 @@ use stable_mir::Error; use stable_mir::convert::{RustcInternal, Stable}; use crate::rustc_smir::context::SmirCtxt; -use crate::rustc_smir::{Bridge, IndexedVal, SmirContainer, Tables}; +use crate::rustc_smir::{Bridge, SmirContainer, Tables}; use crate::stable_mir; pub mod pretty; @@ -273,35 +268,3 @@ macro_rules! run_driver { StableMir::new($callback).run($args) }}; } - -/// Similar to rustc's `FxIndexMap`, `IndexMap` with extra -/// safety features added. -pub struct IndexMap { - index_map: fx::FxIndexMap, -} - -impl Default for IndexMap { - fn default() -> Self { - Self { index_map: FxIndexMap::default() } - } -} - -impl IndexMap { - pub fn create_or_fetch(&mut self, key: K) -> V { - let len = self.index_map.len(); - let v = self.index_map.entry(key).or_insert(V::to_val(len)); - *v - } -} - -impl Index - for IndexMap -{ - type Output = K; - - fn index(&self, index: V) -> &Self::Output { - let (k, v) = self.index_map.get_index(index.to_index()).unwrap(); - assert_eq!(*v, index, "Provided value doesn't match with indexed value"); - k - } -} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 833064ef0c00..370af9d4f2c2 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,19 +9,18 @@ use std::cell::RefCell; use std::fmt::Debug; +use std::hash::Hash; use std::ops::Index; use bridge::*; use context::SmirCtxt; -use rustc_hir::def::DefKind; +use rustc_data_structures::fx::{self, FxIndexMap}; use rustc_middle::mir; use rustc_middle::mir::interpret::AllocId; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use crate::rustc_internal::IndexMap; - pub mod alloc; pub mod bridge; mod builder; @@ -234,6 +233,38 @@ pub trait IndexedVal { fn to_index(&self) -> usize; } +/// Similar to rustc's `FxIndexMap`, `IndexMap` with extra +/// safety features added. +pub struct IndexMap { + index_map: fx::FxIndexMap, +} + +impl Default for IndexMap { + fn default() -> Self { + Self { index_map: FxIndexMap::default() } + } +} + +impl IndexMap { + pub fn create_or_fetch(&mut self, key: K) -> V { + let len = self.index_map.len(); + let v = self.index_map.entry(key).or_insert(V::to_val(len)); + *v + } +} + +impl Index + for IndexMap +{ + type Output = K; + + fn index(&self, index: V) -> &Self::Output { + let (k, v) = self.index_map.get_index(index.to_index()).unwrap(); + assert_eq!(*v, index, "Provided value doesn't match with indexed value"); + k + } +} + /// Iterate over the definitions of the given crate. pub(crate) fn filter_def_ids(tcx: TyCtxt<'_>, krate: CrateNum, mut func: F) -> Vec where From efa26e1d64c374fa9960e5bf8709937fc251816b Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 9 Jun 2025 08:13:27 +0000 Subject: [PATCH 41/62] fix: resolve the unsoundness add a new trait `InternalCx`, which defines the methods that are fine to call from `RustcInternal`. `RustcInternal::internal()` then takes a `impl InternalCx<'tcx>` instead of `TyCtxt<'tcx>`. make `tcx` in `SmirCtxt` public, since we need to pass it to `RustcInternal::internal()` in `SmirInterface`. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 13 +- compiler/rustc_smir/src/rustc_smir/alloc.rs | 4 +- .../src/rustc_smir/context/impls.rs | 77 +----- .../rustc_smir/src/rustc_smir/context/mod.rs | 4 +- .../src/rustc_smir/context/traits.rs | 4 - .../src/stable_mir/compiler_interface.rs | 145 +++++----- .../{ => unstable}/convert/internal.rs | 253 +++++++++--------- .../rustc_smir/src/stable_mir/unstable/mod.rs | 210 +++++++++++++++ 8 files changed, 422 insertions(+), 288 deletions(-) rename compiler/rustc_smir/src/stable_mir/{ => unstable}/convert/internal.rs (78%) create mode 100644 compiler/rustc_smir/src/stable_mir/unstable/mod.rs diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index b99514a3b730..a8d2ab55d037 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -43,11 +43,14 @@ pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T { /// # Panics /// /// This function will panic if StableMIR has not been properly initialized. -pub fn internal<'tcx, S>(item: S) -> S::T<'tcx> +pub fn internal<'tcx, S>(tcx: TyCtxt<'tcx>, item: S) -> S::T<'tcx> where S: RustcInternal, { - with_container(|tables, cx| item.internal(tables, cx)) + // The tcx argument ensures that the item won't outlive the type context. + // See https://github.com/rust-lang/rust/pull/120128/commits/9aace6723572438a94378451793ca37deb768e72 + // for more details. + with_container(|tables, _| item.internal(tables, tcx)) } pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { @@ -69,14 +72,14 @@ where /// Loads the current context and calls a function with it. /// Do not nest these, as that will ICE. -pub(crate) fn with_container<'tcx, R, B: Bridge>( - f: impl FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R, +pub(crate) fn with_container( + f: impl for<'tcx> FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R, ) -> R { assert!(TLV.is_set()); TLV.with(|tlv| { let ptr = tlv.get(); assert!(!ptr.is_null()); - let container = ptr as *const SmirContainer<'tcx, B>; + let container = ptr as *const SmirContainer<'_, B>; let mut tables = unsafe { (*container).tables.borrow_mut() }; let cx = unsafe { (*container).cx.borrow() }; f(&mut *tables, &*cx) diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 6b32b5b07d87..f5412806d335 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -43,8 +43,8 @@ pub fn try_new_slice<'tcx, B: Bridge>( ) -> Result { let alloc_id = cx.tcx.reserve_and_set_memory_alloc(data); let ptr = Pointer::new(alloc_id.into(), Size::ZERO); - let scalar_ptr = Scalar::from_pointer(ptr, &tables.tcx); - let scalar_meta: Scalar = Scalar::from_target_usize(meta, &tables.tcx); + let scalar_ptr = Scalar::from_pointer(ptr, &cx.tcx); + let scalar_meta: Scalar = Scalar::from_target_usize(meta, &cx.tcx); let mut allocation = Allocation::new(layout.size, layout.align.abi, AllocInit::Uninit, ()); allocation .write_scalar(&cx.tcx, alloc_range(Size::ZERO, cx.tcx.data_layout.pointer_size), scalar_ptr) diff --git a/compiler/rustc_smir/src/rustc_smir/context/impls.rs b/compiler/rustc_smir/src/rustc_smir/context/impls.rs index bf86d4ac41dd..edca740cf0e7 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/impls.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/impls.rs @@ -25,44 +25,10 @@ use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_span::{FileNameDisplayPreference, Span, Symbol}; use rustc_target::callconv::FnAbi; -use super::{ - SmirAllocRange, SmirCtxt, SmirExistentialProjection, SmirExistentialTraitRef, SmirRegion, - SmirTraitRef, SmirTy, SmirTypingEnv, -}; +use super::{SmirAllocRange, SmirCtxt, SmirTy, SmirTypingEnv}; use crate::rustc_smir::builder::BodyBuilder; use crate::rustc_smir::{Bridge, SmirError, Tables, filter_def_ids}; -impl<'tcx, B: Bridge> SmirExistentialProjection<'tcx> for SmirCtxt<'tcx, B> { - fn new_from_args( - &self, - def_id: rustc_span::def_id::DefId, - args: ty::GenericArgsRef<'tcx>, - term: ty::Term<'tcx>, - ) -> ty::ExistentialProjection<'tcx> { - ty::ExistentialProjection::new_from_args(self.tcx, def_id, args, term) - } -} - -impl<'tcx, B: Bridge> SmirExistentialTraitRef<'tcx> for SmirCtxt<'tcx, B> { - fn new_from_args( - &self, - trait_def_id: DefId, - args: ty::GenericArgsRef<'tcx>, - ) -> ty::ExistentialTraitRef<'tcx> { - ty::ExistentialTraitRef::new_from_args(self.tcx, trait_def_id, args) - } -} - -impl<'tcx, B: Bridge> SmirTraitRef<'tcx> for SmirCtxt<'tcx, B> { - fn new_from_args( - &self, - trait_def_id: DefId, - args: ty::GenericArgsRef<'tcx>, - ) -> ty::TraitRef<'tcx> { - ty::TraitRef::new_from_args(self.tcx, trait_def_id, args) - } -} - impl<'tcx, B: Bridge> SmirTy<'tcx> for SmirCtxt<'tcx, B> { fn new_foreign(&self, def_id: DefId) -> ty::Ty<'tcx> { ty::Ty::new_foreign(self.tcx, def_id) @@ -85,52 +51,11 @@ impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> { } } -impl<'tcx, B: Bridge> SmirRegion<'tcx> for SmirCtxt<'tcx, B> { - fn lifetimes_re_erased(&self) -> ty::Region<'tcx> { - self.tcx.lifetimes.re_erased - } -} - impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { pub fn lift>>(&self, value: T) -> Option { self.tcx.lift(value) } - pub fn mk_args_from_iter(&self, iter: I) -> T::Output - where - I: Iterator, - T: ty::CollectAndApply, ty::GenericArgsRef<'tcx>>, - { - self.tcx.mk_args_from_iter(iter) - } - - pub fn mk_pat(&self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx> { - self.tcx.mk_pat(v) - } - - pub fn mk_poly_existential_predicates( - &self, - eps: &[ty::PolyExistentialPredicate<'tcx>], - ) -> &'tcx List> { - self.tcx.mk_poly_existential_predicates(eps) - } - - pub fn mk_type_list(&self, v: &[Ty<'tcx>]) -> &'tcx List> { - self.tcx.mk_type_list(v) - } - - pub fn mk_bound_variable_kinds_from_iter(&self, iter: I) -> T::Output - where - I: Iterator, - T: ty::CollectAndApply>, - { - self.tcx.mk_bound_variable_kinds_from_iter(iter) - } - - pub fn mk_place_elems(&self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List> { - self.tcx.mk_place_elems(v) - } - pub fn adt_def(&self, def_id: DefId) -> AdtDef<'tcx> { self.tcx.adt_def(def_id) } diff --git a/compiler/rustc_smir/src/rustc_smir/context/mod.rs b/compiler/rustc_smir/src/rustc_smir/context/mod.rs index b31d92cdfca6..38743e5f7d37 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/mod.rs @@ -21,12 +21,12 @@ pub use traits::*; /// The [`crate::stable_mir::compiler_interface::SmirInterface`] must go through /// this context to obtain rustc-level information. pub struct SmirCtxt<'tcx, B: Bridge> { - pub(crate) tcx: TyCtxt<'tcx>, + pub tcx: TyCtxt<'tcx>, _marker: PhantomData, } impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { - pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self { + pub fn new(tcx: TyCtxt<'tcx>) -> Self { Self { tcx, _marker: Default::default() } } } diff --git a/compiler/rustc_smir/src/rustc_smir/context/traits.rs b/compiler/rustc_smir/src/rustc_smir/context/traits.rs index f5cd7c330b8f..19e09016cdde 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/traits.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/traits.rs @@ -44,7 +44,3 @@ pub trait SmirTypingEnv<'tcx> { pub trait SmirAllocRange<'tcx> { fn alloc_range(&self, offset: rustc_abi::Size, size: rustc_abi::Size) -> AllocRange; } - -pub trait SmirRegion<'tcx> { - fn lifetimes_re_erased(&self) -> ty::Region<'tcx>; -} diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index 54d88ddf1979..80be1f6efe03 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -6,6 +6,7 @@ use std::cell::Cell; use rustc_hir::def::DefKind; +use rustc_smir::context::SmirCtxt; use rustc_smir::{Bridge, SmirContainer}; use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions}; use stable_mir::convert::{RustcInternal, Stable}; @@ -327,16 +328,15 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { /// Check whether the body of a function is available. fn has_body(&self, item: DefId) -> bool { let mut tables = self.tables.borrow_mut(); - let tables_ref = &mut *tables; let cx = &*self.cx.borrow(); - let def = item.internal(tables_ref, cx); + let def = item.internal(&mut *tables, cx.tcx); cx.has_body(def) } fn foreign_modules(&self, crate_num: CrateNum) -> Vec { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - cx.foreign_modules(crate_num.internal(&mut *tables, cx)) + cx.foreign_modules(crate_num.internal(&mut *tables, cx.tcx)) .iter() .map(|did| tables.foreign_module_def(*did)) .collect() @@ -346,7 +346,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn crate_functions(&self, crate_num: CrateNum) -> Vec { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let krate = crate_num.internal(&mut *tables, cx); + let krate = crate_num.internal(&mut *tables, cx.tcx); cx.crate_functions(krate).iter().map(|did| tables.fn_def(*did)).collect() } @@ -354,7 +354,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn crate_statics(&self, crate_num: CrateNum) -> Vec { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let krate = crate_num.internal(&mut *tables, cx); + let krate = crate_num.internal(&mut *tables, cx.tcx); cx.crate_statics(krate).iter().map(|did| tables.static_def(*did)).collect() } @@ -381,7 +381,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let krate = crate_num.internal(&mut *tables, cx); + let krate = crate_num.internal(&mut *tables, cx.tcx); cx.trait_decls(krate).iter().map(|did| tables.trait_def(*did)).collect() } @@ -401,7 +401,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn trait_impls(&self, crate_num: CrateNum) -> ImplTraitDecls { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let krate = crate_num.internal(&mut *tables, cx); + let krate = crate_num.internal(&mut *tables, cx.tcx); cx.trait_impls(krate).iter().map(|did| tables.impl_def(*did)).collect() } @@ -461,19 +461,19 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { /// Get information about the local crate. fn local_crate(&self) -> Crate { let cx = &*self.cx.borrow(); - self.smir_crate(cx.local_crate_num()) + smir_crate(cx, cx.local_crate_num()) } /// Retrieve a list of all external crates. fn external_crates(&self) -> Vec { let cx = &*self.cx.borrow(); - cx.external_crates().iter().map(|crate_num| self.smir_crate(*crate_num)).collect() + cx.external_crates().iter().map(|crate_num| smir_crate(cx, *crate_num)).collect() } /// Find a crate with the given name. fn find_crates(&self, name: &str) -> Vec { let cx = &*self.cx.borrow(); - cx.find_crates(name).iter().map(|crate_num| self.smir_crate(*crate_num)).collect() + cx.find_crates(name).iter().map(|crate_num| smir_crate(cx, *crate_num)).collect() } /// Returns the name of given `DefId`. @@ -574,28 +574,28 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn adt_kind(&self, def: AdtDef) -> AdtKind { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - cx.adt_kind(def.internal(&mut *tables, cx)).stable(&mut *tables, cx) + cx.adt_kind(def.internal(&mut *tables, cx.tcx)).stable(&mut *tables, cx) } /// Returns if the ADT is a box. fn adt_is_box(&self, def: AdtDef) -> bool { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - cx.adt_is_box(def.internal(&mut *tables, cx)) + cx.adt_is_box(def.internal(&mut *tables, cx.tcx)) } /// Returns whether this ADT is simd. fn adt_is_simd(&self, def: AdtDef) -> bool { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - cx.adt_is_simd(def.internal(&mut *tables, cx)) + cx.adt_is_simd(def.internal(&mut *tables, cx.tcx)) } /// Returns whether this definition is a C string. fn adt_is_cstr(&self, def: AdtDef) -> bool { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - cx.adt_is_cstr(def.0.internal(&mut *tables, cx)) + cx.adt_is_cstr(def.0.internal(&mut *tables, cx.tcx)) } /// Returns the representation options for this ADT @@ -607,8 +607,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let def_id = def.0.internal(&mut *tables, cx); - let args_ref = args.internal(&mut *tables, cx); + let def_id = def.0.internal(&mut *tables, cx.tcx); + let args_ref = args.internal(&mut *tables, cx.tcx); cx.fn_sig(def_id, args_ref).stable(&mut *tables, cx) } @@ -616,7 +616,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn intrinsic(&self, item: DefId) -> Option { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let def_id = item.internal(&mut *tables, cx); + let def_id = item.internal(&mut *tables, cx.tcx); cx.intrinsic(def_id).map(|_| IntrinsicDef(item)) } @@ -624,7 +624,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let def_id = def.0.internal(&mut *tables, cx); + let def_id = def.0.internal(&mut *tables, cx.tcx); cx.intrinsic_name(def_id) } @@ -632,7 +632,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let args_ref = args.internal(&mut *tables, cx); + let args_ref = args.internal(&mut *tables, cx.tcx); cx.closure_sig(args_ref).stable(&mut *tables, cx) } @@ -640,7 +640,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn adt_variants_len(&self, def: AdtDef) -> usize { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - cx.adt_variants_len(def.internal(&mut *tables, cx)) + cx.adt_variants_len(def.internal(&mut *tables, cx.tcx)) } /// Discriminant for a given variant index of AdtDef @@ -662,27 +662,31 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn variant_name(&self, def: VariantDef) -> Symbol { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - cx.variant_name(def.internal(&mut *tables, cx)) + cx.variant_name(def.internal(&mut *tables, cx.tcx)) } fn variant_fields(&self, def: VariantDef) -> Vec { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - def.internal(&mut *tables, cx).fields.iter().map(|f| f.stable(&mut *tables, cx)).collect() + def.internal(&mut *tables, cx.tcx) + .fields + .iter() + .map(|f| f.stable(&mut *tables, cx)) + .collect() } /// Evaluate constant as a target usize. fn eval_target_usize(&self, mir_const: &MirConst) -> Result { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let cnst = mir_const.internal(&mut *tables, cx); + let cnst = mir_const.internal(&mut *tables, cx.tcx); cx.eval_target_usize(cnst) } fn eval_target_usize_ty(&self, ty_const: &TyConst) -> Result { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let cnst = ty_const.internal(&mut *tables, cx); + let cnst = ty_const.internal(&mut *tables, cx.tcx); cx.eval_target_usize_ty(cnst) } @@ -690,7 +694,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn try_new_const_zst(&self, ty: Ty) -> Result { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let ty_internal = ty.internal(&mut *tables, cx); + let ty_internal = ty.internal(&mut *tables, cx.tcx); cx.try_new_const_zst(ty_internal).map(|cnst| cnst.stable(&mut *tables, cx)) } @@ -712,14 +716,14 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx)); + let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx.tcx)); cx.try_new_const_uint(value, ty).map(|cnst| cnst.stable(&mut *tables, cx)) } fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx)); + let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx.tcx)); cx.try_new_ty_const_uint(value, ty).map(|cnst| cnst.stable(&mut *tables, cx)) } @@ -727,7 +731,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn new_rigid_ty(&self, kind: RigidTy) -> Ty { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let internal_kind = kind.internal(&mut *tables, cx); + let internal_kind = kind.internal(&mut *tables, cx.tcx); cx.new_rigid_ty(internal_kind).stable(&mut *tables, cx) } @@ -735,7 +739,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn new_box_ty(&self, ty: Ty) -> Ty { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let inner = ty.internal(&mut *tables, cx); + let inner = ty.internal(&mut *tables, cx.tcx); cx.new_box_ty(inner).stable(&mut *tables, cx) } @@ -743,7 +747,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn def_ty(&self, item: DefId) -> Ty { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let inner = item.internal(&mut *tables, cx); + let inner = item.internal(&mut *tables, cx.tcx); cx.def_ty(inner).stable(&mut *tables, cx) } @@ -751,8 +755,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let inner = item.internal(&mut *tables, cx); - let args_ref = args.internal(&mut *tables, cx); + let inner = item.internal(&mut *tables, cx.tcx); + let args_ref = args.internal(&mut *tables, cx.tcx); cx.def_ty_with_args(inner, args_ref).stable(&mut *tables, cx) } @@ -760,7 +764,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn mir_const_pretty(&self, cnst: &MirConst) -> String { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - cnst.internal(&mut *tables, cx).to_string() + cnst.internal(&mut *tables, cx.tcx).to_string() } /// `Span` of an item. @@ -795,7 +799,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> Ty { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let internal_kind = ty.internal(&mut *tables, cx); + let internal_kind = ty.internal(&mut *tables, cx.tcx); cx.rigid_ty_discriminant_ty(internal_kind).stable(&mut *tables, cx) } @@ -868,8 +872,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let def_id = def.0.internal(&mut *tables, cx); - let args_ref = args.internal(&mut *tables, cx); + let def_id = def.0.internal(&mut *tables, cx.tcx); + let args_ref = args.internal(&mut *tables, cx.tcx); cx.resolve_instance(def_id, args_ref).map(|inst| inst.stable(&mut *tables, cx)) } @@ -877,7 +881,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn resolve_drop_in_place(&self, ty: Ty) -> Instance { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let internal_ty = ty.internal(&mut *tables, cx); + let internal_ty = ty.internal(&mut *tables, cx.tcx); cx.resolve_drop_in_place(internal_ty).stable(&mut *tables, cx) } @@ -886,8 +890,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let def_id = def.0.internal(&mut *tables, cx); - let args_ref = args.internal(&mut *tables, cx); + let def_id = def.0.internal(&mut *tables, cx.tcx); + let args_ref = args.internal(&mut *tables, cx.tcx); cx.resolve_for_fn_ptr(def_id, args_ref).stable(&mut *tables, cx) } @@ -900,9 +904,9 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { ) -> Option { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let def_id = def.0.internal(&mut *tables, cx); - let args_ref = args.internal(&mut *tables, cx); - let closure_kind = kind.internal(&mut *tables, cx); + let def_id = def.0.internal(&mut *tables, cx.tcx); + let args_ref = args.internal(&mut *tables, cx.tcx); + let closure_kind = kind.internal(&mut *tables, cx.tcx); cx.resolve_closure(def_id, args_ref, closure_kind).map(|inst| inst.stable(&mut *tables, cx)) } @@ -910,7 +914,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn eval_static_initializer(&self, def: StaticDef) -> Result { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let def_id = def.0.internal(&mut *tables, cx); + let def_id = def.0.internal(&mut *tables, cx.tcx); cx.eval_static_initializer(def_id).stable(&mut *tables, cx) } @@ -920,7 +924,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { let mut tables = self.tables.borrow_mut(); let instance = tables.instances[def]; let cx = &*self.cx.borrow(); - let const_ty = const_ty.internal(&mut *tables, cx); + let const_ty = const_ty.internal(&mut *tables, cx.tcx); cx.eval_instance(instance) .map(|const_val| alloc::try_new_allocation(const_ty, const_val, &mut *tables, cx)) .map_err(|e| e.stable(&mut *tables, cx))? @@ -930,7 +934,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn global_alloc(&self, id: AllocId) -> GlobalAlloc { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let alloc_id = id.internal(&mut *tables, cx); + let alloc_id = id.internal(&mut *tables, cx.tcx); cx.global_alloc(alloc_id).stable(&mut *tables, cx) } @@ -941,15 +945,16 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { return None; }; let cx = &*self.cx.borrow(); - let ty = ty.internal(&mut *tables, cx); - let trait_ref = trait_ref.internal(&mut *tables, cx); + let ty = ty.internal(&mut *tables, cx.tcx); + let trait_ref = trait_ref.internal(&mut *tables, cx.tcx); let alloc_id = cx.vtable_allocation(ty, trait_ref); Some(alloc_id.stable(&mut *tables, cx)) } fn krate(&self, def_id: DefId) -> Crate { let tables = self.tables.borrow(); - self.smir_crate(tables[def_id].krate) + let cx = &*self.cx.borrow(); + smir_crate(cx, tables[def_id].krate) } fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol { @@ -981,7 +986,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let sig = fn_ptr.internal(&mut *tables, cx); + let sig = fn_ptr.internal(&mut *tables, cx.tcx); cx.fn_ptr_abi(sig).map(|fn_abi| fn_abi.stable(&mut *tables, cx)) } @@ -989,7 +994,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn ty_layout(&self, ty: Ty) -> Result { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let internal_ty = ty.internal(&mut *tables, cx); + let internal_ty = ty.internal(&mut *tables, cx.tcx); cx.ty_layout(internal_ty).map(|layout| layout.stable(&mut *tables, cx)) } @@ -997,7 +1002,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn layout_shape(&self, id: Layout) -> LayoutShape { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - id.internal(&mut *tables, cx).0.stable(&mut *tables, cx) + id.internal(&mut *tables, cx.tcx).0.stable(&mut *tables, cx) } /// Get a debug string representation of a place. @@ -1005,16 +1010,16 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - format!("{:?}", place.internal(&mut *tables, cx)) + format!("{:?}", place.internal(&mut *tables, cx.tcx)) } /// Get the resulting type of binary operation. fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let rhs_internal = rhs.internal(&mut *tables, cx); - let lhs_internal = lhs.internal(&mut *tables, cx); - let bin_op_internal = bin_op.internal(&mut *tables, cx); + let rhs_internal = rhs.internal(&mut *tables, cx.tcx); + let lhs_internal = lhs.internal(&mut *tables, cx.tcx); + let bin_op_internal = bin_op.internal(&mut *tables, cx.tcx); cx.binop_ty(bin_op_internal, rhs_internal, lhs_internal).stable(&mut *tables, cx) } @@ -1022,8 +1027,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); - let un_op = un_op.internal(&mut *tables, cx); - let arg = arg.internal(&mut *tables, cx); + let un_op = un_op.internal(&mut *tables, cx.tcx); + let arg = arg.internal(&mut *tables, cx.tcx); cx.unop_ty(un_op, arg).stable(&mut *tables, cx) } @@ -1036,21 +1041,6 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { } } -impl<'tcx> Helper for SmirContainer<'tcx, BridgeTys> { - fn smir_crate(&self, crate_num: rustc_span::def_id::CrateNum) -> Crate { - let cx = &*self.cx.borrow(); - let name = cx.crate_name(crate_num); - let is_local = cx.crate_is_local(crate_num); - let id = cx.crate_num_id(crate_num); - debug!(?name, ?crate_num, "smir_crate"); - Crate { id, name, is_local } - } -} - -trait Helper { - fn smir_crate(&self, crate_num: rustc_span::def_id::CrateNum) -> Crate; -} - // A thread local variable that stores a pointer to [`SmirInterface`]. scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>); @@ -1078,3 +1068,14 @@ pub(crate) fn with(f: impl FnOnce(&dyn SmirInterface) -> R) -> R { f(unsafe { *(ptr as *const &dyn SmirInterface) }) }) } + +fn smir_crate<'tcx>( + cx: &SmirCtxt<'tcx, BridgeTys>, + crate_num: rustc_span::def_id::CrateNum, +) -> Crate { + let name = cx.crate_name(crate_num); + let is_local = cx.crate_is_local(crate_num); + let id = cx.crate_num_id(crate_num); + debug!(?name, ?crate_num, "smir_crate"); + Crate { id, name, is_local } +} diff --git a/compiler/rustc_smir/src/stable_mir/convert/internal.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs similarity index 78% rename from compiler/rustc_smir/src/stable_mir/convert/internal.rs rename to compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs index a8c5f1085285..2a71aece7a0d 100644 --- a/compiler/rustc_smir/src/stable_mir/convert/internal.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs @@ -6,12 +6,11 @@ // Prefer importing stable_mir over internal rustc constructs to make this file more readable. use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy}; -use rustc_smir::context::SmirCtxt; -use rustc_smir::{IndexedVal, Tables}; +use rustc_smir::Tables; use rustc_span::Symbol; use stable_mir::abi::Layout; use stable_mir::compiler_interface::BridgeTys; -use stable_mir::convert::RustcInternal; +use stable_mir::unstable::{RustcInternal, InternalCx}; use stable_mir::mir::alloc::AllocId; use stable_mir::mir::mono::{Instance, MonoItem, StaticDef}; use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, RawPtrKind, Safety, UnOp}; @@ -21,18 +20,19 @@ use stable_mir::ty::{ GenericArgKind, GenericArgs, IntTy, MirConst, Movability, Pattern, Region, RigidTy, Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx, }; -use stable_mir::{CrateItem, CrateNum, DefId}; +use stable_mir::{CrateItem, CrateNum, DefId, IndexedVal}; use crate::{rustc_smir, stable_mir}; + impl RustcInternal for CrateItem { type T<'tcx> = rustc_span::def_id::DefId; fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - self.0.internal(tables, cx) + self.0.internal(tables, tcx) } } @@ -41,7 +41,7 @@ impl RustcInternal for CrateNum { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { rustc_span::def_id::CrateNum::from_usize(*self) } @@ -52,9 +52,9 @@ impl RustcInternal for DefId { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.lift(tables.def_ids[*self]).unwrap() + tcx.lift(tables.def_ids[*self]).unwrap() } } @@ -63,9 +63,9 @@ impl RustcInternal for GenericArgs { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables, cx))) + InternalCx::mk_args_from_iter(tcx, self.0.iter().map(|arg| arg.internal(tables, tcx))) } } @@ -74,14 +74,14 @@ impl RustcInternal for GenericArgKind { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { let arg: rustc_ty::GenericArg<'tcx> = match self { - GenericArgKind::Lifetime(reg) => reg.internal(tables, cx).into(), - GenericArgKind::Type(ty) => ty.internal(tables, cx).into(), - GenericArgKind::Const(cnst) => cnst.internal(tables, cx).into(), + GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(), + GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(), + GenericArgKind::Const(cnst) => cnst.internal(tables, tcx).into(), }; - cx.lift(arg).unwrap() + tcx.lift(arg).unwrap() } } @@ -90,11 +90,10 @@ impl RustcInternal for Region { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { // Cannot recover region. Use erased for now. - use rustc_smir::context::SmirRegion; - cx.lifetimes_re_erased() + tcx.lifetimes_re_erased() } } @@ -103,9 +102,9 @@ impl RustcInternal for Ty { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.lift(tables.types[*self]).unwrap() + tcx.lift(tables.types[*self]).unwrap() } } @@ -114,9 +113,9 @@ impl RustcInternal for TyConst { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.lift(tables.ty_consts[self.id]).unwrap() + tcx.lift(tables.ty_consts[self.id]).unwrap() } } @@ -125,12 +124,12 @@ impl RustcInternal for Pattern { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.mk_pat(match self { + tcx.mk_pat(match self { Pattern::Range { start, end, include_end: _ } => rustc_ty::PatternKind::Range { - start: start.as_ref().unwrap().internal(tables, cx), - end: end.as_ref().unwrap().internal(tables, cx), + start: start.as_ref().unwrap().internal(tables, tcx), + end: end.as_ref().unwrap().internal(tables, tcx), }, }) } @@ -142,63 +141,63 @@ impl RustcInternal for RigidTy { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { RigidTy::Bool => rustc_ty::TyKind::Bool, RigidTy::Char => rustc_ty::TyKind::Char, - RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables, cx)), - RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables, cx)), - RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, cx)), + RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables, tcx)), + RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables, tcx)), + RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, tcx)), RigidTy::Never => rustc_ty::TyKind::Never, RigidTy::Array(ty, cnst) => { - rustc_ty::TyKind::Array(ty.internal(tables, cx), cnst.internal(tables, cx)) + rustc_ty::TyKind::Array(ty.internal(tables, tcx), cnst.internal(tables, tcx)) } RigidTy::Pat(ty, pat) => { - rustc_ty::TyKind::Pat(ty.internal(tables, cx), pat.internal(tables, cx)) + rustc_ty::TyKind::Pat(ty.internal(tables, tcx), pat.internal(tables, tcx)) } RigidTy::Adt(def, args) => { - rustc_ty::TyKind::Adt(def.internal(tables, cx), args.internal(tables, cx)) + rustc_ty::TyKind::Adt(def.internal(tables, tcx), args.internal(tables, tcx)) } RigidTy::Str => rustc_ty::TyKind::Str, - RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, cx)), + RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, tcx)), RigidTy::RawPtr(ty, mutability) => { - rustc_ty::TyKind::RawPtr(ty.internal(tables, cx), mutability.internal(tables, cx)) + rustc_ty::TyKind::RawPtr(ty.internal(tables, tcx), mutability.internal(tables, tcx)) } RigidTy::Ref(region, ty, mutability) => rustc_ty::TyKind::Ref( - region.internal(tables, cx), - ty.internal(tables, cx), - mutability.internal(tables, cx), + region.internal(tables, tcx), + ty.internal(tables, tcx), + mutability.internal(tables, tcx), ), - RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, cx)), + RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, tcx)), RigidTy::FnDef(def, args) => { - rustc_ty::TyKind::FnDef(def.0.internal(tables, cx), args.internal(tables, cx)) + rustc_ty::TyKind::FnDef(def.0.internal(tables, tcx), args.internal(tables, tcx)) } RigidTy::FnPtr(sig) => { - let (sig_tys, hdr) = sig.internal(tables, cx).split(); + let (sig_tys, hdr) = sig.internal(tables, tcx).split(); rustc_ty::TyKind::FnPtr(sig_tys, hdr) } RigidTy::Closure(def, args) => { - rustc_ty::TyKind::Closure(def.0.internal(tables, cx), args.internal(tables, cx)) + rustc_ty::TyKind::Closure(def.0.internal(tables, tcx), args.internal(tables, tcx)) } RigidTy::Coroutine(def, args, _mov) => { - rustc_ty::TyKind::Coroutine(def.0.internal(tables, cx), args.internal(tables, cx)) + rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx)) } RigidTy::CoroutineClosure(def, args) => rustc_ty::TyKind::CoroutineClosure( - def.0.internal(tables, cx), - args.internal(tables, cx), + def.0.internal(tables, tcx), + args.internal(tables, tcx), ), RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness( - def.0.internal(tables, cx), - args.internal(tables, cx), + def.0.internal(tables, tcx), + args.internal(tables, tcx), ), RigidTy::Dynamic(predicate, region, dyn_kind) => rustc_ty::TyKind::Dynamic( - cx.mk_poly_existential_predicates(&predicate.internal(tables, cx)), - region.internal(tables, cx), - dyn_kind.internal(tables, cx), + tcx.mk_poly_existential_predicates(&predicate.internal(tables, tcx)), + region.internal(tables, tcx), + dyn_kind.internal(tables, tcx), ), RigidTy::Tuple(tys) => { - rustc_ty::TyKind::Tuple(cx.mk_type_list(&tys.internal(tables, cx))) + rustc_ty::TyKind::Tuple(tcx.mk_type_list(&tys.internal(tables, tcx))) } } } @@ -210,7 +209,7 @@ impl RustcInternal for IntTy { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { IntTy::Isize => rustc_ty::IntTy::Isize, @@ -229,7 +228,7 @@ impl RustcInternal for UintTy { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { UintTy::Usize => rustc_ty::UintTy::Usize, @@ -248,7 +247,7 @@ impl RustcInternal for FloatTy { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { FloatTy::F16 => rustc_ty::FloatTy::F16, @@ -265,7 +264,7 @@ impl RustcInternal for Mutability { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { Mutability::Not => rustc_ty::Mutability::Not, @@ -280,7 +279,7 @@ impl RustcInternal for Movability { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { Movability::Static => rustc_ty::Movability::Static, @@ -295,7 +294,7 @@ impl RustcInternal for RawPtrKind { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { RawPtrKind::Mut => rustc_middle::mir::RawPtrKind::Mut, @@ -311,13 +310,13 @@ impl RustcInternal for FnSig { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.lift(rustc_ty::FnSig { - inputs_and_output: cx.mk_type_list(&self.inputs_and_output.internal(tables, cx)), + tcx.lift(rustc_ty::FnSig { + inputs_and_output: tcx.mk_type_list(&self.inputs_and_output.internal(tables, tcx)), c_variadic: self.c_variadic, - safety: self.safety.internal(tables, cx), - abi: self.abi.internal(tables, cx), + safety: self.safety.internal(tables, tcx), + abi: self.abi.internal(tables, tcx), }) .unwrap() } @@ -329,7 +328,7 @@ impl RustcInternal for VariantIdx { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { rustc_abi::VariantIdx::from(self.to_index()) } @@ -341,9 +340,9 @@ impl RustcInternal for VariantDef { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - self.adt_def.internal(tables, cx).variant(self.idx.internal(tables, cx)) + self.adt_def.internal(tables, tcx).variant(self.idx.internal(tables, tcx)) } } @@ -352,21 +351,21 @@ impl RustcInternal for MirConst { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { let constant = tables.mir_consts[self.id]; match constant { rustc_middle::mir::Const::Ty(ty, ct) => { - rustc_middle::mir::Const::Ty(cx.lift(ty).unwrap(), cx.lift(ct).unwrap()) + rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap(), tcx.lift(ct).unwrap()) } rustc_middle::mir::Const::Unevaluated(uneval, ty) => { rustc_middle::mir::Const::Unevaluated( - cx.lift(uneval).unwrap(), - cx.lift(ty).unwrap(), + tcx.lift(uneval).unwrap(), + tcx.lift(ty).unwrap(), ) } rustc_middle::mir::Const::Val(const_val, ty) => { - rustc_middle::mir::Const::Val(cx.lift(const_val).unwrap(), cx.lift(ty).unwrap()) + rustc_middle::mir::Const::Val(tcx.lift(const_val).unwrap(), tcx.lift(ty).unwrap()) } } } @@ -378,12 +377,12 @@ impl RustcInternal for MonoItem { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { use rustc_middle::mir::mono as rustc_mono; match self { - MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables, cx)), - MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables, cx)), + MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables, tcx)), + MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables, tcx)), MonoItem::GlobalAsm(_) => { unimplemented!() } @@ -397,9 +396,9 @@ impl RustcInternal for Instance { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.lift(tables.instances[self.def]).unwrap() + tcx.lift(tables.instances[self.def]).unwrap() } } @@ -409,9 +408,9 @@ impl RustcInternal for StaticDef { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - self.0.internal(tables, cx) + self.0.internal(tables, tcx) } } @@ -426,12 +425,12 @@ where fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { rustc_ty::Binder::bind_with_vars( - self.value.internal(tables, cx), - cx.mk_bound_variable_kinds_from_iter( - self.bound_vars.iter().map(|bound| bound.internal(tables, cx)), + self.value.internal(tables, tcx), + tcx.mk_bound_variable_kinds_from_iter( + self.bound_vars.iter().map(|bound| bound.internal(tables, tcx)), ), ) } @@ -443,19 +442,19 @@ impl RustcInternal for BoundVariableKind { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind { BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon, BoundTyKind::Param(def, symbol) => { - rustc_ty::BoundTyKind::Param(def.0.internal(tables, cx), Symbol::intern(symbol)) + rustc_ty::BoundTyKind::Param(def.0.internal(tables, tcx), Symbol::intern(symbol)) } }), BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind { BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::Anon, BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::Named( - def.0.internal(tables, cx), + def.0.internal(tables, tcx), Symbol::intern(symbol), ), BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::ClosureEnv, @@ -471,7 +470,7 @@ impl RustcInternal for DynKind { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { DynKind::Dyn => rustc_ty::DynKind::Dyn, @@ -485,17 +484,17 @@ impl RustcInternal for ExistentialPredicate { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { ExistentialPredicate::Trait(trait_ref) => { - rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, cx)) + rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, tcx)) } ExistentialPredicate::Projection(proj) => { - rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, cx)) + rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, tcx)) } ExistentialPredicate::AutoTrait(trait_def) => { - rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, cx)) + rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, tcx)) } } } @@ -507,13 +506,13 @@ impl RustcInternal for ExistentialProjection { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { use rustc_smir::context::SmirExistentialProjection; - cx.new_from_args( - self.def_id.0.internal(tables, cx), - self.generic_args.internal(tables, cx), - self.term.internal(tables, cx), + tcx.new_from_args( + self.def_id.0.internal(tables, tcx), + self.generic_args.internal(tables, tcx), + self.term.internal(tables, tcx), ) } } @@ -524,11 +523,11 @@ impl RustcInternal for TermKind { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { - TermKind::Type(ty) => ty.internal(tables, cx).into(), - TermKind::Const(cnst) => cnst.internal(tables, cx).into(), + TermKind::Type(ty) => ty.internal(tables, tcx).into(), + TermKind::Const(cnst) => cnst.internal(tables, tcx).into(), } } } @@ -539,10 +538,10 @@ impl RustcInternal for ExistentialTraitRef { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { use rustc_smir::context::SmirExistentialTraitRef; - cx.new_from_args(self.def_id.0.internal(tables, cx), self.generic_args.internal(tables, cx)) + tcx.new_from_args(self.def_id.0.internal(tables, tcx), self.generic_args.internal(tables, tcx)) } } @@ -552,10 +551,10 @@ impl RustcInternal for TraitRef { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { use rustc_smir::context::SmirTraitRef; - cx.new_from_args(self.def_id.0.internal(tables, cx), self.args().internal(tables, cx)) + tcx.new_from_args(self.def_id.0.internal(tables, tcx), self.args().internal(tables, tcx)) } } @@ -564,9 +563,9 @@ impl RustcInternal for AllocId { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.lift(tables.alloc_ids[*self]).unwrap() + tcx.lift(tables.alloc_ids[*self]).unwrap() } } @@ -576,7 +575,7 @@ impl RustcInternal for ClosureKind { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { ClosureKind::Fn => rustc_ty::ClosureKind::Fn, @@ -591,9 +590,9 @@ impl RustcInternal for AdtDef { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.adt_def(self.0.internal(tables, cx)) + InternalCx::adt_def(tcx, self.0.internal(tables, tcx)) } } @@ -603,7 +602,7 @@ impl RustcInternal for Abi { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match *self { Abi::Rust => rustc_abi::ExternAbi::Rust, @@ -643,7 +642,7 @@ impl RustcInternal for Safety { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { Safety::Unsafe => rustc_hir::Safety::Unsafe, @@ -657,7 +656,7 @@ impl RustcInternal for Span { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { tables.spans[*self] } @@ -669,9 +668,9 @@ impl RustcInternal for Layout { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - cx.lift(tables.layouts[*self]).unwrap() + tcx.lift(tables.layouts[*self]).unwrap() } } @@ -681,11 +680,11 @@ impl RustcInternal for Place { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { rustc_middle::mir::Place { local: rustc_middle::mir::Local::from_usize(self.local), - projection: cx.mk_place_elems(&self.projection.internal(tables, cx)), + projection: tcx.mk_place_elems(&self.projection.internal(tables, tcx)), } } } @@ -696,12 +695,12 @@ impl RustcInternal for ProjectionElem { fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { ProjectionElem::Deref => rustc_middle::mir::PlaceElem::Deref, ProjectionElem::Field(idx, ty) => { - rustc_middle::mir::PlaceElem::Field((*idx).into(), ty.internal(tables, cx)) + rustc_middle::mir::PlaceElem::Field((*idx).into(), ty.internal(tables, tcx)) } ProjectionElem::Index(idx) => rustc_middle::mir::PlaceElem::Index((*idx).into()), ProjectionElem::ConstantIndex { offset, min_length, from_end } => { @@ -715,13 +714,13 @@ impl RustcInternal for ProjectionElem { rustc_middle::mir::PlaceElem::Subslice { from: *from, to: *to, from_end: *from_end } } ProjectionElem::Downcast(idx) => { - rustc_middle::mir::PlaceElem::Downcast(None, idx.internal(tables, cx)) + rustc_middle::mir::PlaceElem::Downcast(None, idx.internal(tables, tcx)) } ProjectionElem::OpaqueCast(ty) => { - rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, cx)) + rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, tcx)) } ProjectionElem::Subtype(ty) => { - rustc_middle::mir::PlaceElem::Subtype(ty.internal(tables, cx)) + rustc_middle::mir::PlaceElem::Subtype(ty.internal(tables, tcx)) } } } @@ -733,7 +732,7 @@ impl RustcInternal for BinOp { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { BinOp::Add => rustc_middle::mir::BinOp::Add, @@ -769,7 +768,7 @@ impl RustcInternal for UnOp { fn internal<'tcx>( &self, _tables: &mut Tables<'_, BridgeTys>, - _cx: &SmirCtxt<'tcx, BridgeTys>, + _tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { match self { UnOp::Not => rustc_middle::mir::UnOp::Not, @@ -788,9 +787,9 @@ where fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - (*self).internal(tables, cx) + (*self).internal(tables, tcx) } } @@ -803,9 +802,9 @@ where fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - self.as_ref().map(|inner| inner.internal(tables, cx)) + self.as_ref().map(|inner| inner.internal(tables, tcx)) } } @@ -818,8 +817,8 @@ where fn internal<'tcx>( &self, tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { - self.iter().map(|e| e.internal(tables, cx)).collect() + self.iter().map(|e| e.internal(tables, tcx)).collect() } } diff --git a/compiler/rustc_smir/src/stable_mir/unstable/mod.rs b/compiler/rustc_smir/src/stable_mir/unstable/mod.rs new file mode 100644 index 000000000000..c0e7e60a2c20 --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/unstable/mod.rs @@ -0,0 +1,210 @@ +//! Module that collects the things that have no stability guarantees. +//! +//! We want to keep StableMIR definitions and logic separate from +//! any sort of conversion and usage of internal rustc code. So we +//! restrict the usage of internal items to be inside this module. + +use std::marker::PointeeSized; + +use rustc_hir::def::DefKind; +use rustc_middle::ty::{List, Ty, TyCtxt}; +use rustc_middle::{mir, ty}; +use rustc_smir::Tables; +use rustc_smir::context::{SmirCtxt, SmirExistentialProjection, SmirExistentialTraitRef, SmirTraitRef}; + +use stable_mir::{CtorKind, ItemKind}; + +use crate::{rustc_smir, stable_mir}; + +use super::compiler_interface::BridgeTys; + +pub(crate) mod convert; + +impl<'tcx, T: InternalCx<'tcx>> SmirExistentialProjection<'tcx> for T { + fn new_from_args( + &self, + def_id: rustc_span::def_id::DefId, + args: ty::GenericArgsRef<'tcx>, + term: ty::Term<'tcx>, + ) -> ty::ExistentialProjection<'tcx> { + ty::ExistentialProjection::new_from_args(self.tcx(), def_id, args, term) + } +} + +impl<'tcx, T: InternalCx<'tcx>> SmirExistentialTraitRef<'tcx> for T { + fn new_from_args( + &self, + trait_def_id: rustc_span::def_id::DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> ty::ExistentialTraitRef<'tcx> { + ty::ExistentialTraitRef::new_from_args(self.tcx(), trait_def_id, args) + } +} + +impl<'tcx, T: InternalCx<'tcx>> SmirTraitRef<'tcx> for T { + fn new_from_args( + &self, + trait_def_id: rustc_span::def_id::DefId, + args: ty::GenericArgsRef<'tcx>, + ) -> ty::TraitRef<'tcx> { + ty::TraitRef::new_from_args(self.tcx(), trait_def_id, args) + } +} + +impl<'tcx> InternalCx<'tcx> for TyCtxt<'tcx> { + fn tcx(self) -> TyCtxt<'tcx> { + self + } + + fn lift>>(self, value: T) -> Option { + TyCtxt::lift(self, value) + } + + fn mk_args_from_iter(self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply, ty::GenericArgsRef<'tcx>>, + { + TyCtxt::mk_args_from_iter(self, iter) + } + + fn mk_pat(self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx> { + TyCtxt::mk_pat(self, v) + } + + fn mk_poly_existential_predicates( + self, + eps: &[ty::PolyExistentialPredicate<'tcx>], + ) -> &'tcx List> { + TyCtxt::mk_poly_existential_predicates(self, eps) + } + + fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List> { + TyCtxt::mk_type_list(self, v) + } + + fn lifetimes_re_erased(self) -> ty::Region<'tcx> { + self.lifetimes.re_erased + } + + fn mk_bound_variable_kinds_from_iter(self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply>, + { + TyCtxt::mk_bound_variable_kinds_from_iter(self, iter) + } + + fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List> { + TyCtxt::mk_place_elems(self, v) + } + + fn adt_def(self, def_id: rustc_hir::def_id::DefId) -> ty::AdtDef<'tcx> { + self.adt_def(def_id) + } +} + +/// Trait that defines the methods that are fine to call from [`RustcInternal`]. +/// +/// This trait is only for [`RustcInternal`]. Any other other access to rustc's internals +/// should go through [`crate::rustc_smir::context::SmirCtxt`]. +pub trait InternalCx<'tcx> : Copy + Clone { + fn tcx(self) -> TyCtxt<'tcx>; + + fn lift>>(self, value: T) -> Option; + + fn mk_args_from_iter(self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply, ty::GenericArgsRef<'tcx>>; + + fn mk_pat(self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx>; + + fn mk_poly_existential_predicates( + self, + eps: &[ty::PolyExistentialPredicate<'tcx>], + ) -> &'tcx List>; + + fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List>; + + fn lifetimes_re_erased(self) -> ty::Region<'tcx>; + + fn mk_bound_variable_kinds_from_iter(self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply>; + + fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List>; + + fn adt_def(self, def_id: rustc_hir::def_id::DefId) -> ty::AdtDef<'tcx>; +} + +/// Trait used to convert between an internal MIR type to a Stable MIR type. +/// +/// This trait is currently exposed to users so they can have interoperability between internal MIR +/// and StableMIR constructs. However, they should be used seldom and they have no influence +/// in this crate semver. +#[doc(hidden)] +pub trait Stable<'tcx>: PointeeSized { + /// The stable representation of the type implementing Stable. + type T; + /// Converts an object to the equivalent Stable MIR representation. + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T; +} + +/// Trait used to translate a stable construct to its rustc counterpart. +/// +/// This is basically a mirror of [Stable]. +/// +/// This trait is currently exposed to users so they can have interoperability between internal MIR +/// and StableMIR constructs. They should be used seldom as they have no stability guarantees. +#[doc(hidden)] +pub trait RustcInternal { + type T<'tcx>; + fn internal<'tcx>( + &self, + tables: &mut Tables<'_, BridgeTys>, + tcx: impl InternalCx<'tcx>, + ) -> Self::T<'tcx>; +} + +pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { + match kind { + DefKind::Mod + | DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::Variant + | DefKind::Trait + | DefKind::TyAlias + | DefKind::ForeignTy + | DefKind::TraitAlias + | DefKind::AssocTy + | DefKind::TyParam + | DefKind::ConstParam + | DefKind::Macro(_) + | DefKind::ExternCrate + | DefKind::Use + | DefKind::ForeignMod + | DefKind::OpaqueTy + | DefKind::Field + | DefKind::LifetimeParam + | DefKind::Impl { .. } + | DefKind::GlobalAsm => { + unreachable!("Not a valid item kind: {kind:?}"); + } + DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => { + ItemKind::Fn + } + DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => { + ItemKind::Const + } + DefKind::Static { .. } => ItemKind::Static, + DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const), + DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn), + } +} From a61e5080ecd53f4ab93dd9bd4348bd694bec17b6 Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 9 Jun 2025 08:20:09 +0000 Subject: [PATCH 42/62] refactor: move `convert` to `unstable` We want to keep StableMIR definitions and logic separate from any sort of conversion and usage of internal rustc code. So we bundle all unstable items that have no stability guarantees into `stable_mir::unstable`. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 2 +- compiler/rustc_smir/src/stable_mir/alloc.rs | 2 +- .../src/stable_mir/compiler_interface.rs | 4 +- compiler/rustc_smir/src/stable_mir/mod.rs | 42 +-- .../stable_mir/{ => unstable}/convert/mod.rs | 77 +++-- .../{ => unstable}/convert/stable/abi.rs | 94 +++--- .../{ => unstable}/convert/stable/mir.rs | 188 ++++++------ .../{ => unstable}/convert/stable/mod.rs | 20 +- .../{ => unstable}/convert/stable/ty.rs | 274 +++++++++--------- 9 files changed, 317 insertions(+), 386 deletions(-) rename compiler/rustc_smir/src/stable_mir/{ => unstable}/convert/mod.rs (51%) rename compiler/rustc_smir/src/stable_mir/{ => unstable}/convert/stable/abi.rs (83%) rename compiler/rustc_smir/src/stable_mir/{ => unstable}/convert/stable/mir.rs (89%) rename compiler/rustc_smir/src/stable_mir/{ => unstable}/convert/stable/mod.rs (80%) rename compiler/rustc_smir/src/stable_mir/{ => unstable}/convert/stable/ty.rs (85%) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index a8d2ab55d037..dcdc77b76c21 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::TyCtxt; use rustc_span::def_id::CrateNum; use scoped_tls::scoped_thread_local; use stable_mir::Error; -use stable_mir::convert::{RustcInternal, Stable}; +use stable_mir::unstable::{RustcInternal, Stable}; use crate::rustc_smir::context::SmirCtxt; use crate::rustc_smir::{Bridge, SmirContainer, Tables}; diff --git a/compiler/rustc_smir/src/stable_mir/alloc.rs b/compiler/rustc_smir/src/stable_mir/alloc.rs index 43c1ca49e19d..954d4fe7ff40 100644 --- a/compiler/rustc_smir/src/stable_mir/alloc.rs +++ b/compiler/rustc_smir/src/stable_mir/alloc.rs @@ -13,9 +13,9 @@ use rustc_smir::{Tables, alloc}; use super::Error; use super::compiler_interface::BridgeTys; -use super::convert::Stable; use super::mir::Mutability; use super::ty::{Allocation, ProvenanceMap}; +use super::unstable::Stable; use crate::rustc_smir; /// Creates new empty `Allocation` from given `Align`. diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index 80be1f6efe03..1187f179fbe6 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -9,7 +9,6 @@ use rustc_hir::def::DefKind; use rustc_smir::context::SmirCtxt; use rustc_smir::{Bridge, SmirContainer}; use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions}; -use stable_mir::convert::{RustcInternal, Stable}; use stable_mir::crate_def::Attribute; use stable_mir::mir::alloc::{AllocId, GlobalAlloc}; use stable_mir::mir::mono::{Instance, InstanceDef, StaticDef}; @@ -21,9 +20,10 @@ use stable_mir::ty::{ Generics, ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef, VariantIdx, }; +use stable_mir::unstable::{RustcInternal, Stable, new_item_kind}; use stable_mir::{ AssocItems, Crate, CrateDef, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, - ImplTraitDecls, ItemKind, Symbol, TraitDecls, alloc, mir, new_item_kind, + ImplTraitDecls, ItemKind, Symbol, TraitDecls, alloc, mir, }; use tracing::debug; diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 4726611c46df..65b016ab1371 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -27,8 +27,7 @@ use std::fmt::Debug; use std::{fmt, io}; -use rustc_hir::def::DefKind; -use rustc_smir::IndexedVal; +pub(crate) use rustc_smir::IndexedVal; use serde::Serialize; use stable_mir::compiler_interface::with; pub use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId}; @@ -41,7 +40,7 @@ use crate::{rustc_smir, stable_mir}; pub mod abi; mod alloc; -pub(crate) mod convert; +pub(crate) mod unstable; #[macro_use] pub mod crate_def; pub mod compiler_interface; @@ -222,43 +221,6 @@ pub fn all_trait_impls() -> ImplTraitDecls { with(|cx| cx.all_trait_impls()) } -pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { - match kind { - DefKind::Mod - | DefKind::Struct - | DefKind::Union - | DefKind::Enum - | DefKind::Variant - | DefKind::Trait - | DefKind::TyAlias - | DefKind::ForeignTy - | DefKind::TraitAlias - | DefKind::AssocTy - | DefKind::TyParam - | DefKind::ConstParam - | DefKind::Macro(_) - | DefKind::ExternCrate - | DefKind::Use - | DefKind::ForeignMod - | DefKind::OpaqueTy - | DefKind::Field - | DefKind::LifetimeParam - | DefKind::Impl { .. } - | DefKind::GlobalAsm => { - unreachable!("Not a valid item kind: {kind:?}"); - } - DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => { - ItemKind::Fn - } - DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => { - ItemKind::Const - } - DefKind::Static { .. } => ItemKind::Static, - DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const), - DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn), - } -} - /// A type that provides internal information but that can still be used for debug purpose. #[derive(Clone, PartialEq, Eq, Hash, Serialize)] pub struct Opaque(String); diff --git a/compiler/rustc_smir/src/stable_mir/convert/mod.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/mod.rs similarity index 51% rename from compiler/rustc_smir/src/stable_mir/convert/mod.rs rename to compiler/rustc_smir/src/stable_mir/unstable/convert/mod.rs index 90ed67ed972b..4c8a776d5297 100644 --- a/compiler/rustc_smir/src/stable_mir/convert/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/mod.rs @@ -1,10 +1,23 @@ +//! This module holds the logic to convert rustc internal ADTs into stable mir ADTs. +//! +//! The conversion from stable to internal is not meant to be complete, +//! and it should be added as when needed to be passed as input to rustc_smir functions. +//! +//! For contributors, please make sure to avoid calling rustc's internal functions and queries. +//! These should be done via `rustc_smir` APIs, but it's possible to access ADT fields directly. + use std::ops::RangeInclusive; + use rustc_smir::Tables; use rustc_smir::context::SmirCtxt; -use super::compiler_interface::BridgeTys; -use crate::rustc_smir; +use stable_mir::compiler_interface::BridgeTys; + +use crate::{rustc_smir, stable_mir}; + +use super::Stable; + mod internal; mod stable; @@ -15,10 +28,10 @@ where { type T = T::T; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { (*self).stable(tables, cx) } @@ -30,10 +43,10 @@ where { type T = Option; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { self.as_ref().map(|value| value.stable(tables, cx)) } @@ -46,10 +59,10 @@ where { type T = Result; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { Ok(val) => Ok(val.stable(tables, cx)), @@ -63,10 +76,10 @@ where T: Stable<'tcx>, { type T = Vec; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { self.iter().map(|e| e.stable(tables, cx)).collect() } @@ -78,10 +91,10 @@ where U: Stable<'tcx>, { type T = (T::T, U::T); - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { (self.0.stable(tables, cx), self.1.stable(tables, cx)) } @@ -92,35 +105,11 @@ where T: Stable<'tcx>, { type T = RangeInclusive; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { RangeInclusive::new(self.start().stable(tables, cx), self.end().stable(tables, cx)) } } - -/// Trait used to convert between an internal MIR type to a Stable MIR type. -pub trait Stable<'tcx> { - /// The stable representation of the type implementing Stable. - type T; - /// Converts an object to the equivalent Stable MIR representation. - fn stable( - &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, - ) -> Self::T; -} - -/// Trait used to translate a stable construct to its rustc counterpart. -/// -/// This is basically a mirror of [Stable]. -pub trait RustcInternal { - type T<'tcx>; - fn internal<'tcx>( - &self, - tables: &mut Tables<'_, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, - ) -> Self::T<'tcx>; -} diff --git a/compiler/rustc_smir/src/stable_mir/convert/stable/abi.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs similarity index 83% rename from compiler/rustc_smir/src/stable_mir/convert/stable/abi.rs rename to compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs index b6f02e1bc8f6..02339730b27d 100644 --- a/compiler/rustc_smir/src/stable_mir/convert/stable/abi.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs @@ -4,8 +4,8 @@ use rustc_abi::{ArmCall, CanonAbi, InterruptKind, X86Call}; use rustc_middle::ty; +use rustc_smir::Tables; use rustc_smir::context::SmirCtxt; -use rustc_smir::{IndexedVal, Tables}; use rustc_target::callconv; use stable_mir::abi::{ AddressSpace, ArgAbi, CallConvention, FieldsShape, FloatLength, FnAbi, IntegerLength, @@ -13,16 +13,16 @@ use stable_mir::abi::{ TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange, }; use stable_mir::compiler_interface::BridgeTys; -use stable_mir::convert::Stable; -use stable_mir::opaque; +use stable_mir::unstable::Stable; use stable_mir::target::MachineSize as Size; use stable_mir::ty::{Align, VariantIdx}; +use stable_mir::{IndexedVal, opaque}; use crate::{rustc_smir, stable_mir}; impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx { type T = VariantIdx; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { VariantIdx::to_val(self.as_usize()) } } @@ -30,7 +30,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx { impl<'tcx> Stable<'tcx> for rustc_abi::Endian { type T = stable_mir::target::Endian; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { rustc_abi::Endian::Little => stable_mir::target::Endian::Little, rustc_abi::Endian::Big => stable_mir::target::Endian::Big, @@ -41,10 +41,10 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Endian { impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> { type T = TyAndLayout; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { TyAndLayout { ty: self.ty.stable(tables, cx), layout: self.layout.stable(tables, cx) } } @@ -53,10 +53,10 @@ impl<'tcx> Stable<'tcx> for rustc_abi::TyAndLayout<'tcx, ty::Ty<'tcx>> { impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> { type T = Layout; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { tables.layout_id(cx.lift(*self).unwrap()) } @@ -65,10 +65,10 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Layout<'tcx> { impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData { type T = LayoutShape; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { LayoutShape { fields: self.fields.stable(tables, cx), @@ -83,10 +83,10 @@ impl<'tcx> Stable<'tcx> for rustc_abi::LayoutData Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> { type T = FnAbi; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { assert!(self.args.len() >= self.fixed_count as usize); assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C)); @@ -103,10 +103,10 @@ impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> { impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> { type T = ArgAbi; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { ArgAbi { ty: self.layout.ty.stable(tables, cx), @@ -119,7 +119,7 @@ impl<'tcx> Stable<'tcx> for callconv::ArgAbi<'tcx, ty::Ty<'tcx>> { impl<'tcx> Stable<'tcx> for CanonAbi { type T = CallConvention; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { CanonAbi::C => CallConvention::C, CanonAbi::Rust => CallConvention::Rust, @@ -155,7 +155,7 @@ impl<'tcx> Stable<'tcx> for CanonAbi { impl<'tcx> Stable<'tcx> for callconv::PassMode { type T = PassMode; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { callconv::PassMode::Ignore => PassMode::Ignore, callconv::PassMode::Direct(attr) => PassMode::Direct(opaque(attr)), @@ -177,10 +177,10 @@ impl<'tcx> Stable<'tcx> for callconv::PassMode { impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape { type T = FieldsShape; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { rustc_abi::FieldsShape::Primitive => FieldsShape::Primitive, @@ -198,10 +198,10 @@ impl<'tcx> Stable<'tcx> for rustc_abi::FieldsShape { impl<'tcx> Stable<'tcx> for rustc_abi::Variants { type T = VariantsShape; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { rustc_abi::Variants::Single { index } => { @@ -212,7 +212,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants Stable<'tcx> for rustc_abi::Variants Stable<'tcx> for rustc_abi::TagEncoding { type T = TagEncoding; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { rustc_abi::TagEncoding::Direct => TagEncoding::Direct, @@ -244,10 +244,10 @@ impl<'tcx> Stable<'tcx> for rustc_abi::TagEncoding { impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { type T = ValueAbi; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match *self { rustc_abi::BackendRepr::Scalar(scalar) => ValueAbi::Scalar(scalar.stable(tables, cx)), @@ -265,7 +265,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::BackendRepr { impl<'tcx> Stable<'tcx> for rustc_abi::Size { type T = Size; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { Size::from_bits(self.bits_usize()) } } @@ -273,7 +273,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Size { impl<'tcx> Stable<'tcx> for rustc_abi::Align { type T = Align; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { self.bytes() } } @@ -281,10 +281,10 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Align { impl<'tcx> Stable<'tcx> for rustc_abi::Scalar { type T = Scalar; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { rustc_abi::Scalar::Initialized { value, valid_range } => Scalar::Initialized { @@ -299,10 +299,10 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Scalar { impl<'tcx> Stable<'tcx> for rustc_abi::Primitive { type T = Primitive; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { rustc_abi::Primitive::Int(length, signed) => { @@ -319,7 +319,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Primitive { impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace { type T = AddressSpace; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { AddressSpace(self.0) } } @@ -327,7 +327,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::AddressSpace { impl<'tcx> Stable<'tcx> for rustc_abi::Integer { type T = IntegerLength; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { rustc_abi::Integer::I8 => IntegerLength::I8, rustc_abi::Integer::I16 => IntegerLength::I16, @@ -341,7 +341,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Integer { impl<'tcx> Stable<'tcx> for rustc_abi::Float { type T = FloatLength; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { rustc_abi::Float::F16 => FloatLength::F16, rustc_abi::Float::F32 => FloatLength::F32, @@ -354,7 +354,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Float { impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange { type T = WrappingRange; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { WrappingRange { start: self.start, end: self.end } } } diff --git a/compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mir.rs similarity index 89% rename from compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs rename to compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mir.rs index aa983ddd38d9..a0c3a863b5dc 100644 --- a/compiler/rustc_smir/src/stable_mir/convert/stable/mir.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mir.rs @@ -6,7 +6,7 @@ use rustc_smir::Tables; use rustc_smir::bridge::SmirError; use rustc_smir::context::SmirCtxt; use stable_mir::compiler_interface::BridgeTys; -use stable_mir::convert::Stable; +use stable_mir::unstable::Stable; use stable_mir::mir::alloc::GlobalAlloc; use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment}; use stable_mir::ty::{Allocation, ConstantKind, MirConst}; @@ -17,10 +17,10 @@ use crate::{rustc_smir, stable_mir}; impl<'tcx> Stable<'tcx> for mir::Body<'tcx> { type T = stable_mir::mir::Body; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { stable_mir::mir::Body::new( self.basic_blocks @@ -52,10 +52,10 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> { impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> { type T = stable_mir::mir::VarDebugInfo; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { stable_mir::mir::VarDebugInfo { name: self.name.to_string(), @@ -69,10 +69,10 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> { impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { type T = stable_mir::mir::Statement; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { Statement { kind: self.kind.stable(tables, cx), @@ -83,10 +83,10 @@ impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { impl<'tcx> Stable<'tcx> for mir::SourceInfo { type T = stable_mir::mir::SourceInfo; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { stable_mir::mir::SourceInfo { span: self.span.stable(tables, cx), scope: self.scope.into() } } @@ -94,10 +94,10 @@ impl<'tcx> Stable<'tcx> for mir::SourceInfo { impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> { type T = stable_mir::mir::VarDebugInfoFragment; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { VarDebugInfoFragment { ty: self.ty.stable(tables, cx), @@ -108,10 +108,10 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> { impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> { type T = stable_mir::mir::VarDebugInfoContents; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { mir::VarDebugInfoContents::Place(place) => { @@ -131,10 +131,10 @@ impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> { impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> { type T = stable_mir::mir::StatementKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { mir::StatementKind::Assign(assign) => stable_mir::mir::StatementKind::Assign( @@ -198,10 +198,10 @@ impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> { impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { type T = stable_mir::mir::Rvalue; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::Rvalue::*; match self { @@ -267,7 +267,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> { impl<'tcx> Stable<'tcx> for mir::Mutability { type T = stable_mir::mir::Mutability; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_hir::Mutability::*; match *self { Not => stable_mir::mir::Mutability::Not, @@ -278,7 +278,7 @@ impl<'tcx> Stable<'tcx> for mir::Mutability { impl<'tcx> Stable<'tcx> for mir::RawPtrKind { type T = stable_mir::mir::RawPtrKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use mir::RawPtrKind::*; match *self { Const => stable_mir::mir::RawPtrKind::Const, @@ -290,10 +290,10 @@ impl<'tcx> Stable<'tcx> for mir::RawPtrKind { impl<'tcx> Stable<'tcx> for mir::BorrowKind { type T = stable_mir::mir::BorrowKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::BorrowKind::*; match *self { @@ -306,7 +306,7 @@ impl<'tcx> Stable<'tcx> for mir::BorrowKind { impl<'tcx> Stable<'tcx> for mir::MutBorrowKind { type T = stable_mir::mir::MutBorrowKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::mir::MutBorrowKind::*; match *self { Default => stable_mir::mir::MutBorrowKind::Default, @@ -318,7 +318,7 @@ impl<'tcx> Stable<'tcx> for mir::MutBorrowKind { impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind { type T = stable_mir::mir::FakeBorrowKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::mir::FakeBorrowKind::*; match *self { Deep => stable_mir::mir::FakeBorrowKind::Deep, @@ -329,10 +329,10 @@ impl<'tcx> Stable<'tcx> for mir::FakeBorrowKind { impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> { type T = stable_mir::mir::NullOp; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::NullOp::*; match self { @@ -349,10 +349,10 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> { impl<'tcx> Stable<'tcx> for mir::CastKind { type T = stable_mir::mir::CastKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::CastKind::*; match self { @@ -372,7 +372,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind { impl<'tcx> Stable<'tcx> for mir::FakeReadCause { type T = stable_mir::mir::FakeReadCause; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::mir::FakeReadCause::*; match self { ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard, @@ -388,10 +388,10 @@ impl<'tcx> Stable<'tcx> for mir::FakeReadCause { impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> { type T = stable_mir::mir::Operand; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::Operand::*; match self { @@ -405,10 +405,10 @@ impl<'tcx> Stable<'tcx> for mir::Operand<'tcx> { impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> { type T = stable_mir::mir::ConstOperand; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { stable_mir::mir::ConstOperand { span: self.span.stable(tables, cx), @@ -420,10 +420,10 @@ impl<'tcx> Stable<'tcx> for mir::ConstOperand<'tcx> { impl<'tcx> Stable<'tcx> for mir::Place<'tcx> { type T = stable_mir::mir::Place; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { stable_mir::mir::Place { local: self.local.as_usize(), @@ -434,10 +434,10 @@ impl<'tcx> Stable<'tcx> for mir::Place<'tcx> { impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { type T = stable_mir::mir::ProjectionElem; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::ProjectionElem::*; match self { @@ -475,21 +475,21 @@ impl<'tcx> Stable<'tcx> for mir::PlaceElem<'tcx> { impl<'tcx> Stable<'tcx> for mir::UserTypeProjection { type T = stable_mir::mir::UserTypeProjection; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { UserTypeProjection { base: self.base.as_usize(), projection: opaque(&self.projs) } } } impl<'tcx> Stable<'tcx> for mir::Local { type T = stable_mir::mir::Local; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { self.as_usize() } } impl<'tcx> Stable<'tcx> for mir::RetagKind { type T = stable_mir::mir::RetagKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::mir::RetagKind; match self { RetagKind::FnEntry => stable_mir::mir::RetagKind::FnEntry, @@ -502,7 +502,7 @@ impl<'tcx> Stable<'tcx> for mir::RetagKind { impl<'tcx> Stable<'tcx> for mir::UnwindAction { type T = stable_mir::mir::UnwindAction; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::mir::UnwindAction; match self { UnwindAction::Continue => stable_mir::mir::UnwindAction::Continue, @@ -516,10 +516,10 @@ impl<'tcx> Stable<'tcx> for mir::UnwindAction { impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> { type T = stable_mir::mir::NonDivergingIntrinsic; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::NonDivergingIntrinsic; use stable_mir::mir::CopyNonOverlapping; @@ -540,10 +540,10 @@ impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> { impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { type T = stable_mir::mir::AssertMessage; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::AssertKind; match self { @@ -592,7 +592,7 @@ impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { impl<'tcx> Stable<'tcx> for mir::BinOp { type T = stable_mir::mir::BinOp; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::mir::BinOp; match self { BinOp::Add => stable_mir::mir::BinOp::Add, @@ -627,7 +627,7 @@ impl<'tcx> Stable<'tcx> for mir::BinOp { impl<'tcx> Stable<'tcx> for mir::UnOp { type T = stable_mir::mir::UnOp; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::mir::UnOp; match self { UnOp::Not => stable_mir::mir::UnOp::Not, @@ -639,10 +639,10 @@ impl<'tcx> Stable<'tcx> for mir::UnOp { impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { type T = stable_mir::mir::AggregateKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { mir::AggregateKind::Array(ty) => { @@ -687,10 +687,10 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> { impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> { type T = stable_mir::mir::InlineAsmOperand; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::mir::InlineAsmOperand; @@ -714,10 +714,10 @@ impl<'tcx> Stable<'tcx> for mir::InlineAsmOperand<'tcx> { impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> { type T = stable_mir::mir::Terminator; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::mir::Terminator; Terminator { @@ -729,10 +729,10 @@ impl<'tcx> Stable<'tcx> for mir::Terminator<'tcx> { impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { type T = stable_mir::mir::TerminatorKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::mir::TerminatorKind; match self { @@ -818,10 +818,10 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> { impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> { type T = Allocation; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { self.inner().stable(tables, cx) } @@ -830,10 +830,10 @@ impl<'tcx> Stable<'tcx> for mir::interpret::ConstAllocation<'tcx> { impl<'tcx> Stable<'tcx> for mir::interpret::Allocation { type T = stable_mir::ty::Allocation; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_smir::context::SmirAllocRange; alloc::allocation_filter( @@ -847,11 +847,7 @@ impl<'tcx> Stable<'tcx> for mir::interpret::Allocation { impl<'tcx> Stable<'tcx> for mir::interpret::AllocId { type T = stable_mir::mir::alloc::AllocId; - fn stable( - &self, - tables: &mut Tables<'tcx, BridgeTys>, - _: &SmirCtxt<'tcx, BridgeTys>, - ) -> Self::T { + fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { tables.create_alloc_id(*self) } } @@ -859,10 +855,10 @@ impl<'tcx> Stable<'tcx> for mir::interpret::AllocId { impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> { type T = GlobalAlloc; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { mir::interpret::GlobalAlloc::Function { instance, .. } => { @@ -885,10 +881,10 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> { impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { type T = stable_mir::ty::MirConst; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let id = tables.intern_mir_const(cx.lift(*self).unwrap()); match *self { @@ -925,7 +921,7 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled { type T = Error; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { Error::new(format!("{self:?}")) } } @@ -933,10 +929,10 @@ impl<'tcx> Stable<'tcx> for mir::interpret::ErrorHandled { impl<'tcx> Stable<'tcx> for MonoItem<'tcx> { type T = stable_mir::mir::mono::MonoItem; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::mir::mono::MonoItem as StableMonoItem; match self { diff --git a/compiler/rustc_smir/src/stable_mir/convert/stable/mod.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mod.rs similarity index 80% rename from compiler/rustc_smir/src/stable_mir/convert/stable/mod.rs rename to compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mod.rs index 1cead1c3c37b..bd6542394dc8 100644 --- a/compiler/rustc_smir/src/stable_mir/convert/stable/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mod.rs @@ -14,7 +14,7 @@ mod ty; impl<'tcx> Stable<'tcx> for rustc_hir::Safety { type T = stable_mir::mir::Safety; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { rustc_hir::Safety::Unsafe => stable_mir::mir::Safety::Unsafe, rustc_hir::Safety::Safe => stable_mir::mir::Safety::Safe, @@ -24,14 +24,14 @@ impl<'tcx> Stable<'tcx> for rustc_hir::Safety { impl<'tcx> Stable<'tcx> for FieldIdx { type T = usize; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { self.as_usize() } } impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource { type T = stable_mir::mir::CoroutineSource; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_hir::CoroutineSource; match self { CoroutineSource::Block => stable_mir::mir::CoroutineSource::Block, @@ -43,10 +43,10 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource { impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind { type T = stable_mir::mir::CoroutineKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_hir::{CoroutineDesugaring, CoroutineKind}; match *self { @@ -78,7 +78,7 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind { impl<'tcx> Stable<'tcx> for rustc_span::Symbol { type T = stable_mir::Symbol; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { self.to_string() } } @@ -86,11 +86,7 @@ impl<'tcx> Stable<'tcx> for rustc_span::Symbol { impl<'tcx> Stable<'tcx> for rustc_span::Span { type T = stable_mir::ty::Span; - fn stable( - &self, - tables: &mut Tables<'tcx, BridgeTys>, - _: &SmirCtxt<'tcx, BridgeTys>, - ) -> Self::T { + fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { tables.create_span(*self) } } diff --git a/compiler/rustc_smir/src/stable_mir/convert/stable/ty.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs similarity index 85% rename from compiler/rustc_smir/src/stable_mir/convert/stable/ty.rs rename to compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs index d84bc119ecc0..77cec3b2bef8 100644 --- a/compiler/rustc_smir/src/stable_mir/convert/stable/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs @@ -6,7 +6,7 @@ use rustc_smir::Tables; use rustc_smir::context::SmirCtxt; use stable_mir::alloc; use stable_mir::compiler_interface::BridgeTys; -use stable_mir::convert::Stable; +use stable_mir::unstable::Stable; use stable_mir::ty::{ AdtKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, TyKind, UintTy, }; @@ -15,7 +15,7 @@ use crate::{rustc_smir, stable_mir}; impl<'tcx> Stable<'tcx> for ty::AliasTyKind { type T = stable_mir::ty::AliasKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { ty::Projection => stable_mir::ty::AliasKind::Projection, ty::Inherent => stable_mir::ty::AliasKind::Inherent, @@ -27,10 +27,10 @@ impl<'tcx> Stable<'tcx> for ty::AliasTyKind { impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> { type T = stable_mir::ty::AliasTy; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ty::AliasTy { args, def_id, .. } = self; stable_mir::ty::AliasTy { def_id: tables.alias_def(*def_id), args: args.stable(tables, cx) } @@ -39,10 +39,10 @@ impl<'tcx> Stable<'tcx> for ty::AliasTy<'tcx> { impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> { type T = stable_mir::ty::AliasTerm; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ty::AliasTerm { args, def_id, .. } = self; stable_mir::ty::AliasTerm { @@ -55,7 +55,7 @@ impl<'tcx> Stable<'tcx> for ty::AliasTerm<'tcx> { impl<'tcx> Stable<'tcx> for ty::DynKind { type T = stable_mir::ty::DynKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { ty::Dyn => stable_mir::ty::DynKind::Dyn, } @@ -65,10 +65,10 @@ impl<'tcx> Stable<'tcx> for ty::DynKind { impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> { type T = stable_mir::ty::ExistentialPredicate; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::ExistentialPredicate::*; match self { @@ -86,10 +86,10 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialPredicate<'tcx> { impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> { type T = stable_mir::ty::ExistentialTraitRef; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ty::ExistentialTraitRef { def_id, args, .. } = self; stable_mir::ty::ExistentialTraitRef { @@ -102,10 +102,10 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialTraitRef<'tcx> { impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> { type T = stable_mir::ty::TermKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::TermKind; match self { @@ -121,10 +121,10 @@ impl<'tcx> Stable<'tcx> for ty::TermKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> { type T = stable_mir::ty::ExistentialProjection; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ty::ExistentialProjection { def_id, args, term, .. } = self; stable_mir::ty::ExistentialProjection { @@ -137,10 +137,10 @@ impl<'tcx> Stable<'tcx> for ty::ExistentialProjection<'tcx> { impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion { type T = stable_mir::mir::PointerCoercion; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::ty::adjustment::PointerCoercion; match self { @@ -160,7 +160,7 @@ impl<'tcx> Stable<'tcx> for ty::adjustment::PointerCoercion { impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex { type T = usize; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { self.as_usize() } } @@ -168,7 +168,7 @@ impl<'tcx> Stable<'tcx> for ty::UserTypeAnnotationIndex { impl<'tcx> Stable<'tcx> for ty::AdtKind { type T = AdtKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { ty::AdtKind::Struct => AdtKind::Struct, ty::AdtKind::Union => AdtKind::Union, @@ -180,10 +180,10 @@ impl<'tcx> Stable<'tcx> for ty::AdtKind { impl<'tcx> Stable<'tcx> for ty::FieldDef { type T = stable_mir::ty::FieldDef; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { stable_mir::ty::FieldDef { def: tables.create_def_id(self.did), @@ -194,10 +194,10 @@ impl<'tcx> Stable<'tcx> for ty::FieldDef { impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> { type T = stable_mir::ty::GenericArgs; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { GenericArgs(self.iter().map(|arg| arg.kind().stable(tables, cx)).collect()) } @@ -206,10 +206,10 @@ impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> { impl<'tcx> Stable<'tcx> for ty::GenericArgKind<'tcx> { type T = stable_mir::ty::GenericArgKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::GenericArgKind; match self { @@ -228,10 +228,10 @@ where { type T = stable_mir::ty::Binder; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::Binder; @@ -252,10 +252,10 @@ where { type T = stable_mir::ty::EarlyBinder; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::EarlyBinder; @@ -265,10 +265,10 @@ where impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { type T = stable_mir::ty::FnSig; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::FnSig; @@ -288,11 +288,7 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { impl<'tcx> Stable<'tcx> for ty::BoundTyKind { type T = stable_mir::ty::BoundTyKind; - fn stable( - &self, - tables: &mut Tables<'tcx, BridgeTys>, - _: &SmirCtxt<'tcx, BridgeTys>, - ) -> Self::T { + fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { use stable_mir::ty::BoundTyKind; match self { @@ -307,11 +303,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundTyKind { impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { type T = stable_mir::ty::BoundRegionKind; - fn stable( - &self, - tables: &mut Tables<'tcx, BridgeTys>, - _: &SmirCtxt<'tcx, BridgeTys>, - ) -> Self::T { + fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { use stable_mir::ty::BoundRegionKind; match self { @@ -327,10 +319,10 @@ impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { impl<'tcx> Stable<'tcx> for ty::BoundVariableKind { type T = stable_mir::ty::BoundVariableKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::BoundVariableKind; @@ -349,7 +341,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundVariableKind { impl<'tcx> Stable<'tcx> for ty::IntTy { type T = IntTy; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { ty::IntTy::Isize => IntTy::Isize, ty::IntTy::I8 => IntTy::I8, @@ -364,7 +356,7 @@ impl<'tcx> Stable<'tcx> for ty::IntTy { impl<'tcx> Stable<'tcx> for ty::UintTy { type T = UintTy; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { ty::UintTy::Usize => UintTy::Usize, ty::UintTy::U8 => UintTy::U8, @@ -379,7 +371,7 @@ impl<'tcx> Stable<'tcx> for ty::UintTy { impl<'tcx> Stable<'tcx> for ty::FloatTy { type T = FloatTy; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { ty::FloatTy::F16 => FloatTy::F16, ty::FloatTy::F32 => FloatTy::F32, @@ -391,10 +383,10 @@ impl<'tcx> Stable<'tcx> for ty::FloatTy { impl<'tcx> Stable<'tcx> for Ty<'tcx> { type T = stable_mir::ty::Ty; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { tables.intern_ty(cx.lift(*self).unwrap()) } @@ -402,10 +394,10 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> { impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { type T = stable_mir::ty::TyKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match self { ty::Bool => TyKind::RigidTy(RigidTy::Bool), @@ -488,10 +480,10 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { type T = stable_mir::ty::Pattern; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { match **self { ty::PatternKind::Range { start, end } => stable_mir::ty::Pattern::Range { @@ -508,10 +500,10 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { type T = stable_mir::ty::TyConst; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ct = cx.lift(*self).unwrap(); let kind = match ct.kind() { @@ -546,7 +538,7 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { impl<'tcx> Stable<'tcx> for ty::ParamConst { type T = stable_mir::ty::ParamConst; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use stable_mir::ty::ParamConst; ParamConst { index: self.index, name: self.name.to_string() } } @@ -554,7 +546,7 @@ impl<'tcx> Stable<'tcx> for ty::ParamConst { impl<'tcx> Stable<'tcx> for ty::ParamTy { type T = stable_mir::ty::ParamTy; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use stable_mir::ty::ParamTy; ParamTy { index: self.index, name: self.name.to_string() } } @@ -562,10 +554,10 @@ impl<'tcx> Stable<'tcx> for ty::ParamTy { impl<'tcx> Stable<'tcx> for ty::BoundTy { type T = stable_mir::ty::BoundTy; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::BoundTy; BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables, cx) } @@ -574,7 +566,7 @@ impl<'tcx> Stable<'tcx> for ty::BoundTy { impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind { type T = stable_mir::ty::TraitSpecializationKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use stable_mir::ty::TraitSpecializationKind; match self { @@ -589,10 +581,10 @@ impl<'tcx> Stable<'tcx> for ty::trait_def::TraitSpecializationKind { impl<'tcx> Stable<'tcx> for ty::TraitDef { type T = stable_mir::ty::TraitDecl; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::opaque; use stable_mir::ty::TraitDecl; @@ -619,10 +611,10 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef { impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> { type T = stable_mir::ty::TraitRef; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::TraitRef; @@ -633,10 +625,10 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> { impl<'tcx> Stable<'tcx> for ty::Generics { type T = stable_mir::ty::Generics; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::Generics; @@ -661,7 +653,7 @@ impl<'tcx> Stable<'tcx> for ty::Generics { impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { type T = stable_mir::ty::GenericParamDefKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use stable_mir::ty::GenericParamDefKind; match self { ty::GenericParamDefKind::Lifetime => GenericParamDefKind::Lifetime, @@ -678,10 +670,10 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDefKind { impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef { type T = stable_mir::ty::GenericParamDef; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { GenericParamDef { name: self.name.to_string(), @@ -696,10 +688,10 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::GenericParamDef { impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> { type T = stable_mir::ty::PredicateKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::ty::PredicateKind; match self { @@ -735,10 +727,10 @@ impl<'tcx> Stable<'tcx> for ty::PredicateKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { type T = stable_mir::ty::ClauseKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use rustc_middle::ty::ClauseKind; match *self { @@ -778,7 +770,7 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::ClosureKind { type T = stable_mir::ty::ClosureKind; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::ty::ClosureKind::*; match self { Fn => stable_mir::ty::ClosureKind::Fn, @@ -791,10 +783,10 @@ impl<'tcx> Stable<'tcx> for ty::ClosureKind { impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> { type T = stable_mir::ty::SubtypePredicate; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ty::SubtypePredicate { a, b, a_is_expected: _ } = self; stable_mir::ty::SubtypePredicate { a: a.stable(tables, cx), b: b.stable(tables, cx) } @@ -804,10 +796,10 @@ impl<'tcx> Stable<'tcx> for ty::SubtypePredicate<'tcx> { impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> { type T = stable_mir::ty::CoercePredicate; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ty::CoercePredicate { a, b } = self; stable_mir::ty::CoercePredicate { a: a.stable(tables, cx), b: b.stable(tables, cx) } @@ -817,7 +809,7 @@ impl<'tcx> Stable<'tcx> for ty::CoercePredicate<'tcx> { impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection { type T = stable_mir::ty::AliasRelationDirection; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::ty::AliasRelationDirection::*; match self { Equate => stable_mir::ty::AliasRelationDirection::Equate, @@ -829,10 +821,10 @@ impl<'tcx> Stable<'tcx> for ty::AliasRelationDirection { impl<'tcx> Stable<'tcx> for ty::TraitPredicate<'tcx> { type T = stable_mir::ty::TraitPredicate; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ty::TraitPredicate { trait_ref, polarity } = self; stable_mir::ty::TraitPredicate { @@ -848,10 +840,10 @@ where { type T = stable_mir::ty::OutlivesPredicate; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ty::OutlivesPredicate(a, b) = self; stable_mir::ty::OutlivesPredicate(a.stable(tables, cx), b.stable(tables, cx)) @@ -861,10 +853,10 @@ where impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { type T = stable_mir::ty::ProjectionPredicate; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let ty::ProjectionPredicate { projection_term, term } = self; stable_mir::ty::ProjectionPredicate { @@ -877,7 +869,7 @@ impl<'tcx> Stable<'tcx> for ty::ProjectionPredicate<'tcx> { impl<'tcx> Stable<'tcx> for ty::ImplPolarity { type T = stable_mir::ty::ImplPolarity; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::ty::ImplPolarity::*; match self { Positive => stable_mir::ty::ImplPolarity::Positive, @@ -890,7 +882,7 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity { impl<'tcx> Stable<'tcx> for ty::PredicatePolarity { type T = stable_mir::ty::PredicatePolarity; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_middle::ty::PredicatePolarity::*; match self { Positive => stable_mir::ty::PredicatePolarity::Positive, @@ -902,10 +894,10 @@ impl<'tcx> Stable<'tcx> for ty::PredicatePolarity { impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { type T = stable_mir::ty::Region; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { Region { kind: self.kind().stable(tables, cx) } } @@ -914,10 +906,10 @@ impl<'tcx> Stable<'tcx> for ty::Region<'tcx> { impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { type T = stable_mir::ty::RegionKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::{BoundRegion, EarlyParamRegion, RegionKind}; match self { @@ -951,10 +943,10 @@ impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> { impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { type T = stable_mir::mir::mono::Instance; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { let def = tables.instance_def(cx.lift(*self).unwrap()); let kind = match self.def { @@ -984,7 +976,7 @@ impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> { impl<'tcx> Stable<'tcx> for ty::Variance { type T = stable_mir::mir::Variance; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { ty::Bivariant => stable_mir::mir::Variance::Bivariant, ty::Contravariant => stable_mir::mir::Variance::Contravariant, @@ -997,7 +989,7 @@ impl<'tcx> Stable<'tcx> for ty::Variance { impl<'tcx> Stable<'tcx> for ty::Movability { type T = stable_mir::ty::Movability; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { match self { ty::Movability::Static => stable_mir::ty::Movability::Static, ty::Movability::Movable => stable_mir::ty::Movability::Movable, @@ -1008,7 +1000,7 @@ impl<'tcx> Stable<'tcx> for ty::Movability { impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi { type T = stable_mir::ty::Abi; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use rustc_abi::ExternAbi; use stable_mir::ty::Abi; match *self { @@ -1046,10 +1038,10 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ExternAbi { impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule { type T = stable_mir::ty::ForeignModule; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { stable_mir::ty::ForeignModule { def_id: tables.foreign_module_def(self.def_id), @@ -1061,10 +1053,10 @@ impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule { impl<'tcx> Stable<'tcx> for ty::AssocKind { type T = stable_mir::ty::AssocKind; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { use stable_mir::ty::{AssocKind, AssocTypeData}; match *self { @@ -1087,7 +1079,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocKind { impl<'tcx> Stable<'tcx> for ty::AssocItemContainer { type T = stable_mir::ty::AssocItemContainer; - fn stable(&self, _: &mut Tables<'tcx, BridgeTys>, _: &SmirCtxt<'tcx, BridgeTys>) -> Self::T { + fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &SmirCtxt<'_, BridgeTys>) -> Self::T { use stable_mir::ty::AssocItemContainer; match self { ty::AssocItemContainer::Trait => AssocItemContainer::Trait, @@ -1099,10 +1091,10 @@ impl<'tcx> Stable<'tcx> for ty::AssocItemContainer { impl<'tcx> Stable<'tcx> for ty::AssocItem { type T = stable_mir::ty::AssocItem; - fn stable( + fn stable<'cx>( &self, - tables: &mut Tables<'tcx, BridgeTys>, - cx: &SmirCtxt<'tcx, BridgeTys>, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, ) -> Self::T { stable_mir::ty::AssocItem { def_id: tables.assoc_def(self.def_id), @@ -1116,11 +1108,7 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem { impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData { type T = stable_mir::ty::ImplTraitInTraitData; - fn stable( - &self, - tables: &mut Tables<'tcx, BridgeTys>, - _: &SmirCtxt<'tcx, BridgeTys>, - ) -> Self::T { + fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { use stable_mir::ty::ImplTraitInTraitData; match self { ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => { From e3f2096849c9e5a8fe725c26a6e53906f8bfffdc Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 9 Jun 2025 08:26:12 +0000 Subject: [PATCH 43/62] refactor: avoid calling internal functions in `predicates_of()` and `explicit_predicates_of()` --- .../src/rustc_smir/context/impls.rs | 34 +++++++++++++++---- .../src/stable_mir/compiler_interface.rs | 23 ++++--------- .../stable_mir/unstable/convert/internal.rs | 15 ++++---- .../src/stable_mir/unstable/convert/mod.rs | 6 +--- .../stable_mir/unstable/convert/stable/abi.rs | 4 +-- .../stable_mir/unstable/convert/stable/mir.rs | 8 +++-- .../stable_mir/unstable/convert/stable/mod.rs | 6 +++- .../stable_mir/unstable/convert/stable/ty.rs | 20 ++++++++--- .../rustc_smir/src/stable_mir/unstable/mod.rs | 20 +++++------ 9 files changed, 82 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/context/impls.rs b/compiler/rustc_smir/src/rustc_smir/context/impls.rs index edca740cf0e7..2d0b2a968b16 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/impls.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/impls.rs @@ -15,9 +15,9 @@ use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; use rustc_middle::ty::{ - AdtDef, AdtKind, AssocItem, ClosureKind, GenericArgsRef, GenericPredicates, Instance, - InstanceKind, IntrinsicDef, List, PolyFnSig, ScalarInt, TraitDef, Ty, TyCtxt, TyKind, - TypeVisitableExt, UintTy, ValTree, VariantDef, + AdtDef, AdtKind, AssocItem, ClosureKind, GenericArgsRef, Instance, InstanceKind, IntrinsicDef, + List, PolyFnSig, ScalarInt, TraitDef, Ty, TyCtxt, TyKind, TypeVisitableExt, UintTy, ValTree, + VariantDef, }; use rustc_middle::{mir, ty}; use rustc_session::cstore::ForeignModule; @@ -197,12 +197,32 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { self.tcx.generics_of(def_id) } - pub fn predicates_of(&self, def_id: DefId) -> GenericPredicates<'tcx> { - self.tcx.predicates_of(def_id) + pub fn predicates_of( + &self, + def_id: DefId, + ) -> (Option, Vec<(ty::PredicateKind<'tcx>, Span)>) { + let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id); + ( + parent, + predicates + .iter() + .map(|(clause, span)| (clause.as_predicate().kind().skip_binder(), *span)) + .collect(), + ) } - pub fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates<'tcx> { - self.tcx.explicit_predicates_of(def_id) + pub fn explicit_predicates_of( + &self, + def_id: DefId, + ) -> (Option, Vec<(ty::PredicateKind<'tcx>, Span)>) { + let ty::GenericPredicates { parent, predicates } = self.tcx.explicit_predicates_of(def_id); + ( + parent, + predicates + .iter() + .map(|(clause, span)| (clause.as_predicate().kind().skip_binder(), *span)) + .collect(), + ) } pub fn crate_name(&self, crate_num: CrateNum) -> String { diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index 1187f179fbe6..3577c15f9117 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -423,17 +423,12 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); let did = tables[def_id]; - let rustc_middle::ty::GenericPredicates { parent, predicates } = cx.predicates_of(did); + let (parent, kinds) = cx.predicates_of(did); stable_mir::ty::GenericPredicates { parent: parent.map(|did| tables.trait_def(did)), - predicates: predicates + predicates: kinds .iter() - .map(|(clause, span)| { - ( - clause.as_predicate().kind().skip_binder().stable(&mut *tables, cx), - span.stable(&mut *tables, cx), - ) - }) + .map(|(kind, span)| (kind.stable(&mut *tables, cx), span.stable(&mut *tables, cx))) .collect(), } } @@ -442,18 +437,12 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { let mut tables = self.tables.borrow_mut(); let cx = &*self.cx.borrow(); let did = tables[def_id]; - let rustc_middle::ty::GenericPredicates { parent, predicates } = - cx.explicit_predicates_of(did); + let (parent, kinds) = cx.explicit_predicates_of(did); stable_mir::ty::GenericPredicates { parent: parent.map(|did| tables.trait_def(did)), - predicates: predicates + predicates: kinds .iter() - .map(|(clause, span)| { - ( - clause.as_predicate().kind().skip_binder().stable(&mut *tables, cx), - span.stable(&mut *tables, cx), - ) - }) + .map(|(kind, span)| (kind.stable(&mut *tables, cx), span.stable(&mut *tables, cx))) .collect(), } } diff --git a/compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs index 2a71aece7a0d..4cbe02bfa0db 100644 --- a/compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs @@ -10,7 +10,6 @@ use rustc_smir::Tables; use rustc_span::Symbol; use stable_mir::abi::Layout; use stable_mir::compiler_interface::BridgeTys; -use stable_mir::unstable::{RustcInternal, InternalCx}; use stable_mir::mir::alloc::AllocId; use stable_mir::mir::mono::{Instance, MonoItem, StaticDef}; use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, RawPtrKind, Safety, UnOp}; @@ -20,11 +19,11 @@ use stable_mir::ty::{ GenericArgKind, GenericArgs, IntTy, MirConst, Movability, Pattern, Region, RigidTy, Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx, }; +use stable_mir::unstable::{InternalCx, RustcInternal}; use stable_mir::{CrateItem, CrateNum, DefId, IndexedVal}; use crate::{rustc_smir, stable_mir}; - impl RustcInternal for CrateItem { type T<'tcx> = rustc_span::def_id::DefId; fn internal<'tcx>( @@ -447,9 +446,10 @@ impl RustcInternal for BoundVariableKind { match self { BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind { BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon, - BoundTyKind::Param(def, symbol) => { - rustc_ty::BoundTyKind::Param(def.0.internal(tables, tcx), Symbol::intern(symbol)) - } + BoundTyKind::Param(def, symbol) => rustc_ty::BoundTyKind::Param( + def.0.internal(tables, tcx), + Symbol::intern(symbol), + ), }), BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind { BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::Anon, @@ -541,7 +541,10 @@ impl RustcInternal for ExistentialTraitRef { tcx: impl InternalCx<'tcx>, ) -> Self::T<'tcx> { use rustc_smir::context::SmirExistentialTraitRef; - tcx.new_from_args(self.def_id.0.internal(tables, tcx), self.generic_args.internal(tables, tcx)) + tcx.new_from_args( + self.def_id.0.internal(tables, tcx), + self.generic_args.internal(tables, tcx), + ) } } diff --git a/compiler/rustc_smir/src/stable_mir/unstable/convert/mod.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/mod.rs index 4c8a776d5297..6e1b85671f84 100644 --- a/compiler/rustc_smir/src/stable_mir/unstable/convert/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/mod.rs @@ -8,16 +8,12 @@ use std::ops::RangeInclusive; - use rustc_smir::Tables; use rustc_smir::context::SmirCtxt; - use stable_mir::compiler_interface::BridgeTys; -use crate::{rustc_smir, stable_mir}; - use super::Stable; - +use crate::{rustc_smir, stable_mir}; mod internal; mod stable; diff --git a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs index 02339730b27d..0d8ecf4df2af 100644 --- a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs @@ -13,9 +13,9 @@ use stable_mir::abi::{ TagEncoding, TyAndLayout, ValueAbi, VariantsShape, WrappingRange, }; use stable_mir::compiler_interface::BridgeTys; -use stable_mir::unstable::Stable; use stable_mir::target::MachineSize as Size; use stable_mir::ty::{Align, VariantIdx}; +use stable_mir::unstable::Stable; use stable_mir::{IndexedVal, opaque}; use crate::{rustc_smir, stable_mir}; @@ -212,7 +212,7 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Variants Stable<'tcx> for mir::interpret::Allocation { impl<'tcx> Stable<'tcx> for mir::interpret::AllocId { type T = stable_mir::mir::alloc::AllocId; - fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + _: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T { tables.create_alloc_id(*self) } } diff --git a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mod.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mod.rs index bd6542394dc8..799917c6e171 100644 --- a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mod.rs @@ -86,7 +86,11 @@ impl<'tcx> Stable<'tcx> for rustc_span::Symbol { impl<'tcx> Stable<'tcx> for rustc_span::Span { type T = stable_mir::ty::Span; - fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + _: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T { tables.create_span(*self) } } diff --git a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs index 77cec3b2bef8..13f9fd6a86a8 100644 --- a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs @@ -6,10 +6,10 @@ use rustc_smir::Tables; use rustc_smir::context::SmirCtxt; use stable_mir::alloc; use stable_mir::compiler_interface::BridgeTys; -use stable_mir::unstable::Stable; use stable_mir::ty::{ AdtKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, TyKind, UintTy, }; +use stable_mir::unstable::Stable; use crate::{rustc_smir, stable_mir}; @@ -288,7 +288,11 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> { impl<'tcx> Stable<'tcx> for ty::BoundTyKind { type T = stable_mir::ty::BoundTyKind; - fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + _: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::BoundTyKind; match self { @@ -303,7 +307,11 @@ impl<'tcx> Stable<'tcx> for ty::BoundTyKind { impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { type T = stable_mir::ty::BoundRegionKind; - fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + _: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::BoundRegionKind; match self { @@ -1108,7 +1116,11 @@ impl<'tcx> Stable<'tcx> for ty::AssocItem { impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData { type T = stable_mir::ty::ImplTraitInTraitData; - fn stable<'cx>(&self, tables: &mut Tables<'cx, BridgeTys>, _: &SmirCtxt<'cx, BridgeTys>) -> Self::T { + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + _: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T { use stable_mir::ty::ImplTraitInTraitData; match self { ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => { diff --git a/compiler/rustc_smir/src/stable_mir/unstable/mod.rs b/compiler/rustc_smir/src/stable_mir/unstable/mod.rs index c0e7e60a2c20..77a772019ebe 100644 --- a/compiler/rustc_smir/src/stable_mir/unstable/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/mod.rs @@ -1,7 +1,7 @@ //! Module that collects the things that have no stability guarantees. //! -//! We want to keep StableMIR definitions and logic separate from -//! any sort of conversion and usage of internal rustc code. So we +//! We want to keep StableMIR definitions and logic separate from +//! any sort of conversion and usage of internal rustc code. So we //! restrict the usage of internal items to be inside this module. use std::marker::PointeeSized; @@ -10,13 +10,13 @@ use rustc_hir::def::DefKind; use rustc_middle::ty::{List, Ty, TyCtxt}; use rustc_middle::{mir, ty}; use rustc_smir::Tables; -use rustc_smir::context::{SmirCtxt, SmirExistentialProjection, SmirExistentialTraitRef, SmirTraitRef}; - +use rustc_smir::context::{ + SmirCtxt, SmirExistentialProjection, SmirExistentialTraitRef, SmirTraitRef, +}; use stable_mir::{CtorKind, ItemKind}; -use crate::{rustc_smir, stable_mir}; - use super::compiler_interface::BridgeTys; +use crate::{rustc_smir, stable_mir}; pub(crate) mod convert; @@ -86,7 +86,7 @@ impl<'tcx> InternalCx<'tcx> for TyCtxt<'tcx> { fn lifetimes_re_erased(self) -> ty::Region<'tcx> { self.lifetimes.re_erased } - + fn mk_bound_variable_kinds_from_iter(self, iter: I) -> T::Output where I: Iterator, @@ -94,7 +94,7 @@ impl<'tcx> InternalCx<'tcx> for TyCtxt<'tcx> { { TyCtxt::mk_bound_variable_kinds_from_iter(self, iter) } - + fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List> { TyCtxt::mk_place_elems(self, v) } @@ -105,10 +105,10 @@ impl<'tcx> InternalCx<'tcx> for TyCtxt<'tcx> { } /// Trait that defines the methods that are fine to call from [`RustcInternal`]. -/// +/// /// This trait is only for [`RustcInternal`]. Any other other access to rustc's internals /// should go through [`crate::rustc_smir::context::SmirCtxt`]. -pub trait InternalCx<'tcx> : Copy + Clone { +pub trait InternalCx<'tcx>: Copy + Clone { fn tcx(self) -> TyCtxt<'tcx>; fn lift>>(self, value: T) -> Option; From b7be9cd151290250d74c7ccedda00ce9b11c6a44 Mon Sep 17 00:00:00 2001 From: Makai Date: Sat, 21 Jun 2025 10:33:02 +0000 Subject: [PATCH 44/62] refactor: don't use rustc_type_ir directly --- .../src/rustc_smir/context/impls.rs | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/context/impls.rs b/compiler/rustc_smir/src/rustc_smir/context/impls.rs index 2d0b2a968b16..edeedbd70898 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/impls.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/impls.rs @@ -7,17 +7,15 @@ use std::iter; use rustc_abi::{Endian, Layout}; use rustc_hir::def::DefKind; use rustc_hir::{Attribute, LangItem}; -use rustc_middle::infer::canonical::ir::{ - Binder, EarlyBinder, ExistentialTraitRef, FnSig, TraitRef, -}; use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; use rustc_middle::ty::{ - AdtDef, AdtKind, AssocItem, ClosureKind, GenericArgsRef, Instance, InstanceKind, IntrinsicDef, - List, PolyFnSig, ScalarInt, TraitDef, Ty, TyCtxt, TyKind, TypeVisitableExt, UintTy, ValTree, - VariantDef, + AdtDef, AdtKind, AssocItem, Binder, ClosureKind, CoroutineArgsExt, EarlyBinder, + ExistentialTraitRef, FnSig, GenericArgsRef, Instance, InstanceKind, IntrinsicDef, List, + PolyFnSig, ScalarInt, TraitDef, TraitRef, Ty, TyCtxt, TyKind, TypeVisitableExt, UintTy, + ValTree, VariantDef, }; use rustc_middle::{mir, ty}; use rustc_session::cstore::ForeignModule; @@ -189,7 +187,7 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { self.tcx.trait_impls_in_crate(crate_num).iter().map(|impl_def_id| *impl_def_id).collect() } - pub fn trait_impl(&self, impl_def: DefId) -> EarlyBinder, TraitRef>> { + pub fn trait_impl(&self, impl_def: DefId) -> EarlyBinder<'tcx, TraitRef<'tcx>> { self.tcx.impl_trait_ref(impl_def).unwrap() } @@ -370,7 +368,7 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { &self, def_id: DefId, args_ref: GenericArgsRef<'tcx>, - ) -> Binder, FnSig>> { + ) -> Binder<'tcx, FnSig<'tcx>> { let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, args_ref); sig } @@ -387,10 +385,7 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { } /// Retrieve the closure signature for the given generic arguments. - pub fn closure_sig( - &self, - args_ref: GenericArgsRef<'tcx>, - ) -> Binder, FnSig>> { + pub fn closure_sig(&self, args_ref: GenericArgsRef<'tcx>) -> Binder<'tcx, FnSig<'tcx>> { args_ref.as_closure().sig() } @@ -686,7 +681,7 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { pub fn vtable_allocation( &self, ty: Ty<'tcx>, - trait_ref: Option, ExistentialTraitRef>>>, + trait_ref: Option>>, ) -> AllocId { let alloc_id = self.tcx.vtable_allocation(( ty, From 854292d589098ab4de4934cdcdcc886e77a5b1d7 Mon Sep 17 00:00:00 2001 From: Makai Date: Sat, 21 Jun 2025 10:40:14 +0000 Subject: [PATCH 45/62] refactor: rewrite `adt_repr()`, `adt_discr_for_variant()` and `coroutine_discr_for_variant()` --- .../src/rustc_smir/context/impls.rs | 27 +++++++++++- .../src/stable_mir/compiler_interface.rs | 44 +++++++++++++++---- .../stable_mir/unstable/convert/stable/abi.rs | 28 ++++++++---- .../stable_mir/unstable/convert/stable/ty.rs | 8 +++- 4 files changed, 88 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/context/impls.rs b/compiler/rustc_smir/src/rustc_smir/context/impls.rs index edeedbd70898..89ae47143ef6 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/impls.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/impls.rs @@ -4,13 +4,14 @@ use std::iter; -use rustc_abi::{Endian, Layout}; +use rustc_abi::{Endian, Layout, ReprOptions}; use rustc_hir::def::DefKind; use rustc_hir::{Attribute, LangItem}; use rustc_middle::mir::interpret::{AllocId, ConstAllocation, ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::{BinOp, Body, Const as MirConst, ConstValue, UnOp}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; +use rustc_middle::ty::util::Discr; use rustc_middle::ty::{ AdtDef, AdtKind, AssocItem, Binder, ClosureKind, CoroutineArgsExt, EarlyBinder, ExistentialTraitRef, FnSig, GenericArgsRef, Instance, InstanceKind, IntrinsicDef, List, @@ -363,6 +364,11 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { self.tcx.is_lang_item(def_id, LangItem::CStr) } + /// Returns the representation options for this ADT. + pub fn adt_repr(&self, def: AdtDef<'tcx>) -> ReprOptions { + def.repr() + } + /// Retrieve the function signature for the given generic arguments. pub fn fn_sig( &self, @@ -394,6 +400,25 @@ impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> { def.variants().len() } + /// Discriminant for a given variant index of AdtDef. + pub fn adt_discr_for_variant( + &self, + adt: AdtDef<'tcx>, + variant: rustc_abi::VariantIdx, + ) -> Discr<'tcx> { + adt.discriminant_for_variant(self.tcx, variant) + } + + /// Discriminant for a given variand index and args of a coroutine. + pub fn coroutine_discr_for_variant( + &self, + coroutine: DefId, + args: GenericArgsRef<'tcx>, + variant: rustc_abi::VariantIdx, + ) -> Discr<'tcx> { + args.as_coroutine().discriminant_for_variant(coroutine, self.tcx, variant) + } + /// The name of a variant. pub fn variant_name(&self, def: &'tcx VariantDef) -> String { def.name.to_string() diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index 3577c15f9117..c7f3d25cd715 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -152,6 +152,9 @@ pub(crate) trait SmirInterface { /// Returns whether this definition is a C string. fn adt_is_cstr(&self, def: AdtDef) -> bool; + /// Returns the representation options for this ADT. + fn adt_repr(&self, def: AdtDef) -> ReprOptions; + /// Retrieve the function signature for the given generic arguments. fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig; @@ -167,6 +170,17 @@ pub(crate) trait SmirInterface { /// The number of variants in this ADT. fn adt_variants_len(&self, def: AdtDef) -> usize; + /// Discriminant for a given variant index of AdtDef. + fn adt_discr_for_variant(&self, adt: AdtDef, variant: VariantIdx) -> Discr; + + /// Discriminant for a given variand index and args of a coroutine. + fn coroutine_discr_for_variant( + &self, + coroutine: CoroutineDef, + args: &GenericArgs, + variant: VariantIdx, + ) -> Discr; + /// The name of a variant. fn variant_name(&self, def: VariantDef) -> Symbol; fn variant_fields(&self, def: VariantDef) -> Vec; @@ -588,8 +602,10 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { } /// Returns the representation options for this ADT - pub(crate) fn adt_repr(&self, def: AdtDef) -> ReprOptions { - self.cx.adt_repr(def) + fn adt_repr(&self, def: AdtDef) -> ReprOptions { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.adt_repr(def.internal(&mut *tables, cx.tcx)).stable(&mut *tables, cx) } /// Retrieve the function signature for the given generic arguments. @@ -632,19 +648,31 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> { cx.adt_variants_len(def.internal(&mut *tables, cx.tcx)) } - /// Discriminant for a given variant index of AdtDef - pub(crate) fn adt_discr_for_variant(&self, adt: AdtDef, variant: VariantIdx) -> Discr { - self.cx.adt_discr_for_variant(adt, variant) + /// Discriminant for a given variant index of AdtDef. + fn adt_discr_for_variant(&self, adt: AdtDef, variant: VariantIdx) -> Discr { + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + cx.adt_discr_for_variant( + adt.internal(&mut *tables, cx.tcx), + variant.internal(&mut *tables, cx.tcx), + ) + .stable(&mut *tables, cx) } - /// Discriminant for a given variand index and args of a coroutine - pub(crate) fn coroutine_discr_for_variant( + /// Discriminant for a given variand index and args of a coroutine. + fn coroutine_discr_for_variant( &self, coroutine: CoroutineDef, args: &GenericArgs, variant: VariantIdx, ) -> Discr { - self.cx.coroutine_discr_for_variant(coroutine, args, variant) + let mut tables = self.tables.borrow_mut(); + let cx = &*self.cx.borrow(); + let tcx = cx.tcx; + let def = coroutine.def_id().internal(&mut *tables, tcx); + let args_ref = args.internal(&mut *tables, tcx); + cx.coroutine_discr_for_variant(def, args_ref, variant.internal(&mut *tables, tcx)) + .stable(&mut *tables, cx) } /// The name of a variant. diff --git a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs index 0d8ecf4df2af..d8823a0d10c0 100644 --- a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/abi.rs @@ -362,7 +362,11 @@ impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange { impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags { type T = ReprFlags; - fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + fn stable<'cx>( + &self, + _tables: &mut Tables<'cx, BridgeTys>, + _cx: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T { ReprFlags { is_simd: self.intersects(Self::IS_SIMD), is_c: self.intersects(Self::IS_C), @@ -375,11 +379,15 @@ impl<'tcx> Stable<'tcx> for rustc_abi::ReprFlags { impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType { type T = IntegerType; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T { match self { rustc_abi::IntegerType::Pointer(signed) => IntegerType::Pointer { is_signed: *signed }, rustc_abi::IntegerType::Fixed(integer, signed) => { - IntegerType::Fixed { length: integer.stable(tables), is_signed: *signed } + IntegerType::Fixed { length: integer.stable(tables, cx), is_signed: *signed } } } } @@ -388,12 +396,16 @@ impl<'tcx> Stable<'tcx> for rustc_abi::IntegerType { impl<'tcx> Stable<'tcx> for rustc_abi::ReprOptions { type T = ReprOptions; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T { ReprOptions { - int: self.int.map(|int| int.stable(tables)), - align: self.align.map(|align| align.stable(tables)), - pack: self.pack.map(|pack| pack.stable(tables)), - flags: self.flags.stable(tables), + int: self.int.map(|int| int.stable(tables, cx)), + align: self.align.map(|align| align.stable(tables, cx)), + pack: self.pack.map(|pack| pack.stable(tables, cx)), + flags: self.flags.stable(tables, cx), } } } diff --git a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs index 13f9fd6a86a8..c0a430079d8b 100644 --- a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/ty.rs @@ -1139,7 +1139,11 @@ impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData { impl<'tcx> Stable<'tcx> for rustc_middle::ty::util::Discr<'tcx> { type T = stable_mir::ty::Discr; - fn stable(&self, tables: &mut Tables<'_>) -> Self::T { - stable_mir::ty::Discr { val: self.val, ty: self.ty.stable(tables) } + fn stable<'cx>( + &self, + tables: &mut Tables<'cx, BridgeTys>, + cx: &SmirCtxt<'cx, BridgeTys>, + ) -> Self::T { + stable_mir::ty::Discr { val: self.val, ty: self.ty.stable(tables, cx) } } } From e26ae60be37be8303f956971925ac440b1cf0e71 Mon Sep 17 00:00:00 2001 From: Makai Date: Wed, 25 Jun 2025 16:27:54 +0000 Subject: [PATCH 46/62] refactor: implement a new bridge trait `Allocation` --- compiler/rustc_smir/src/rustc_smir/alloc.rs | 11 +++++--- compiler/rustc_smir/src/rustc_smir/bridge.rs | 14 +++++++++- compiler/rustc_smir/src/rustc_smir/mod.rs | 2 ++ compiler/rustc_smir/src/stable_mir/alloc.rs | 9 +------ .../src/stable_mir/compiler_interface.rs | 2 ++ compiler/rustc_smir/src/stable_mir/mod.rs | 27 ++++++++++++++++++- .../stable_mir/unstable/convert/stable/mir.rs | 4 ++- 7 files changed, 54 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index f5412806d335..ecaf3571896e 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -10,7 +10,8 @@ use rustc_middle::mir::interpret::{ }; use rustc_middle::ty::{Ty, layout}; -use super::SmirCtxt; +use super::{SmirCtxt, Tables}; +use crate::rustc_smir::bridge::Allocation as _; use crate::rustc_smir::{Bridge, SmirError}; pub fn create_ty_and_layout<'tcx, B: Bridge>( @@ -70,10 +71,12 @@ pub fn try_new_indirect<'tcx, B: Bridge>( } /// Creates an `Allocation` only from information within the `AllocRange`. -pub fn allocation_filter( +pub fn allocation_filter<'tcx, B: Bridge>( alloc: &rustc_middle::mir::interpret::Allocation, alloc_range: AllocRange, -) -> (Vec>, Vec<(usize, AllocId)>) { + tables: &mut Tables<'tcx, B>, + cx: &SmirCtxt<'tcx, B>, +) -> B::Allocation { let mut bytes: Vec> = alloc .inspect_with_uninit_and_ptr_outside_interpreter( alloc_range.start.bytes_usize()..alloc_range.end().bytes_usize(), @@ -97,5 +100,5 @@ pub fn allocation_filter( ptrs.push((offset.bytes_usize() - alloc_range.start.bytes_usize(), prov.alloc_id())); } - (bytes, ptrs) + B::Allocation::new(bytes, ptrs, alloc.align.bytes(), alloc.mutability, tables, cx) } diff --git a/compiler/rustc_smir/src/rustc_smir/bridge.rs b/compiler/rustc_smir/src/rustc_smir/bridge.rs index 0a1c09043ea1..a31eb93d0e80 100644 --- a/compiler/rustc_smir/src/rustc_smir/bridge.rs +++ b/compiler/rustc_smir/src/rustc_smir/bridge.rs @@ -6,7 +6,8 @@ use std::fmt::Debug; -use super::Bridge; +use super::context::SmirCtxt; +use super::{Bridge, Tables}; pub trait SmirError { fn new(msg: String) -> Self; @@ -17,6 +18,17 @@ pub trait Prov { fn new(aid: B::AllocId) -> Self; } +pub trait Allocation { + fn new<'tcx>( + bytes: Vec>, + ptrs: Vec<(usize, rustc_middle::mir::interpret::AllocId)>, + align: u64, + mutability: rustc_middle::mir::Mutability, + tables: &mut Tables<'tcx, B>, + cx: &SmirCtxt<'tcx, B>, + ) -> Self; +} + macro_rules! make_bridge_trait { ($name:ident) => { pub trait $name { diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 370af9d4f2c2..e8b7a3fec092 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -225,6 +225,8 @@ pub trait Bridge: Sized { type OpaqueDef: OpaqueDef; type Prov: Prov; type StaticDef: StaticDef; + + type Allocation: Allocation; } pub trait IndexedVal { diff --git a/compiler/rustc_smir/src/stable_mir/alloc.rs b/compiler/rustc_smir/src/stable_mir/alloc.rs index 954d4fe7ff40..120cb4404b96 100644 --- a/compiler/rustc_smir/src/stable_mir/alloc.rs +++ b/compiler/rustc_smir/src/stable_mir/alloc.rs @@ -73,12 +73,5 @@ pub(super) fn allocation_filter<'tcx>( tables: &mut Tables<'tcx, BridgeTys>, cx: &SmirCtxt<'tcx, BridgeTys>, ) -> Allocation { - let (bytes, ptrs) = alloc::allocation_filter(alloc, alloc_range); - let ptrs = ptrs.iter().map(|(i, aid)| (*i, tables.prov(*aid))).collect(); - Allocation { - bytes, - provenance: ProvenanceMap { ptrs }, - align: alloc.align.bytes(), - mutability: alloc.mutability.stable(tables, cx), - } + alloc::allocation_filter(alloc, alloc_range, tables, cx) } diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index c7f3d25cd715..a19968d2ab77 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -63,6 +63,8 @@ impl Bridge for BridgeTys { type OpaqueDef = stable_mir::ty::OpaqueDef; type Prov = stable_mir::ty::Prov; type StaticDef = stable_mir::mir::mono::StaticDef; + + type Allocation = stable_mir::ty::Allocation; } /// Stable public API for querying compiler information. diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 65b016ab1371..70c09c128541 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -28,13 +28,18 @@ use std::fmt::Debug; use std::{fmt, io}; pub(crate) use rustc_smir::IndexedVal; +use rustc_smir::Tables; +use rustc_smir::context::SmirCtxt; use serde::Serialize; use stable_mir::compiler_interface::with; pub use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId}; pub use stable_mir::error::*; use stable_mir::mir::mono::StaticDef; use stable_mir::mir::{Body, Mutability}; -use stable_mir::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, Span, TraitDef, Ty}; +use stable_mir::ty::{ + AssocItem, FnDef, ForeignModuleDef, ImplDef, ProvenanceMap, Span, TraitDef, Ty, +}; +use stable_mir::unstable::Stable; use crate::{rustc_smir, stable_mir}; @@ -277,3 +282,23 @@ impl rustc_smir::bridge::Prov for stable_mir::ty: Self(aid) } } + +impl rustc_smir::bridge::Allocation for stable_mir::ty::Allocation { + fn new<'tcx>( + bytes: Vec>, + ptrs: Vec<(usize, rustc_middle::mir::interpret::AllocId)>, + align: u64, + mutability: rustc_middle::mir::Mutability, + tables: &mut Tables<'tcx, compiler_interface::BridgeTys>, + cx: &SmirCtxt<'tcx, compiler_interface::BridgeTys>, + ) -> Self { + Self { + bytes, + provenance: ProvenanceMap { + ptrs: ptrs.iter().map(|(i, aid)| (*i, tables.prov(*aid))).collect(), + }, + align, + mutability: mutability.stable(tables, cx), + } + } +} diff --git a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mir.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mir.rs index 8b41c80432ed..99f9f456567c 100644 --- a/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mir.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/stable/mir.rs @@ -358,7 +358,9 @@ impl<'tcx> Stable<'tcx> for mir::CastKind { match self { PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress, PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance, - PointerCoercion(c, _) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables, cx)), + PointerCoercion(c, _) => { + stable_mir::mir::CastKind::PointerCoercion(c.stable(tables, cx)) + } IntToInt => stable_mir::mir::CastKind::IntToInt, FloatToInt => stable_mir::mir::CastKind::FloatToInt, FloatToFloat => stable_mir::mir::CastKind::FloatToFloat, From 0403990000438742065e54c4cae9bb1afb0e6038 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 3 Jul 2025 20:53:10 -0700 Subject: [PATCH 47/62] mbe: Gracefully handle macro rules that end after `=>` Add a test for various cases of invalid macro definitions. Closes: https://github.com/rust-lang/rust/issues/143351 --- compiler/rustc_expand/src/mbe/macro_rules.rs | 9 +++ tests/ui/parser/macro/bad-macro-definition.rs | 22 ++++++++ .../parser/macro/bad-macro-definition.stderr | 56 +++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 tests/ui/parser/macro/bad-macro-definition.rs create mode 100644 tests/ui/parser/macro/bad-macro-definition.stderr diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index dad2fd99ef20..2ffd4e3cf285 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -411,6 +411,15 @@ pub fn compile_declarative_macro( if let Err(e) = p.expect(exp!(FatArrow)) { return dummy_syn_ext(e.emit()); } + if p.token == token::Eof { + let err_sp = p.token.span.shrink_to_hi(); + let guar = sess + .dcx() + .struct_span_err(err_sp, "macro definition ended unexpectedly") + .with_span_label(err_sp, "expected right-hand side of macro rule") + .emit(); + return dummy_syn_ext(guar); + } let rhs_tt = p.parse_token_tree(); let rhs_tt = mbe::quoted::parse( &TokenStream::new(vec![rhs_tt]), diff --git a/tests/ui/parser/macro/bad-macro-definition.rs b/tests/ui/parser/macro/bad-macro-definition.rs new file mode 100644 index 000000000000..3c5c93ea3b3e --- /dev/null +++ b/tests/ui/parser/macro/bad-macro-definition.rs @@ -0,0 +1,22 @@ +#![crate_type = "lib"] + +macro_rules! a { {} => } +//~^ ERROR: macro definition ended unexpectedly + +macro_rules! b { 0 => } +//~^ ERROR: macro definition ended unexpectedly +//~| ERROR: invalid macro matcher + +macro_rules! c { x => } +//~^ ERROR: macro definition ended unexpectedly +//~| ERROR: invalid macro matcher + +macro_rules! d { _ => } +//~^ ERROR: macro definition ended unexpectedly +//~| ERROR: invalid macro matcher + +macro_rules! e { {} } +//~^ ERROR: expected `=>`, found end of macro arguments + +macro_rules! f {} +//~^ ERROR: macros must contain at least one rule diff --git a/tests/ui/parser/macro/bad-macro-definition.stderr b/tests/ui/parser/macro/bad-macro-definition.stderr new file mode 100644 index 000000000000..de6d9d6a38b1 --- /dev/null +++ b/tests/ui/parser/macro/bad-macro-definition.stderr @@ -0,0 +1,56 @@ +error: macro definition ended unexpectedly + --> $DIR/bad-macro-definition.rs:3:23 + | +LL | macro_rules! a { {} => } + | ^ expected right-hand side of macro rule + +error: invalid macro matcher; matchers must be contained in balanced delimiters + --> $DIR/bad-macro-definition.rs:6:18 + | +LL | macro_rules! b { 0 => } + | ^ + +error: macro definition ended unexpectedly + --> $DIR/bad-macro-definition.rs:6:22 + | +LL | macro_rules! b { 0 => } + | ^ expected right-hand side of macro rule + +error: invalid macro matcher; matchers must be contained in balanced delimiters + --> $DIR/bad-macro-definition.rs:10:18 + | +LL | macro_rules! c { x => } + | ^ + +error: macro definition ended unexpectedly + --> $DIR/bad-macro-definition.rs:10:22 + | +LL | macro_rules! c { x => } + | ^ expected right-hand side of macro rule + +error: invalid macro matcher; matchers must be contained in balanced delimiters + --> $DIR/bad-macro-definition.rs:14:18 + | +LL | macro_rules! d { _ => } + | ^ + +error: macro definition ended unexpectedly + --> $DIR/bad-macro-definition.rs:14:22 + | +LL | macro_rules! d { _ => } + | ^ expected right-hand side of macro rule + +error: expected `=>`, found end of macro arguments + --> $DIR/bad-macro-definition.rs:18:20 + | +LL | macro_rules! e { {} } + | ^ expected `=>` + +error: macros must contain at least one rule + --> $DIR/bad-macro-definition.rs:21:1 + | +LL | macro_rules! f {} + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 9 previous errors + From b33dc21d78821ac0fc33241d96badb64a001e0fd Mon Sep 17 00:00:00 2001 From: clubby789 Date: Thu, 3 Jul 2025 17:22:31 +0100 Subject: [PATCH 48/62] Assign dependency bump PRs to me --- .github/workflows/dependencies.yml | 1 + triagebot.toml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/dependencies.yml b/.github/workflows/dependencies.yml index 98d8c14f7d18..9d4b6192d6ea 100644 --- a/.github/workflows/dependencies.yml +++ b/.github/workflows/dependencies.yml @@ -19,6 +19,7 @@ env: PR_TITLE: Weekly `cargo update` PR_MESSAGE: | Automation to keep dependencies in `Cargo.lock` current. + r? dep-bumps The following is the output from `cargo update`: COMMIT_MESSAGE: "cargo update \n\n" diff --git a/triagebot.toml b/triagebot.toml index 6385528e7b6e..23defca5c500 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -1350,6 +1350,9 @@ project-exploit-mitigations = [ compiletest = [ "@jieyouxu", ] +dep-bumps = [ + "@clubby789", +] [assign.owners] "/.github/workflows" = ["infra-ci"] From 98659a339dd7203e0f23871b327b9305940e0d61 Mon Sep 17 00:00:00 2001 From: dianne Date: Fri, 4 Jul 2025 01:23:36 -0700 Subject: [PATCH 49/62] treat box patterns as deref patterns in THIR and usefulness analysis This removes special-casing of boxes from `rustc_pattern_analysis`, as a first step in replacing `box_patterns` with `deref_patterns`. Incidentally, it fixes a bug caused by box patterns being represented as structs rather than pointers, where `exhaustive_patterns` could generate spurious `unreachable_patterns` lints on arms required for exhaustiveness; following the lint's advice would result in an error. --- .../rustc_mir_build/src/thir/pattern/mod.rs | 7 +- compiler/rustc_pattern_analysis/src/rustc.rs | 87 +++++-------------- tests/ui/uninhabited/uninhabited-patterns.rs | 6 +- .../uninhabited/uninhabited-patterns.stderr | 40 +++++---- 4 files changed, 57 insertions(+), 83 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index e44a440b5c13..a44afed5492d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -319,9 +319,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { } PatKind::Deref { subpattern } } - hir::PatKind::Box(subpattern) => { - PatKind::Deref { subpattern: self.lower_pattern(subpattern) } - } + hir::PatKind::Box(subpattern) => PatKind::DerefPattern { + subpattern: self.lower_pattern(subpattern), + borrow: hir::ByRef::No, + }, hir::PatKind::Slice(prefix, slice, suffix) => { self.slice_or_array_pattern(pat.span, ty, prefix, slice, suffix) diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index 46ced7500ea2..e53cebc59baf 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -221,27 +221,19 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { let slice = match ctor { Struct | Variant(_) | UnionField => match ty.kind() { ty::Tuple(fs) => reveal_and_alloc(cx, fs.iter()), - ty::Adt(adt, args) => { - if adt.is_box() { - // The only legal patterns of type `Box` (outside `std`) are `_` and box - // patterns. If we're here we can assume this is a box pattern. - reveal_and_alloc(cx, once(args.type_at(0))) - } else { - let variant = - &adt.variant(RustcPatCtxt::variant_index_for_adt(&ctor, *adt)); - let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| { - let is_visible = - adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx); - let is_uninhabited = cx.is_uninhabited(*ty); - let is_unstable = - cx.tcx.lookup_stability(field.did).is_some_and(|stab| { - stab.is_unstable() && stab.feature != sym::rustc_private - }); - let skip = is_uninhabited && (!is_visible || is_unstable); - (ty, PrivateUninhabitedField(skip)) + ty::Adt(adt, _) => { + let variant = &adt.variant(RustcPatCtxt::variant_index_for_adt(&ctor, *adt)); + let tys = cx.variant_sub_tys(ty, variant).map(|(field, ty)| { + let is_visible = + adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx); + let is_uninhabited = cx.is_uninhabited(*ty); + let is_unstable = cx.tcx.lookup_stability(field.did).is_some_and(|stab| { + stab.is_unstable() && stab.feature != sym::rustc_private }); - cx.dropless_arena.alloc_from_iter(tys) - } + let skip = is_uninhabited && (!is_visible || is_unstable); + (ty, PrivateUninhabitedField(skip)) + }); + cx.dropless_arena.alloc_from_iter(tys) } _ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"), }, @@ -273,14 +265,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { Struct | Variant(_) | UnionField => match ty.kind() { ty::Tuple(fs) => fs.len(), ty::Adt(adt, ..) => { - if adt.is_box() { - // The only legal patterns of type `Box` (outside `std`) are `_` and box - // patterns. If we're here we can assume this is a box pattern. - 1 - } else { - let variant_idx = RustcPatCtxt::variant_index_for_adt(&ctor, *adt); - adt.variant(variant_idx).fields.len() - } + let variant_idx = RustcPatCtxt::variant_index_for_adt(&ctor, *adt); + adt.variant(variant_idx).fields.len() } _ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"), }, @@ -470,8 +456,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { fields = vec![self.lower_pat(subpattern).at_index(0)]; arity = 1; ctor = match ty.kind() { - // This is a box pattern. - ty::Adt(adt, ..) if adt.is_box() => Struct, ty::Ref(..) => Ref, _ => span_bug!( pat.span, @@ -501,28 +485,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { .map(|ipat| self.lower_pat(&ipat.pattern).at_index(ipat.field.index())) .collect(); } - ty::Adt(adt, _) if adt.is_box() => { - // The only legal patterns of type `Box` (outside `std`) are `_` and box - // patterns. If we're here we can assume this is a box pattern. - // FIXME(Nadrieril): A `Box` can in theory be matched either with `Box(_, - // _)` or a box pattern. As a hack to avoid an ICE with the former, we - // ignore other fields than the first one. This will trigger an error later - // anyway. - // See https://github.com/rust-lang/rust/issues/82772, - // explanation: https://github.com/rust-lang/rust/pull/82789#issuecomment-796921977 - // The problem is that we can't know from the type whether we'll match - // normally or through box-patterns. We'll have to figure out a proper - // solution when we introduce generalized deref patterns. Also need to - // prevent mixing of those two options. - let pattern = subpatterns.into_iter().find(|pat| pat.field.index() == 0); - if let Some(pat) = pattern { - fields = vec![self.lower_pat(&pat.pattern).at_index(0)]; - } else { - fields = vec![]; - } - ctor = Struct; - arity = 1; - } ty::Adt(adt, _) => { ctor = match pat.kind { PatKind::Leaf { .. } if adt.is_union() => UnionField, @@ -825,11 +787,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { Bool(b) => b.to_string(), Str(s) => s.to_string(), IntRange(range) => return self.print_pat_range(range, *pat.ty()), - Struct if pat.ty().is_box() => { - // Outside of the `alloc` crate, the only way to create a struct pattern - // of type `Box` is to use a `box` pattern via #[feature(box_patterns)]. - format!("box {}", print(&pat.fields[0])) - } Struct | Variant(_) | UnionField => { let enum_info = match *pat.ty().kind() { ty::Adt(adt_def, _) if adt_def.is_enum() => EnumInfo::Enum { @@ -866,6 +823,14 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { print::write_ref_like(&mut s, pat.ty().inner(), &print(&pat.fields[0])).unwrap(); s } + DerefPattern(_) if pat.ty().is_box() && !self.tcx.features().deref_patterns() => { + // FIXME(deref_patterns): Remove this special handling once `box_patterns` is gone. + // HACK(@dianne): `box _` syntax is exposed on stable in diagnostics, e.g. to + // witness non-exhaustiveness of `match Box::new(0) { Box { .. } if false => {} }`. + // To avoid changing diagnostics before deref pattern syntax is finalized, let's use + // `box _` syntax unless `deref_patterns` is enabled. + format!("box {}", print(&pat.fields[0])) + } DerefPattern(_) => format!("deref!({})", print(&pat.fields[0])), Slice(slice) => { let (prefix_len, has_dot_dot) = match slice.kind { @@ -964,12 +929,8 @@ impl<'p, 'tcx: 'p> PatCx for RustcPatCtxt<'p, 'tcx> { ty: &Self::Ty, ) -> fmt::Result { if let ty::Adt(adt, _) = ty.kind() { - if adt.is_box() { - write!(f, "Box")? - } else { - let variant = adt.variant(Self::variant_index_for_adt(ctor, *adt)); - write!(f, "{}", variant.name)?; - } + let variant = adt.variant(Self::variant_index_for_adt(ctor, *adt)); + write!(f, "{}", variant.name)?; } Ok(()) } diff --git a/tests/ui/uninhabited/uninhabited-patterns.rs b/tests/ui/uninhabited/uninhabited-patterns.rs index b7429464fa5a..1f30af2acc69 100644 --- a/tests/ui/uninhabited/uninhabited-patterns.rs +++ b/tests/ui/uninhabited/uninhabited-patterns.rs @@ -27,7 +27,11 @@ fn main() { let x: Result, &[Result]> = Err(&[]); match x { - Ok(box _) => (), //~ ERROR unreachable pattern + Ok(box _) => (), // We'd get a non-exhaustiveness error if this arm was removed; don't lint. + Err(&[]) => (), + Err(&[..]) => (), + } + match x { //~ ERROR non-exhaustive patterns Err(&[]) => (), Err(&[..]) => (), } diff --git a/tests/ui/uninhabited/uninhabited-patterns.stderr b/tests/ui/uninhabited/uninhabited-patterns.stderr index 7a872767d959..62113c82a364 100644 --- a/tests/ui/uninhabited/uninhabited-patterns.stderr +++ b/tests/ui/uninhabited/uninhabited-patterns.stderr @@ -1,8 +1,26 @@ -error: unreachable pattern - --> $DIR/uninhabited-patterns.rs:30:9 +error[E0004]: non-exhaustive patterns: `Ok(_)` not covered + --> $DIR/uninhabited-patterns.rs:34:11 | -LL | Ok(box _) => (), - | ^^^^^^^^^------- +LL | match x { + | ^ pattern `Ok(_)` not covered + | +note: `Result, &[Result]>` defined here + --> $SRC_DIR/core/src/result.rs:LL:COL + ::: $SRC_DIR/core/src/result.rs:LL:COL + | + = note: not covered + = note: the matched value is of type `Result, &[Result]>` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ Err(&[..]) => (), +LL ~ Ok(_) => todo!(), + | + +error: unreachable pattern + --> $DIR/uninhabited-patterns.rs:43:9 + | +LL | Err(Ok(_y)) => (), + | ^^^^^^^^^^^------- | | | matches no values because `NotSoSecretlyEmpty` is uninhabited | help: remove the match arm @@ -15,18 +33,7 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/uninhabited-patterns.rs:39:9 - | -LL | Err(Ok(_y)) => (), - | ^^^^^^^^^^^------- - | | - | matches no values because `NotSoSecretlyEmpty` is uninhabited - | help: remove the match arm - | - = note: to learn more about uninhabited types, see https://doc.rust-lang.org/nomicon/exotic-sizes.html#empty-types - -error: unreachable pattern - --> $DIR/uninhabited-patterns.rs:42:15 + --> $DIR/uninhabited-patterns.rs:46:15 | LL | while let Some(_y) = foo() { | ^^^^^^^^ matches no values because `NotSoSecretlyEmpty` is uninhabited @@ -35,3 +42,4 @@ LL | while let Some(_y) = foo() { error: aborting due to 3 previous errors +For more information about this error, try `rustc --explain E0004`. From e631555a4838aaa5ea8e10dadf7e54cf9711ed10 Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 4 Jul 2025 11:43:43 +0300 Subject: [PATCH 50/62] bump termize dep --- Cargo.lock | 16 +++++++++++++--- compiler/rustc_errors/Cargo.toml | 2 +- compiler/rustc_session/Cargo.toml | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7cf10628b005..3901e07c5fce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -581,7 +581,7 @@ dependencies = [ "serde_json", "syn 2.0.104", "tempfile", - "termize", + "termize 0.1.1", "tokio", "toml 0.7.8", "ui_test", @@ -3761,7 +3761,7 @@ dependencies = [ "serde", "serde_json", "termcolor", - "termize", + "termize 0.2.0", "tracing", "windows 0.61.3", ] @@ -4522,7 +4522,7 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", - "termize", + "termize 0.2.0", "tracing", "windows 0.61.3", ] @@ -5294,6 +5294,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "termize" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8da106d1a19c5b9c53c03311936568a0439926a7607815bd3461139cbab1cc" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + [[package]] name = "test-float-parse" version = "0.1.0" diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 82e7468211db..c4181a62a35d 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -28,7 +28,7 @@ rustc_type_ir = { path = "../rustc_type_ir" } serde = { version = "1.0.125", features = [ "derive" ] } serde_json = "1.0.59" termcolor = "1.2.0" -termize = "0.1.1" +termize = "0.2" tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 5b88a7017c51..0516982aeabb 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -22,7 +22,7 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -termize = "0.1.1" +termize = "0.2" tracing = "0.1" # tidy-alphabetical-end From 9345940c12315c69fb9f4f10cdb463aca581a7ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 10:37:42 +0200 Subject: [PATCH 51/62] Add josh-sync config file --- src/doc/rustc-dev-guide/josh-sync.toml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/doc/rustc-dev-guide/josh-sync.toml diff --git a/src/doc/rustc-dev-guide/josh-sync.toml b/src/doc/rustc-dev-guide/josh-sync.toml new file mode 100644 index 000000000000..7882051e2339 --- /dev/null +++ b/src/doc/rustc-dev-guide/josh-sync.toml @@ -0,0 +1,3 @@ +org = "rust-lang" +repo = "rustc-dev-guide" +path = "src/doc/rustc-dev-guide" From ac1a8b398b8c0f33e982ba736d31492d911c3050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 4 Jul 2025 11:07:45 +0200 Subject: [PATCH 52/62] Prepare for merging from rust-lang/rust This updates the rust-version file to c96a69059ecc618b519da385a6ccd03155aa0237. --- src/doc/rustc-dev-guide/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version index c986141b6548..e444613e6311 100644 --- a/src/doc/rustc-dev-guide/rust-version +++ b/src/doc/rustc-dev-guide/rust-version @@ -1 +1 @@ -bc4376fa73b636eb6f2c7d48b1f731d70f022c4b +c96a69059ecc618b519da385a6ccd03155aa0237 From 2d3ff91add77a2ae5959f5134e12f5c0eec59ce5 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 3 Jul 2025 13:42:36 +0000 Subject: [PATCH 53/62] Remove names_imported_by_glob_use query. --- compiler/rustc_middle/src/query/mod.rs | 3 --- compiler/rustc_middle/src/ty/context.rs | 4 ---- src/tools/clippy/clippy_lints/src/wildcard_imports.rs | 2 +- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index aefae3a3b146..17a29c9ae4b2 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -2264,9 +2264,6 @@ rustc_queries! { query maybe_unused_trait_imports(_: ()) -> &'tcx FxIndexSet { desc { "fetching potentially unused trait imports" } } - query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx FxIndexSet { - desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id) } - } query stability_index(_: ()) -> &'tcx stability::Index { arena_cache diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8aa50d14faa6..9518757c5ae1 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3413,10 +3413,6 @@ pub struct DeducedParamAttrs { pub fn provide(providers: &mut Providers) { providers.maybe_unused_trait_imports = |tcx, ()| &tcx.resolutions(()).maybe_unused_trait_imports; - providers.names_imported_by_glob_use = |tcx, id| { - tcx.arena.alloc(tcx.resolutions(()).glob_map.get(&id).cloned().unwrap_or_default()) - }; - providers.extern_mod_stmt_cnum = |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned(); providers.is_panic_runtime = diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs index d9dda6eadb2a..22fd15d153ab 100644 --- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs +++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs @@ -130,7 +130,7 @@ impl LateLintPass<'_> for WildcardImports { } if let ItemKind::Use(use_path, UseKind::Glob) = &item.kind && (self.warn_on_all || !self.check_exceptions(cx, item, use_path.segments)) - && let used_imports = cx.tcx.names_imported_by_glob_use(item.owner_id.def_id) + && let Some(used_imports) = cx.tcx.resolutions(()).glob_map.get(&item.owner_id.def_id) && !used_imports.is_empty() // Already handled by `unused_imports` && !used_imports.contains(&kw::Underscore) { From c7ee3a5e3f6efc979ea75e4b385af8ced11fdb03 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 9 Aug 2023 17:47:20 +0000 Subject: [PATCH 54/62] Save metadata among work products. --- compiler/rustc_interface/src/queries.rs | 15 ++++++++++++- compiler/rustc_metadata/src/rmeta/encoder.rs | 23 +++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 2bc30fa7cb04..370e886c525f 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -45,11 +45,24 @@ impl Linker { } pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) { - let (codegen_results, work_products) = sess.time("finish_ongoing_codegen", || { + let (codegen_results, mut work_products) = sess.time("finish_ongoing_codegen", || { codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames) }); sess.timings.end_section(sess.dcx(), TimingSection::Codegen); + if sess.opts.incremental.is_some() + && let Some(path) = self.metadata.path() + && let Some((id, product)) = + rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( + sess, + "metadata", + &[("rmeta", path)], + &[], + ) + { + work_products.insert(id, product); + } + sess.dcx().abort_if_errors(); let _timer = sess.timer("link"); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 90bc427a19ae..806c8bd782cd 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2307,6 +2307,8 @@ pub struct EncodedMetadata { // This is an optional stub metadata containing only the crate header. // The header should be very small, so we load it directly into memory. stub_metadata: Option>, + // The path containing the metadata, to record as work product. + path: Option>, // We need to carry MaybeTempDir to avoid deleting the temporary // directory while accessing the Mmap. _temp_dir: Option, @@ -2322,14 +2324,24 @@ impl EncodedMetadata { let file = std::fs::File::open(&path)?; let file_metadata = file.metadata()?; if file_metadata.len() == 0 { - return Ok(Self { full_metadata: None, stub_metadata: None, _temp_dir: None }); + return Ok(Self { + full_metadata: None, + stub_metadata: None, + path: None, + _temp_dir: None, + }); } let full_mmap = unsafe { Some(Mmap::map(file)?) }; let stub = if let Some(stub_path) = stub_path { Some(std::fs::read(stub_path)?) } else { None }; - Ok(Self { full_metadata: full_mmap, stub_metadata: stub, _temp_dir: temp_dir }) + Ok(Self { + full_metadata: full_mmap, + stub_metadata: stub, + path: Some(path.into()), + _temp_dir: temp_dir, + }) } #[inline] @@ -2341,6 +2353,11 @@ impl EncodedMetadata { pub fn stub_or_full(&self) -> &[u8] { self.stub_metadata.as_deref().unwrap_or(self.full()) } + + #[inline] + pub fn path(&self) -> Option<&Path> { + self.path.as_deref() + } } impl Encodable for EncodedMetadata { @@ -2365,7 +2382,7 @@ impl Decodable for EncodedMetadata { None }; - Self { full_metadata, stub_metadata: stub, _temp_dir: None } + Self { full_metadata, stub_metadata: stub, path: None, _temp_dir: None } } } From 761d366415678605c67026dde6c7166e7a3541c2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 9 Aug 2023 18:04:41 +0000 Subject: [PATCH 55/62] Reuse metadata file from work products. --- Cargo.lock | 1 + compiler/rustc_metadata/Cargo.toml | 1 + compiler/rustc_metadata/src/rmeta/encoder.rs | 83 +++++++++++++------ .../rustc_middle/src/dep_graph/dep_node.rs | 7 ++ compiler/rustc_middle/src/dep_graph/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 4 + compiler/rustc_query_impl/src/plumbing.rs | 11 +++ 7 files changed, 82 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7cf10628b005..815575bdc063 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4133,6 +4133,7 @@ dependencies = [ "rustc_fs_util", "rustc_hir", "rustc_hir_pretty", + "rustc_incremental", "rustc_index", "rustc_macros", "rustc_middle", diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml index a163518fd195..0edc1d18ecc7 100644 --- a/compiler/rustc_metadata/Cargo.toml +++ b/compiler/rustc_metadata/Cargo.toml @@ -20,6 +20,7 @@ rustc_fluent_macro = { path = "../rustc_fluent_macro" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_hir = { path = "../rustc_hir" } rustc_hir_pretty = { path = "../rustc_hir_pretty" } +rustc_incremental = { path = "../rustc_incremental" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 806c8bd782cd..18db0380183a 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2386,7 +2386,43 @@ impl Decodable for EncodedMetadata { } } +#[instrument(level = "trace", skip(tcx))] pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { + if let Some(ref_path) = ref_path { + let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub"); + + with_encode_metadata_header(tcx, ref_path, |ecx| { + let header: LazyValue = ecx.lazy(CrateHeader { + name: tcx.crate_name(LOCAL_CRATE), + triple: tcx.sess.opts.target_triple.clone(), + hash: tcx.crate_hash(LOCAL_CRATE), + is_proc_macro_crate: false, + is_stub: true, + }); + header.position.get() + }); + } + + let dep_node = tcx.metadata_dep_node(); + + if tcx.dep_graph.is_fully_enabled() + && let work_product_id = &rustc_middle::dep_graph::WorkProductId::from_cgu_name("metadata") + && let Some(work_product) = tcx.dep_graph.previous_work_product(work_product_id) + && tcx.try_mark_green(&dep_node) + { + let saved_path = &work_product.saved_files["rmeta"]; + let incr_comp_session_dir = tcx.sess.incr_comp_session_dir_opt().unwrap(); + let source_file = rustc_incremental::in_incr_comp_dir(&incr_comp_session_dir, saved_path); + debug!("copying preexisting metadata from {source_file:?} to {path:?}"); + match rustc_fs_util::link_or_copy(&source_file, path) { + Ok(_) => {} + Err(err) => { + tcx.dcx().emit_fatal(FailCreateFileEncoder { err }); + } + }; + return; + }; + let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata"); // Since encoding metadata is not in a query, and nothing is cached, @@ -2406,35 +2442,30 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { ); } - with_encode_metadata_header(tcx, path, |ecx| { - // Encode all the entries and extra information in the crate, - // culminating in the `CrateRoot` which points to all of it. - let root = ecx.encode_crate_root(); + tcx.dep_graph.with_task( + dep_node, + tcx, + path, + |tcx, path| { + with_encode_metadata_header(tcx, path, |ecx| { + // Encode all the entries and extra information in the crate, + // culminating in the `CrateRoot` which points to all of it. + let root = ecx.encode_crate_root(); - // Flush buffer to ensure backing file has the correct size. - ecx.opaque.flush(); - // Record metadata size for self-profiling - tcx.prof.artifact_size( - "crate_metadata", - "crate_metadata", - ecx.opaque.file().metadata().unwrap().len(), - ); + // Flush buffer to ensure backing file has the correct size. + ecx.opaque.flush(); + // Record metadata size for self-profiling + tcx.prof.artifact_size( + "crate_metadata", + "crate_metadata", + ecx.opaque.file().metadata().unwrap().len(), + ); - root.position.get() - }); - - if let Some(ref_path) = ref_path { - with_encode_metadata_header(tcx, ref_path, |ecx| { - let header: LazyValue = ecx.lazy(CrateHeader { - name: tcx.crate_name(LOCAL_CRATE), - triple: tcx.sess.opts.target_triple.clone(), - hash: tcx.crate_hash(LOCAL_CRATE), - is_proc_macro_crate: false, - is_stub: true, + root.position.get() }); - header.position.get() - }); - } + }, + None, + ); } fn with_encode_metadata_header( diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 0c998a2cbb38..0c757a390ca0 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -98,6 +98,7 @@ rustc_with_all_queries!(define_dep_nodes![ [] fn TraitSelect() -> (), [] fn CompileCodegenUnit() -> (), [] fn CompileMonoItem() -> (), + [] fn Metadata() -> (), ]); // WARNING: `construct` is generic and does not know that `CompileCodegenUnit` takes `Symbol`s as keys. @@ -115,6 +116,12 @@ pub(crate) fn make_compile_mono_item<'tcx>( DepNode::construct(tcx, dep_kinds::CompileMonoItem, mono_item) } +// WARNING: `construct` is generic and does not know that `Metadata` takes `()`s as keys. +// Be very careful changing this type signature! +pub(crate) fn make_metadata(tcx: TyCtxt<'_>) -> DepNode { + DepNode::construct(tcx, dep_kinds::Metadata, &()) +} + pub trait DepNodeExt: Sized { fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option; diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 0a8e6153817e..781e3e442e64 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -9,7 +9,7 @@ use crate::ty::{self, TyCtxt}; mod dep_node; pub use dep_node::{DepKind, DepNode, DepNodeExt, dep_kinds, label_strs}; -pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item}; +pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item, make_metadata}; pub use rustc_query_system::dep_graph::debug::{DepNodeFilter, EdgeFilter}; pub use rustc_query_system::dep_graph::{ DepContext, DepGraphQuery, DepNodeIndex, Deps, SerializedDepGraph, SerializedDepNodeIndex, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8aa50d14faa6..e56f98291f1e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -3364,6 +3364,10 @@ impl<'tcx> TyCtxt<'tcx> { self.resolver_for_lowering_raw(()).0 } + pub fn metadata_dep_node(self) -> crate::dep_graph::DepNode { + crate::dep_graph::make_metadata(self) + } + /// Given an `impl_id`, return the trait it implements. /// Return `None` if this is an inherent impl. pub fn impl_trait_ref( diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 9fbbcdc75569..55549cba737e 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -923,6 +923,17 @@ macro_rules! define_queries { } } + pub(crate) fn Metadata<'tcx>() -> DepKindStruct<'tcx> { + DepKindStruct { + is_anon: false, + is_eval_always: false, + fingerprint_style: FingerprintStyle::Unit, + force_from_dep_node: None, + try_load_from_on_disk_cache: None, + name: &"Metadata", + } + } + $(pub(crate) fn $name<'tcx>()-> DepKindStruct<'tcx> { $crate::plumbing::query_callback::>( is_anon!([$($modifiers)*]), From 904bc2958f369733c09f698a95a401ae44b3c40b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 30 Jun 2025 15:56:54 +0000 Subject: [PATCH 56/62] Lighten formatting. --- compiler/rustc_metadata/src/rmeta/encoder.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 18db0380183a..eaac3694f1f9 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -16,6 +16,7 @@ use rustc_hir as hir; use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE, LocalDefId, LocalDefIdSet}; use rustc_hir::definitions::DefPathData; use rustc_hir_pretty::id_to_string; +use rustc_middle::dep_graph::WorkProductId; use rustc_middle::middle::dependency_format::Linkage; use rustc_middle::middle::exported_symbols::metadata_symbol_name; use rustc_middle::mir::interpret; @@ -2406,8 +2407,8 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { let dep_node = tcx.metadata_dep_node(); if tcx.dep_graph.is_fully_enabled() - && let work_product_id = &rustc_middle::dep_graph::WorkProductId::from_cgu_name("metadata") - && let Some(work_product) = tcx.dep_graph.previous_work_product(work_product_id) + && let work_product_id = WorkProductId::from_cgu_name("metadata") + && let Some(work_product) = tcx.dep_graph.previous_work_product(&work_product_id) && tcx.try_mark_green(&dep_node) { let saved_path = &work_product.saved_files["rmeta"]; @@ -2416,9 +2417,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { debug!("copying preexisting metadata from {source_file:?} to {path:?}"); match rustc_fs_util::link_or_copy(&source_file, path) { Ok(_) => {} - Err(err) => { - tcx.dcx().emit_fatal(FailCreateFileEncoder { err }); - } + Err(err) => tcx.dcx().emit_fatal(FailCreateFileEncoder { err }), }; return; }; From 17ce06a45958c41917de18641a693ec095d7d389 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 3 Jul 2025 14:00:14 +0000 Subject: [PATCH 57/62] Add comment and move assertion. --- compiler/rustc_metadata/src/rmeta/encoder.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index eaac3694f1f9..b0ec605a85fe 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2389,6 +2389,11 @@ impl Decodable for EncodedMetadata { #[instrument(level = "trace", skip(tcx))] pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { + // Since encoding metadata is not in a query, and nothing is cached, + // there's no need to do dep-graph tracking for any of it. + tcx.dep_graph.assert_ignored(); + + // Generate the metadata stub manually, as that is a small file compared to full metadata. if let Some(ref_path) = ref_path { let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub"); @@ -2401,11 +2406,14 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { is_stub: true, }); header.position.get() - }); + }) } + let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata"); + let dep_node = tcx.metadata_dep_node(); + // If the metadata dep-node is green, try to reuse the saved work product. if tcx.dep_graph.is_fully_enabled() && let work_product_id = WorkProductId::from_cgu_name("metadata") && let Some(work_product) = tcx.dep_graph.previous_work_product(&work_product_id) @@ -2422,12 +2430,6 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { return; }; - let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata"); - - // Since encoding metadata is not in a query, and nothing is cached, - // there's no need to do dep-graph tracking for any of it. - tcx.dep_graph.assert_ignored(); - if tcx.sess.threads() != 1 { // Prefetch some queries used by metadata encoding. // This is not necessary for correctness, but is only done for performance reasons. @@ -2441,6 +2443,8 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { ); } + // Perform metadata encoding inside a task, so the dep-graph can check if any encoded + // information changes, and maybe reuse the work product. tcx.dep_graph.with_task( dep_node, tcx, @@ -2461,7 +2465,7 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) { ); root.position.get() - }); + }) }, None, ); From f4ef1a769a4bc67089b0c2c93c6ff891daed4385 Mon Sep 17 00:00:00 2001 From: Ayush Singh Date: Sun, 25 May 2025 12:21:27 +0530 Subject: [PATCH 58/62] std: sys: net: uefi: tcp4: Implement write A blocking implementation of tcp4 write. Signed-off-by: Ayush Singh --- .../std/src/sys/net/connection/uefi/mod.rs | 11 ++--- .../std/src/sys/net/connection/uefi/tcp.rs | 8 +++- .../std/src/sys/net/connection/uefi/tcp4.rs | 40 +++++++++++++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/net/connection/uefi/mod.rs b/library/std/src/sys/net/connection/uefi/mod.rs index 46d67c8e5101..2d465bd0efaa 100644 --- a/library/std/src/sys/net/connection/uefi/mod.rs +++ b/library/std/src/sys/net/connection/uefi/mod.rs @@ -7,7 +7,7 @@ use crate::time::Duration; mod tcp; pub(crate) mod tcp4; -pub struct TcpStream(#[expect(dead_code)] tcp::Tcp); +pub struct TcpStream(tcp::Tcp); impl TcpStream { pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result { @@ -54,12 +54,13 @@ impl TcpStream { false } - pub fn write(&self, _: &[u8]) -> io::Result { - unsupported() + pub fn write(&self, buf: &[u8]) -> io::Result { + self.0.write(buf) } - pub fn write_vectored(&self, _: &[IoSlice<'_>]) -> io::Result { - unsupported() + pub fn write_vectored(&self, buf: &[IoSlice<'_>]) -> io::Result { + // FIXME: UEFI does support vectored write, so implement that. + crate::io::default_write_vectored(|b| self.write(b), buf) } pub fn is_write_vectored(&self) -> bool { diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index f87accdc41de..9c3462e3468c 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -3,7 +3,7 @@ use crate::io; use crate::net::SocketAddr; pub(crate) enum Tcp { - V4(#[expect(dead_code)] tcp4::Tcp4), + V4(tcp4::Tcp4), } impl Tcp { @@ -18,4 +18,10 @@ impl Tcp { SocketAddr::V6(_) => todo!(), } } + + pub(crate) fn write(&self, buf: &[u8]) -> io::Result { + match self { + Self::V4(client) => client.write(buf), + } + } } diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs index f7ca373b52b5..d0f0d27d975f 100644 --- a/library/std/src/sys/net/connection/uefi/tcp4.rs +++ b/library/std/src/sys/net/connection/uefi/tcp4.rs @@ -88,6 +88,46 @@ impl Tcp4 { } } + pub(crate) fn write(&self, buf: &[u8]) -> io::Result { + let evt = unsafe { self.create_evt() }?; + let completion_token = + tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; + let data_len = u32::try_from(buf.len()).unwrap_or(u32::MAX); + + let fragment = tcp4::FragmentData { + fragment_length: data_len, + fragment_buffer: buf.as_ptr().cast::().cast_mut(), + }; + let mut tx_data = tcp4::TransmitData { + push: r_efi::efi::Boolean::FALSE, + urgent: r_efi::efi::Boolean::FALSE, + data_length: data_len, + fragment_count: 1, + fragment_table: [fragment], + }; + + let protocol = self.protocol.as_ptr(); + let mut token = tcp4::IoToken { + completion_token, + packet: tcp4::IoTokenPacket { + tx_data: (&raw mut tx_data).cast::>(), + }, + }; + + let r = unsafe { ((*protocol).transmit)(protocol, &mut token) }; + if r.is_error() { + return Err(io::Error::from_raw_os_error(r.as_usize())); + } + + self.wait_for_flag(); + + if completion_token.status.is_error() { + Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) + } else { + Ok(data_len as usize) + } + } + unsafe fn create_evt(&self) -> io::Result { self.flag.store(false, Ordering::Relaxed); helpers::OwnedEvent::new( From 71176a28e698d04b23a3e20d8a8d93de4d467609 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 4 Jul 2025 19:14:26 +0200 Subject: [PATCH 59/62] clean up GVN TypeId test --- ...onst_eval_polymorphic.no_optimize.GVN.diff | 12 ++++ ...t_eval_polymorphic.optimize_false.GVN.diff | 13 +++++ ...st_eval_polymorphic.optimize_true.GVN.diff | 13 +++++ tests/mir-opt/gvn_const_eval_polymorphic.rs | 57 +++++++++++++++++++ ...type_id_polymorphic.cursed_is_i32.GVN.diff | 12 ---- tests/mir-opt/gvn_type_id_polymorphic.rs | 22 ------- 6 files changed, 95 insertions(+), 34 deletions(-) create mode 100644 tests/mir-opt/gvn_const_eval_polymorphic.no_optimize.GVN.diff create mode 100644 tests/mir-opt/gvn_const_eval_polymorphic.optimize_false.GVN.diff create mode 100644 tests/mir-opt/gvn_const_eval_polymorphic.optimize_true.GVN.diff create mode 100644 tests/mir-opt/gvn_const_eval_polymorphic.rs delete mode 100644 tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff delete mode 100644 tests/mir-opt/gvn_type_id_polymorphic.rs diff --git a/tests/mir-opt/gvn_const_eval_polymorphic.no_optimize.GVN.diff b/tests/mir-opt/gvn_const_eval_polymorphic.no_optimize.GVN.diff new file mode 100644 index 000000000000..a91561ba304b --- /dev/null +++ b/tests/mir-opt/gvn_const_eval_polymorphic.no_optimize.GVN.diff @@ -0,0 +1,12 @@ +- // MIR for `no_optimize` before GVN ++ // MIR for `no_optimize` after GVN + + fn no_optimize() -> bool { + let mut _0: bool; + + bb0: { + _0 = Eq(const no_optimize::::{constant#0}, const no_optimize::::{constant#1}); + return; + } + } + diff --git a/tests/mir-opt/gvn_const_eval_polymorphic.optimize_false.GVN.diff b/tests/mir-opt/gvn_const_eval_polymorphic.optimize_false.GVN.diff new file mode 100644 index 000000000000..bdfa2987b23c --- /dev/null +++ b/tests/mir-opt/gvn_const_eval_polymorphic.optimize_false.GVN.diff @@ -0,0 +1,13 @@ +- // MIR for `optimize_false` before GVN ++ // MIR for `optimize_false` after GVN + + fn optimize_false() -> bool { + let mut _0: bool; + + bb0: { +- _0 = Eq(const optimize_false::::{constant#0}, const optimize_false::::{constant#1}); ++ _0 = const false; + return; + } + } + diff --git a/tests/mir-opt/gvn_const_eval_polymorphic.optimize_true.GVN.diff b/tests/mir-opt/gvn_const_eval_polymorphic.optimize_true.GVN.diff new file mode 100644 index 000000000000..dc337d43fb04 --- /dev/null +++ b/tests/mir-opt/gvn_const_eval_polymorphic.optimize_true.GVN.diff @@ -0,0 +1,13 @@ +- // MIR for `optimize_true` before GVN ++ // MIR for `optimize_true` after GVN + + fn optimize_true() -> bool { + let mut _0: bool; + + bb0: { +- _0 = Eq(const optimize_true::::{constant#0}, const optimize_true::::{constant#1}); ++ _0 = const true; + return; + } + } + diff --git a/tests/mir-opt/gvn_const_eval_polymorphic.rs b/tests/mir-opt/gvn_const_eval_polymorphic.rs new file mode 100644 index 000000000000..7320ad947ff2 --- /dev/null +++ b/tests/mir-opt/gvn_const_eval_polymorphic.rs @@ -0,0 +1,57 @@ +//@ test-mir-pass: GVN +//@ compile-flags: --crate-type lib + +//! Regressions test for a mis-optimization where some functions +//! (`type_id` / `type_name` / `needs_drop`) could be evaluated in +//! a generic context, even though their value depends on some type +//! parameter `T`. +//! +//! In particular, `type_name_of_val(&generic::)` was incorrectly +//! evaluated to the string "crate_name::generic::", and +//! `no_optimize` was incorrectly optimized to `false`. + +#![feature(const_type_name)] + +fn generic() {} + +const fn type_name_contains_i32(_: &T) -> bool { + let pattern = b"i32"; + let name = std::any::type_name::().as_bytes(); + let mut i = 0; + 'outer: while i < name.len() - pattern.len() + 1 { + let mut j = 0; + while j < pattern.len() { + if name[i + j] != pattern[j] { + i += 1; + continue 'outer; + } + j += 1; + } + return true; + } + false +} + +// EMIT_MIR gvn_const_eval_polymorphic.optimize_true.GVN.diff +fn optimize_true() -> bool { + // CHECK-LABEL: fn optimize_true( + // CHECK: _0 = const true; + // CHECK-NEXT: return; + (const { type_name_contains_i32(&generic::) }) == const { true } +} + +// EMIT_MIR gvn_const_eval_polymorphic.optimize_false.GVN.diff +fn optimize_false() -> bool { + // CHECK-LABEL: fn optimize_false( + // CHECK: _0 = const false; + // CHECK-NEXT: return; + (const { type_name_contains_i32(&generic::) }) == const { true } +} + +// EMIT_MIR gvn_const_eval_polymorphic.no_optimize.GVN.diff +fn no_optimize() -> bool { + // CHECK-LABEL: fn no_optimize( + // CHECK: _0 = Eq(const no_optimize::::{constant#0}, const no_optimize::::{constant#1}); + // CHECK-NEXT: return; + (const { type_name_contains_i32(&generic::) }) == const { true } +} diff --git a/tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff b/tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff deleted file mode 100644 index 2f83f54d2afd..000000000000 --- a/tests/mir-opt/gvn_type_id_polymorphic.cursed_is_i32.GVN.diff +++ /dev/null @@ -1,12 +0,0 @@ -- // MIR for `cursed_is_i32` before GVN -+ // MIR for `cursed_is_i32` after GVN - - fn cursed_is_i32() -> bool { - let mut _0: bool; - - bb0: { - _0 = Eq(const cursed_is_i32::::{constant#0}, const cursed_is_i32::::{constant#1}); - return; - } - } - diff --git a/tests/mir-opt/gvn_type_id_polymorphic.rs b/tests/mir-opt/gvn_type_id_polymorphic.rs deleted file mode 100644 index 39bc5c24ecc6..000000000000 --- a/tests/mir-opt/gvn_type_id_polymorphic.rs +++ /dev/null @@ -1,22 +0,0 @@ -//@ test-mir-pass: GVN -//@ compile-flags: -C opt-level=2 - -#![feature(core_intrinsics)] - -fn generic() {} - -const fn type_id_of_val(_: &T) -> u128 { - std::intrinsics::type_id::() -} - -// EMIT_MIR gvn_type_id_polymorphic.cursed_is_i32.GVN.diff -fn cursed_is_i32() -> bool { - // CHECK-LABEL: fn cursed_is_i32( - // CHECK: _0 = Eq(const cursed_is_i32::::{constant#0}, const cursed_is_i32::::{constant#1}); - // CHECK-NEXT: return; - (const { type_id_of_val(&generic::) } == const { type_id_of_val(&generic::) }) -} - -fn main() { - dbg!(cursed_is_i32::()); -} From 027126ce0b682367dc796c2cdcf844e162fca496 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Thu, 3 Jul 2025 09:10:49 +0200 Subject: [PATCH 60/62] Port `#[non_exhaustive]` to the new attribute parsing infrastructure --- .../src/attributes.rs | 3 +++ .../src/encode_cross_crate.rs | 1 + .../rustc_attr_parsing/src/attributes/mod.rs | 1 + .../src/attributes/non_exhaustive.rs | 13 ++++++++++ compiler/rustc_attr_parsing/src/context.rs | 2 ++ compiler/rustc_hir_analysis/src/collect.rs | 8 ++++--- compiler/rustc_middle/src/ty/adt.rs | 5 +++- compiler/rustc_parse/src/validate_attr.rs | 1 + compiler/rustc_passes/src/check_attr.rs | 16 ++++++------- compiler/rustc_resolve/src/diagnostics.rs | 6 ++--- src/librustdoc/clean/types.rs | 4 +++- .../clippy_lints/src/exhaustive_items.rs | 6 +++-- .../clippy_lints/src/manual_non_exhaustive.rs | 13 +++++----- src/tools/clippy/clippy_utils/src/attrs.rs | 9 +++---- tests/ui/attributes/malformed-attrs.stderr | 15 +++++++----- .../lint/unused/unused-attr-duplicate.stderr | 24 +++++++++---------- .../invalid-attribute.stderr | 10 +++++--- 17 files changed, 88 insertions(+), 49 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 3b5e06c2a88f..b5934f4e36e8 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -284,6 +284,9 @@ pub enum AttributeKind { /// Represents `#[no_mangle]` NoMangle(Span), + /// Represents `#[non_exhaustive]` + NonExhaustive(Span), + /// Represents `#[optimize(size|speed)]` Optimize(OptimizeAttr, Span), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index 145cfba8e424..02e95ddcb6fd 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -36,6 +36,7 @@ impl AttributeKind { Naked(..) => No, NoImplicitPrelude(..) => No, NoMangle(..) => No, + NonExhaustive(..) => Yes, Optimize(..) => No, PassByValue(..) => Yes, PubTransparent(..) => Yes, diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 0898b44863a3..f5ac3890a46a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -36,6 +36,7 @@ pub(crate) mod lint_helpers; pub(crate) mod loop_match; pub(crate) mod must_use; pub(crate) mod no_implicit_prelude; +pub(crate) mod non_exhaustive; pub(crate) mod repr; pub(crate) mod rustc_internal; pub(crate) mod semantics; diff --git a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs new file mode 100644 index 000000000000..94f6a65c74ec --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs @@ -0,0 +1,13 @@ +use rustc_attr_data_structures::AttributeKind; +use rustc_span::{Span, Symbol, sym}; + +use crate::attributes::{NoArgsAttributeParser, OnDuplicate}; +use crate::context::Stage; + +pub(crate) struct NonExhaustiveParser; + +impl NoArgsAttributeParser for NonExhaustiveParser { + const PATH: &[Symbol] = &[sym::non_exhaustive]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive; +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 5ddb686a8c09..265e1bb6a8cb 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -27,6 +27,7 @@ use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTranspa use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; +use crate::attributes::non_exhaustive::NonExhaustiveParser; use crate::attributes::repr::{AlignParser, ReprParser}; use crate::attributes::rustc_internal::{ RustcLayoutScalarValidRangeEnd, RustcLayoutScalarValidRangeStart, @@ -144,6 +145,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index aad9b08b2a3a..271104c20c62 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -779,9 +779,11 @@ fn lower_variant<'tcx>( fields, parent_did.to_def_id(), recovered, - adt_kind == AdtKind::Struct && tcx.has_attr(parent_did, sym::non_exhaustive) - || variant_did - .is_some_and(|variant_did| tcx.has_attr(variant_did, sym::non_exhaustive)), + adt_kind == AdtKind::Struct + && find_attr!(tcx.get_all_attrs(parent_did), AttributeKind::NonExhaustive(..)) + || variant_did.is_some_and(|variant_did| { + find_attr!(tcx.get_all_attrs(variant_did), AttributeKind::NonExhaustive(..)) + }), ) } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 6d5a3abf665b..44165b06f1c3 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -4,6 +4,7 @@ use std::ops::Range; use std::str; use rustc_abi::{FIRST_VARIANT, ReprOptions, VariantIdx}; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; @@ -278,7 +279,9 @@ impl AdtDefData { debug!("AdtDef::new({:?}, {:?}, {:?}, {:?})", did, kind, variants, repr); let mut flags = AdtFlags::NO_ADT_FLAGS; - if kind == AdtKind::Enum && tcx.has_attr(did, sym::non_exhaustive) { + if kind == AdtKind::Enum + && find_attr!(tcx.get_all_attrs(did), AttributeKind::NonExhaustive(..)) + { debug!("found non-exhaustive variant list for {:?}", did); flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE; } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 47249b38df5f..27355a422d1f 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -303,6 +303,7 @@ fn emit_malformed_attribute( | sym::rustc_allow_const_fn_unstable | sym::naked | sym::no_mangle + | sym::non_exhaustive | sym::must_use | sym::track_caller | sym::link_name diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c0ef81166ea0..c5ced4064140 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -194,6 +194,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { Attribute::Parsed(AttributeKind::TrackCaller(attr_span)) => { self.check_track_caller(hir_id, *attr_span, attrs, span, target) } + Attribute::Parsed(AttributeKind::NonExhaustive(attr_span)) => { + self.check_non_exhaustive(hir_id, *attr_span, span, target, item) + } Attribute::Parsed( AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span) | AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span), @@ -237,7 +240,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::no_sanitize, ..] => { self.check_no_sanitize(attr, span, target) } - [sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target, item), [sym::marker, ..] => self.check_marker(hir_id, attr, span, target), [sym::thread_local, ..] => self.check_thread_local(attr, span, target), [sym::doc, ..] => self.check_doc_attrs( @@ -779,7 +781,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_non_exhaustive( &self, hir_id: HirId, - attr: &Attribute, + attr_span: Span, span: Span, target: Target, item: Option>, @@ -794,7 +796,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { && fields.iter().any(|f| f.default.is_some()) { self.dcx().emit_err(errors::NonExhaustiveWithDefaultFieldValues { - attr_span: attr.span(), + attr_span, defn_span: span, }); } @@ -805,13 +807,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { // erroneously allowed it and some crates used it accidentally, to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { - self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "non_exhaustive"); + self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "non_exhaustive"); } _ => { - self.dcx().emit_err(errors::NonExhaustiveWrongLocation { - attr_span: attr.span(), - defn_span: span, - }); + self.dcx() + .emit_err(errors::NonExhaustiveWrongLocation { attr_span, defn_span: span }); } } } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 18078b760c3e..c99bc747fd21 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -5,7 +5,7 @@ use rustc_ast::{ self as ast, CRATE_NODE_ID, Crate, ItemKind, MetaItemInner, MetaItemKind, ModKind, NodeId, Path, }; use rustc_ast_pretty::pprust; -use rustc_attr_data_structures::{self as attr, Stability}; +use rustc_attr_data_structures::{self as attr, AttributeKind, Stability, find_attr}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::unord::{UnordMap, UnordSet}; use rustc_errors::codes::*; @@ -1998,9 +1998,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Otherwise, point out if the struct has any private fields. if let Some(def_id) = res.opt_def_id() && !def_id.is_local() - && let Some(attr) = self.tcx.get_attr(def_id, sym::non_exhaustive) + && let Some(attr_span) = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::NonExhaustive(span) => *span) { - non_exhaustive = Some(attr.span()); + non_exhaustive = Some(attr_span); } else if let Some(span) = ctor_fields_span { let label = errors::ConstructorPrivateIfAnyFieldPrivate { span }; err.subdiagnostic(label); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index cc8f4bbb42cc..de920469fdca 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -621,7 +621,7 @@ impl Item { } pub(crate) fn is_non_exhaustive(&self) -> bool { - self.attrs.other_attrs.iter().any(|a| a.has_name(sym::non_exhaustive)) + find_attr!(&self.attrs.other_attrs, AttributeKind::NonExhaustive(..)) } /// Returns a documentation-level item type from the item. @@ -776,6 +776,8 @@ impl Item { } else if let hir::Attribute::Parsed(AttributeKind::ExportName { name, .. }) = attr { Some(format!("#[export_name = \"{name}\"]")) + } else if let hir::Attribute::Parsed(AttributeKind::NonExhaustive(..)) = attr { + Some("#[non_exhaustive]".to_string()) } else if is_json { match attr { // rustdoc-json stores this in `Item::deprecation`, so we diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs index 86d9038ec45d..7dda3e0fdb91 100644 --- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs @@ -4,7 +4,9 @@ use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; -use rustc_span::sym; +use rustc_attr_data_structures::AttributeKind; +use rustc_attr_data_structures::find_attr; + declare_clippy_lint! { /// ### What it does @@ -85,7 +87,7 @@ impl LateLintPass<'_> for ExhaustiveItems { }; if cx.effective_visibilities.is_exported(item.owner_id.def_id) && let attrs = cx.tcx.hir_attrs(item.hir_id()) - && !attrs.iter().any(|a| a.has_name(sym::non_exhaustive)) + && !find_attr!(attrs, AttributeKind::NonExhaustive(..)) && fields.iter().all(|f| cx.tcx.visibility(f.def_id).is_public()) { span_lint_and_then(cx, lint, item.span, msg, |diag| { diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs index 3562b1ff5cce..51696b388800 100644 --- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs +++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs @@ -4,7 +4,6 @@ use clippy_utils::is_doc_hidden; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_indent; use itertools::Itertools; -use rustc_ast::attr; use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -12,7 +11,9 @@ use rustc_hir::{Expr, ExprKind, Item, ItemKind, QPath, TyKind, VariantData}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::def_id::LocalDefId; -use rustc_span::{Span, sym}; +use rustc_span::Span; +use rustc_attr_data_structures::find_attr; +use rustc_attr_data_structures::AttributeKind; declare_clippy_lint! { /// ### What it does @@ -93,7 +94,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { .then_some((v.def_id, v.span)) }); if let Ok((id, span)) = iter.exactly_one() - && !attr::contains_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) + && !find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(..)) { self.potential_enums.push((item.owner_id.def_id, id, item.span, span)); } @@ -113,10 +114,10 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive { item.span, "this seems like a manual implementation of the non-exhaustive pattern", |diag| { - if let Some(non_exhaustive) = - attr::find_by_name(cx.tcx.hir_attrs(item.hir_id()), sym::non_exhaustive) + if let Some(non_exhaustive_span) = + find_attr!(cx.tcx.hir_attrs(item.hir_id()), AttributeKind::NonExhaustive(span) => *span) { - diag.span_note(non_exhaustive.span(), "the struct is already non-exhaustive"); + diag.span_note(non_exhaustive_span, "the struct is already non-exhaustive"); } else { let indent = snippet_indent(cx, item.span).unwrap_or_default(); diag.span_suggestion_verbose( diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index 8a0ff5323c98..4c7a589e185b 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -7,9 +7,10 @@ use rustc_middle::ty::{AdtDef, TyCtxt}; use rustc_session::Session; use rustc_span::{Span, Symbol}; use std::str::FromStr; - +use rustc_attr_data_structures::find_attr; use crate::source::SpanRangeExt; use crate::{sym, tokenize_with_text}; +use rustc_attr_data_structures::AttributeKind; /// Deprecation status of attributes known by Clippy. pub enum DeprecationStatus { @@ -165,13 +166,13 @@ pub fn is_doc_hidden(attrs: &[impl AttributeExt]) -> bool { pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool { adt.is_variant_list_non_exhaustive() - || tcx.has_attr(adt.did(), sym::non_exhaustive) + || find_attr!(tcx.get_all_attrs(adt.did()), AttributeKind::NonExhaustive(..)) || adt.variants().iter().any(|variant_def| { - variant_def.is_field_list_non_exhaustive() || tcx.has_attr(variant_def.def_id, sym::non_exhaustive) + variant_def.is_field_list_non_exhaustive() || find_attr!(tcx.get_all_attrs(variant_def.def_id), AttributeKind::NonExhaustive(..)) }) || adt .all_fields() - .any(|field_def| tcx.has_attr(field_def.did, sym::non_exhaustive)) + .any(|field_def| find_attr!(tcx.get_all_attrs(field_def.did), AttributeKind::NonExhaustive(..))) } /// Checks if the given span contains a `#[cfg(..)]` attribute diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index bdebe155aba0..32b0ddf87ba4 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -206,12 +206,6 @@ error: malformed `automatically_derived` attribute input LL | #[automatically_derived = 18] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[automatically_derived]` -error: malformed `non_exhaustive` attribute input - --> $DIR/malformed-attrs.rs:196:1 - | -LL | #[non_exhaustive = 1] - | ^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]` - error: malformed `thread_local` attribute input --> $DIR/malformed-attrs.rs:202:1 | @@ -552,6 +546,15 @@ LL | #[rustc_layout_scalar_valid_range_end] | expected this to be a list | help: must be of the form: `#[rustc_layout_scalar_valid_range_end(end)]` +error[E0565]: malformed `non_exhaustive` attribute input + --> $DIR/malformed-attrs.rs:196:1 + | +LL | #[non_exhaustive = 1] + | ^^^^^^^^^^^^^^^^^---^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[non_exhaustive]` + error: attribute should be applied to `const fn` --> $DIR/malformed-attrs.rs:34:1 | diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr index d9ceca2f29bd..eff478d04aee 100644 --- a/tests/ui/lint/unused/unused-attr-duplicate.stderr +++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr @@ -65,18 +65,6 @@ LL | #[should_panic] | ^^^^^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! -error: unused attribute - --> $DIR/unused-attr-duplicate.rs:66:1 - | -LL | #[non_exhaustive] - | ^^^^^^^^^^^^^^^^^ help: remove this attribute - | -note: attribute also specified here - --> $DIR/unused-attr-duplicate.rs:65:1 - | -LL | #[non_exhaustive] - | ^^^^^^^^^^^^^^^^^ - error: unused attribute --> $DIR/unused-attr-duplicate.rs:70:1 | @@ -190,6 +178,18 @@ LL | #[must_use] | ^^^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +error: unused attribute + --> $DIR/unused-attr-duplicate.rs:66:1 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/unused-attr-duplicate.rs:65:1 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ + error: unused attribute --> $DIR/unused-attr-duplicate.rs:74:1 | diff --git a/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr b/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr index 136cd763b05c..1ac017aa08b9 100644 --- a/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr +++ b/tests/ui/rfcs/rfc-2008-non-exhaustive/invalid-attribute.stderr @@ -1,8 +1,11 @@ -error: malformed `non_exhaustive` attribute input +error[E0565]: malformed `non_exhaustive` attribute input --> $DIR/invalid-attribute.rs:1:1 | LL | #[non_exhaustive(anything)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[non_exhaustive]` + | ^^^^^^^^^^^^^^^^----------^ + | | | + | | didn't expect any arguments here + | help: must be of the form: `#[non_exhaustive]` error[E0701]: attribute should be applied to a struct or enum --> $DIR/invalid-attribute.rs:5:1 @@ -27,4 +30,5 @@ LL | | } error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0701`. +Some errors have detailed explanations: E0565, E0701. +For more information about an error, try `rustc --explain E0565`. From 1620117f94914c62e09b47ce25fe3cd15c4e132c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Jul 2025 09:01:43 +0200 Subject: [PATCH 61/62] 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 5a4378e78f91..0130cf13a45f 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -837c5dd7de03aa97190593aef4e70d53e1bb574b +733b47ea4b1b86216f14ef56e49440c33933f230 From 72043e3181a4050f02cdb1d6e2574c54c1b47013 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Jul 2025 09:12:36 +0200 Subject: [PATCH 62/62] fmt --- src/tools/miri/src/shims/foreign_items.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index 1b66735ddb18..9ddba8c2b48d 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -615,7 +615,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { // This is a no-op shim that only exists to prevent making the allocator shims instantly stable. let [] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?; } - name if name == this.mangle_internal_symbol("__rust_alloc_error_handler_should_panic_v2") => { + name if name + == this.mangle_internal_symbol("__rust_alloc_error_handler_should_panic_v2") => + { // Gets the value of the `oom` option. let [] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?; let val = this.tcx.sess.opts.unstable_opts.oom.should_panic();