Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on May 28, 2025. It is now read-only.
/rustPublic archive
forked fromrust-lang/rust

Commit7114d69

Browse files
authored
Unrolled build forrust-lang#140402
Rollup merge ofrust-lang#140402 - lcnr:normalizes-to-certainty-yes, r=compiler-errorsonly return nested goals for `Certainty::Yes`Ambiguous `NormalizesTo` goals can otherwise repeatedly add the same nested goals to the parent.r? ```@compiler-errors```
2 parents25cdf1f +016105c commit7114d69

File tree

3 files changed

+66
-32
lines changed

3 files changed

+66
-32
lines changed

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

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,19 @@ where
8181
/// the values inferred while solving the instantiated goal.
8282
/// - `external_constraints`: additional constraints which aren't expressible
8383
/// using simple unification of inference variables.
84+
///
85+
/// This takes the `shallow_certainty` which represents whether we're confident
86+
/// that the final result of the current goal only depends on the nested goals.
87+
///
88+
/// In case this is `Certainy::Maybe`, there may still be additional nested goals
89+
/// or inference constraints required for this candidate to be hold. The candidate
90+
/// always requires all already added constraints and nested goals.
8491
#[instrument(level ="trace", skip(self), ret)]
8592
pub(incrate::solve)fnevaluate_added_goals_and_make_canonical_response(
8693
&mutself,
87-
certainty:Certainty,
94+
shallow_certainty:Certainty,
8895
) ->QueryResult<I>{
89-
self.inspect.make_canonical_response(certainty);
96+
self.inspect.make_canonical_response(shallow_certainty);
9097

9198
let goals_certainty =self.try_evaluate_added_goals()?;
9299
assert_eq!(
@@ -103,26 +110,29 @@ where
103110
NoSolution
104111
})?;
105112

106-
// When normalizing, we've replaced the expected term with an unconstrained
107-
// inference variable. This means that we dropped information which could
108-
// have been important. We handle this by instead returning the nested goals
109-
// to the caller, where they are then handled.
110-
//
111-
// As we return all ambiguous nested goals, we can ignore the certainty returned
112-
// by `try_evaluate_added_goals()`.
113-
let(certainty, normalization_nested_goals) =matchself.current_goal_kind{
114-
CurrentGoalKind::NormalizesTo =>{
115-
let goals = std::mem::take(&mutself.nested_goals);
116-
if goals.is_empty(){
117-
assert!(matches!(goals_certainty,Certainty::Yes));
113+
let(certainty, normalization_nested_goals) =
114+
match(self.current_goal_kind, shallow_certainty){
115+
// When normalizing, we've replaced the expected term with an unconstrained
116+
// inference variable. This means that we dropped information which could
117+
// have been important. We handle this by instead returning the nested goals
118+
// to the caller, where they are then handled. We only do so if we do not
119+
// need to recompute the `NormalizesTo` goal afterwards to avoid repeatedly
120+
// uplifting its nested goals. This is the case if the `shallow_certainty` is
121+
// `Certainty::Yes`.
122+
(CurrentGoalKind::NormalizesTo,Certainty::Yes) =>{
123+
let goals = std::mem::take(&mutself.nested_goals);
124+
// As we return all ambiguous nested goals, we can ignore the certainty
125+
// returned by `self.try_evaluate_added_goals()`.
126+
if goals.is_empty(){
127+
assert!(matches!(goals_certainty,Certainty::Yes));
128+
}
129+
(Certainty::Yes,NestedNormalizationGoals(goals))
118130
}
119-
(certainty,NestedNormalizationGoals(goals))
120-
}
121-
CurrentGoalKind::Misc |CurrentGoalKind::CoinductiveTrait =>{
122-
let certainty = certainty.unify_with(goals_certainty);
123-
(certainty,NestedNormalizationGoals::empty())
124-
}
125-
};
131+
_ =>{
132+
let certainty = shallow_certainty.unify_with(goals_certainty);
133+
(certainty,NestedNormalizationGoals::empty())
134+
}
135+
};
126136

127137
ifletCertainty::Maybe(cause @MaybeCause::Overflow{ ..}) = certainty{
128138
// If we have overflow, it's probable that we're substituting a type

‎compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs‎

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mod opaque_types;
66
use rustc_type_ir::fast_reject::DeepRejectCtxt;
77
use rustc_type_ir::inherent::*;
88
use rustc_type_ir::lang_items::TraitSolverLangItem;
9-
use rustc_type_ir::{selfas ty,Interner,NormalizesTo,Upcastas _};
9+
use rustc_type_ir::{selfas ty,Interner,NormalizesTo,PredicateKind,Upcastas _};
1010
use tracing::instrument;
1111

1212
usecrate::delegate::SolverDelegate;
@@ -221,13 +221,21 @@ where
221221
Ok(Some(target_item_def_id)) => target_item_def_id,
222222
Ok(None) =>{
223223
match ecx.typing_mode(){
224-
// In case the associated item is hidden due to specialization, we have to
225-
// return ambiguity this would otherwise be incomplete, resulting in
226-
// unsoundness during coherence (#105782).
224+
// In case the associated item is hidden due to specialization,
225+
// normalizing this associated item is always ambiguous. Treating
226+
// the associated item as rigid would be incomplete and allow for
227+
// overlapping impls, see #105782.
228+
//
229+
// As this ambiguity is unavoidable we emit a nested ambiguous
230+
// goal instead of using `Certainty::AMBIGUOUS`. This allows us to
231+
// return the nested goals to the parent `AliasRelate` goal. This
232+
// would be relevant if any of the nested goals refer to the `term`.
233+
// This is not the case here and we only prefer adding an ambiguous
234+
// nested goal for consistency.
227235
ty::TypingMode::Coherence =>{
228-
returnecx.evaluate_added_goals_and_make_canonical_response(
229-
Certainty::AMBIGUOUS,
230-
);
236+
ecx.add_goal(GoalSource::Misc, goal.with(cx,PredicateKind::Ambiguous));
237+
return ecx
238+
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
231239
}
232240
// Outside of coherence, we treat the associated item as rigid instead.
233241
ty::TypingMode::Analysis{ ..}
@@ -254,10 +262,20 @@ where
254262
// treat it as rigid.
255263
if cx.impl_self_is_guaranteed_unsized(impl_def_id){
256264
match ecx.typing_mode(){
265+
// Trying to normalize such associated items is always ambiguous
266+
// during coherence to avoid cyclic reasoning. See the example in
267+
// tests/ui/traits/trivial-unsized-projection-in-coherence.rs.
268+
//
269+
// As this ambiguity is unavoidable we emit a nested ambiguous
270+
// goal instead of using `Certainty::AMBIGUOUS`. This allows us to
271+
// return the nested goals to the parent `AliasRelate` goal. This
272+
// would be relevant if any of the nested goals refer to the `term`.
273+
// This is not the case here and we only prefer adding an ambiguous
274+
// nested goal for consistency.
257275
ty::TypingMode::Coherence =>{
258-
returnecx.evaluate_added_goals_and_make_canonical_response(
259-
Certainty::AMBIGUOUS,
260-
);
276+
ecx.add_goal(GoalSource::Misc, goal.with(cx,PredicateKind::Ambiguous));
277+
return ecx
278+
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
261279
}
262280
ty::TypingMode::Analysis{ ..}
263281
| ty::TypingMode::Borrowck{ ..}

‎compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
44
use rustc_index::bit_set::GrowableBitSet;
55
use rustc_type_ir::inherent::*;
6+
use rustc_type_ir::solve::GoalSource;
67
use rustc_type_ir::{selfas ty,Interner,TypingMode, fold_regions};
78

89
usecrate::delegate::SolverDelegate;
@@ -31,7 +32,12 @@ where
3132
goal.param_env,
3233
expected,
3334
);
34-
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
35+
// Trying to normalize an opaque type during coherence is always ambiguous.
36+
// We add a nested ambiguous goal here instead of using `Certainty::AMBIGUOUS`.
37+
// This allows us to return the nested goals to the parent `AliasRelate` goal.
38+
// This can then allow nested goals to fail after we've constrained the `term`.
39+
self.add_goal(GoalSource::Misc, goal.with(cx, ty::PredicateKind::Ambiguous));
40+
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
3541
}
3642
TypingMode::Analysis{ defining_opaque_types_and_generators} =>{
3743
letSome(def_id) = opaque_ty

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp