Skip to content

Commit

Permalink
Auto merge of #129057 - GuillaumeGomez:rollup-q2yyzru, r=GuillaumeGomez
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #127857 (Allow to customize `// TODO:` comment for deprecated safe autofix)
 - #128410 (Migrate `remap-path-prefix-dwarf` `run-make` test to rmake)
 - #128828 (`-Znext-solver` caching)
 - #128873 (Add windows-targets crate to std's sysroot)
 - #129034 (Add `#[must_use]` attribute to `Coroutine` trait)
 - #129049 (compiletest: Don't panic on unknown JSON-like output lines)
 - #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
  • Loading branch information
bors committed Aug 13, 2024
2 parents 80eb5a8 + d3a37ef commit a1df0fa
Show file tree
Hide file tree
Showing 43 changed files with 1,220 additions and 786 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,8 +643,8 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
through unstable paths"
),
rustc_attr!(
rustc_deprecated_safe_2024, Normal, template!(Word), WarnFollowing,
EncodeCrossCrate::Yes,
rustc_deprecated_safe_2024, Normal, template!(List: r#"audit_that = "...""#),
ErrorFollowing, EncodeCrossCrate::Yes,
"rustc_deprecated_safe_2024 is supposed to be used in libstd only",
),

Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ macro_rules! arena_types {
[] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>,
[] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>,
[] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>,
[] canonical_goal_evaluation:
rustc_type_ir::solve::inspect::CanonicalGoalEvaluationStep<
rustc_middle::ty::TyCtxt<'tcx>
>,
[] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>,
[] type_op_subtype:
rustc_middle::infer::canonical::Canonical<'tcx,
Expand Down
9 changes: 0 additions & 9 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.mk_predefined_opaques_in_body(data)
}
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
type CanonicalGoalEvaluationStepRef =
&'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>;
type CanonicalVars = CanonicalVarInfos<'tcx>;
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
self.mk_canonical_var_infos(infos)
Expand Down Expand Up @@ -277,13 +275,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.debug_assert_args_compatible(def_id, args);
}

fn intern_canonical_goal_evaluation_step(
self,
step: solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>,
) -> &'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>> {
self.arena.alloc(step)
}

fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
where
I: Iterator<Item = T>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ mir_build_call_to_deprecated_safe_fn_requires_unsafe =
call to deprecated safe function `{$function}` is unsafe and requires unsafe block
.note = consult the function's documentation for information on how to avoid undefined behavior
.label = call to unsafe function
.suggestion = you can wrap the call in an `unsafe` block if you can guarantee the code is only ever called from single-threaded code
.suggestion = you can wrap the call in an `unsafe` block if you can guarantee {$guarantee}
mir_build_call_to_fn_with_requires_unsafe =
call to function `{$function}` with `#[target_feature]` is unsafe and requires unsafe block
Expand Down
28 changes: 26 additions & 2 deletions compiler/rustc_mir_build/src/check_unsafety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,18 +96,42 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
// from an edition before 2024.
&UnsafeOpKind::CallToUnsafeFunction(Some(id))
if !span.at_least_rust_2024()
&& self.tcx.has_attr(id, sym::rustc_deprecated_safe_2024) =>
&& let Some(attr) = self.tcx.get_attr(id, sym::rustc_deprecated_safe_2024) =>
{
let suggestion = attr
.meta_item_list()
.unwrap_or_default()
.into_iter()
.find(|item| item.has_name(sym::audit_that))
.map(|item| {
item.value_str().expect(
"`#[rustc_deprecated_safe_2024(audit_that)]` must have a string value",
)
});

let sm = self.tcx.sess.source_map();
let guarantee = suggestion
.as_ref()
.map(|suggestion| format!("that {}", suggestion))
.unwrap_or_else(|| String::from("its unsafe preconditions"));
let suggestion = suggestion
.and_then(|suggestion| {
sm.indentation_before(span).map(|indent| {
format!("{}// TODO: Audit that {}.\n", indent, suggestion) // ignore-tidy-todo
})
})
.unwrap_or_default();

self.tcx.emit_node_span_lint(
DEPRECATED_SAFE_2024,
self.hir_context,
span,
CallToDeprecatedSafeFnRequiresUnsafe {
span,
function: with_no_trimmed_paths!(self.tcx.def_path_str(id)),
guarantee,
sub: CallToDeprecatedSafeFnRequiresUnsafeSub {
indent: sm.indentation_before(span).unwrap_or_default(),
start_of_line_suggestion: suggestion,
start_of_line: sm.span_extend_to_line(span).shrink_to_lo(),
left: span.shrink_to_lo(),
right: span.shrink_to_hi(),
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_mir_build/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,16 @@ pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe {
#[label]
pub(crate) span: Span,
pub(crate) function: String,
pub(crate) guarantee: String,
#[subdiagnostic]
pub(crate) sub: CallToDeprecatedSafeFnRequiresUnsafeSub,
}

#[derive(Subdiagnostic)]
#[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")]
pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub {
pub(crate) indent: String,
#[suggestion_part(
code = "{indent}// TODO: Audit that the environment access only happens in single-threaded code.\n" // ignore-tidy-todo
)]
pub(crate) start_of_line_suggestion: String,
#[suggestion_part(code = "{start_of_line_suggestion}")]
pub(crate) start_of_line: Span,
#[suggestion_part(code = "unsafe {{ ")]
pub(crate) left: Span,
Expand Down
106 changes: 14 additions & 92 deletions compiler/rustc_next_trait_solver/src/solve/inspect/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@
//! see the comment on [ProofTreeBuilder].

use std::marker::PhantomData;
use std::mem;

use derive_where::derive_where;
use rustc_type_ir::inherent::*;
use rustc_type_ir::{self as ty, search_graph, Interner};
use rustc_type_ir::{self as ty, Interner};

use crate::delegate::SolverDelegate;
use crate::solve::eval_ctxt::canonical;
Expand Down Expand Up @@ -94,31 +93,10 @@ impl<I: Interner> WipGoalEvaluation<I> {
}
}

#[derive_where(PartialEq, Eq; I: Interner)]
pub(in crate::solve) enum WipCanonicalGoalEvaluationKind<I: Interner> {
Overflow,
CycleInStack,
ProvisionalCacheHit,
Interned { final_revision: I::CanonicalGoalEvaluationStepRef },
}

impl<I: Interner> std::fmt::Debug for WipCanonicalGoalEvaluationKind<I> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Overflow => write!(f, "Overflow"),
Self::CycleInStack => write!(f, "CycleInStack"),
Self::ProvisionalCacheHit => write!(f, "ProvisionalCacheHit"),
Self::Interned { final_revision: _ } => {
f.debug_struct("Interned").finish_non_exhaustive()
}
}
}
}

#[derive_where(PartialEq, Eq, Debug; I: Interner)]
struct WipCanonicalGoalEvaluation<I: Interner> {
goal: CanonicalInput<I>,
kind: Option<WipCanonicalGoalEvaluationKind<I>>,
encountered_overflow: bool,
/// Only used for uncached goals. After we finished evaluating
/// the goal, this is interned and moved into `kind`.
final_revision: Option<WipCanonicalGoalEvaluationStep<I>>,
Expand All @@ -127,25 +105,17 @@ struct WipCanonicalGoalEvaluation<I: Interner> {

impl<I: Interner> WipCanonicalGoalEvaluation<I> {
fn finalize(self) -> inspect::CanonicalGoalEvaluation<I> {
// We've already interned the final revision in
// `fn finalize_canonical_goal_evaluation`.
assert!(self.final_revision.is_none());
let kind = match self.kind.unwrap() {
WipCanonicalGoalEvaluationKind::Overflow => {
inspect::CanonicalGoalEvaluation {
goal: self.goal,
kind: if self.encountered_overflow {
assert!(self.final_revision.is_none());
inspect::CanonicalGoalEvaluationKind::Overflow
}
WipCanonicalGoalEvaluationKind::CycleInStack => {
inspect::CanonicalGoalEvaluationKind::CycleInStack
}
WipCanonicalGoalEvaluationKind::ProvisionalCacheHit => {
inspect::CanonicalGoalEvaluationKind::ProvisionalCacheHit
}
WipCanonicalGoalEvaluationKind::Interned { final_revision } => {
} else {
let final_revision = self.final_revision.unwrap().finalize();
inspect::CanonicalGoalEvaluationKind::Evaluation { final_revision }
}
};

inspect::CanonicalGoalEvaluation { goal: self.goal, kind, result: self.result.unwrap() }
},
result: self.result.unwrap(),
}
}
}

Expand Down Expand Up @@ -308,7 +278,7 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
) -> ProofTreeBuilder<D> {
self.nested(|| WipCanonicalGoalEvaluation {
goal,
kind: None,
encountered_overflow: false,
final_revision: None,
result: None,
})
Expand All @@ -329,11 +299,11 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}

pub fn canonical_goal_evaluation_kind(&mut self, kind: WipCanonicalGoalEvaluationKind<I>) {
pub fn canonical_goal_evaluation_overflow(&mut self) {
if let Some(this) = self.as_mut() {
match this {
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {
assert_eq!(canonical_goal_evaluation.kind.replace(kind), None);
canonical_goal_evaluation.encountered_overflow = true;
}
_ => unreachable!(),
};
Expand Down Expand Up @@ -547,51 +517,3 @@ impl<D: SolverDelegate<Interner = I>, I: Interner> ProofTreeBuilder<D> {
}
}
}

impl<D, I> search_graph::ProofTreeBuilder<I> for ProofTreeBuilder<D>
where
D: SolverDelegate<Interner = I>,
I: Interner,
{
fn try_apply_proof_tree(
&mut self,
proof_tree: Option<I::CanonicalGoalEvaluationStepRef>,
) -> bool {
if !self.is_noop() {
if let Some(final_revision) = proof_tree {
let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision };
self.canonical_goal_evaluation_kind(kind);
true
} else {
false
}
} else {
true
}
}

fn on_provisional_cache_hit(&mut self) {
self.canonical_goal_evaluation_kind(WipCanonicalGoalEvaluationKind::ProvisionalCacheHit);
}

fn on_cycle_in_stack(&mut self) {
self.canonical_goal_evaluation_kind(WipCanonicalGoalEvaluationKind::CycleInStack);
}

fn finalize_canonical_goal_evaluation(
&mut self,
tcx: I,
) -> Option<I::CanonicalGoalEvaluationStepRef> {
self.as_mut().map(|this| match this {
DebugSolver::CanonicalGoalEvaluation(evaluation) => {
let final_revision = mem::take(&mut evaluation.final_revision).unwrap();
let final_revision =
tcx.intern_canonical_goal_evaluation_step(final_revision.finalize());
let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision };
assert_eq!(evaluation.kind.replace(kind), None);
final_revision
}
_ => unreachable!(),
})
}
}
66 changes: 44 additions & 22 deletions compiler/rustc_next_trait_solver/src/solve/search_graph.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::convert::Infallible;
use std::marker::PhantomData;

use rustc_type_ir::inherent::*;
use rustc_type_ir::search_graph::{self, CycleKind, UsageKind};
use rustc_type_ir::search_graph::{self, PathKind};
use rustc_type_ir::solve::{CanonicalInput, Certainty, QueryResult};
use rustc_type_ir::Interner;

use super::inspect::{self, ProofTreeBuilder};
use super::FIXPOINT_STEP_LIMIT;
use super::inspect::ProofTreeBuilder;
use super::{has_no_inference_or_external_constraints, FIXPOINT_STEP_LIMIT};
use crate::delegate::SolverDelegate;

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

const ENABLE_PROVISIONAL_CACHE: bool = true;
type ValidationScope = Infallible;
fn enter_validation_scope(
_cx: Self::Cx,
_input: CanonicalInput<I>,
) -> Option<Self::ValidationScope> {
None
}

const FIXPOINT_STEP_LIMIT: usize = FIXPOINT_STEP_LIMIT;

type ProofTreeBuilder = ProofTreeBuilder<D>;
fn inspect_is_noop(inspect: &mut Self::ProofTreeBuilder) -> bool {
inspect.is_noop()
}

const DIVIDE_AVAILABLE_DEPTH_ON_OVERFLOW: usize = 4;
fn recursion_limit(cx: I) -> usize {
cx.recursion_limit()
}

fn initial_provisional_result(
cx: I,
kind: CycleKind,
kind: PathKind,
input: CanonicalInput<I>,
) -> QueryResult<I> {
match kind {
CycleKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes),
CycleKind::Inductive => response_no_constraints(cx, input, Certainty::overflow(false)),
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes),
PathKind::Inductive => response_no_constraints(cx, input, Certainty::overflow(false)),
}
}

fn reached_fixpoint(
cx: I,
kind: UsageKind,
fn is_initial_provisional_result(
cx: Self::Cx,
kind: PathKind,
input: CanonicalInput<I>,
provisional_result: Option<QueryResult<I>>,
result: QueryResult<I>,
) -> bool {
if let Some(r) = provisional_result {
r == result
} else {
match kind {
UsageKind::Single(CycleKind::Coinductive) => {
response_no_constraints(cx, input, Certainty::Yes) == result
}
UsageKind::Single(CycleKind::Inductive) => {
response_no_constraints(cx, input, Certainty::overflow(false)) == result
}
UsageKind::Mixed => false,
match kind {
PathKind::Coinductive => response_no_constraints(cx, input, Certainty::Yes) == result,
PathKind::Inductive => {
response_no_constraints(cx, input, Certainty::overflow(false)) == result
}
}
}
Expand All @@ -68,14 +74,30 @@ where
inspect: &mut ProofTreeBuilder<D>,
input: CanonicalInput<I>,
) -> QueryResult<I> {
inspect.canonical_goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow);
inspect.canonical_goal_evaluation_overflow();
response_no_constraints(cx, input, Certainty::overflow(true))
}

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

fn is_ambiguous_result(result: QueryResult<I>) -> bool {
result.is_ok_and(|response| {
has_no_inference_or_external_constraints(response)
&& matches!(response.value.certainty, Certainty::Maybe(_))
})
}

fn propagate_ambiguity(
cx: I,
for_input: CanonicalInput<I>,
from_result: QueryResult<I>,
) -> QueryResult<I> {
let certainty = from_result.unwrap().value.certainty;
response_no_constraints(cx, for_input, certainty)
}

fn step_is_coinductive(cx: I, input: CanonicalInput<I>) -> bool {
input.value.goal.predicate.is_coinductive(cx)
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ symbols! {
attr,
attr_literals,
attributes,
audit_that,
augmented_assignments,
auto_traits,
automatically_derived,
Expand Down
Loading

0 comments on commit a1df0fa

Please sign in to comment.