Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #113667

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 4

[*.rs]
max_line_length = 100

[*.md]
Expand Down
19 changes: 17 additions & 2 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2970,10 +2970,25 @@ fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
return;
}

let self_contained_linker = sess.opts.cg.link_self_contained.linker();

// FIXME: some targets default to using `lld`, but users can only override the linker on the CLI
// and cannot yet select the precise linker flavor to opt out of that. See for example issue
// #113597 for the `thumbv6m-none-eabi` target: a driver is used, and its default linker
// conflicts with the target's flavor, causing unexpected arguments being passed.
//
// Until the new `LinkerFlavor`-like CLI options are stabilized, we only adopt MCP510's behavior
// if its dedicated unstable CLI flags are used, to keep the current sub-optimal stable
// behavior.
let using_mcp510 =
self_contained_linker || sess.opts.cg.linker_flavor.is_some_and(|f| f.is_unstable());
if !using_mcp510 && !unstable_use_lld {
return;
}

// 1. Implement the "self-contained" part of this feature by adding rustc distribution
// directories to the tool's search path.
let self_contained_linker = sess.opts.cg.link_self_contained.linker() || unstable_use_lld;
if self_contained_linker {
if self_contained_linker || unstable_use_lld {
for path in sess.get_tools_search_paths(false) {
cmd.arg({
let mut arg = OsString::from("-B");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::FnCtxt;
use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_infer::traits::ObligationCauseCode;
use rustc_infer::{infer::type_variable::TypeVariableOriginKind, traits::ObligationCauseCode};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_span::{self, symbol::kw, Span};
use rustc_trait_selection::traits;
Expand Down Expand Up @@ -254,8 +254,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
type BreakTy = ty::GenericArg<'tcx>;
fn visit_ty(&mut self, ty: Ty<'tcx>) -> std::ops::ControlFlow<Self::BreakTy> {
if let Some(origin) = self.0.type_var_origin(ty)
&& let rustc_infer::infer::type_variable::TypeVariableOriginKind::TypeParameterDefinition(_, def_id) =
origin.kind
&& let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind
&& let generics = self.0.tcx.generics_of(self.1)
&& let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id)
&& let Some(subst) = ty::InternalSubsts::identity_for_item(self.0.tcx, self.1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
let ty_vars = infcx_inner.type_variables();
let var_origin = ty_vars.var_origin(ty_vid);
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind
&& !var_origin.span.from_expansion()
&& name != kw::SelfUpper && !var_origin.span.from_expansion()
{
let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id));
let idx = generics.param_def_id_to_index(infcx.tcx, def_id).unwrap();
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/traits/solve/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub enum GoalEvaluationKind<'tcx> {
}
impl Debug for GoalEvaluation<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ProofTreeFormatter { f, on_newline: true }.format_goal_evaluation(self)
ProofTreeFormatter::new(f).format_goal_evaluation(self)
}
}

Expand All @@ -43,7 +43,7 @@ pub struct AddedGoalsEvaluation<'tcx> {
}
impl Debug for AddedGoalsEvaluation<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ProofTreeFormatter { f, on_newline: true }.format_nested_goal_evaluation(self)
ProofTreeFormatter::new(f).format_nested_goal_evaluation(self)
}
}

Expand All @@ -58,7 +58,7 @@ pub struct GoalEvaluationStep<'tcx> {
}
impl Debug for GoalEvaluationStep<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ProofTreeFormatter { f, on_newline: true }.format_evaluation_step(self)
ProofTreeFormatter::new(f).format_evaluation_step(self)
}
}

Expand All @@ -78,6 +78,6 @@ pub enum CandidateKind<'tcx> {
}
impl Debug for GoalCandidate<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
ProofTreeFormatter { f, on_newline: true }.format_candidate(self)
ProofTreeFormatter::new(f).format_candidate(self)
}
}
112 changes: 59 additions & 53 deletions compiler/rustc_middle/src/traits/solve/inspect/format.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
use super::*;

pub(super) struct ProofTreeFormatter<'a, 'b> {
pub(super) f: &'a mut (dyn Write + 'b),
pub(super) on_newline: bool,
f: &'a mut (dyn Write + 'b),
}

impl Write for ProofTreeFormatter<'_, '_> {
/// A formatter which adds 4 spaces of indentation to its input before
/// passing it on to its nested formatter.
///
/// We can use this for arbitrary levels of indentation by nesting it.
struct Indentor<'a, 'b> {
f: &'a mut (dyn Write + 'b),
on_newline: bool,
}

impl Write for Indentor<'_, '_> {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
for line in s.split_inclusive("\n") {
if self.on_newline {
Expand All @@ -19,49 +27,52 @@ impl Write for ProofTreeFormatter<'_, '_> {
}
}

impl ProofTreeFormatter<'_, '_> {
fn nested(&mut self) -> ProofTreeFormatter<'_, '_> {
ProofTreeFormatter { f: self, on_newline: true }
impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
pub(super) fn new(f: &'a mut (dyn Write + 'b)) -> Self {
ProofTreeFormatter { f }
}

pub(super) fn format_goal_evaluation(&mut self, goal: &GoalEvaluation<'_>) -> std::fmt::Result {
let f = &mut *self.f;
fn nested<F, R>(&mut self, func: F) -> R
where
F: FnOnce(&mut ProofTreeFormatter<'_, '_>) -> R,
{
func(&mut ProofTreeFormatter { f: &mut Indentor { f: self.f, on_newline: true } })
}

pub(super) fn format_goal_evaluation(&mut self, goal: &GoalEvaluation<'_>) -> std::fmt::Result {
let goal_text = match goal.is_normalizes_to_hack {
IsNormalizesToHack::Yes => "NORMALIZES-TO HACK GOAL",
IsNormalizesToHack::No => "GOAL",
};

writeln!(f, "{}: {:?}", goal_text, goal.uncanonicalized_goal,)?;
writeln!(f, "CANONICALIZED: {:?}", goal.canonicalized_goal)?;
writeln!(self.f, "{}: {:?}", goal_text, goal.uncanonicalized_goal)?;
writeln!(self.f, "CANONICALIZED: {:?}", goal.canonicalized_goal)?;

match &goal.kind {
GoalEvaluationKind::CacheHit(CacheHit::Global) => {
writeln!(f, "GLOBAL CACHE HIT: {:?}", goal.result)
writeln!(self.f, "GLOBAL CACHE HIT: {:?}", goal.result)
}
GoalEvaluationKind::CacheHit(CacheHit::Provisional) => {
writeln!(f, "PROVISIONAL CACHE HIT: {:?}", goal.result)
writeln!(self.f, "PROVISIONAL CACHE HIT: {:?}", goal.result)
}
GoalEvaluationKind::Uncached { revisions } => {
for (n, step) in revisions.iter().enumerate() {
let f = &mut *self.f;
writeln!(f, "REVISION {n}: {:?}", step.result)?;
let mut f = self.nested();
f.format_evaluation_step(step)?;
writeln!(self.f, "REVISION {n}: {:?}", step.result)?;
self.nested(|this| this.format_evaluation_step(step))?;
}

let f = &mut *self.f;
writeln!(f, "RESULT: {:?}", goal.result)
writeln!(self.f, "RESULT: {:?}", goal.result)
}
}?;

if goal.returned_goals.len() > 0 {
let f = &mut *self.f;
writeln!(f, "NESTED GOALS ADDED TO CALLER: [")?;
let mut f = self.nested();
for goal in goal.returned_goals.iter() {
writeln!(f, "ADDED GOAL: {:?},", goal)?;
}
writeln!(self.f, "NESTED GOALS ADDED TO CALLER: [")?;
self.nested(|this| {
for goal in goal.returned_goals.iter() {
writeln!(this.f, "ADDED GOAL: {:?},", goal)?;
}
Ok(())
})?;

writeln!(self.f, "]")?;
}

Expand All @@ -72,58 +83,53 @@ impl ProofTreeFormatter<'_, '_> {
&mut self,
evaluation_step: &GoalEvaluationStep<'_>,
) -> std::fmt::Result {
let f = &mut *self.f;
writeln!(f, "INSTANTIATED: {:?}", evaluation_step.instantiated_goal)?;
writeln!(self.f, "INSTANTIATED: {:?}", evaluation_step.instantiated_goal)?;

for candidate in &evaluation_step.candidates {
let mut f = self.nested();
f.format_candidate(candidate)?;
self.nested(|this| this.format_candidate(candidate))?;
}
for nested_goal_evaluation in &evaluation_step.nested_goal_evaluations {
let mut f = self.nested();
f.format_nested_goal_evaluation(nested_goal_evaluation)?;
for nested in &evaluation_step.nested_goal_evaluations {
self.nested(|this| this.format_nested_goal_evaluation(nested))?;
}

Ok(())
}

pub(super) fn format_candidate(&mut self, candidate: &GoalCandidate<'_>) -> std::fmt::Result {
let f = &mut *self.f;

match &candidate.kind {
CandidateKind::NormalizedSelfTyAssembly => {
writeln!(f, "NORMALIZING SELF TY FOR ASSEMBLY:")
writeln!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:")
}
CandidateKind::Candidate { name, result } => {
writeln!(f, "CANDIDATE {}: {:?}", name, result)
writeln!(self.f, "CANDIDATE {}: {:?}", name, result)
}
}?;

let mut f = self.nested();
for candidate in &candidate.candidates {
f.format_candidate(candidate)?;
}
for nested_evaluations in &candidate.nested_goal_evaluations {
f.format_nested_goal_evaluation(nested_evaluations)?;
}

Ok(())
self.nested(|this| {
for candidate in &candidate.candidates {
this.format_candidate(candidate)?;
}
for nested in &candidate.nested_goal_evaluations {
this.format_nested_goal_evaluation(nested)?;
}
Ok(())
})
}

pub(super) fn format_nested_goal_evaluation(
&mut self,
nested_goal_evaluation: &AddedGoalsEvaluation<'_>,
) -> std::fmt::Result {
let f = &mut *self.f;
writeln!(f, "TRY_EVALUATE_ADDED_GOALS: {:?}", nested_goal_evaluation.result)?;
writeln!(self.f, "TRY_EVALUATE_ADDED_GOALS: {:?}", nested_goal_evaluation.result)?;

for (n, revision) in nested_goal_evaluation.evaluations.iter().enumerate() {
let f = &mut *self.f;
writeln!(f, "REVISION {n}")?;
let mut f = self.nested();
for goal_evaluation in revision {
f.format_goal_evaluation(goal_evaluation)?;
}
writeln!(self.f, "REVISION {n}")?;
self.nested(|this| {
for goal_evaluation in revision {
this.format_goal_evaluation(goal_evaluation)?;
}
Ok(())
})?;
}

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_smir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The WIP stable interface to rustc internals.
//!
//! For more information see https://github.com/rust-lang/project-stable-mir
//! For more information see <https://github.com/rust-lang/project-stable-mir>
//!
//! # Note
//!
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ impl NestedGoals<'_> {
#[derive(PartialEq, Eq, Debug, Hash, HashStable, Clone, Copy)]
pub enum GenerateProofTree {
Yes(UseGlobalCache),
No,
IfEnabled,
Never,
}

#[derive(PartialEq, Eq, Debug, Hash, HashStable, Clone, Copy)]
Expand Down Expand Up @@ -202,7 +203,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
(&tree, infcx.tcx.sess.opts.unstable_opts.dump_solver_proof_tree)
{
let mut lock = std::io::stdout().lock();
let _ = lock.write_fmt(format_args!("{tree:?}"));
let _ = lock.write_fmt(format_args!("{tree:?}\n"));
let _ = lock.flush();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
self.instantiate_binder_with_placeholders(obligation.predicate),
);

let (result, _) = EvalCtxt::enter_root(self, GenerateProofTree::No, |ecx| {
let (result, _) = EvalCtxt::enter_root(self, GenerateProofTree::Never, |ecx| {
let goal = Goal::new(ecx.tcx(), trait_goal.param_env, trait_goal.predicate);
let (orig_values, canonical_goal) = ecx.canonicalize_goal(goal);
let mut candidates = ecx.compute_canonical_trait_candidates(canonical_goal);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_trait_selection/src/solve/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
.map(|obligation| {
let code = infcx.probe(|_| {
match infcx
.evaluate_root_goal(obligation.clone().into(), GenerateProofTree::No)
.evaluate_root_goal(obligation.clone().into(), GenerateProofTree::IfEnabled)
.0
{
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity), _)) => {
Expand Down Expand Up @@ -96,7 +96,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
for obligation in mem::take(&mut self.obligations) {
let goal = obligation.clone().into();
let (changed, certainty, nested_goals) =
match infcx.evaluate_root_goal(goal, GenerateProofTree::No).0 {
match infcx.evaluate_root_goal(goal, GenerateProofTree::IfEnabled).0 {
Ok(result) => result,
Err(NoSolution) => {
errors.push(FulfillmentError {
Expand Down
37 changes: 15 additions & 22 deletions compiler/rustc_trait_selection/src/solve/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,30 +200,23 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
tcx: TyCtxt<'tcx>,
generate_proof_tree: GenerateProofTree,
) -> ProofTreeBuilder<'tcx> {
let generate_proof_tree = match (
tcx.sess.opts.unstable_opts.dump_solver_proof_tree,
tcx.sess.opts.unstable_opts.dump_solver_proof_tree_use_cache,
generate_proof_tree,
) {
(_, Some(use_cache), GenerateProofTree::Yes(_)) => {
GenerateProofTree::Yes(UseGlobalCache::from_bool(use_cache))
}

(DumpSolverProofTree::Always, use_cache, GenerateProofTree::No) => {
let use_cache = use_cache.unwrap_or(true);
GenerateProofTree::Yes(UseGlobalCache::from_bool(use_cache))
}

(_, None, GenerateProofTree::Yes(_)) => generate_proof_tree,
(DumpSolverProofTree::Never, _, _) => generate_proof_tree,
(DumpSolverProofTree::OnError, _, _) => generate_proof_tree,
};

match generate_proof_tree {
GenerateProofTree::No => ProofTreeBuilder::new_noop(),
GenerateProofTree::Yes(global_cache_disabled) => {
ProofTreeBuilder::new_root(global_cache_disabled)
GenerateProofTree::Never => ProofTreeBuilder::new_noop(),
GenerateProofTree::IfEnabled => {
let opts = &tcx.sess.opts.unstable_opts;
match opts.dump_solver_proof_tree {
DumpSolverProofTree::Always => {
let use_cache = opts.dump_solver_proof_tree_use_cache.unwrap_or(true);
ProofTreeBuilder::new_root(UseGlobalCache::from_bool(use_cache))
}
// `OnError` is handled by reevaluating goals in error
// reporting with `GenerateProofTree::Yes`.
DumpSolverProofTree::OnError | DumpSolverProofTree::Never => {
ProofTreeBuilder::new_noop()
}
}
}
GenerateProofTree::Yes(use_cache) => ProofTreeBuilder::new_root(use_cache),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3556,7 +3556,7 @@ pub fn dump_proof_tree<'tcx>(o: &Obligation<'tcx, ty::Predicate<'tcx>>, infcx: &
.1
.expect("proof tree should have been generated");
let mut lock = std::io::stdout().lock();
let _ = lock.write_fmt(format_args!("{tree:?}"));
let _ = lock.write_fmt(format_args!("{tree:?}\n"));
let _ = lock.flush();
});
}
Loading