From fdefffecb2a1c2b89dfc2c5ad041c02144adda81 Mon Sep 17 00:00:00 2001 From: xtex Date: Sun, 30 Mar 2025 10:00:45 +0800 Subject: [PATCH 1/7] compiler: report error when trait object type param reference self Fixes #139082. Emits an error when `Self` is found in the projection bounds of a trait object. In type aliases, `Self` has no meaning, so `type A = &'static dyn B` where `trait B = Fn() -> Self` will expands to `type A = &'static Fn() -> Self` which is illegal, causing the region solver to bail out when hitting the uninferred Self. Bug: #139082 Signed-off-by: xtex --- compiler/rustc_hir_analysis/messages.ftl | 3 +++ compiler/rustc_hir_analysis/src/errors.rs | 8 ++++++++ .../src/hir_ty_lowering/dyn_compatibility.rs | 14 ++++++++++++++ .../trait-alias-self-projection.rs | 12 ++++++++++++ .../trait-alias-self-projection.stderr | 9 +++++++++ 5 files changed, 46 insertions(+) create mode 100644 tests/ui/dyn-compatibility/trait-alias-self-projection.rs create mode 100644 tests/ui/dyn-compatibility/trait-alias-self-projection.stderr diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 194f2cd04e468..2f7c3cb3c7d80 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -486,6 +486,9 @@ hir_analysis_self_in_impl_self = `Self` is not valid in the self type of an impl block .note = replace `Self` with a different type +hir_analysis_self_in_type_alias = `Self` is not allowed in type aliases + .label = `Self` is only available in impls, traits, and concrete type definitions + hir_analysis_self_ty_not_captured = `impl Trait` must mention the `Self` type of the trait in `use<...>` .label = `Self` type parameter is implicitly captured by this `impl Trait` .note = currently, all type parameters are required to be mentioned in the precise captures list diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index f2560f22874bc..e6090a128b1c8 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1707,3 +1707,11 @@ pub(crate) enum SupertraitItemShadowee { traits: DiagSymbolList, }, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_self_in_type_alias, code = E0411)] +pub(crate) struct SelfInTypeAlias { + #[primary_span] + #[label] + pub span: Span, +} diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index 27643e715e6b1..28b55fff4ac9d 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -16,6 +16,7 @@ use smallvec::{SmallVec, smallvec}; use tracing::{debug, instrument}; use super::HirTyLowerer; +use crate::errors::SelfInTypeAlias; use crate::hir_ty_lowering::{ GenericArgCountMismatch, GenericArgCountResult, PredicateFilter, RegionInferReason, }; @@ -113,6 +114,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // ``` let mut projection_bounds = FxIndexMap::default(); for (proj, proj_span) in elaborated_projection_bounds { + let proj = proj.map_bound(|mut b| { + if let Some(term_ty) = &b.term.as_type() { + let references_self = term_ty.walk().any(|arg| arg == dummy_self.into()); + if references_self { + // With trait alias and type alias combined, type resolver + // may not be able to catch all illegal `Self` usages (issue 139082) + let guar = tcx.dcx().emit_err(SelfInTypeAlias { span }); + b.term = replace_dummy_self_with_error(tcx, b.term, guar); + } + } + b + }); + let key = ( proj.skip_binder().projection_term.def_id, tcx.anonymize_bound_vars( diff --git a/tests/ui/dyn-compatibility/trait-alias-self-projection.rs b/tests/ui/dyn-compatibility/trait-alias-self-projection.rs new file mode 100644 index 0000000000000..0badb738809e9 --- /dev/null +++ b/tests/ui/dyn-compatibility/trait-alias-self-projection.rs @@ -0,0 +1,12 @@ +#![feature(trait_alias)] +trait B = Fn() -> Self; +type D = &'static dyn B; +//~^ ERROR E0411 + +fn a() -> D { + unreachable!(); +} + +fn main() { + _ = a(); +} diff --git a/tests/ui/dyn-compatibility/trait-alias-self-projection.stderr b/tests/ui/dyn-compatibility/trait-alias-self-projection.stderr new file mode 100644 index 0000000000000..dccee02e9cd18 --- /dev/null +++ b/tests/ui/dyn-compatibility/trait-alias-self-projection.stderr @@ -0,0 +1,9 @@ +error[E0411]: `Self` is not allowed in type aliases + --> $DIR/trait-alias-self-projection.rs:3:19 + | +LL | type D = &'static dyn B; + | ^^^^^ `Self` is only available in impls, traits, and concrete type definitions + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0411`. From f343b9d1fded2e9c33a1202b3c767bb2deb7eb4d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 4 Apr 2025 02:16:12 +0000 Subject: [PATCH 2/7] Don't construct preds w escaping bound vars in diagnostic_hir_wf_check --- .../rustc_hir_analysis/src/hir_wf_check.rs | 11 +++- .../diagnostic-hir-wf-check.rs | 18 +++++ .../diagnostic-hir-wf-check.stderr | 65 +++++++++++++++++++ 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs create mode 100644 tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index c01b81563dcf7..64c1a78bd1c8b 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -4,7 +4,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ObligationCause, WellFormedLoc}; use rustc_middle::bug; use rustc_middle::query::Providers; -use rustc_middle::ty::{self, TyCtxt, TypingMode, fold_regions}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode, fold_regions}; use rustc_span::def_id::LocalDefId; use rustc_trait_selection::traits::{self, ObligationCtxt}; use tracing::debug; @@ -77,6 +77,15 @@ fn diagnostic_hir_wf_check<'tcx>( let tcx_ty = fold_regions(self.tcx, tcx_ty, |r, _| { if r.is_bound() { self.tcx.lifetimes.re_erased } else { r } }); + + // We may be checking the WFness of a type in an opaque with a non-lifetime bound. + // Perhaps we could rebind all the escaping bound vars, but they're coming from + // arbitrary debruijn indices and aren't particularly important anyways, since they + // are only coming from `feature(non_lifetime_binders)` anyways. + if tcx_ty.has_escaping_bound_vars() { + return; + } + let cause = traits::ObligationCause::new( ty.span, self.def_id, diff --git a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs new file mode 100644 index 0000000000000..74c23a59bee9e --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.rs @@ -0,0 +1,18 @@ +// Make sure not to construct predicates with escaping bound vars in `diagnostic_hir_wf_check`. +// Regression test for . + +#![feature(non_lifetime_binders)] +//~^ WARN the feature `non_lifetime_binders` is incomplete + +trait A {} +impl A for () {} + +trait B {} +struct W(T); + +fn b() -> (W<()>, impl for A) { (W(()), ()) } +//~^ ERROR the trait bound `(): B` is not satisfied +//~| ERROR the trait bound `(): B` is not satisfied +//~| ERROR the trait bound `(): B` is not satisfied + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr new file mode 100644 index 0000000000000..df99f4a67abb2 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/diagnostic-hir-wf-check.stderr @@ -0,0 +1,65 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/diagnostic-hir-wf-check.rs:4:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0277]: the trait bound `(): B` is not satisfied + --> $DIR/diagnostic-hir-wf-check.rs:13:12 + | +LL | fn b() -> (W<()>, impl for A) { (W(()), ()) } + | ^^^^^ the trait `B` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/diagnostic-hir-wf-check.rs:10:1 + | +LL | trait B {} + | ^^^^^^^ +note: required by a bound in `W` + --> $DIR/diagnostic-hir-wf-check.rs:11:13 + | +LL | struct W(T); + | ^ required by this bound in `W` + +error[E0277]: the trait bound `(): B` is not satisfied + --> $DIR/diagnostic-hir-wf-check.rs:13:42 + | +LL | fn b() -> (W<()>, impl for A) { (W(()), ()) } + | - ^^ the trait `B` is not implemented for `()` + | | + | required by a bound introduced by this call + | +help: this trait has no implementations, consider adding one + --> $DIR/diagnostic-hir-wf-check.rs:10:1 + | +LL | trait B {} + | ^^^^^^^ +note: required by a bound in `W` + --> $DIR/diagnostic-hir-wf-check.rs:11:13 + | +LL | struct W(T); + | ^ required by this bound in `W` + +error[E0277]: the trait bound `(): B` is not satisfied + --> $DIR/diagnostic-hir-wf-check.rs:13:40 + | +LL | fn b() -> (W<()>, impl for A) { (W(()), ()) } + | ^^^^^ the trait `B` is not implemented for `()` + | +help: this trait has no implementations, consider adding one + --> $DIR/diagnostic-hir-wf-check.rs:10:1 + | +LL | trait B {} + | ^^^^^^^ +note: required by a bound in `W` + --> $DIR/diagnostic-hir-wf-check.rs:11:13 + | +LL | struct W(T); + | ^ required by this bound in `W` + +error: aborting due to 3 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. From 45afefa7c025f3847439822b053edf76ae62e561 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 5 Apr 2025 19:33:47 +0000 Subject: [PATCH 3/7] Fix trait upcasting to dyn type with no principal when there are projections --- .../src/traits/select/confirmation.rs | 38 ++++++++++++------- .../dyn-drop-principal-with-projections.rs | 13 +++++++ 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 tests/ui/traits/dyn-drop-principal-with-projections.rs diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 2cb7d2d893135..9d5eb551fe6f7 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1090,26 +1090,36 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { { // See `assemble_candidates_for_unsizing` for more info. // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`. - let iter = data_a - .principal() - .filter(|_| { - // optionally drop the principal, if we're unsizing to no principal - data_b.principal().is_some() - }) - .map(|b| b.map_bound(ty::ExistentialPredicate::Trait)) - .into_iter() - .chain( + let existential_predicates = if data_b.principal().is_some() { + tcx.mk_poly_existential_predicates_from_iter( data_a - .projection_bounds() - .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)), + .principal() + .map(|b| b.map_bound(ty::ExistentialPredicate::Trait)) + .into_iter() + .chain( + data_a + .projection_bounds() + .map(|b| b.map_bound(ty::ExistentialPredicate::Projection)), + ) + .chain( + data_b + .auto_traits() + .map(ty::ExistentialPredicate::AutoTrait) + .map(ty::Binder::dummy), + ), ) - .chain( + } else { + // If we're unsizing to a dyn type that has no principal, then drop + // the principal and projections from the type. We use the auto traits + // from the RHS type since as we noted that we've checked for auto + // trait compatibility during unsizing. + tcx.mk_poly_existential_predicates_from_iter( data_b .auto_traits() .map(ty::ExistentialPredicate::AutoTrait) .map(ty::Binder::dummy), - ); - let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter); + ) + }; let source_trait = Ty::new_dynamic(tcx, existential_predicates, r_b, dyn_a); // Require that the traits involved in this upcast are **equal**; diff --git a/tests/ui/traits/dyn-drop-principal-with-projections.rs b/tests/ui/traits/dyn-drop-principal-with-projections.rs new file mode 100644 index 0000000000000..912061847c69f --- /dev/null +++ b/tests/ui/traits/dyn-drop-principal-with-projections.rs @@ -0,0 +1,13 @@ +//@ check-pass + +trait Tr { + type Assoc; +} + +impl Tr for () { + type Assoc = (); +} + +fn main() { + let x = &() as &(dyn Tr + Send) as &dyn Send; +} From 253da2f22b8d67e764b72c15d2541c1ca2bc9b3d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 7 Apr 2025 05:37:25 +0000 Subject: [PATCH 4/7] Don't call Span.with_parent on the good path in has_stashed_diagnostic --- compiler/rustc_errors/src/lib.rs | 70 ++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index f5f7618285e1f..75bb0e8e7b43f 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -589,7 +589,8 @@ struct DiagCtxtInner { /// add more information). All stashed diagnostics must be emitted with /// `emit_stashed_diagnostics` by the time the `DiagCtxtInner` is dropped, /// otherwise an assertion failure will occur. - stashed_diagnostics: FxIndexMap<(Span, StashKey), (DiagInner, Option)>, + stashed_diagnostics: + FxIndexMap)>>, future_breakage_diagnostics: Vec, @@ -912,8 +913,12 @@ impl<'a> DiagCtxtHandle<'a> { // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic // if/when we have a more robust macro-friendly replacement for `(span, key)` as a key. // See the PR for a discussion. - let key = (span.with_parent(None), key); - self.inner.borrow_mut().stashed_diagnostics.insert(key, (diag, guar)); + self.inner + .borrow_mut() + .stashed_diagnostics + .entry(key) + .or_default() + .insert(span.with_parent(None), (diag, guar)); guar } @@ -922,9 +927,10 @@ impl<'a> DiagCtxtHandle<'a> { /// and [`StashKey`] as the key. Panics if the found diagnostic is an /// error. pub fn steal_non_err(self, span: Span, key: StashKey) -> Option> { - let key = (span.with_parent(None), key); // FIXME(#120456) - is `swap_remove` correct? - let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key)?; + let (diag, guar) = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then( + |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)), + )?; assert!(!diag.is_error()); assert!(guar.is_none()); Some(Diag::new_diagnostic(self, diag)) @@ -943,9 +949,10 @@ impl<'a> DiagCtxtHandle<'a> { where F: FnMut(&mut Diag<'_>), { - let key = (span.with_parent(None), key); // FIXME(#120456) - is `swap_remove` correct? - let err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key); + let err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then( + |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)), + ); err.map(|(err, guar)| { // The use of `::` is safe because level is `Level::Error`. assert_eq!(err.level, Error); @@ -966,9 +973,10 @@ impl<'a> DiagCtxtHandle<'a> { key: StashKey, new_err: Diag<'_>, ) -> ErrorGuaranteed { - let key = (span.with_parent(None), key); // FIXME(#120456) - is `swap_remove` correct? - let old_err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key); + let old_err = self.inner.borrow_mut().stashed_diagnostics.get_mut(&key).and_then( + |stashed_diagnostics| stashed_diagnostics.swap_remove(&span.with_parent(None)), + ); match old_err { Some((old_err, guar)) => { assert_eq!(old_err.level, Error); @@ -983,7 +991,14 @@ impl<'a> DiagCtxtHandle<'a> { } pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool { - self.inner.borrow().stashed_diagnostics.get(&(span.with_parent(None), key)).is_some() + let inner = self.inner.borrow(); + if let Some(stashed_diagnostics) = inner.stashed_diagnostics.get(&key) + && !stashed_diagnostics.is_empty() + { + stashed_diagnostics.contains_key(&span.with_parent(None)) + } else { + false + } } /// Emit all stashed diagnostics. @@ -997,7 +1012,11 @@ impl<'a> DiagCtxtHandle<'a> { let inner = self.inner.borrow(); inner.err_guars.len() + inner.lint_err_guars.len() - + inner.stashed_diagnostics.values().filter(|(_diag, guar)| guar.is_some()).count() + + inner + .stashed_diagnostics + .values() + .map(|a| a.values().filter(|(_, guar)| guar.is_some()).count()) + .sum::() } /// This excludes lint errors and delayed bugs. Unless absolutely @@ -1486,16 +1505,18 @@ impl DiagCtxtInner { fn emit_stashed_diagnostics(&mut self) -> Option { let mut guar = None; let has_errors = !self.err_guars.is_empty(); - for (_, (diag, _guar)) in std::mem::take(&mut self.stashed_diagnostics).into_iter() { - if !diag.is_error() { - // Unless they're forced, don't flush stashed warnings when - // there are errors, to avoid causing warning overload. The - // stash would've been stolen already if it were important. - if !diag.is_force_warn() && has_errors { - continue; + for (_, stashed_diagnostics) in std::mem::take(&mut self.stashed_diagnostics).into_iter() { + for (_, (diag, _guar)) in stashed_diagnostics { + if !diag.is_error() { + // Unless they're forced, don't flush stashed warnings when + // there are errors, to avoid causing warning overload. The + // stash would've been stolen already if it were important. + if !diag.is_force_warn() && has_errors { + continue; + } } + guar = guar.or(self.emit_diagnostic(diag, None)); } - guar = guar.or(self.emit_diagnostic(diag, None)); } guar } @@ -1688,6 +1709,7 @@ impl DiagCtxtInner { if let Some((_diag, guar)) = self .stashed_diagnostics .values() + .flat_map(|stashed_diagnostics| stashed_diagnostics.values()) .find(|(diag, guar)| guar.is_some() && diag.is_lint.is_none()) { *guar @@ -1700,13 +1722,9 @@ impl DiagCtxtInner { fn has_errors(&self) -> Option { self.err_guars.get(0).copied().or_else(|| self.lint_err_guars.get(0).copied()).or_else( || { - if let Some((_diag, guar)) = - self.stashed_diagnostics.values().find(|(_diag, guar)| guar.is_some()) - { - *guar - } else { - None - } + self.stashed_diagnostics.values().find_map(|stashed_diagnostics| { + stashed_diagnostics.values().find_map(|(_, guar)| *guar) + }) }, ) } From 1862b311f67dce3d503a5d09dca249cace03967e Mon Sep 17 00:00:00 2001 From: lcnr Date: Mon, 7 Apr 2025 12:18:56 +0200 Subject: [PATCH 5/7] rm `RegionInferenceContext::var_infos` we already track this info in the `definitions` field --- .../src/diagnostics/bound_region_errors.rs | 4 ++-- compiler/rustc_borrowck/src/diagnostics/mod.rs | 9 +++------ compiler/rustc_borrowck/src/polonius/dump.rs | 4 ++-- compiler/rustc_borrowck/src/region_infer/mod.rs | 5 +---- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index aa968a1e40f3e..e12441182186b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -406,8 +406,8 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> { // started MIR borrowchecking with, so the region // constraints have already been taken. Use the data from // our `mbcx` instead. - |vid| mbcx.regioncx.var_infos[vid].origin, - |vid| mbcx.regioncx.var_infos[vid].universe, + |vid| RegionVariableOrigin::Nll(mbcx.regioncx.definitions[vid].origin), + |vid| mbcx.regioncx.definitions[vid].universe, ) } } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 899e145c2c049..07555956f994c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -8,9 +8,7 @@ use rustc_errors::{Applicability, Diag, EmissionGuarantee, MultiSpan, listify}; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::{self as hir, CoroutineKind, LangItem}; use rustc_index::IndexSlice; -use rustc_infer::infer::{ - BoundRegionConversionTime, NllRegionVariableOrigin, RegionVariableOrigin, -}; +use rustc_infer::infer::{BoundRegionConversionTime, NllRegionVariableOrigin}; use rustc_infer::traits::SelectionError; use rustc_middle::bug; use rustc_middle::mir::{ @@ -633,9 +631,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { ) { let predicate_span = path.iter().find_map(|constraint| { let outlived = constraint.sub; - if let Some(origin) = self.regioncx.var_infos.get(outlived) - && let RegionVariableOrigin::Nll(NllRegionVariableOrigin::Placeholder(_)) = - origin.origin + if let Some(origin) = self.regioncx.definitions.get(outlived) + && let NllRegionVariableOrigin::Placeholder(_) = origin.origin && let ConstraintCategory::Predicate(span) = constraint.category { Some(span) diff --git a/compiler/rustc_borrowck/src/polonius/dump.rs b/compiler/rustc_borrowck/src/polonius/dump.rs index aa64a7c4e2a68..6f3b599d26f1b 100644 --- a/compiler/rustc_borrowck/src/polonius/dump.rs +++ b/compiler/rustc_borrowck/src/polonius/dump.rs @@ -334,7 +334,7 @@ fn emit_mermaid_nll_regions<'tcx>( writeln!(out, "flowchart TD")?; // Emit the region nodes. - for region in regioncx.var_infos.indices() { + for region in regioncx.definitions.indices() { write!(out, "{}[\"", region.as_usize())?; render_region(region, regioncx, out)?; writeln!(out, "\"]")?; @@ -387,7 +387,7 @@ fn emit_mermaid_nll_sccs<'tcx>( // Gather and emit the SCC nodes. let mut nodes_per_scc: IndexVec<_, _> = regioncx.constraint_sccs().all_sccs().map(|_| Vec::new()).collect(); - for region in regioncx.var_infos.indices() { + for region in regioncx.definitions.indices() { let scc = regioncx.constraint_sccs().scc(region); nodes_per_scc[scc].push(region); } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index a80d74d9e370a..3ec93e0587ef8 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -139,13 +139,11 @@ impl RegionTracker { } pub struct RegionInferenceContext<'tcx> { - pub var_infos: VarInfos, - /// Contains the definition for every region variable. Region /// variables are identified by their index (`RegionVid`). The /// definition contains information about where the region came /// from as well as its final inferred value. - definitions: IndexVec>, + pub(crate) definitions: IndexVec>, /// The liveness constraints added to each region. For most /// regions, these start out empty and steadily grow, though for @@ -449,7 +447,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { Rc::new(member_constraints.into_mapped(|r| constraint_sccs.scc(r))); let mut result = Self { - var_infos, definitions, liveness_constraints, constraints, From e1a69da856c31bfaad602388f69ea86f111ebfe6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 7 Apr 2025 18:16:07 +0200 Subject: [PATCH 6/7] unstable-book/intrinsics: wordsmith MIR-lowering intrinsic docs --- src/doc/unstable-book/src/language-features/intrinsics.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/language-features/intrinsics.md b/src/doc/unstable-book/src/language-features/intrinsics.md index a0e38f340f581..9e59dd889985c 100644 --- a/src/doc/unstable-book/src/language-features/intrinsics.md +++ b/src/doc/unstable-book/src/language-features/intrinsics.md @@ -53,7 +53,8 @@ Various intrinsics have native MIR operations that they correspond to. Instead o backends to implement both the intrinsic and the MIR operation, the `lower_intrinsics` pass will convert the calls to the MIR operation. Backends do not need to know about these intrinsics at all. These intrinsics only make sense without a body, and can be declared as a `#[rustc_intrinsic]`. -The body is never used, as calls to the intrinsic do not exist anymore after MIR analyses. +The body is never used as the lowering pass implements support for all backends, so we never have to +use the fallback logic. ## Intrinsics without fallback logic From a7400a8b9065b3563d7345c220590282d768be65 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 7 Apr 2025 19:06:34 +0200 Subject: [PATCH 7/7] update intrinsics/mod.rs comment about const intrinsics --- library/core/src/intrinsics/mod.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 7fa57df9928c3..933b5aec70c63 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -5,15 +5,11 @@ //! //! # Const intrinsics //! -//! Note: any changes to the constness of intrinsics should be discussed with the language team. -//! This includes changes in the stability of the constness. -//! -//! //FIXME(#132735) "old" style intrinsics support has been removed -//! In order to make an intrinsic usable at compile-time, it needs to be declared in the "new" -//! style, i.e. as a `#[rustc_intrinsic]` function, not inside an `extern` block. Then copy the -//! implementation from to +//! In order to make an intrinsic unstable usable at compile-time, copy the implementation from +//! to //! -//! and make the intrinsic declaration a `const fn`. +//! and make the intrinsic declaration below a `const fn`. This should be done in coordination with +//! wg-const-eval. //! //! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute, //! `#[rustc_intrinsic_const_stable_indirect]` needs to be added to the intrinsic. Such a change requires