17b322fa69
stabilize `-Znext-solver=coherence` r? `@compiler-errors` --- This PR stabilizes the use of the next generation trait solver in coherence checking by enabling `-Znext-solver=coherence` by default. More specifically its use in the *implicit negative overlap check*. The tracking issue for this is https://github.com/rust-lang/rust/issues/114862. Closes #114862. ## Background ### The next generation trait solver The new solver lives in [`rustc_trait_selection::solve`](https://github.com/rust-lang/rust/blob/master/compiler/rustc_trait_selection/src/solve/mod.rs) and is intended to replace the existing *evaluate*, *fulfill*, and *project* implementation. It also has a wider impact on the rest of the type system, for example by changing our approach to handling associated types. For a more detailed explanation of the new trait solver, see the [rustc-dev-guide](https://rustc-dev-guide.rust-lang.org/solve/trait-solving.html). This does not stabilize the current behavior of the new trait solver, only the behavior impacting the implicit negative overlap check. There are many areas in the new solver which are not yet finalized. We are confident that their final design will not conflict with the user-facing behavior observable via coherence. More on that further down. Please check out [the chapter](https://rustc-dev-guide.rust-lang.org/solve/significant-changes.html) summarizing the most significant changes between the existing and new implementations. ### Coherence and the implicit negative overlap check Coherence checking detects any overlapping impls. Overlapping trait impls always error while overlapping inherent impls result in an error if they have methods with the same name. Coherence also results in an error if any other impls could exist, even if they are currently unknown. This affects impls which may get added to upstream crates in a backwards compatible way and impls from downstream crates. Coherence failing to detect overlap is generally considered to be unsound, even if it is difficult to actually get runtime UB this way. It is quite easy to get ICEs due to bugs in coherence. It currently consists of two checks: The [orphan check] validates that impls do not overlap with other impls we do not know about: either because they may be defined in a sibling crate, or because an upstream crate is allowed to add it without being considered a breaking change. The [overlap check] validates that impls do not overlap with other impls we know about. This is done as follows: - Instantiate the generic parameters of both impls with inference variables - Equate the `TraitRef`s of both impls. If it fails there is no overlap. - [implicit negative]: Check whether any of the instantiated `where`-bounds of one of the impls definitely do not hold when using the constraints from the previous step. If a `where`-bound does not hold, there is no overlap. - *explicit negative (still unstable, ignored going forward)*: Check whether the any negated `where`-bounds can be proven, e.g. a `&mut u32: Clone` bound definitely does not hold as an explicit `impl<T> !Clone for &mut T` exists. The overlap check has to *prove that unifying the impls does not succeed*. This means that **incorrectly getting a type error during coherence is unsound** as it would allow impls to overlap: coherence has to be *complete*. Completeness means that we never incorrectly error. This means that during coherence we must only add inference constraints if they are definitely necessary. During ordinary type checking [this does not hold](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=01d93b592bd9036ac96071cbf1d624a9), so the trait solver has to behave differently, depending on whether we're in coherence or not. The implicit negative check only considers goals to "definitely not hold" if they could not be implemented downstream, by a sibling, or upstream in a backwards compatible way. If the goal is is "unknowable" as it may get added in another crate, we add an ambiguous candidate: [source]( |
||
---|---|---|
.. | ||
alias-liveness | ||
auxiliary | ||
diagnostics | ||
explicit-generic-args-with-impl-trait | ||
in-ctfe | ||
in-trait | ||
issues | ||
multiple-lifetimes | ||
precise-capturing | ||
rpit | ||
transmute | ||
arg-position-impl-trait-too-long.rs | ||
arg-position-impl-trait-too-long.stderr | ||
associated-impl-trait-type-generic-trait.rs | ||
associated-impl-trait-type-issue-114325.rs | ||
associated-impl-trait-type-trivial.rs | ||
associated-impl-trait-type.rs | ||
associated-type-cycle.rs | ||
associated-type-cycle.stderr | ||
associated-type-undefine.rs | ||
associated-type-undefine.stderr | ||
async_scope_creep.rs | ||
auto-trait-coherence.next.stderr | ||
auto-trait-coherence.old.stderr | ||
auto-trait-coherence.rs | ||
auto-trait-coherence.stderr | ||
auto-trait-leak2.rs | ||
auto-trait-leak2.stderr | ||
auto-trait-leak-rpass.rs | ||
auto-trait-leak.rs | ||
auto-trait-leak.stderr | ||
auto-trait-selection-freeze.next.stderr | ||
auto-trait-selection-freeze.old.stderr | ||
auto-trait-selection-freeze.rs | ||
auto-trait-selection.next.stderr | ||
auto-trait-selection.old.stderr | ||
auto-trait-selection.rs | ||
autoderef.rs | ||
bivariant-lifetime-liveness.rs | ||
bound-normalization-fail.rs | ||
bound-normalization-fail.stderr | ||
bound-normalization-pass.rs | ||
bounds_regression.rs | ||
call_method_ambiguous.next.stderr | ||
call_method_ambiguous.rs | ||
call_method_on_inherent_impl_on_rigid_type.current.stderr | ||
call_method_on_inherent_impl_on_rigid_type.next.stderr | ||
call_method_on_inherent_impl_on_rigid_type.rs | ||
call_method_on_inherent_impl_ref.current.stderr | ||
call_method_on_inherent_impl_ref.next.stderr | ||
call_method_on_inherent_impl_ref.rs | ||
call_method_on_inherent_impl.next.stderr | ||
call_method_on_inherent_impl.rs | ||
call_method_without_import.no_import.stderr | ||
call_method_without_import.rs | ||
can-return-unconstrained-closure.rs | ||
capture-lifetime-not-in-hir.rs | ||
capture-lifetime-not-in-hir.stderr | ||
closure-calling-parent-fn.rs | ||
closure-in-impl-trait-arg.rs | ||
closure-in-impl-trait.rs | ||
coherence-treats-tait-ambig.current.stderr | ||
coherence-treats-tait-ambig.rs | ||
coherence-treats-tait-ambig.stderr | ||
cross-return-site-inference.rs | ||
cross-return-site-inference.stderr | ||
deduce-signature-from-supertrait.rs | ||
defined-by-trait-resolution.rs | ||
defining-use-captured-non-universal-region.infer.stderr | ||
defining-use-captured-non-universal-region.rs | ||
defining-use-captured-non-universal-region.statik.stderr | ||
defining-use-uncaptured-non-universal-region-2.rs | ||
defining-use-uncaptured-non-universal-region-3.rs | ||
defining-use-uncaptured-non-universal-region.rs | ||
deprecated_annotation.rs | ||
different_where_bounds.rs | ||
divergence.rs | ||
does-not-live-long-enough.rs | ||
does-not-live-long-enough.stderr | ||
dont-suggest-box-on-empty-else-arm.rs | ||
dont-suggest-box-on-empty-else-arm.stderr | ||
dyn-impl-type-mismatch.rs | ||
dyn-impl-type-mismatch.stderr | ||
dyn-trait-elided-two-inputs-assoc.rs | ||
dyn-trait-elided-two-inputs-param.rs | ||
dyn-trait-elided-two-inputs-ref-assoc.rs | ||
dyn-trait-elided-two-inputs-ref-param.rs | ||
dyn-trait-return-should-be-impl-trait.rs | ||
dyn-trait-return-should-be-impl-trait.stderr | ||
eagerly-reveal-in-local-body.rs | ||
equal-hidden-lifetimes.rs | ||
equality2.rs | ||
equality2.stderr | ||
equality-in-canonical-query.rs | ||
equality-rpass.rs | ||
equality-rpass.stderr | ||
equality.rs | ||
equality.stderr | ||
erased-regions-in-hidden-ty.current.stderr | ||
erased-regions-in-hidden-ty.next.stderr | ||
erased-regions-in-hidden-ty.rs | ||
example-calendar.rs | ||
example-st.rs | ||
example-st.stderr | ||
extra-impl-in-trait-impl.fixed | ||
extra-impl-in-trait-impl.rs | ||
extra-impl-in-trait-impl.stderr | ||
extra-item.rs | ||
extra-item.stderr | ||
failed-to-resolve-instance-ice-105488.rs | ||
failed-to-resolve-instance-ice-105488.stderr | ||
failed-to-resolve-instance-ice-123145.rs | ||
failed-to-resolve-instance-ice-123145.stderr | ||
fallback_inference.rs | ||
fallback_inference.stderr | ||
fallback.rs | ||
feature-self-return-type.rs | ||
feature-self-return-type.stderr | ||
fresh-lifetime-from-bare-trait-obj-114664.rs | ||
fresh-lifetime-from-bare-trait-obj-114664.stderr | ||
future-no-bound-vars-ice-112347.rs | ||
generic-with-implicit-hrtb-without-dyn.edition2015.stderr | ||
generic-with-implicit-hrtb-without-dyn.edition2021.stderr | ||
generic-with-implicit-hrtb-without-dyn.rs | ||
hidden-lifetimes.rs | ||
hidden-lifetimes.stderr | ||
hidden-type-is-opaque-2.default.stderr | ||
hidden-type-is-opaque-2.next.stderr | ||
hidden-type-is-opaque-2.rs | ||
hidden-type-is-opaque.rs | ||
ice-unexpected-param-type-whensubstituting-in-region-112823.rs | ||
ice-unexpected-param-type-whensubstituting-in-region-112823.stderr | ||
impl_fn_associativity.rs | ||
impl_trait_projections.rs | ||
impl_trait_projections.stderr | ||
impl-fn-hrtb-bounds-2.rs | ||
impl-fn-hrtb-bounds-2.stderr | ||
impl-fn-hrtb-bounds.rs | ||
impl-fn-hrtb-bounds.stderr | ||
impl-fn-parsing-ambiguities.rs | ||
impl-fn-parsing-ambiguities.stderr | ||
impl-fn-predefined-lifetimes.rs | ||
impl-fn-predefined-lifetimes.stderr | ||
impl-generic-mismatch-ab.rs | ||
impl-generic-mismatch-ab.stderr | ||
impl-generic-mismatch.rs | ||
impl-generic-mismatch.stderr | ||
impl-subtyper2.rs | ||
impl-subtyper.rs | ||
impl-trait-in-macro.rs | ||
impl-trait-in-macro.stderr | ||
impl-trait-plus-priority.rs | ||
impl-trait-plus-priority.stderr | ||
implicit-capture-late.rs | ||
implicit-capture-late.stderr | ||
in-assoc-type-unconstrained.rs | ||
in-assoc-type-unconstrained.stderr | ||
in-assoc-type.rs | ||
in-assoc-type.stderr | ||
issue-35668.rs | ||
issue-35668.stderr | ||
issue-36792.rs | ||
issue-46959.rs | ||
issue-49556.rs | ||
issue-49579.rs | ||
issue-49685.rs | ||
issue-51185.rs | ||
issue-54966.rs | ||
issue-54966.stderr | ||
issue-55872-1.rs | ||
issue-55872-1.stderr | ||
issue-55872-2.rs | ||
issue-55872-2.stderr | ||
issue-55872-3.rs | ||
issue-55872-3.stderr | ||
issue-55872.rs | ||
issue-55872.stderr | ||
issue-56445.rs | ||
issue-68532.rs | ||
issue-72911.rs | ||
issue-72911.stderr | ||
issue-87450.rs | ||
issue-87450.stderr | ||
issue-99073-2.rs | ||
issue-99073-2.stderr | ||
issue-99073.rs | ||
issue-99073.stderr | ||
issue-99642-2.rs | ||
issue-99642.rs | ||
issue-99914.rs | ||
issue-99914.stderr | ||
issue-100075-2.rs | ||
issue-100075-2.stderr | ||
issue-100075.rs | ||
issue-100075.stderr | ||
issue-100187.rs | ||
issue-102605.rs | ||
issue-102605.stderr | ||
issue-103181-1.current.stderr | ||
issue-103181-1.next.stderr | ||
issue-103181-1.rs | ||
issue-103181-2.rs | ||
issue-103181-2.stderr | ||
issue-103599.rs | ||
issue-103599.stderr | ||
issue-108591.rs | ||
issue-108592.rs | ||
lazy_subtyping_of_opaques.rs | ||
lifetime-ambiguity-regression.rs | ||
lifetimes2.rs | ||
lifetimes.rs | ||
mapping-duplicated-lifetimes-issue-114597.rs | ||
method-resolution2.next.stderr | ||
method-resolution2.rs | ||
method-resolution3.current.stderr | ||
method-resolution3.next.stderr | ||
method-resolution3.rs | ||
method-resolution4.next.stderr | ||
method-resolution4.rs | ||
method-resolution.rs | ||
method-suggestion-no-duplication.rs | ||
method-suggestion-no-duplication.stderr | ||
multiple-defining-usages-in-body.rs | ||
multiple-defining-usages-in-body.stderr | ||
must_outlive_least_region_or_bound.rs | ||
must_outlive_least_region_or_bound.stderr | ||
needs_least_region_or_bound.rs | ||
negative-reasoning.rs | ||
negative-reasoning.stderr | ||
nested_impl_trait.rs | ||
nested_impl_trait.stderr | ||
nested-hkl-lifetime.rs | ||
nested-return-type2-tait2.rs | ||
nested-return-type2-tait2.stderr | ||
nested-return-type2-tait3.rs | ||
nested-return-type2-tait3.stderr | ||
nested-return-type2-tait.rs | ||
nested-return-type2-tait.stderr | ||
nested-return-type2.rs | ||
nested-return-type3-tait2.rs | ||
nested-return-type3-tait2.stderr | ||
nested-return-type3-tait3.rs | ||
nested-return-type3-tait3.stderr | ||
nested-return-type3-tait.rs | ||
nested-return-type3-tait.stderr | ||
nested-return-type3.rs | ||
nested-return-type4.rs | ||
nested-return-type4.stderr | ||
nested-return-type.rs | ||
nested-rpit-hrtb-2.rs | ||
nested-rpit-hrtb-2.stderr | ||
nested-rpit-hrtb.rs | ||
nested-rpit-hrtb.stderr | ||
nested-rpit-with-anonymous-lifetimes.rs | ||
nesting.rs | ||
no-method-suggested-traits.rs | ||
no-method-suggested-traits.stderr | ||
no-trait.rs | ||
no-trait.stderr | ||
normalize-opaque-with-bound-vars.rs | ||
normalize-tait-in-const.rs | ||
normalize-tait-in-const.stderr | ||
not_general_enough_regression_106630.rs | ||
object-unsafe-trait-in-return-position-dyn-trait.rs | ||
object-unsafe-trait-in-return-position-dyn-trait.stderr | ||
object-unsafe-trait-in-return-position-impl-trait.rs | ||
object-unsafe-trait-in-return-position-impl-trait.stderr | ||
opaque-cast-field-access-in-future.rs | ||
opaque-cast-field-access-in-future.stderr | ||
opaque-used-in-extraneous-argument.rs | ||
opaque-used-in-extraneous-argument.stderr | ||
point-to-type-err-cause-on-impl-trait-return.rs | ||
point-to-type-err-cause-on-impl-trait-return.stderr | ||
printing-binder.rs | ||
printing-binder.stderr | ||
private_unused.rs | ||
projection-mismatch-in-impl-where-clause.rs | ||
projection-mismatch-in-impl-where-clause.stderr | ||
projection.rs | ||
question_mark.rs | ||
recursive-auto-trait.rs | ||
recursive-bound-eval.next.stderr | ||
recursive-bound-eval.rs | ||
recursive-coroutine-boxed.next.stderr | ||
recursive-coroutine-boxed.rs | ||
recursive-coroutine-indirect.current.stderr | ||
recursive-coroutine-indirect.next.stderr | ||
recursive-coroutine-indirect.rs | ||
recursive-ice-101862.rs | ||
recursive-ice-101862.stderr | ||
recursive-impl-trait-type-direct.rs | ||
recursive-impl-trait-type-indirect.rs | ||
recursive-impl-trait-type-indirect.stderr | ||
recursive-impl-trait-type-through-non-recursive.rs | ||
recursive-impl-trait-type-through-non-recursive.stderr | ||
recursive-parent-trait-method-call.rs | ||
recursive-type-alias-impl-trait-declaration-too-subtle-2.rs | ||
recursive-type-alias-impl-trait-declaration-too-subtle.rs | ||
recursive-type-alias-impl-trait-declaration-too-subtle.stderr | ||
recursive-type-alias-impl-trait-declaration.rs | ||
recursive-type-alias-impl-trait-declaration.stderr | ||
region-escape-via-bound-contravariant-closure.rs | ||
region-escape-via-bound-contravariant.rs | ||
region-escape-via-bound.rs | ||
region-escape-via-bound.stderr | ||
return-position-impl-trait-minimal.rs | ||
reveal-during-codegen.rs | ||
rpit-assoc-pair-with-lifetime.rs | ||
rpit-assoc-pair-with-lifetime.stderr | ||
rpit-not-sized.rs | ||
rpit-not-sized.stderr | ||
stashed-diag-issue-121504.rs | ||
stashed-diag-issue-121504.stderr | ||
static-lifetime-return-position-impl-trait.rs | ||
static-return-lifetime-infered.rs | ||
static-return-lifetime-infered.stderr | ||
stranded-opaque.rs | ||
stranded-opaque.stderr | ||
suggest-calling-rpit-closure.rs | ||
suggest-calling-rpit-closure.stderr | ||
trait_resolution.rs | ||
trait_type.rs | ||
trait_type.stderr | ||
trait_upcasting_reference_mismatch.rs | ||
trait_upcasting_reference_mismatch.stderr | ||
trait_upcasting.rs | ||
two_tait_defining_each_other2.current.stderr | ||
two_tait_defining_each_other2.next.stderr | ||
two_tait_defining_each_other2.rs | ||
two_tait_defining_each_other3.current.stderr | ||
two_tait_defining_each_other3.rs | ||
two_tait_defining_each_other.current.stderr | ||
two_tait_defining_each_other.rs | ||
type_parameters_captured.rs | ||
type_parameters_captured.stderr | ||
type-alias-generic-param.rs | ||
type-alias-generic-param.stderr | ||
type-alias-impl-trait-in-fn-body.rs | ||
type-alias-impl-trait-in-fn-body.stderr | ||
type-arg-mismatch-due-to-impl-trait.rs | ||
type-arg-mismatch-due-to-impl-trait.stderr | ||
unactionable_diagnostic.fixed | ||
unactionable_diagnostic.rs | ||
unactionable_diagnostic.stderr | ||
universal_hrtb_anon.rs | ||
universal_hrtb_named.rs | ||
universal_in_adt_in_parameters.rs | ||
universal_in_impl_trait_in_parameters.rs | ||
universal_in_trait_defn_parameters.rs | ||
universal_multiple_bounds.rs | ||
universal_wrong_bounds.rs | ||
universal_wrong_bounds.stderr | ||
universal_wrong_hrtb.rs | ||
universal_wrong_hrtb.stderr | ||
universal-mismatched-type.rs | ||
universal-mismatched-type.stderr | ||
universal-two-impl-traits.rs | ||
universal-two-impl-traits.stderr | ||
unsafety-checking-cycle.rs | ||
unsize_adt.rs | ||
unsize_slice.rs | ||
unsize_tuple.rs | ||
unsized_coercion2.old.stderr | ||
unsized_coercion2.rs | ||
unsized_coercion3.next.stderr | ||
unsized_coercion3.old.stderr | ||
unsized_coercion3.rs | ||
unsized_coercion4.rs | ||
unsized_coercion5.next.stderr | ||
unsized_coercion5.old.stderr | ||
unsized_coercion5.rs | ||
unsized_coercion.next.stderr | ||
unsized_coercion.rs | ||
upvar_captures.rs | ||
upvar_captures.stderr | ||
variance.e2024.stderr | ||
variance.new.stderr | ||
variance.old.stderr | ||
variance.rs | ||
wf-check-hidden-type.rs | ||
wf-check-hidden-type.stderr | ||
wf-eval-order.rs | ||
where-allowed-2.rs | ||
where-allowed-2.stderr | ||
where-allowed.rs | ||
where-allowed.stderr | ||
xcrate_simple.rs | ||
xcrate.rs |