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 5 pull requests #125079

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
5 changes: 3 additions & 2 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#![allow(internal_features)]
#![feature(decl_macro)]
#![feature(let_chains)]
#![feature(panic_backtrace_config)]
#![feature(panic_update_hook)]
#![feature(result_flattening)]

Expand Down Expand Up @@ -1317,8 +1318,8 @@ pub fn install_ice_hook(
// by the user. Compiler developers and other rustc users can
// opt in to less-verbose backtraces by manually setting "RUST_BACKTRACE"
// (e.g. `RUST_BACKTRACE=1`)
if std::env::var_os("RUST_BACKTRACE").is_none() {
std::env::set_var("RUST_BACKTRACE", "full");
if env::var_os("RUST_BACKTRACE").is_none() {
panic::set_backtrace_style(panic::BacktraceStyle::Full);
}

let using_internal_features = Arc::new(std::sync::atomic::AtomicBool::default());
Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_middle/src/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,18 @@ pub enum SelectionCandidate<'tcx> {
/// Implementation of transmutability trait.
TransmutabilityCandidate,

ParamCandidate(ty::PolyTraitPredicate<'tcx>),
/// A candidate from the `ParamEnv`.
ParamCandidate {
/// The actual `where`-bound, e.g. `T: Trait`.
predicate: ty::PolyTraitPredicate<'tcx>,
/// `true` if the where-bound has no bound vars and does
/// not refer to any parameters or inference variables.
///
/// We prefer all other candidates over global where-bounds.
/// Notably, global where-bounds do not shadow impls.
is_global: bool,
},

ImplCandidate(DefId),
AutoImplCandidate,

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/traits/solve/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ pub enum ProbeKind<'tcx> {
/// do a probe to find out what projection type(s) may be used to prove that
/// the source type upholds all of the target type's object bounds.
UpcastProjectionCompatibility,
/// Looking for param-env candidates that satisfy the trait ref for a projection.
ShadowedEnvProbing,
/// Try to unify an opaque type with an existing key in the storage.
OpaqueTypeStorageLookup { result: QueryResult<'tcx> },
}
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/traits/solve/inspect/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
ProbeKind::TraitCandidate { source, result } => {
write!(self.f, "CANDIDATE {source:?}: {result:?}")
}
ProbeKind::ShadowedEnvProbing => {
write!(self.f, "PROBING FOR IMPLS SHADOWED BY PARAM-ENV CANDIDATE:")
}
}?;

self.nested(|this| {
Expand Down
19 changes: 8 additions & 11 deletions compiler/rustc_trait_selection/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Code shared by trait and projection goals for candidate assembly.

use crate::solve::GoalSource;
use crate::solve::{inspect, EvalCtxt, SolverMode};
use crate::solve::{EvalCtxt, SolverMode};
use rustc_hir::def_id::DefId;
use rustc_infer::traits::query::NoSolution;
use rustc_middle::bug;
Expand All @@ -16,7 +16,6 @@ use rustc_middle::ty::{fast_reject, TypeFoldable};
use rustc_middle::ty::{ToPredicate, TypeVisitableExt};
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
use std::fmt::Debug;
use std::mem;

pub(super) mod structural_traits;

Expand Down Expand Up @@ -792,17 +791,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
) {
// HACK: We temporarily remove the `ProofTreeBuilder` to
// avoid adding `Trait` candidates to the candidates used
// to prove the current goal.
let inspect = mem::replace(&mut self.inspect, inspect::ProofTreeBuilder::new_noop());

let tcx = self.tcx();
let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> =
goal.with(tcx, goal.predicate.trait_ref(tcx));
let mut trait_candidates_from_env = Vec::new();
self.assemble_param_env_candidates(trait_goal, &mut trait_candidates_from_env);
self.assemble_alias_bound_candidates(trait_goal, &mut trait_candidates_from_env);

let mut trait_candidates_from_env = vec![];
self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| {
ecx.assemble_param_env_candidates(trait_goal, &mut trait_candidates_from_env);
ecx.assemble_alias_bound_candidates(trait_goal, &mut trait_candidates_from_env);
});

if !trait_candidates_from_env.is_empty() {
let trait_env_result = self.merge_candidates(trait_candidates_from_env);
match trait_env_result.unwrap().value.certainty {
Expand Down Expand Up @@ -831,7 +829,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
}
}
}
self.inspect = inspect;
}

/// If there are multiple ways to prove a trait or projection goal, we have
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,8 @@ fn to_selection<'tcx>(
| ProbeKind::UnsizeAssembly
| ProbeKind::UpcastProjectionCompatibility
| ProbeKind::OpaqueTypeStorageLookup { result: _ }
| ProbeKind::Root { result: _ } => {
| ProbeKind::Root { result: _ }
| ProbeKind::ShadowedEnvProbing => {
span_bug!(span, "didn't expect to assemble trait candidate from {:#?}", cand.kind())
}
})
Expand Down
32 changes: 23 additions & 9 deletions compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,25 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
match *step {
inspect::ProbeStep::AddGoal(source, goal) => nested_goals.push((source, goal)),
inspect::ProbeStep::NestedProbe(ref probe) => {
// Nested probes have to prove goals added in their parent
// but do not leak them, so we truncate the added goals
// afterwards.
let num_goals = nested_goals.len();
self.candidates_recur(candidates, nested_goals, probe);
nested_goals.truncate(num_goals);
match probe.kind {
// These never assemble candidates for the goal we're trying to solve.
inspect::ProbeKind::UpcastProjectionCompatibility
| inspect::ProbeKind::ShadowedEnvProbing => continue,

inspect::ProbeKind::NormalizedSelfTyAssembly
| inspect::ProbeKind::UnsizeAssembly
| inspect::ProbeKind::Root { .. }
| inspect::ProbeKind::TryNormalizeNonRigid { .. }
| inspect::ProbeKind::TraitCandidate { .. }
| inspect::ProbeKind::OpaqueTypeStorageLookup { .. } => {
// Nested probes have to prove goals added in their parent
// but do not leak them, so we truncate the added goals
// afterwards.
let num_goals = nested_goals.len();
self.candidates_recur(candidates, nested_goals, probe);
nested_goals.truncate(num_goals);
}
}
}
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
assert_eq!(shallow_certainty.replace(c), None);
Expand All @@ -308,9 +321,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
}

match probe.kind {
inspect::ProbeKind::NormalizedSelfTyAssembly
| inspect::ProbeKind::UnsizeAssembly
| inspect::ProbeKind::UpcastProjectionCompatibility => (),
inspect::ProbeKind::UpcastProjectionCompatibility
| inspect::ProbeKind::ShadowedEnvProbing => bug!(),

inspect::ProbeKind::NormalizedSelfTyAssembly | inspect::ProbeKind::UnsizeAssembly => {}

// We add a candidate even for the root evaluation if there
// is only one way to prove a given goal, e.g. for `WellFormed`.
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,12 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
) -> IntersectionHasImpossibleObligations<'tcx> {
let infcx = selcx.infcx;

// Elaborate obligations in case the current obligation is unknowable,
// but its super trait bound is not. See #124532 for more details.
let obligations = util::elaborate(infcx.tcx, obligations.iter().cloned());
if infcx.next_trait_solver() {
let ocx = ObligationCtxt::new(infcx);
ocx.register_obligations(obligations.iter().cloned());
ocx.register_obligations(obligations);
let errors_and_ambiguities = ocx.select_all_or_error();
// We only care about the obligations that are *definitely* true errors.
// Ambiguities do not prove the disjointness of two impls.
Expand All @@ -388,7 +391,7 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
for obligation in obligations {
// We use `evaluate_root_obligation` to correctly track intercrate
// ambiguity clauses.
let evaluation_result = selcx.evaluate_root_obligation(obligation);
let evaluation_result = selcx.evaluate_root_obligation(&obligation);

match evaluation_result {
Ok(result) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,16 +252,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id());

// Keep only those bounds which may apply, and propagate overflow if it occurs.
for bound in matching_bounds {
if bound.skip_binder().polarity != stack.obligation.predicate.skip_binder().polarity {
for predicate in matching_bounds {
if predicate.skip_binder().polarity != stack.obligation.predicate.skip_binder().polarity
{
continue;
}

// FIXME(oli-obk): it is suspicious that we are dropping the constness and
// polarity here.
let wc = self.where_clause_may_apply(stack, bound.map_bound(|t| t.trait_ref))?;
let wc = self.where_clause_may_apply(stack, predicate.map_bound(|t| t.trait_ref))?;
if wc.may_apply() {
candidates.vec.push(ParamCandidate(bound));
let is_global = predicate.is_global() && !predicate.has_bound_vars();
candidates.vec.push(ParamCandidate { predicate, is_global });
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}

ParamCandidate(param) => {
ParamCandidate { predicate, is_global: _ } => {
let obligations =
self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
self.confirm_param_candidate(obligation, predicate.map_bound(|t| t.trait_ref));
ImplSource::Param(obligations)
}

Expand Down
Loading
Loading