Skip to content

Commit 095aa1d

Browse files
committed
sadness and sorrow
1 parent 102a7d6 commit 095aa1d

File tree

12 files changed

+175
-60
lines changed

12 files changed

+175
-60
lines changed

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ use crate::delegate::SolverDelegate;
2323
use crate::solve::inspect::ProbeKind;
2424
use crate::solve::{
2525
BuiltinImplSource, CandidateSource, CanonicalResponse, Certainty, EvalCtxt, Goal, GoalSource,
26-
MaybeCause, NoSolution, ParamEnvSource, QueryResult, has_no_inference_or_external_constraints,
26+
MaybeCause, NoSolution, OpaqueTypesJank, ParamEnvSource, QueryResult,
27+
has_no_inference_or_external_constraints,
2728
};
2829

2930
enum AliasBoundKind {
@@ -474,7 +475,7 @@ where
474475
//
475476
// cc trait-system-refactor-initiative#105
476477
let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
477-
let certainty = Certainty::Maybe(cause);
478+
let certainty = Certainty::Maybe { cause, opaque_types_jank: OpaqueTypesJank::AllGood };
478479
self.probe_trait_candidate(source)
479480
.enter(|this| this.evaluate_added_goals_and_make_canonical_response(certainty))
480481
}
@@ -975,6 +976,10 @@ where
975976
) {
976977
let self_ty = goal.predicate.self_ty();
977978
let opaque_types = self.opaques_with_sub_unified_hidden_type(self_ty);
979+
if opaque_types.is_empty() {
980+
candidates.extend(self.forced_ambiguity(MaybeCause::Ambiguity));
981+
}
982+
978983
for &alias_ty in &opaque_types {
979984
debug!("self ty is sub unified with {alias_ty:?}");
980985

@@ -1029,7 +1034,7 @@ where
10291034
// impls for it.
10301035
//
10311036
// See tests/ui/impl-trait/non-defining-uses/use-blanket-impl.rs for an example.
1032-
if !opaque_types.is_empty() && assemble_from.should_assemble_impl_candidates() {
1037+
if assemble_from.should_assemble_impl_candidates() {
10331038
let cx = self.cx();
10341039
cx.for_each_blanket_impl(goal.predicate.trait_def_id(cx), |impl_def_id| {
10351040
// For every `default impl`, there's always a non-default `impl`
@@ -1060,7 +1065,15 @@ where
10601065
}
10611066

10621067
if candidates.is_empty() {
1063-
candidates.extend(self.forced_ambiguity(MaybeCause::Ambiguity));
1068+
let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
1069+
let certainty = Certainty::Maybe {
1070+
cause: MaybeCause::Ambiguity,
1071+
opaque_types_jank: OpaqueTypesJank::ErrorIfRigidSelfTy,
1072+
};
1073+
candidates
1074+
.extend(self.probe_trait_candidate(source).enter(|this| {
1075+
this.evaluate_added_goals_and_make_canonical_response(certainty)
1076+
}));
10641077
}
10651078
}
10661079

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_index::IndexVec;
1515
use rustc_type_ir::data_structures::HashSet;
1616
use rustc_type_ir::inherent::*;
1717
use rustc_type_ir::relate::solver_relating::RelateExt;
18+
use rustc_type_ir::solve::OpaqueTypesJank;
1819
use rustc_type_ir::{
1920
self as ty, Canonical, CanonicalVarKind, CanonicalVarValues, InferCtxtLike, Interner,
2021
TypeFoldable,
@@ -141,8 +142,10 @@ where
141142
}
142143
};
143144

144-
if let Certainty::Maybe(cause @ MaybeCause::Overflow { keep_constraints: false, .. }) =
145-
certainty
145+
if let Certainty::Maybe {
146+
cause: cause @ MaybeCause::Overflow { keep_constraints: false, .. },
147+
opaque_types_jank,
148+
} = certainty
146149
{
147150
// If we have overflow, it's probable that we're substituting a type
148151
// into itself infinitely and any partial substitutions in the query
@@ -155,7 +158,7 @@ where
155158
//
156159
// Changing this to retain some constraints in the future
157160
// won't be a breaking change, so this is good enough for now.
158-
return Ok(self.make_ambiguous_response_no_constraints(cause));
161+
return Ok(self.make_ambiguous_response_no_constraints(cause, opaque_types_jank));
159162
}
160163

161164
let external_constraints =
@@ -199,10 +202,13 @@ where
199202
.count();
200203
if num_non_region_vars > self.cx().recursion_limit() {
201204
debug!(?num_non_region_vars, "too many inference variables -> overflow");
202-
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
203-
suggest_increasing_limit: true,
204-
keep_constraints: false,
205-
}));
205+
return Ok(self.make_ambiguous_response_no_constraints(
206+
MaybeCause::Overflow {
207+
suggest_increasing_limit: true,
208+
keep_constraints: false,
209+
},
210+
OpaqueTypesJank::AllGood,
211+
));
206212
}
207213
}
208214
}
@@ -216,13 +222,14 @@ where
216222
/// ambiguity but return constrained variables to guide inference.
217223
pub(in crate::solve) fn make_ambiguous_response_no_constraints(
218224
&self,
219-
maybe_cause: MaybeCause,
225+
cause: MaybeCause,
226+
opaque_types_jank: OpaqueTypesJank,
220227
) -> CanonicalResponse<I> {
221228
response_no_constraints_raw(
222229
self.cx(),
223230
self.max_input_universe,
224231
self.variables,
225-
Certainty::Maybe(maybe_cause),
232+
Certainty::Maybe { cause, opaque_types_jank },
226233
)
227234
}
228235

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_type_ir::inherent::*;
88
use rustc_type_ir::relate::Relate;
99
use rustc_type_ir::relate::solver_relating::RelateExt;
1010
use rustc_type_ir::search_graph::{CandidateHeadUsages, PathKind};
11+
use rustc_type_ir::solve::OpaqueTypesJank;
1112
use rustc_type_ir::{
1213
self as ty, CanonicalVarValues, InferCtxtLike, Interner, TypeFoldable, TypeFolder,
1314
TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
@@ -151,6 +152,11 @@ pub trait SolverDelegateEvalExt: SolverDelegate {
151152
stalled_on: Option<GoalStalledOn<Self::Interner>>,
152153
) -> Result<GoalEvaluation<Self::Interner>, NoSolution>;
153154

155+
fn root_goal_may_hold_opaque_types_jank(
156+
&self,
157+
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
158+
) -> bool;
159+
154160
/// Check whether evaluating `goal` with a depth of `root_depth` may
155161
/// succeed. This only returns `false` if the goal is guaranteed to
156162
/// not hold. In case evaluation overflows and fails with ambiguity this
@@ -193,6 +199,27 @@ where
193199
})
194200
}
195201

202+
fn root_goal_may_hold_opaque_types_jank(
203+
&self,
204+
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
205+
) -> bool {
206+
self.probe(|| {
207+
EvalCtxt::enter_root(self, self.cx().recursion_limit(), I::Span::dummy(), |ecx| {
208+
ecx.evaluate_goal(GoalSource::Misc, goal, None)
209+
})
210+
.is_ok_and(|r| match r.certainty {
211+
Certainty::Yes
212+
| Certainty::Maybe { cause: _, opaque_types_jank: OpaqueTypesJank::AllGood } => {
213+
true
214+
}
215+
Certainty::Maybe {
216+
cause: _,
217+
opaque_types_jank: OpaqueTypesJank::ErrorIfRigidSelfTy,
218+
} => false,
219+
})
220+
})
221+
}
222+
196223
fn root_goal_may_hold_with_depth(
197224
&self,
198225
root_depth: usize,
@@ -407,8 +434,12 @@ where
407434
// If we have run this goal before, and it was stalled, check that any of the goal's
408435
// args have changed. Otherwise, we don't need to re-run the goal because it'll remain
409436
// stalled, since it'll canonicalize the same way and evaluation is pure.
410-
if let Some(GoalStalledOn { num_opaques, ref stalled_vars, ref sub_roots, stalled_cause }) =
411-
stalled_on
437+
if let Some(GoalStalledOn {
438+
num_opaques,
439+
ref stalled_vars,
440+
ref sub_roots,
441+
stalled_certainty,
442+
}) = stalled_on
412443
&& !stalled_vars.iter().any(|value| self.delegate.is_changed_arg(*value))
413444
&& !sub_roots
414445
.iter()
@@ -419,7 +450,7 @@ where
419450
NestedNormalizationGoals::empty(),
420451
GoalEvaluation {
421452
goal,
422-
certainty: Certainty::Maybe(stalled_cause),
453+
certainty: stalled_certainty,
423454
has_changed: HasChanged::No,
424455
stalled_on,
425456
},
@@ -468,7 +499,7 @@ where
468499

469500
let stalled_on = match certainty {
470501
Certainty::Yes => None,
471-
Certainty::Maybe(stalled_cause) => match has_changed {
502+
Certainty::Maybe { .. } => match has_changed {
472503
// FIXME: We could recompute a *new* set of stalled variables by walking
473504
// through the orig values, resolving, and computing the root vars of anything
474505
// that is not resolved. Only when *these* have changed is it meaningful
@@ -518,7 +549,7 @@ where
518549
.len(),
519550
stalled_vars,
520551
sub_roots,
521-
stalled_cause,
552+
stalled_certainty: certainty,
522553
})
523554
}
524555
},
@@ -634,7 +665,7 @@ where
634665
if let Some(certainty) = self.delegate.compute_goal_fast_path(goal, self.origin_span) {
635666
match certainty {
636667
Certainty::Yes => {}
637-
Certainty::Maybe(_) => {
668+
Certainty::Maybe { .. } => {
638669
self.nested_goals.push((source, goal, None));
639670
unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
640671
}
@@ -710,7 +741,7 @@ where
710741

711742
match certainty {
712743
Certainty::Yes => {}
713-
Certainty::Maybe(_) => {
744+
Certainty::Maybe { .. } => {
714745
self.nested_goals.push((source, with_resolved_vars, stalled_on));
715746
unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
716747
}
@@ -724,7 +755,7 @@ where
724755

725756
match certainty {
726757
Certainty::Yes => {}
727-
Certainty::Maybe(_) => {
758+
Certainty::Maybe { .. } => {
728759
self.nested_goals.push((source, goal, stalled_on));
729760
unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
730761
}

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,10 @@ where
158158
if self.may_use_unstable_feature(param_env, symbol) {
159159
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
160160
} else {
161-
self.evaluate_added_goals_and_make_canonical_response(Certainty::Maybe(
162-
MaybeCause::Ambiguity,
163-
))
161+
self.evaluate_added_goals_and_make_canonical_response(Certainty::Maybe {
162+
cause: MaybeCause::Ambiguity,
163+
opaque_types_jank: OpaqueTypesJank::AllGood,
164+
})
164165
}
165166
}
166167

@@ -278,18 +279,21 @@ where
278279

279280
fn bail_with_ambiguity(&mut self, candidates: &[Candidate<I>]) -> CanonicalResponse<I> {
280281
debug_assert!(candidates.len() > 1);
281-
let maybe_cause =
282-
candidates.iter().fold(MaybeCause::Ambiguity, |maybe_cause, candidates| {
283-
// Pull down the certainty of `Certainty::Yes` to ambiguity when combining
282+
let (cause, opaque_types_jank) = candidates.iter().fold(
283+
(MaybeCause::Ambiguity, OpaqueTypesJank::AllGood),
284+
|(c, jank), candidates| {
285+
// We pull down the certainty of `Certainty::Yes` to ambiguity when combining
284286
// these responses, b/c we're combining more than one response and this we
285287
// don't know which one applies.
286-
let candidate = match candidates.result.value.certainty {
287-
Certainty::Yes => MaybeCause::Ambiguity,
288-
Certainty::Maybe(candidate) => candidate,
289-
};
290-
maybe_cause.or(candidate)
291-
});
292-
self.make_ambiguous_response_no_constraints(maybe_cause)
288+
match candidates.result.value.certainty {
289+
Certainty::Yes => (c, jank),
290+
Certainty::Maybe { cause, opaque_types_jank } => {
291+
(c.or(cause), jank.or(opaque_types_jank))
292+
}
293+
}
294+
},
295+
);
296+
self.make_ambiguous_response_no_constraints(cause, opaque_types_jank)
293297
}
294298

295299
/// If we fail to merge responses we flounder and return overflow or ambiguity.
@@ -427,6 +431,7 @@ pub struct GoalStalledOn<I: Interner> {
427431
pub num_opaques: usize,
428432
pub stalled_vars: Vec<I::GenericArg>,
429433
pub sub_roots: Vec<TyVid>,
430-
/// The cause that will be returned on subsequent evaluations if this goal remains stalled.
431-
pub stalled_cause: MaybeCause,
434+
/// The certainty that will be returned on subsequent evaluations if this
435+
/// goal remains stalled.
436+
pub stalled_certainty: Certainty,
432437
}

compiler/rustc_next_trait_solver/src/solve/search_graph.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ where
9393
fn is_ambiguous_result(result: QueryResult<I>) -> bool {
9494
result.is_ok_and(|response| {
9595
has_no_inference_or_external_constraints(response)
96-
&& matches!(response.value.certainty, Certainty::Maybe(_))
96+
&& matches!(response.value.certainty, Certainty::Maybe { .. })
9797
})
9898
}
9999

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ where
204204
//
205205
// Only goals proven via the trait solver should be region dependent.
206206
Certainty::Yes => {}
207-
Certainty::Maybe(_) => {
207+
Certainty::Maybe { .. } => {
208208
self.obligations.register(obligation, None);
209209
}
210210
}
@@ -258,7 +258,7 @@ where
258258
infcx.push_hir_typeck_potentially_region_dependent_goal(obligation);
259259
}
260260
}
261-
Certainty::Maybe(_) => self.obligations.register(obligation, stalled_on),
261+
Certainty::Maybe { .. } => self.obligations.register(obligation, stalled_on),
262262
}
263263
}
264264

compiler/rustc_trait_selection/src/solve/fulfill/derive_errors.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,17 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>(
9595
root_obligation.cause.span,
9696
None,
9797
) {
98-
Ok(GoalEvaluation { certainty: Certainty::Maybe(MaybeCause::Ambiguity), .. }) => {
99-
(FulfillmentErrorCode::Ambiguity { overflow: None }, true)
100-
}
98+
Ok(GoalEvaluation {
99+
certainty: Certainty::Maybe { cause: MaybeCause::Ambiguity, .. },
100+
..
101+
}) => (FulfillmentErrorCode::Ambiguity { overflow: None }, true),
101102
Ok(GoalEvaluation {
102103
certainty:
103-
Certainty::Maybe(MaybeCause::Overflow {
104-
suggest_increasing_limit,
105-
keep_constraints: _,
106-
}),
104+
Certainty::Maybe {
105+
cause:
106+
MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
107+
..
108+
},
107109
..
108110
}) => (
109111
FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) },
@@ -266,7 +268,8 @@ impl<'tcx> BestObligation<'tcx> {
266268
);
267269
// Skip nested goals that aren't the *reason* for our goal's failure.
268270
match (self.consider_ambiguities, nested_goal.result()) {
269-
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {}
271+
(true, Ok(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. }))
272+
| (false, Err(_)) => {}
270273
_ => continue,
271274
}
272275

@@ -407,7 +410,8 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
407410
let tcx = goal.infcx().tcx;
408411
// Skip goals that aren't the *reason* for our goal's failure.
409412
match (self.consider_ambiguities, goal.result()) {
410-
(true, Ok(Certainty::Maybe(MaybeCause::Ambiguity))) | (false, Err(_)) => {}
413+
(true, Ok(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. })) | (false, Err(_)) => {
414+
}
411415
_ => return ControlFlow::Continue(()),
412416
}
413417

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
332332
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
333333
assert_matches!(
334334
shallow_certainty.replace(c),
335-
None | Some(Certainty::Maybe(MaybeCause::Ambiguity))
335+
None | Some(Certainty::Maybe { cause: MaybeCause::Ambiguity, .. })
336336
);
337337
}
338338
inspect::ProbeStep::NestedProbe(ref probe) => {

0 commit comments

Comments
 (0)