Skip to content
Closed
5 changes: 5 additions & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
r#"`rustc_doc_primitive` is a rustc internal attribute"#,
),
rustc_attr!(
rustc_filter_proof_tree_dump, Normal, template!(List: "filter1, filter2, ..."), DuplicatesOk,
"the `#[rustc_filter_proof_tree_dump(...)]` attribute is used to filter out proof trees \
from `-Zdump-solver-proof-tree` output.",
),

// ==========================================================================
// Internal attributes, Testing:
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,9 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
match ty.kind() {
ty::Adt(adt_def, _) => Some(*adt_def),
// FIXME(#104767): Should we handle bound regions here?
ty::Alias(ty::Projection | ty::Inherent, _) if !ty.has_escaping_bound_vars() => {
ty::Alias(ty::Projection | ty::Inherent | ty::Weak, _)
if !ty.has_escaping_bound_vars() =>
{
self.normalize(span, ty).ty_adt_def()
}
_ => None,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/def_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ pub struct LocalDefId {
impl !Ord for LocalDefId {}
impl !PartialOrd for LocalDefId {}

/// The [`DefId`] for the local crate root.
pub const CRATE_DEF_ID: LocalDefId = LocalDefId { local_def_index: CRATE_DEF_INDEX };

impl Idx for LocalDefId {
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 @@ -1287,6 +1287,7 @@ symbols! {
rustc_error,
rustc_evaluate_where_clauses,
rustc_expected_cgu_reuse,
rustc_filter_proof_tree_dump,
rustc_has_incoherent_inherent_impls,
rustc_host,
rustc_if_this_changed,
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,12 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution>,
Option<inspect::GoalEvaluation<'tcx>>,
) {
EvalCtxt::enter_root(self, generate_proof_tree, |ecx| {
ecx.evaluate_goal(IsNormalizesToHack::No, goal)
})
EvalCtxt::enter_root(
self,
generate_proof_tree,
|| format!("{:?}", goal.predicate),
|ecx| ecx.evaluate_goal(IsNormalizesToHack::No, goal),
)
}
}

Expand All @@ -176,6 +179,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
fn enter_root<R>(
infcx: &InferCtxt<'tcx>,
generate_proof_tree: GenerateProofTree,
filter: impl FnOnce() -> String,
f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> R,
) -> (R, Option<inspect::GoalEvaluation<'tcx>>) {
let mode = if infcx.intercrate { SolverMode::Coherence } else { SolverMode::Normal };
Expand All @@ -194,7 +198,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
var_values: CanonicalVarValues::dummy(),
nested_goals: NestedGoals::new(),
tainted: Ok(()),
inspect: ProofTreeBuilder::new_maybe_root(infcx.tcx, generate_proof_tree),
inspect: ProofTreeBuilder::new_maybe_root(infcx.tcx, generate_proof_tree, filter),
};
let result = f(&mut ecx);

Expand Down
75 changes: 40 additions & 35 deletions compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,46 +43,51 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
self.instantiate_binder_with_placeholders(obligation.predicate),
);

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);

// pseudo-winnow
if candidates.len() == 0 {
return Err(SelectionError::Unimplemented);
} else if candidates.len() > 1 {
let mut i = 0;
while i < candidates.len() {
let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| {
candidate_should_be_dropped_in_favor_of(
ecx.tcx(),
&candidates[i],
&candidates[j],
)
});
if should_drop_i {
candidates.swap_remove(i);
} else {
i += 1;
if i > 1 {
return Ok(None);
let (result, _) = EvalCtxt::enter_root(
self,
GenerateProofTree::Never,
|| unreachable!("proof trees cannot be generated for selection"),
|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);

// pseudo-winnow
if candidates.len() == 0 {
return Err(SelectionError::Unimplemented);
} else if candidates.len() > 1 {
let mut i = 0;
while i < candidates.len() {
let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| {
candidate_should_be_dropped_in_favor_of(
ecx.tcx(),
&candidates[i],
&candidates[j],
)
});
if should_drop_i {
candidates.swap_remove(i);
} else {
i += 1;
if i > 1 {
return Ok(None);
}
}
}
}
}

let candidate = candidates.pop().unwrap();
let (certainty, nested_goals) = ecx
.instantiate_and_apply_query_response(
trait_goal.param_env,
orig_values,
candidate.result,
)
.map_err(|_| SelectionError::Unimplemented)?;
let candidate = candidates.pop().unwrap();
let (certainty, nested_goals) = ecx
.instantiate_and_apply_query_response(
trait_goal.param_env,
orig_values,
candidate.result,
)
.map_err(|_| SelectionError::Unimplemented)?;

Ok(Some((candidate, certainty, nested_goals)))
});
Ok(Some((candidate, certainty, nested_goals)))
},
);

let (candidate, certainty, nested_goals) = match result {
Ok(Some((candidate, certainty, nested_goals))) => (candidate, certainty, nested_goals),
Expand Down
43 changes: 41 additions & 2 deletions compiler/rustc_trait_selection/src/solve/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use rustc_middle::traits::solve::{
};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::config::DumpSolverProofTree;
use rustc_span::def_id::CRATE_DEF_ID;

use super::eval_ctxt::UseGlobalCache;
use super::GenerateProofTree;
Expand Down Expand Up @@ -199,15 +200,53 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
pub fn new_maybe_root(
tcx: TyCtxt<'tcx>,
generate_proof_tree: GenerateProofTree,
filter: impl FnOnce() -> String,
) -> ProofTreeBuilder<'tcx> {
match generate_proof_tree {
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))
let should_generate = if tcx
.get_attrs(CRATE_DEF_ID, rustc_span::sym::rustc_filter_proof_tree_dump)
.next()
.is_some()
{
// dont do the filtering behaviour if there are no attributes anywhere
let goal = filter();
tcx
.get_attrs(CRATE_DEF_ID, rustc_span::sym::rustc_filter_proof_tree_dump)
.flat_map(|attr| {
let meta = attr.meta_kind().unwrap();
match meta {
rustc_ast::MetaItemKind::Word
| rustc_ast::MetaItemKind::NameValue(_) => {
bug!("wrong attribute kind for `rustc_filter_proof_tree_dump`")
}
rustc_ast::MetaItemKind::List(nested_meta) => {
nested_meta.into_iter().map(|nested_meta| {
match nested_meta {
rustc_ast::NestedMetaItem::MetaItem(_) => unreachable!("only string literals are supported in `rustc_filter_proof_tree_dump`"),
rustc_ast::NestedMetaItem::Lit(lit) => match lit.kind {
rustc_ast::LitKind::Str(sym, _) => sym,
_ => unreachable!("only string literals are supported in `rustc_filter_proof_tree_dump`"),
},
}
})
}
}
}).any(|sym| goal.as_str() == sym.as_str())
} else {
true
};

if should_generate {
let use_cache = opts.dump_solver_proof_tree_use_cache.unwrap_or(true);
ProofTreeBuilder::new_root(UseGlobalCache::from_bool(use_cache))
} else {
ProofTreeBuilder::new_noop()
}
}
// `OnError` is handled by reevaluating goals in error
// reporting with `GenerateProofTree::Yes`.
Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
- [mipsel-sony-psx](platform-support/mipsel-sony-psx.md)
- [mipsisa\*r6\*-unknown-linux-gnu\*](platform-support/mips-release-6.md)
- [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md)
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
Expand Down
10 changes: 5 additions & 5 deletions src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,10 @@ target | std | host | notes
[`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX)
`mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc
`mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat
`mipsisa32r6-unknown-linux-gnu` | ? | |
`mipsisa32r6el-unknown-linux-gnu` | ? | |
`mipsisa64r6-unknown-linux-gnuabi64` | ? | |
`mipsisa64r6el-unknown-linux-gnuabi64` | ? | |
[`mipsisa32r6-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Big Endian
[`mipsisa32r6el-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Little Endian
[`mipsisa64r6-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ? | | 64-bit MIPS Release 6 Big Endian
[`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | | ✓ | 64-bit MIPS Release 6 Little Endian
`msp430-none-elf` | * | | 16-bit MSP430 microcontrollers
`powerpc-unknown-linux-gnuspe` | ✓ | | PowerPC SPE Linux
`powerpc-unknown-linux-musl` | ? | |
Expand All @@ -305,7 +305,7 @@ target | std | host | notes
`riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD
`riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia
`riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.0)
[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ? | RISC-V NetBSD
[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | RISC-V NetBSD
[`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64
`s390x-unknown-linux-musl` | | | S390x Linux (kernel 3.2, MUSL)
`sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux
Expand Down
Loading