Skip to content

Commit a1df0fa

Browse files
committed
Auto merge of rust-lang#129057 - GuillaumeGomez:rollup-q2yyzru, r=GuillaumeGomez
Rollup of 7 pull requests Successful merges: - rust-lang#127857 (Allow to customize `// TODO:` comment for deprecated safe autofix) - rust-lang#128410 (Migrate `remap-path-prefix-dwarf` `run-make` test to rmake) - rust-lang#128828 (`-Znext-solver` caching) - rust-lang#128873 (Add windows-targets crate to std's sysroot) - rust-lang#129034 (Add `#[must_use]` attribute to `Coroutine` trait) - rust-lang#129049 (compiletest: Don't panic on unknown JSON-like output lines) - rust-lang#129050 (Emit a warning instead of an error if `--generate-link-to-definition` is used with other output formats than HTML) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 80eb5a8 + d3a37ef commit a1df0fa

File tree

43 files changed

+1220
-786
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1220
-786
lines changed

compiler/rustc_feature/src/builtin_attrs.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -643,8 +643,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
643643
through unstable paths"
644644
),
645645
rustc_attr!(
646-
rustc_deprecated_safe_2024, Normal, template!(Word), WarnFollowing,
647-
EncodeCrossCrate::Yes,
646+
rustc_deprecated_safe_2024, Normal, template!(List: r#"audit_that = "...""#),
647+
ErrorFollowing, EncodeCrossCrate::Yes,
648648
"rustc_deprecated_safe_2024 is supposed to be used in libstd only",
649649
),
650650

compiler/rustc_middle/src/arena.rs

-4
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ macro_rules! arena_types {
6161
[] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>,
6262
[] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>,
6363
[] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>,
64-
[] canonical_goal_evaluation:
65-
rustc_type_ir::solve::inspect::CanonicalGoalEvaluationStep<
66-
rustc_middle::ty::TyCtxt<'tcx>
67-
>,
6864
[] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>,
6965
[] type_op_subtype:
7066
rustc_middle::infer::canonical::Canonical<'tcx,

compiler/rustc_middle/src/ty/context.rs

-9
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
107107
self.mk_predefined_opaques_in_body(data)
108108
}
109109
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
110-
type CanonicalGoalEvaluationStepRef =
111-
&'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>;
112110
type CanonicalVars = CanonicalVarInfos<'tcx>;
113111
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
114112
self.mk_canonical_var_infos(infos)
@@ -277,13 +275,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
277275
self.debug_assert_args_compatible(def_id, args);
278276
}
279277

280-
fn intern_canonical_goal_evaluation_step(
281-
self,
282-
step: solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>,
283-
) -> &'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>> {
284-
self.arena.alloc(step)
285-
}
286-
287278
fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
288279
where
289280
I: Iterator<Item = T>,

compiler/rustc_mir_build/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ mir_build_call_to_deprecated_safe_fn_requires_unsafe =
3030
call to deprecated safe function `{$function}` is unsafe and requires unsafe block
3131
.note = consult the function's documentation for information on how to avoid undefined behavior
3232
.label = call to unsafe function
33-
.suggestion = you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code
33+
.suggestion = you can wrap the call in an `unsafe` block if you can guarantee {$guarantee}
3434
3535
mir_build_call_to_fn_with_requires_unsafe =
3636
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block

compiler/rustc_mir_build/src/check_unsafety.rs

+26-2
Original file line numberDiff line numberDiff line change
@@ -96,18 +96,42 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
9696
// from an edition before 2024.
9797
&UnsafeOpKind::CallToUnsafeFunction(Some(id))
9898
if !span.at_least_rust_2024()
99-
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
99+
&& let Some(attr) = self.tcx.get_attr(id, sym::rustc_deprecated_safe_2024) =>
100100
{
101+
let suggestion = attr
102+
.meta_item_list()
103+
.unwrap_or_default()
104+
.into_iter()
105+
.find(|item| item.has_name(sym::audit_that))
106+
.map(|item| {
107+
item.value_str().expect(
108+
"`#[rustc_deprecated_safe_2024(audit_that)]` must have a string value",
109+
)
110+
});
111+
101112
let sm = self.tcx.sess.source_map();
113+
let guarantee = suggestion
114+
.as_ref()
115+
.map(|suggestion| format!("that {}", suggestion))
116+
.unwrap_or_else(|| String::from("its unsafe preconditions"));
117+
let suggestion = suggestion
118+
.and_then(|suggestion| {
119+
sm.indentation_before(span).map(|indent| {
120+
format!("{}// TODO: Audit that {}.\n", indent, suggestion) // ignore-tidy-todo
121+
})
122+
})
123+
.unwrap_or_default();
124+
102125
self.tcx.emit_node_span_lint(
103126
DEPRECATED_SAFE_2024,
104127
self.hir_context,
105128
span,
106129
CallToDeprecatedSafeFnRequiresUnsafe {
107130
span,
108131
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
132+
guarantee,
109133
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
110-
indent: sm.indentation_before(span).unwrap_or_default(),
134+
start_of_line_suggestion: suggestion,
111135
start_of_line: sm.span_extend_to_line(span).shrink_to_lo(),
112136
left: span.shrink_to_lo(),
113137
right: span.shrink_to_hi(),

compiler/rustc_mir_build/src/errors.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,16 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe {
2828
#[label]
2929
pub(crate) span: Span,
3030
pub(crate) function: String,
31+
pub(crate) guarantee: String,
3132
#[subdiagnostic]
3233
pub(crate) sub: CallToDeprecatedSafeFnRequiresUnsafeSub,
3334
}
3435

3536
#[derive(Subdiagnostic)]
3637
#[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")]
3738
pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub {
38-
pub(crate) indent: String,
39-
#[suggestion_part(
40-
code = "{indent}// TODO: Audit that the environment access only happens in single-threaded code.\n" // ignore-tidy-todo
41-
)]
39+
pub(crate) start_of_line_suggestion: String,
40+
#[suggestion_part(code = "{start_of_line_suggestion}")]
4241
pub(crate) start_of_line: Span,
4342
#[suggestion_part(code = "unsafe {{ ")]
4443
pub(crate) left: Span,

compiler/rustc_next_trait_solver/src/solve/inspect/build.rs

+14-92
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
//! see the comment on [ProofTreeBuilder].
66
77
use std::marker::PhantomData;
8-
use std::mem;
98

109
use derive_where::derive_where;
1110
use rustc_type_ir::inherent::*;
12-
use rustc_type_ir::{self as ty, search_graph, Interner};
11+
use rustc_type_ir::{self as ty, Interner};
1312

1413
use crate::delegate::SolverDelegate;
1514
use crate::solve::eval_ctxt::canonical;
@@ -94,31 +93,10 @@ impl<I: Interner> WipGoalEvaluation<I> {
9493
}
9594
}
9695

97-
#[derive_where(PartialEq, Eq; I: Interner)]
98-
pub(in crate::solve) enum WipCanonicalGoalEvaluationKind<I: Interner> {
99-
Overflow,
100-
CycleInStack,
101-
ProvisionalCacheHit,
102-
Interned { final_revision: I::CanonicalGoalEvaluationStepRef },
103-
}
104-
105-
impl<I: Interner> std::fmt::Debug for WipCanonicalGoalEvaluationKind<I> {
106-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107-
match self {
108-
Self::Overflow => write!(f, "Overflow"),
109-
Self::CycleInStack => write!(f, "CycleInStack"),
110-
Self::ProvisionalCacheHit => write!(f, "ProvisionalCacheHit"),
111-
Self::Interned { final_revision: _ } => {
112-
f.debug_struct("Interned").finish_non_exhaustive()
113-
}
114-
}
115-
}
116-
}
117-
11896
#[derive_where(PartialEq, Eq, Debug; I: Interner)]
11997
struct WipCanonicalGoalEvaluation<I: Interner> {
12098
goal: CanonicalInput<I>,
121-
kind: Option<WipCanonicalGoalEvaluationKind<I>>,
99+
encountered_overflow: bool,
122100
/// Only used for uncached goals. After we finished evaluating
123101
/// the goal, this is interned and moved into `kind`.
124102
final_revision: Option<WipCanonicalGoalEvaluationStep<I>>,
@@ -127,25 +105,17 @@ struct WipCanonicalGoalEvaluation<I: Interner> {
127105

128106
impl<I: Interner> WipCanonicalGoalEvaluation<I> {
129107
fn finalize(self) -> inspect::CanonicalGoalEvaluation<I> {
130-
// We've already interned the final revision in
131-
// `fn finalize_canonical_goal_evaluation`.
132-
assert!(self.final_revision.is_none());
133-
let kind = match self.kind.unwrap() {
134-
WipCanonicalGoalEvaluationKind::Overflow => {
108+
inspect::CanonicalGoalEvaluation {
109+
goal: self.goal,
110+
kind: if self.encountered_overflow {
111+
assert!(self.final_revision.is_none());
135112
inspect::CanonicalGoalEvaluationKind::Overflow
136-
}
137-
WipCanonicalGoalEvaluationKind::CycleInStack => {
138-
inspect::CanonicalGoalEvaluationKind::CycleInStack
139-
}
140-
WipCanonicalGoalEvaluationKind::ProvisionalCacheHit => {
141-
inspect::CanonicalGoalEvaluationKind::ProvisionalCacheHit
142-
}
143-
WipCanonicalGoalEvaluationKind::Interned { final_revision } => {
113+
} else {
114+
let final_revision = self.final_revision.unwrap().finalize();
144115
inspect::CanonicalGoalEvaluationKind::Evaluation { final_revision }
145-
}
146-
};
147-
148-
inspect::CanonicalGoalEvaluation { goal: self.goal, kind, result: self.result.unwrap() }
116+
},
117+
result: self.result.unwrap(),
118+
}
149119
}
150120
}
151121

@@ -308,7 +278,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
308278
) -> ProofTreeBuilder<D> {
309279
self.nested(|| WipCanonicalGoalEvaluation {
310280
goal,
311-
kind: None,
281+
encountered_overflow: false,
312282
final_revision: None,
313283
result: None,
314284
})
@@ -329,11 +299,11 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
329299
}
330300
}
331301

332-
pub fn canonical_goal_evaluation_kind(&mut self, kind: WipCanonicalGoalEvaluationKind<I>) {
302+
pub fn canonical_goal_evaluation_overflow(&mut self) {
333303
if let Some(this) = self.as_mut() {
334304
match this {
335305
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {
336-
assert_eq!(canonical_goal_evaluation.kind.replace(kind), None);
306+
canonical_goal_evaluation.encountered_overflow = true;
337307
}
338308
_ => unreachable!(),
339309
};
@@ -547,51 +517,3 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
547517
}
548518
}
549519
}
550-
551-
impl<D, I> search_graph::ProofTreeBuilder<I> for ProofTreeBuilder<D>
552-
where
553-
D: SolverDelegate<Interner = I>,
554-
I: Interner,
555-
{
556-
fn try_apply_proof_tree(
557-
&mut self,
558-
proof_tree: Option<I::CanonicalGoalEvaluationStepRef>,
559-
) -> bool {
560-
if !self.is_noop() {
561-
if let Some(final_revision) = proof_tree {
562-
let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision };
563-
self.canonical_goal_evaluation_kind(kind);
564-
true
565-
} else {
566-
false
567-
}
568-
} else {
569-
true
570-
}
571-
}
572-
573-
fn on_provisional_cache_hit(&mut self) {
574-
self.canonical_goal_evaluation_kind(WipCanonicalGoalEvaluationKind::ProvisionalCacheHit);
575-
}
576-
577-
fn on_cycle_in_stack(&mut self) {
578-
self.canonical_goal_evaluation_kind(WipCanonicalGoalEvaluationKind::CycleInStack);
579-
}
580-
581-
fn finalize_canonical_goal_evaluation(
582-
&mut self,
583-
tcx: I,
584-
) -> Option<I::CanonicalGoalEvaluationStepRef> {
585-
self.as_mut().map(|this| match this {
586-
DebugSolver::CanonicalGoalEvaluation(evaluation) => {
587-
let final_revision = mem::take(&mut evaluation.final_revision).unwrap();
588-
let final_revision =
589-
tcx.intern_canonical_goal_evaluation_step(final_revision.finalize());
590-
let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision };
591-
assert_eq!(evaluation.kind.replace(kind), None);
592-
final_revision
593-
}
594-
_ => unreachable!(),
595-
})
596-
}
597-
}

compiler/rustc_next_trait_solver/src/solve/search_graph.rs

+44-22
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
use std::convert::Infallible;
12
use std::marker::PhantomData;
23

34
use rustc_type_ir::inherent::*;
4-
use rustc_type_ir::search_graph::{self, CycleKind, UsageKind};
5+
use rustc_type_ir::search_graph::{self, PathKind};
56
use rustc_type_ir::solve::{CanonicalInput, Certainty, QueryResult};
67
use rustc_type_ir::Interner;
78

8-
use super::inspect::{self, ProofTreeBuilder};
9-
use super::FIXPOINT_STEP_LIMIT;
9+
use super::inspect::ProofTreeBuilder;
10+
use super::{has_no_inference_or_external_constraints, FIXPOINT_STEP_LIMIT};
1011
use crate::delegate::SolverDelegate;
1112

1213
/// This type is never constructed. We only use it to implement `search_graph::Delegate`
@@ -22,43 +23,48 @@ where
2223
{
2324
type Cx = D::Interner;
2425

26+
const ENABLE_PROVISIONAL_CACHE: bool = true;
27+
type ValidationScope = Infallible;
28+
fn enter_validation_scope(
29+
_cx: Self::Cx,
30+
_input: CanonicalInput<I>,
31+
) -> Option<Self::ValidationScope> {
32+
None
33+
}
34+
2535
const FIXPOINT_STEP_LIMIT: usize = FIXPOINT_STEP_LIMIT;
2636

2737
type ProofTreeBuilder = ProofTreeBuilder<D>;
38+
fn inspect_is_noop(inspect: &mut Self::ProofTreeBuilder) -> bool {
39+
inspect.is_noop()
40+
}
2841

42+
const DIVIDE_AVAILABLE_DEPTH_ON_OVERFLOW: usize = 4;
2943
fn recursion_limit(cx: I) -> usize {
3044
cx.recursion_limit()
3145
}
3246

3347
fn initial_provisional_result(
3448
cx: I,
35-
kind: CycleKind,
49+
kind: PathKind,
3650
input: CanonicalInput<I>,
3751
) -> QueryResult<I> {
3852
match kind {
39-
CycleKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes),
40-
CycleKind::Inductive => response_no_constraints(cx, input, Certainty::overflow(false)),
53+
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes),
54+
PathKind::Inductive => response_no_constraints(cx, input, Certainty::overflow(false)),
4155
}
4256
}
4357

44-
fn reached_fixpoint(
45-
cx: I,
46-
kind: UsageKind,
58+
fn is_initial_provisional_result(
59+
cx: Self::Cx,
60+
kind: PathKind,
4761
input: CanonicalInput<I>,
48-
provisional_result: Option<QueryResult<I>>,
4962
result: QueryResult<I>,
5063
) -> bool {
51-
if let Some(r) = provisional_result {
52-
r == result
53-
} else {
54-
match kind {
55-
UsageKind::Single(CycleKind::Coinductive) => {
56-
response_no_constraints(cx, input, Certainty::Yes) == result
57-
}
58-
UsageKind::Single(CycleKind::Inductive) => {
59-
response_no_constraints(cx, input, Certainty::overflow(false)) == result
60-
}
61-
UsageKind::Mixed => false,
64+
match kind {
65+
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes) == result,
66+
PathKind::Inductive => {
67+
response_no_constraints(cx, input, Certainty::overflow(false)) == result
6268
}
6369
}
6470
}
@@ -68,14 +74,30 @@ where
6874
inspect: &mut ProofTreeBuilder<D>,
6975
input: CanonicalInput<I>,
7076
) -> QueryResult<I> {
71-
inspect.canonical_goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow);
77+
inspect.canonical_goal_evaluation_overflow();
7278
response_no_constraints(cx, input, Certainty::overflow(true))
7379
}
7480

7581
fn on_fixpoint_overflow(cx: I, input: CanonicalInput<I>) -> QueryResult<I> {
7682
response_no_constraints(cx, input, Certainty::overflow(false))
7783
}
7884

85+
fn is_ambiguous_result(result: QueryResult<I>) -> bool {
86+
result.is_ok_and(|response| {
87+
has_no_inference_or_external_constraints(response)
88+
&& matches!(response.value.certainty, Certainty::Maybe(_))
89+
})
90+
}
91+
92+
fn propagate_ambiguity(
93+
cx: I,
94+
for_input: CanonicalInput<I>,
95+
from_result: QueryResult<I>,
96+
) -> QueryResult<I> {
97+
let certainty = from_result.unwrap().value.certainty;
98+
response_no_constraints(cx, for_input, certainty)
99+
}
100+
79101
fn step_is_coinductive(cx: I, input: CanonicalInput<I>) -> bool {
80102
input.value.goal.predicate.is_coinductive(cx)
81103
}

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ symbols! {
472472
attr,
473473
attr_literals,
474474
attributes,
475+
audit_that,
475476
augmented_assignments,
476477
auto_traits,
477478
automatically_derived,

0 commit comments

Comments
 (0)