Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
280dfab
-Zsanitize and -Zsanitizer-cfi-normalize-integers flags are now targe…
azhogin Mar 20, 2025
abc57dc
Remove estebank from automated review assignment
jieyouxu May 2, 2025
fcc63ac
Add tests for `-Zremap-path-scope` and paths in diagnostics with deps
Urgau May 6, 2025
e534797
Rework `-Zremap-path-scope` macro test with dependency check
Urgau May 6, 2025
df13f7c
Require T: TypeFoldable in Binder<T> visit
compiler-errors Apr 23, 2025
1f774d7
Only prefer param-env candidates if they remain non-global after norm
compiler-errors May 6, 2025
8a21d1b
Review
compiler-errors May 7, 2025
a910329
Use MaybeCause::or to allow constraints from overflows if they are co…
compiler-errors May 6, 2025
b27d630
Point out region bound mismatches in check_region_bounds_on_impl_item
compiler-errors Apr 30, 2025
3286d4a
[win][arm64] Disable various DebugInfo tests that don't work on Arm64…
dpaoliello May 7, 2025
742aaf9
[arm64] Pointer auth test should link with C static library statically
dpaoliello May 7, 2025
fc0ef54
opaque_type_storage to InferCtxtLike
lcnr May 4, 2025
e7979ea
detect additional uses of opaques after writeback
lcnr May 4, 2025
0cacc05
[win][arm64] Disable FS tests that require symlinks
dpaoliello May 7, 2025
f03d246
Better error message for late/early lifetime param mismatch
compiler-errors May 1, 2025
aeb70c7
rustdoc-json: Remove newlines from attributes
aDotInTheVoid May 7, 2025
75ca6c6
[win][arm64] Disable MSVC Linker 'Arm Hazard' warning
dpaoliello May 7, 2025
38e3fa6
style: Never break within a nullary function call `func()` or a unit …
joshtriplett May 7, 2025
5913e55
Add `DefPathData::OpaqueLifetime` to avoid conflicts for remapped opa…
Zoxc May 7, 2025
1799f5f
triagebot: Better message for changes to `tests/rustdoc-json`
aDotInTheVoid May 7, 2025
01f04d1
Rollup merge of #138736 - azhogin:azhogin/sanitizers-target-modificat…
Zalathar May 8, 2025
646c0bf
Rollup merge of #140260 - compiler-errors:only-global-post-norm, r=lcnr
Zalathar May 8, 2025
b8ec2c8
Rollup merge of #140523 - compiler-errors:late-early-mismatch, r=jack…
Zalathar May 8, 2025
7b771f2
Rollup merge of #140579 - jieyouxu:temp-remove, r=wesleywiser
Zalathar May 8, 2025
69fabc3
Rollup merge of #140641 - lcnr:opaque-type-storage-entries, r=compile…
Zalathar May 8, 2025
f7bc4ee
Rollup merge of #140711 - compiler-errors:combine-maybes, r=lcnr
Zalathar May 8, 2025
c968cc8
Rollup merge of #140716 - Urgau:improve-remap_scope-tests, r=jieyouxu
Zalathar May 8, 2025
91961de
Rollup merge of #140755 - dpaoliello:arm64windebuginfo, r=jieyouxu
Zalathar May 8, 2025
faa36f6
Rollup merge of #140756 - dpaoliello:paclink, r=jieyouxu
Zalathar May 8, 2025
1336b56
Rollup merge of #140758 - dpaoliello:armhazard, r=jieyouxu
Zalathar May 8, 2025
a2443fe
Rollup merge of #140759 - dpaoliello:symlink, r=workingjubilee
Zalathar May 8, 2025
18a61c1
Rollup merge of #140762 - aDotInTheVoid:popnl, r=GuillaumeGomez
Zalathar May 8, 2025
4f3afa8
Rollup merge of #140764 - joshtriplett:style-nullary-functions, r=tra…
Zalathar May 8, 2025
b80749c
Rollup merge of #140769 - Zoxc:fix-140731, r=oli-obk
Zalathar May 8, 2025
b62764b
Rollup merge of #140773 - aDotInTheVoid:rdj-triagdfsadgs, r=dtolnay
Zalathar May 8, 2025
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
Prev Previous commit
Next Next commit
Use MaybeCause::or to allow constraints from overflows if they are co…
…mbined with ambiguity
  • Loading branch information
compiler-errors committed May 7, 2025
commit a910329c671aea4342413ecd8f88f09e47f8b85a
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,14 @@ where
(Certainty::Yes, NestedNormalizationGoals(goals))
}
_ => {
let certainty = shallow_certainty.unify_with(goals_certainty);
let certainty = shallow_certainty.and(goals_certainty);
(certainty, NestedNormalizationGoals::empty())
}
};

if let Certainty::Maybe(cause @ MaybeCause::Overflow { .. }) = certainty {
if let Certainty::Maybe(cause @ MaybeCause::Overflow { keep_constraints: false, .. }) =
certainty
{
// If we have overflow, it's probable that we're substituting a type
// into itself infinitely and any partial substitutions in the query
// response are probably not useful anyways, so just return an empty
Expand Down Expand Up @@ -193,6 +195,7 @@ where
debug!(?num_non_region_vars, "too many inference variables -> overflow");
return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
suggest_increasing_limit: true,
keep_constraints: false,
}));
}
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,7 @@ where
Certainty::Yes => {}
Certainty::Maybe(_) => {
self.nested_goals.push((source, with_resolved_vars));
unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
}
}
} else {
Expand All @@ -680,7 +680,7 @@ where
Certainty::Yes => {}
Certainty::Maybe(_) => {
self.nested_goals.push((source, goal));
unchanged_certainty = unchanged_certainty.map(|c| c.unify_with(certainty));
unchanged_certainty = unchanged_certainty.map(|c| c.and(certainty));
}
}
}
Expand Down
22 changes: 12 additions & 10 deletions compiler/rustc_next_trait_solver/src/solve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,16 +253,18 @@ where
}

fn bail_with_ambiguity(&mut self, responses: &[CanonicalResponse<I>]) -> CanonicalResponse<I> {
debug_assert!(!responses.is_empty());
if let Certainty::Maybe(maybe_cause) =
responses.iter().fold(Certainty::AMBIGUOUS, |certainty, response| {
certainty.unify_with(response.value.certainty)
})
{
self.make_ambiguous_response_no_constraints(maybe_cause)
} else {
panic!("expected flounder response to be ambiguous")
}
debug_assert!(responses.len() > 1);
let maybe_cause = responses.iter().fold(MaybeCause::Ambiguity, |maybe_cause, response| {
// Pull down the certainty of `Certainty::Yes` to ambiguity when combining
// these responses, b/c we're combining more than one response and this we
// don't know which one applies.
let candidate = match response.value.certainty {
Certainty::Yes => MaybeCause::Ambiguity,
Certainty::Maybe(candidate) => candidate,
};
maybe_cause.or(candidate)
});
self.make_ambiguous_response_no_constraints(maybe_cause)
}

/// If we fail to merge responses we flounder and return overflow or ambiguity.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,13 @@ pub(super) fn fulfillment_error_for_stalled<'tcx>(
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {
(FulfillmentErrorCode::Ambiguity { overflow: None }, true)
}
Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => (
Ok((
_,
Certainty::Maybe(MaybeCause::Overflow {
suggest_increasing_limit,
keep_constraints: _,
}),
)) => (
FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) },
// Don't look into overflows because we treat overflows weirdly anyways.
// We discard the inference constraints from overflowing goals, so
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
if let Some(term_hack) = normalizes_to_term_hack {
infcx
.probe(|_| term_hack.constrain(infcx, DUMMY_SP, uncanonicalized_goal.param_env))
.map(|certainty| ok.value.certainty.unify_with(certainty))
.map(|certainty| ok.value.certainty.and(certainty))
} else {
Ok(ok.value.certainty)
}
Expand Down
55 changes: 47 additions & 8 deletions compiler/rustc_type_ir/src/solve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,17 +266,17 @@ impl Certainty {
/// however matter for diagnostics. If `T: Foo` resulted in overflow and `T: Bar`
/// in ambiguity without changing the inference state, we still want to tell the
/// user that `T: Baz` results in overflow.
pub fn unify_with(self, other: Certainty) -> Certainty {
pub fn and(self, other: Certainty) -> Certainty {
match (self, other) {
(Certainty::Yes, Certainty::Yes) => Certainty::Yes,
(Certainty::Yes, Certainty::Maybe(_)) => other,
(Certainty::Maybe(_), Certainty::Yes) => self,
(Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.unify_with(b)),
(Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.and(b)),
}
}

pub const fn overflow(suggest_increasing_limit: bool) -> Certainty {
Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit })
Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: false })
}
}

Expand All @@ -289,19 +289,58 @@ pub enum MaybeCause {
/// or we hit a case where we just don't bother, e.g. `?x: Trait` goals.
Ambiguity,
/// We gave up due to an overflow, most often by hitting the recursion limit.
Overflow { suggest_increasing_limit: bool },
Overflow { suggest_increasing_limit: bool, keep_constraints: bool },
}

impl MaybeCause {
fn unify_with(self, other: MaybeCause) -> MaybeCause {
fn and(self, other: MaybeCause) -> MaybeCause {
match (self, other) {
(MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
(MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other,
(MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self,
(
MaybeCause::Overflow { suggest_increasing_limit: a },
MaybeCause::Overflow { suggest_increasing_limit: b },
) => MaybeCause::Overflow { suggest_increasing_limit: a || b },
MaybeCause::Overflow {
suggest_increasing_limit: limit_a,
keep_constraints: keep_a,
},
MaybeCause::Overflow {
suggest_increasing_limit: limit_b,
keep_constraints: keep_b,
},
) => MaybeCause::Overflow {
suggest_increasing_limit: limit_a && limit_b,
keep_constraints: keep_a && keep_b,
},
}
}

pub fn or(self, other: MaybeCause) -> MaybeCause {
match (self, other) {
(MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,

// When combining ambiguity + overflow, we can keep constraints.
(
MaybeCause::Ambiguity,
MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },
(
MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: _ },
MaybeCause::Ambiguity,
) => MaybeCause::Overflow { suggest_increasing_limit, keep_constraints: true },

(
MaybeCause::Overflow {
suggest_increasing_limit: limit_a,
keep_constraints: keep_a,
},
MaybeCause::Overflow {
suggest_increasing_limit: limit_b,
keep_constraints: keep_b,
},
) => MaybeCause::Overflow {
suggest_increasing_limit: limit_a || limit_b,
keep_constraints: keep_a || keep_b,
},
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//@ check-pass
//@ compile-flags: -Znext-solver

// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/201>.
// See comment below on `fn main`.

trait Intersect<U> {
type Output;
}

impl<T, U> Intersect<Vec<U>> for T
where
T: Intersect<U>,
{
type Output = T;
}

impl Intersect<Cuboid> for Cuboid {
type Output = Cuboid;
}

fn intersect<T, U>(_: &T, _: &U) -> T::Output
where
T: Intersect<U>,
{
todo!()
}

struct Cuboid;
impl Cuboid {
fn method(&self) {}
}

fn main() {
let x = vec![];
// Here we end up trying to normalize `<Cuboid as Intersect<Vec<?0>>>::Output`
// for the return type of the function, to constrain `y`. The impl then requires
// `Cuboid: Intersect<?0>`, which has two candidates. One that constrains
// `?0 = Vec<?1>`, which itself has the same two candidates and ends up leading
// to a recursion depth overflow. In the second impl, we constrain `?0 = Cuboid`.
//
// Floundering leads to us combining the overflow candidate and yes candidate to
// overflow. Because the response was overflow, we used to bubble it up to the
// parent normalizes-to goal, which caused us to drop its constraint that would
// guide us to normalize the associated type mentioned before.
//
// After this PR, we implement a new floundering "algebra" such that `Overflow OR Maybe`
// returns anew `Overflow { keep_constraints: true }`, which means that we don't
// need to drop constraints in the parent normalizes-to goal. This allows us to
// normalize `y` to `Cuboid`, and allows us to call the method successfully. We
// then constrain the `?0` in `let x: Vec<Cuboid> = x` below, so that we don't have
// a left over ambiguous goal.
let y = intersect(&Cuboid, &x);
y.method();
let x: Vec<Cuboid> = x;
}
Loading