Skip to content

Commit d6d3b34

Browse files
committed
Auto merge of #124660 - matthiaskrgr:rollup-j8bfzfn, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #124461 (handle the targets that are missing in stage0) - #124492 (Generalize `adjust_from_tcx` for `Allocation`) - #124588 (Use `ObligationCtxt` in favor of `TraitEngine` in many more places) - #124612 (Add support for inputing via stdin with run-make-support) - #124613 (Allow fmt to run on rmake.rs test files) - #124649 (Fix HorizonOS build broken by #124210) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 561b5de + a7f4a2e commit d6d3b34

File tree

32 files changed

+355
-233
lines changed

32 files changed

+355
-233
lines changed

compiler/rustc_hir_analysis/src/autoderef.rs

+15-21
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use crate::errors::AutoDerefReachedRecursionLimit;
2+
use crate::traits;
23
use crate::traits::query::evaluate_obligation::InferCtxtExt;
3-
use crate::traits::{self, TraitEngine, TraitEngineExt};
44
use rustc_infer::infer::InferCtxt;
55
use rustc_middle::ty::TypeVisitableExt;
66
use rustc_middle::ty::{self, Ty, TyCtxt};
77
use rustc_session::Limit;
88
use rustc_span::def_id::LocalDefId;
99
use rustc_span::def_id::LOCAL_CRATE;
1010
use rustc_span::Span;
11-
use rustc_trait_selection::traits::StructurallyNormalizeExt;
11+
use rustc_trait_selection::traits::ObligationCtxt;
1212

1313
#[derive(Copy, Clone, Debug)]
1414
pub enum AutoderefKind {
@@ -167,25 +167,19 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
167167
&self,
168168
ty: Ty<'tcx>,
169169
) -> Option<(Ty<'tcx>, Vec<traits::PredicateObligation<'tcx>>)> {
170-
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self.infcx);
171-
172-
let cause = traits::ObligationCause::misc(self.span, self.body_id);
173-
let normalized_ty = match self
174-
.infcx
175-
.at(&cause, self.param_env)
176-
.structurally_normalize(ty, &mut *fulfill_cx)
177-
{
178-
Ok(normalized_ty) => normalized_ty,
179-
Err(errors) => {
180-
// This shouldn't happen, except for evaluate/fulfill mismatches,
181-
// but that's not a reason for an ICE (`predicate_may_hold` is conservative
182-
// by design).
183-
debug!(?errors, "encountered errors while fulfilling");
184-
return None;
185-
}
170+
let ocx = ObligationCtxt::new(self.infcx);
171+
let Ok(normalized_ty) = ocx.structurally_normalize(
172+
&traits::ObligationCause::misc(self.span, self.body_id),
173+
self.param_env,
174+
ty,
175+
) else {
176+
// We shouldn't have errors here, except for evaluate/fulfill mismatches,
177+
// but that's not a reason for an ICE (`predicate_may_hold` is conservative
178+
// by design).
179+
// FIXME(-Znext-solver): This *actually* shouldn't happen then.
180+
return None;
186181
};
187-
188-
let errors = fulfill_cx.select_where_possible(self.infcx);
182+
let errors = ocx.select_where_possible();
189183
if !errors.is_empty() {
190184
// This shouldn't happen, except for evaluate/fulfill mismatches,
191185
// but that's not a reason for an ICE (`predicate_may_hold` is conservative
@@ -194,7 +188,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
194188
return None;
195189
}
196190

197-
Some((normalized_ty, fulfill_cx.pending_obligations()))
191+
Some((normalized_ty, ocx.into_pending_obligations()))
198192
}
199193

200194
/// Returns the final type we ended up with, which may be an inference

compiler/rustc_hir_typeck/src/coercion.rs

+9-13
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ use rustc_hir::Expr;
4545
use rustc_hir_analysis::hir_ty_lowering::HirTyLowerer;
4646
use rustc_infer::infer::type_variable::TypeVariableOrigin;
4747
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
48-
use rustc_infer::traits::TraitEngineExt as _;
49-
use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause, TraitEngine};
48+
use rustc_infer::traits::{IfExpressionCause, MatchExpressionArmCause};
5049
use rustc_infer::traits::{Obligation, PredicateObligation};
5150
use rustc_middle::lint::in_external_macro;
5251
use rustc_middle::traits::BuiltinImplSource;
@@ -65,7 +64,6 @@ use rustc_trait_selection::infer::InferCtxtExt as _;
6564
use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt;
6665
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
6766
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
68-
use rustc_trait_selection::traits::TraitEngineExt as _;
6967
use rustc_trait_selection::traits::{
7068
self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
7169
};
@@ -164,11 +162,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
164162
// Filter these cases out to make sure our coercion is more accurate.
165163
match res {
166164
Ok(InferOk { value, obligations }) if self.next_trait_solver() => {
167-
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
168-
fulfill_cx.register_predicate_obligations(self, obligations);
169-
let errs = fulfill_cx.select_where_possible(self);
170-
if errs.is_empty() {
171-
Ok(InferOk { value, obligations: fulfill_cx.pending_obligations() })
165+
let ocx = ObligationCtxt::new(self);
166+
ocx.register_obligations(obligations);
167+
if ocx.select_where_possible().is_empty() {
168+
Ok(InferOk { value, obligations: ocx.into_pending_obligations() })
172169
} else {
173170
Err(TypeError::Mismatch)
174171
}
@@ -631,13 +628,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
631628
// but we need to constrain vars before processing goals mentioning
632629
// them.
633630
Some(ty::PredicateKind::AliasRelate(..)) => {
634-
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
635-
fulfill_cx.register_predicate_obligation(self, obligation);
636-
let errs = fulfill_cx.select_where_possible(self);
637-
if !errs.is_empty() {
631+
let ocx = ObligationCtxt::new(self);
632+
ocx.register_obligation(obligation);
633+
if !ocx.select_where_possible().is_empty() {
638634
return Err(TypeError::Mismatch);
639635
}
640-
coercion.obligations.extend(fulfill_cx.pending_obligations());
636+
coercion.obligations.extend(ocx.into_pending_obligations());
641637
continue;
642638
}
643639
_ => {

compiler/rustc_infer/src/traits/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,18 @@ impl<'tcx> FulfillmentError<'tcx> {
206206
) -> FulfillmentError<'tcx> {
207207
FulfillmentError { obligation, code, root_obligation }
208208
}
209+
210+
pub fn is_true_error(&self) -> bool {
211+
match self.code {
212+
FulfillmentErrorCode::SelectionError(_)
213+
| FulfillmentErrorCode::ProjectionError(_)
214+
| FulfillmentErrorCode::SubtypeError(_, _)
215+
| FulfillmentErrorCode::ConstEquateError(_, _) => true,
216+
FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => {
217+
false
218+
}
219+
}
220+
}
209221
}
210222

211223
impl<'tcx> PolyTraitObligation<'tcx> {

compiler/rustc_middle/src/mir/interpret/allocation.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ use provenance_map::*;
2929
pub use init_mask::{InitChunk, InitChunkIter};
3030

3131
/// Functionality required for the bytes of an `Allocation`.
32-
pub trait AllocBytes:
33-
Clone + fmt::Debug + Eq + PartialEq + Hash + Deref<Target = [u8]> + DerefMut<Target = [u8]>
34-
{
32+
pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Target = [u8]> {
3533
/// Create an `AllocBytes` from a slice of `u8`.
3634
fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, _align: Align) -> Self;
3735

@@ -346,10 +344,10 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
346344
}
347345
}
348346

349-
impl<Bytes: AllocBytes> Allocation<CtfeProvenance, (), Bytes> {
347+
impl Allocation {
350348
/// Adjust allocation from the ones in `tcx` to a custom Machine instance
351-
/// with a different `Provenance` and `Extra` type.
352-
pub fn adjust_from_tcx<Prov: Provenance, Extra, Err>(
349+
/// with a different `Provenance`, `Extra` and `Byte` type.
350+
pub fn adjust_from_tcx<Prov: Provenance, Extra, Bytes: AllocBytes, Err>(
353351
self,
354352
cx: &impl HasDataLayout,
355353
extra: Extra,
@@ -371,7 +369,7 @@ impl<Bytes: AllocBytes> Allocation<CtfeProvenance, (), Bytes> {
371369
}
372370
// Create allocation.
373371
Ok(Allocation {
374-
bytes,
372+
bytes: AllocBytes::from_bytes(Cow::Owned(Vec::from(bytes)), self.align),
375373
provenance: ProvenanceMap::from_presorted_ptrs(new_provenance),
376374
init_mask: self.init_mask,
377375
align: self.align,

compiler/rustc_trait_selection/src/infer.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
2-
use crate::traits::{self, ObligationCtxt, SelectionContext, TraitEngineExt as _};
2+
use crate::traits::{self, ObligationCtxt, SelectionContext};
3+
34
use rustc_hir::def_id::DefId;
45
use rustc_hir::lang_items::LangItem;
5-
use rustc_infer::traits::{Obligation, TraitEngine, TraitEngineExt as _};
6+
use rustc_infer::traits::Obligation;
67
use rustc_macros::extension;
78
use rustc_middle::arena::ArenaAllocatable;
89
use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse};
@@ -93,9 +94,9 @@ impl<'tcx> InferCtxt<'tcx> {
9394
ty::TraitRef::new(self.tcx, trait_def_id, [ty]),
9495
)) {
9596
Ok(Some(selection)) => {
96-
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
97-
fulfill_cx.register_predicate_obligations(self, selection.nested_obligations());
98-
Some(fulfill_cx.select_all_or_error(self))
97+
let ocx = ObligationCtxt::new(self);
98+
ocx.register_obligations(selection.nested_obligations());
99+
Some(ocx.select_all_or_error())
99100
}
100101
Ok(None) | Err(_) => None,
101102
}

compiler/rustc_trait_selection/src/solve/inspect/analyse.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_ast_ir::visit::VisitorResult;
1414
use rustc_infer::infer::resolve::EagerResolver;
1515
use rustc_infer::infer::type_variable::TypeVariableOrigin;
1616
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
17-
use rustc_infer::traits::{TraitEngine, TraitEngineExt};
1817
use rustc_macros::extension;
1918
use rustc_middle::infer::unify_key::ConstVariableOrigin;
2019
use rustc_middle::traits::query::NoSolution;
@@ -26,9 +25,9 @@ use rustc_middle::ty::TypeFoldable;
2625
use rustc_span::{Span, DUMMY_SP};
2726

2827
use crate::solve::eval_ctxt::canonical;
29-
use crate::solve::FulfillmentCtxt;
3028
use crate::solve::{EvalCtxt, GoalEvaluationKind, GoalSource};
3129
use crate::solve::{GenerateProofTree, InferCtxtEvalExt};
30+
use crate::traits::ObligationCtxt;
3231

3332
pub struct InspectConfig {
3433
pub max_depth: usize,
@@ -74,14 +73,13 @@ impl<'tcx> NormalizesToTermHack<'tcx> {
7473
.eq(DefineOpaqueTypes::Yes, self.term, self.unconstrained_term)
7574
.map_err(|_| NoSolution)
7675
.and_then(|InferOk { value: (), obligations }| {
77-
let mut fulfill_cx = FulfillmentCtxt::new(infcx);
78-
fulfill_cx.register_predicate_obligations(infcx, obligations);
79-
if fulfill_cx.select_where_possible(infcx).is_empty() {
80-
if fulfill_cx.pending_obligations().is_empty() {
81-
Ok(Certainty::Yes)
82-
} else {
83-
Ok(Certainty::AMBIGUOUS)
84-
}
76+
let ocx = ObligationCtxt::new(infcx);
77+
ocx.register_obligations(obligations);
78+
let errors = ocx.select_all_or_error();
79+
if errors.is_empty() {
80+
Ok(Certainty::Yes)
81+
} else if errors.iter().all(|e| !e.is_true_error()) {
82+
Ok(Certainty::AMBIGUOUS)
8583
} else {
8684
Err(NoSolution)
8785
}

compiler/rustc_trait_selection/src/traits/coherence.rs

+38-41
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@
66
77
use crate::infer::outlives::env::OutlivesEnvironment;
88
use crate::infer::InferOk;
9-
use crate::regions::InferCtxtRegionExt;
109
use crate::solve::inspect::{InspectGoal, ProofTreeInferCtxtExt, ProofTreeVisitor};
11-
use crate::solve::{deeply_normalize_for_diagnostics, inspect, FulfillmentCtxt};
12-
use crate::traits::engine::TraitEngineExt as _;
10+
use crate::solve::{deeply_normalize_for_diagnostics, inspect};
1311
use crate::traits::select::IntercrateAmbiguityCause;
14-
use crate::traits::structural_normalize::StructurallyNormalizeExt;
1512
use crate::traits::NormalizeExt;
1613
use crate::traits::SkipLeakCheck;
1714
use crate::traits::{
@@ -22,7 +19,7 @@ use rustc_errors::{Diag, EmissionGuarantee};
2219
use rustc_hir::def::DefKind;
2320
use rustc_hir::def_id::DefId;
2421
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
25-
use rustc_infer::traits::{util, FulfillmentErrorCode, TraitEngine, TraitEngineExt};
22+
use rustc_infer::traits::{util, FulfillmentErrorCode};
2623
use rustc_middle::traits::query::NoSolution;
2724
use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
2825
use rustc_middle::traits::specialization_graph::OverlapMode;
@@ -35,6 +32,7 @@ use std::fmt::Debug;
3532
use std::ops::ControlFlow;
3633

3734
use super::error_reporting::suggest_new_overflow_limit;
35+
use super::ObligationCtxt;
3836

3937
/// Whether we do the orphan check relative to this crate or to some remote crate.
4038
#[derive(Copy, Clone, Debug)]
@@ -361,23 +359,27 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
361359
let infcx = selcx.infcx;
362360

363361
if infcx.next_trait_solver() {
364-
let mut fulfill_cx = FulfillmentCtxt::new(infcx);
365-
fulfill_cx.register_predicate_obligations(infcx, obligations.iter().cloned());
366-
362+
let ocx = ObligationCtxt::new(infcx);
363+
ocx.register_obligations(obligations.iter().cloned());
364+
let errors_and_ambiguities = ocx.select_all_or_error();
367365
// We only care about the obligations that are *definitely* true errors.
368366
// Ambiguities do not prove the disjointness of two impls.
369-
let errors = fulfill_cx.select_where_possible(infcx);
367+
let (errors, ambiguities): (Vec<_>, Vec<_>) =
368+
errors_and_ambiguities.into_iter().partition(|error| error.is_true_error());
369+
370370
if errors.is_empty() {
371-
let overflow_errors = fulfill_cx.collect_remaining_errors(infcx);
372-
let overflowing_predicates = overflow_errors
373-
.into_iter()
374-
.filter(|e| match e.code {
375-
FulfillmentErrorCode::Ambiguity { overflow: Some(true) } => true,
376-
_ => false,
377-
})
378-
.map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate))
379-
.collect();
380-
IntersectionHasImpossibleObligations::No { overflowing_predicates }
371+
IntersectionHasImpossibleObligations::No {
372+
overflowing_predicates: ambiguities
373+
.into_iter()
374+
.filter(|error| {
375+
matches!(
376+
error.code,
377+
FulfillmentErrorCode::Ambiguity { overflow: Some(true) }
378+
)
379+
})
380+
.map(|e| infcx.resolve_vars_if_possible(e.obligation.predicate))
381+
.collect(),
382+
}
381383
} else {
382384
IntersectionHasImpossibleObligations::Yes
383385
}
@@ -589,22 +591,22 @@ fn try_prove_negated_where_clause<'tcx>(
589591
// Without this, we over-eagerly register coherence ambiguity candidates when
590592
// impl candidates do exist.
591593
let ref infcx = root_infcx.fork_with_intercrate(false);
592-
let mut fulfill_cx = FulfillmentCtxt::new(infcx);
593-
594-
fulfill_cx.register_predicate_obligation(
595-
infcx,
596-
Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, negative_predicate),
597-
);
598-
if !fulfill_cx.select_all_or_error(infcx).is_empty() {
594+
let ocx = ObligationCtxt::new(infcx);
595+
ocx.register_obligation(Obligation::new(
596+
infcx.tcx,
597+
ObligationCause::dummy(),
598+
param_env,
599+
negative_predicate,
600+
));
601+
if !ocx.select_all_or_error().is_empty() {
599602
return false;
600603
}
601604

602605
// FIXME: We could use the assumed_wf_types from both impls, I think,
603606
// if that wasn't implemented just for LocalDefId, and we'd need to do
604607
// the normalization ourselves since this is totally fallible...
605608
let outlives_env = OutlivesEnvironment::new(param_env);
606-
607-
let errors = infcx.resolve_regions(&outlives_env);
609+
let errors = ocx.resolve_regions(&outlives_env);
608610
if !errors.is_empty() {
609611
return false;
610612
}
@@ -1129,22 +1131,17 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
11291131
result: Ok(_),
11301132
} = cand.kind()
11311133
{
1132-
let lazily_normalize_ty = |ty: Ty<'tcx>| {
1133-
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx);
1134+
let lazily_normalize_ty = |mut ty: Ty<'tcx>| {
11341135
if matches!(ty.kind(), ty::Alias(..)) {
1135-
// FIXME(-Znext-solver=coherence): we currently don't
1136-
// normalize opaque types here, resulting in diverging behavior
1137-
// for TAITs.
1138-
match infcx
1139-
.at(&ObligationCause::dummy(), param_env)
1140-
.structurally_normalize(ty, &mut *fulfill_cx)
1141-
{
1142-
Ok(ty) => Ok(ty),
1143-
Err(_errs) => Err(()),
1136+
let ocx = ObligationCtxt::new(infcx);
1137+
ty = ocx
1138+
.structurally_normalize(&ObligationCause::dummy(), param_env, ty)
1139+
.map_err(|_| ())?;
1140+
if !ocx.select_where_possible().is_empty() {
1141+
return Err(());
11441142
}
1145-
} else {
1146-
Ok(ty)
11471143
}
1144+
Ok(ty)
11481145
};
11491146

11501147
infcx.probe(|_| {

0 commit comments

Comments
 (0)