Skip to content

Commit bf1b174

Browse files
committed
Auto merge of #136203 - matthiaskrgr:rollup-1k0f44l, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #135869 (Make docs for AtomicUsize::from_mut platform-independent) - #135892 (-Znext-solver: "normalize" signature before checking it mentions self in `deduce_closure_signature`) - #136055 (Implement MIR const trait stability checks) - #136066 (Pass spans to `perform_locally_in_new_solver`) - #136071 ([Clippy] Add vec_reserve & vecdeque_reserve diagnostic items) - #136124 (Arbitrary self types v2: explain test.) - #136149 (Flip the `rustc-rayon`/`indexmap` dependency order) - #136173 (Update comments and sort target_arch in c_char_definition) - #136178 (Update username in build helper example) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 77a4553 + 9715fea commit bf1b174

37 files changed

+561
-167
lines changed

Cargo.lock

+3-3
Original file line numberDiff line numberDiff line change
@@ -1859,7 +1859,6 @@ checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f"
18591859
dependencies = [
18601860
"equivalent",
18611861
"hashbrown 0.15.2",
1862-
"rustc-rayon",
18631862
"serde",
18641863
]
18651864

@@ -3240,11 +3239,12 @@ dependencies = [
32403239

32413240
[[package]]
32423241
name = "rustc-rayon"
3243-
version = "0.5.0"
3242+
version = "0.5.1"
32443243
source = "registry+https://github.com/rust-lang/crates.io-index"
3245-
checksum = "eb81aadc8837ca6ecebe0fe1353f15df83b3b3cc2cf7a8afd571bc22aa121710"
3244+
checksum = "2cd9fb077db982d7ceb42a90471e5a69a990b58f71e06f0d8340bb2cf35eb751"
32463245
dependencies = [
32473246
"either",
3247+
"indexmap",
32483248
"rustc-rayon-core",
32493249
]
32503250

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ impl<'tcx> TypeOpInfo<'tcx> for AscribeUserTypeQuery<'tcx> {
310310
let (infcx, key, _) =
311311
mbcx.infcx.tcx.infer_ctxt().build_with_canonical(cause.span, &self.canonical_query);
312312
let ocx = ObligationCtxt::new(&infcx);
313-
type_op_ascribe_user_type_with_span(&ocx, key, Some(cause.span)).ok()?;
313+
type_op_ascribe_user_type_with_span(&ocx, key, cause.span).ok()?;
314314
let diag = try_extract_error_from_fulfill_cx(
315315
&ocx,
316316
mbcx.mir_def_id(),

compiler/rustc_const_eval/messages.ftl

+2-1
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ const_eval_uninhabited_enum_variant_read =
403403
const_eval_uninhabited_enum_variant_written =
404404
writing discriminant of an uninhabited enum variant
405405
406-
const_eval_unmarked_const_fn_exposed = `{$def_path}` cannot be (indirectly) exposed to stable
406+
const_eval_unmarked_const_item_exposed = `{$def_path}` cannot be (indirectly) exposed to stable
407407
.help = either mark the callee as `#[rustc_const_stable_indirect]`, or the caller as `#[rustc_const_unstable]`
408408
const_eval_unmarked_intrinsic_exposed = intrinsic `{$def_path}` cannot be (indirectly) exposed to stable
409409
.help = mark the caller as `#[rustc_const_unstable]`, or mark the intrinsic `#[rustc_intrinsic_const_stable_indirect]` (but this requires team approval)
@@ -414,6 +414,7 @@ const_eval_unreachable_unwind =
414414
415415
const_eval_unsized_local = unsized locals are not supported
416416
const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn
417+
const_eval_unstable_const_trait = `{$def_path}` is not yet stable as a const trait
417418
const_eval_unstable_in_stable_exposed =
418419
const function that might be (indirectly) exposed to stable cannot use `#[feature({$gate})]`
419420
.is_function_call = mark the callee as `#[rustc_const_stable_indirect]` if it does not itself require any unstable features

compiler/rustc_const_eval/src/check_consts/check.rs

+87-81
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::ops::Deref;
88

99
use rustc_attr_parsing::{ConstStability, StabilityLevel};
1010
use rustc_errors::{Diag, ErrorGuaranteed};
11+
use rustc_hir::def::DefKind;
1112
use rustc_hir::def_id::DefId;
1213
use rustc_hir::{self as hir, LangItem};
1314
use rustc_index::bit_set::DenseBitSet;
@@ -29,7 +30,7 @@ use super::ops::{self, NonConstOp, Status};
2930
use super::qualifs::{self, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
3031
use super::resolver::FlowSensitiveAnalysis;
3132
use super::{ConstCx, Qualif};
32-
use crate::check_consts::is_safe_to_expose_on_stable_const_fn;
33+
use crate::check_consts::is_fn_or_trait_safe_to_expose_on_stable;
3334
use crate::errors;
3435

3536
type QualifResults<'mir, 'tcx, Q> =
@@ -470,6 +471,88 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
470471
self.tcx.crate_level_attribute_injection_span(self.tcx.local_def_id_to_hir_id(id))
471472
})
472473
}
474+
475+
/// Check the const stability of the given item (fn or trait).
476+
fn check_callee_stability(&mut self, def_id: DefId) {
477+
match self.tcx.lookup_const_stability(def_id) {
478+
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
479+
// All good.
480+
}
481+
None => {
482+
// This doesn't need a separate const-stability check -- const-stability equals
483+
// regular stability, and regular stability is checked separately.
484+
// However, we *do* have to worry about *recursive* const stability.
485+
if self.enforce_recursive_const_stability()
486+
&& !is_fn_or_trait_safe_to_expose_on_stable(self.tcx, def_id)
487+
{
488+
self.dcx().emit_err(errors::UnmarkedConstItemExposed {
489+
span: self.span,
490+
def_path: self.tcx.def_path_str(def_id),
491+
});
492+
}
493+
}
494+
Some(ConstStability {
495+
level: StabilityLevel::Unstable { implied_by: implied_feature, issue, .. },
496+
feature,
497+
..
498+
}) => {
499+
// An unstable const fn/trait with a feature gate.
500+
let callee_safe_to_expose_on_stable =
501+
is_fn_or_trait_safe_to_expose_on_stable(self.tcx, def_id);
502+
503+
// We only honor `span.allows_unstable` aka `#[allow_internal_unstable]` if
504+
// the callee is safe to expose, to avoid bypassing recursive stability.
505+
// This is not ideal since it means the user sees an error, not the macro
506+
// author, but that's also the case if one forgets to set
507+
// `#[allow_internal_unstable]` in the first place. Note that this cannot be
508+
// integrated in the check below since we want to enforce
509+
// `callee_safe_to_expose_on_stable` even if
510+
// `!self.enforce_recursive_const_stability()`.
511+
if (self.span.allows_unstable(feature)
512+
|| implied_feature.is_some_and(|f| self.span.allows_unstable(f)))
513+
&& callee_safe_to_expose_on_stable
514+
{
515+
return;
516+
}
517+
518+
// We can't use `check_op` to check whether the feature is enabled because
519+
// the logic is a bit different than elsewhere: local functions don't need
520+
// the feature gate, and there might be an "implied" gate that also suffices
521+
// to allow this.
522+
let feature_enabled = def_id.is_local()
523+
|| self.tcx.features().enabled(feature)
524+
|| implied_feature.is_some_and(|f| self.tcx.features().enabled(f))
525+
|| {
526+
// When we're compiling the compiler itself we may pull in
527+
// crates from crates.io, but those crates may depend on other
528+
// crates also pulled in from crates.io. We want to ideally be
529+
// able to compile everything without requiring upstream
530+
// modifications, so in the case that this looks like a
531+
// `rustc_private` crate (e.g., a compiler crate) and we also have
532+
// the `-Z force-unstable-if-unmarked` flag present (we're
533+
// compiling a compiler crate), then let this missing feature
534+
// annotation slide.
535+
// This matches what we do in `eval_stability_allow_unstable` for
536+
// regular stability.
537+
feature == sym::rustc_private
538+
&& issue == NonZero::new(27812)
539+
&& self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
540+
};
541+
// Even if the feature is enabled, we still need check_op to double-check
542+
// this if the callee is not safe to expose on stable.
543+
if !feature_enabled || !callee_safe_to_expose_on_stable {
544+
self.check_op(ops::CallUnstable {
545+
def_id,
546+
feature,
547+
feature_enabled,
548+
safe_to_expose_on_stable: callee_safe_to_expose_on_stable,
549+
suggestion_span: self.crate_inject_span(),
550+
is_function_call: self.tcx.def_kind(def_id) != DefKind::Trait,
551+
});
552+
}
553+
}
554+
}
555+
}
473556
}
474557

475558
impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
@@ -733,8 +816,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
733816
span: *fn_span,
734817
call_source,
735818
});
736-
// FIXME(const_trait_impl): do a more fine-grained check whether this
737-
// particular trait can be const-stably called.
819+
self.check_callee_stability(trait_did);
738820
} else {
739821
// Not even a const trait.
740822
self.check_op(ops::FnCallNonConst {
@@ -810,7 +892,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
810892
// fallback body is safe to expose on stable.
811893
let is_const_stable = intrinsic.const_stable
812894
|| (!intrinsic.must_be_overridden
813-
&& is_safe_to_expose_on_stable_const_fn(tcx, callee));
895+
&& is_fn_or_trait_safe_to_expose_on_stable(tcx, callee));
814896
match tcx.lookup_const_stability(callee) {
815897
None => {
816898
// This doesn't need a separate const-stability check -- const-stability equals
@@ -859,83 +941,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
859941
}
860942

861943
// Finally, stability for regular function calls -- this is the big one.
862-
match tcx.lookup_const_stability(callee) {
863-
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }) => {
864-
// All good.
865-
}
866-
None => {
867-
// This doesn't need a separate const-stability check -- const-stability equals
868-
// regular stability, and regular stability is checked separately.
869-
// However, we *do* have to worry about *recursive* const stability.
870-
if self.enforce_recursive_const_stability()
871-
&& !is_safe_to_expose_on_stable_const_fn(tcx, callee)
872-
{
873-
self.dcx().emit_err(errors::UnmarkedConstFnExposed {
874-
span: self.span,
875-
def_path: self.tcx.def_path_str(callee),
876-
});
877-
}
878-
}
879-
Some(ConstStability {
880-
level: StabilityLevel::Unstable { implied_by: implied_feature, issue, .. },
881-
feature,
882-
..
883-
}) => {
884-
// An unstable const fn with a feature gate.
885-
let callee_safe_to_expose_on_stable =
886-
is_safe_to_expose_on_stable_const_fn(tcx, callee);
887-
888-
// We only honor `span.allows_unstable` aka `#[allow_internal_unstable]` if
889-
// the callee is safe to expose, to avoid bypassing recursive stability.
890-
// This is not ideal since it means the user sees an error, not the macro
891-
// author, but that's also the case if one forgets to set
892-
// `#[allow_internal_unstable]` in the first place. Note that this cannot be
893-
// integrated in the check below since we want to enforce
894-
// `callee_safe_to_expose_on_stable` even if
895-
// `!self.enforce_recursive_const_stability()`.
896-
if (self.span.allows_unstable(feature)
897-
|| implied_feature.is_some_and(|f| self.span.allows_unstable(f)))
898-
&& callee_safe_to_expose_on_stable
899-
{
900-
return;
901-
}
902-
903-
// We can't use `check_op` to check whether the feature is enabled because
904-
// the logic is a bit different than elsewhere: local functions don't need
905-
// the feature gate, and there might be an "implied" gate that also suffices
906-
// to allow this.
907-
let feature_enabled = callee.is_local()
908-
|| tcx.features().enabled(feature)
909-
|| implied_feature.is_some_and(|f| tcx.features().enabled(f))
910-
|| {
911-
// When we're compiling the compiler itself we may pull in
912-
// crates from crates.io, but those crates may depend on other
913-
// crates also pulled in from crates.io. We want to ideally be
914-
// able to compile everything without requiring upstream
915-
// modifications, so in the case that this looks like a
916-
// `rustc_private` crate (e.g., a compiler crate) and we also have
917-
// the `-Z force-unstable-if-unmarked` flag present (we're
918-
// compiling a compiler crate), then let this missing feature
919-
// annotation slide.
920-
// This matches what we do in `eval_stability_allow_unstable` for
921-
// regular stability.
922-
feature == sym::rustc_private
923-
&& issue == NonZero::new(27812)
924-
&& tcx.sess.opts.unstable_opts.force_unstable_if_unmarked
925-
};
926-
// Even if the feature is enabled, we still need check_op to double-check
927-
// this if the callee is not safe to expose on stable.
928-
if !feature_enabled || !callee_safe_to_expose_on_stable {
929-
self.check_op(ops::FnCallUnstable {
930-
def_id: callee,
931-
feature,
932-
feature_enabled,
933-
safe_to_expose_on_stable: callee_safe_to_expose_on_stable,
934-
suggestion_span: self.crate_inject_span(),
935-
});
936-
}
937-
}
938-
}
944+
self.check_callee_stability(callee);
939945
}
940946

941947
// Forbid all `Drop` terminators unless the place being dropped is a local with no

compiler/rustc_const_eval/src/check_consts/mod.rs

+3-17
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
5656
self.const_kind == Some(hir::ConstContext::ConstFn)
5757
&& (self.tcx.features().staged_api()
5858
|| self.tcx.sess.opts.unstable_opts.force_unstable_if_unmarked)
59-
&& is_safe_to_expose_on_stable_const_fn(self.tcx, self.def_id().to_def_id())
59+
&& is_fn_or_trait_safe_to_expose_on_stable(self.tcx, self.def_id().to_def_id())
6060
}
6161

6262
fn is_async(&self) -> bool {
@@ -84,28 +84,14 @@ pub fn rustc_allow_const_fn_unstable(
8484
attr::rustc_allow_const_fn_unstable(tcx.sess, attrs).any(|name| name == feature_gate)
8585
}
8686

87-
/// Returns `true` if the given `const fn` is "safe to expose on stable".
88-
///
89-
/// Panics if the given `DefId` does not refer to a `const fn`.
87+
/// Returns `true` if the given `def_id` (trait or function) is "safe to expose on stable".
9088
///
9189
/// This is relevant within a `staged_api` crate. Unlike with normal features, the use of unstable
9290
/// const features *recursively* taints the functions that use them. This is to avoid accidentally
9391
/// exposing e.g. the implementation of an unstable const intrinsic on stable. So we partition the
9492
/// world into two functions: those that are safe to expose on stable (and hence may not use
9593
/// unstable features, not even recursively), and those that are not.
96-
pub fn is_safe_to_expose_on_stable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
97-
// A default body in a `#[const_trait]` is not const-stable because const trait fns currently
98-
// cannot be const-stable. These functions can't be called from anything stable, so we shouldn't
99-
// restrict them to only call const-stable functions.
100-
if tcx.is_const_default_method(def_id) {
101-
// FIXME(const_trait_impl): we have to eventually allow some of these if these things can ever be stable.
102-
// They should probably behave like regular `const fn` for that...
103-
return false;
104-
}
105-
106-
// Const-stability is only relevant for `const fn`.
107-
assert!(tcx.is_const_fn(def_id));
108-
94+
pub fn is_fn_or_trait_safe_to_expose_on_stable(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
10995
match tcx.lookup_const_stability(def_id) {
11096
None => {
11197
// In a `staged_api` crate, we do enforce recursive const stability for all unmarked

compiler/rustc_const_eval/src/check_consts/ops.rs

+18-9
Original file line numberDiff line numberDiff line change
@@ -377,36 +377,45 @@ fn build_error_for_const_call<'tcx>(
377377
err
378378
}
379379

380-
/// A call to an `#[unstable]` const fn or `#[rustc_const_unstable]` function.
380+
/// A call to an `#[unstable]` const fn, `#[rustc_const_unstable]` function or trait.
381381
///
382-
/// Contains the name of the feature that would allow the use of this function.
382+
/// Contains the name of the feature that would allow the use of this function/trait.
383383
#[derive(Debug)]
384-
pub(crate) struct FnCallUnstable {
384+
pub(crate) struct CallUnstable {
385385
pub def_id: DefId,
386386
pub feature: Symbol,
387387
/// If this is true, then the feature is enabled, but we need to still check if it is safe to
388388
/// expose on stable.
389389
pub feature_enabled: bool,
390390
pub safe_to_expose_on_stable: bool,
391391
pub suggestion_span: Option<Span>,
392+
/// true if `def_id` is the function we are calling, false if `def_id` is an unstable trait.
393+
pub is_function_call: bool,
392394
}
393395

394-
impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
396+
impl<'tcx> NonConstOp<'tcx> for CallUnstable {
395397
fn status_in_item(&self, _ccx: &ConstCx<'_, 'tcx>) -> Status {
396398
Status::Unstable {
397399
gate: self.feature,
398400
gate_already_checked: self.feature_enabled,
399401
safe_to_expose_on_stable: self.safe_to_expose_on_stable,
400-
is_function_call: true,
402+
is_function_call: self.is_function_call,
401403
}
402404
}
403405

404406
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
405407
assert!(!self.feature_enabled);
406-
let mut err = ccx.dcx().create_err(errors::UnstableConstFn {
407-
span,
408-
def_path: ccx.tcx.def_path_str(self.def_id),
409-
});
408+
let mut err = if self.is_function_call {
409+
ccx.dcx().create_err(errors::UnstableConstFn {
410+
span,
411+
def_path: ccx.tcx.def_path_str(self.def_id),
412+
})
413+
} else {
414+
ccx.dcx().create_err(errors::UnstableConstTrait {
415+
span,
416+
def_path: ccx.tcx.def_path_str(self.def_id),
417+
})
418+
};
410419
// FIXME: make this translatable
411420
let msg = format!("add `#![feature({})]` to the crate attributes to enable", self.feature);
412421
#[allow(rustc::untranslatable_diagnostic)]

compiler/rustc_const_eval/src/errors.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ pub(crate) struct UnstableConstFn {
121121
pub def_path: String,
122122
}
123123

124+
#[derive(Diagnostic)]
125+
#[diag(const_eval_unstable_const_trait)]
126+
pub(crate) struct UnstableConstTrait {
127+
#[primary_span]
128+
pub span: Span,
129+
pub def_path: String,
130+
}
131+
124132
#[derive(Diagnostic)]
125133
#[diag(const_eval_unstable_intrinsic)]
126134
pub(crate) struct UnstableIntrinsic {
@@ -139,9 +147,9 @@ pub(crate) struct UnstableIntrinsic {
139147
}
140148

141149
#[derive(Diagnostic)]
142-
#[diag(const_eval_unmarked_const_fn_exposed)]
150+
#[diag(const_eval_unmarked_const_item_exposed)]
143151
#[help]
144-
pub(crate) struct UnmarkedConstFnExposed {
152+
pub(crate) struct UnmarkedConstItemExposed {
145153
#[primary_span]
146154
pub span: Span,
147155
pub def_path: String,

compiler/rustc_data_structures/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ bitflags = "2.4.1"
1010
either = "1.0"
1111
elsa = "=1.7.1"
1212
ena = "0.14.3"
13-
indexmap = { version = "2.4.0", features = ["rustc-rayon"] }
13+
indexmap = "2.4.0"
1414
jobserver_crate = { version = "0.1.28", package = "jobserver" }
1515
measureme = "11"
1616
rustc-hash = "2.0.0"
17-
rustc-rayon = "0.5.0"
17+
rustc-rayon = { version = "0.5.1", features = ["indexmap"] }
1818
rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
1919
rustc_arena = { path = "../rustc_arena" }
2020
rustc_graphviz = { path = "../rustc_graphviz" }

0 commit comments

Comments
 (0)