Skip to content

Rollup of 8 pull requests #93288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 35 commits into from
Jan 25, 2022
Merged
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
18c14ad
Add a `try_clone()` function to `OwnedFd`.
sunfishcode Sep 9, 2021
622dfcc
Fix Windows compilation errors.
sunfishcode Sep 9, 2021
c986c6b
Fix more Windows compilation errors.
sunfishcode Sep 9, 2021
2d6a4c8
Fix another Windows compilation error.
sunfishcode Sep 9, 2021
53e072f
Fix compilation on WASI, which doesn't yet support `dup`.
sunfishcode Oct 5, 2021
83aebf8
Use the correct `cvt` for converting socket errors on Windows.
sunfishcode Jan 12, 2022
02f1a56
Properly track `DepNode`s in trait evaluation provisional cache
Aaron1011 Jan 19, 2022
f518827
Use impl1 and impl2 instead of a and b prefixes
spastorino Jan 21, 2022
052b31b
Move auxiliary fns out of overlap_with_probe
spastorino Jan 21, 2022
f4b4294
Remove FIXME and fix inconsistency of local blanket impls by using HI…
CraftSpider Jan 21, 2022
66d056a
Update test to include `self` case
CraftSpider Jan 21, 2022
1a0278e
Work around missing code coverage data causing llvm-cov failures
wesleywiser Jan 21, 2022
b2a45f0
Extract stable_disjoint fn
spastorino Jan 21, 2022
c2890ed
Add overlap mode
spastorino Jan 21, 2022
d2d25a5
Implement stable with negative coherence mode
spastorino Jan 21, 2022
1ec962f
Do not pass OverlapMode down, just create a closure to properly set t…
spastorino Jan 21, 2022
19e3c86
Make strict_disjoint use explicit_disjoint
spastorino Jan 21, 2022
e2567b0
Remove intermediate function doesn't make more sense
spastorino Jan 21, 2022
762bdbf
Change signature of point_at_arg_instead_of_call_if_possible
jackh726 Dec 25, 2021
ce31f68
Move param count error emission to near end of check_argument_types
jackh726 Jan 20, 2022
e5f2fdb
Restructure the code leveraging in abilities more than modes
spastorino Jan 22, 2022
9220631
Add has tests for blanket_with_local trait methods
CraftSpider Jan 23, 2022
7847ca8
Document OverlapMode
spastorino Jan 23, 2022
2693832
Rename strict_check to negative_impl_exists
spastorino Jan 23, 2022
8189bac
FIXME include regions too
spastorino Jan 23, 2022
11b17c6
rustdoc settings: use radio buttons for theme
jsha Jan 23, 2022
e02e958
Use error-on-mismatch policy for PAuth module flags.
jacobbramley Jan 19, 2022
687bb58
Rollup merge of #88794 - sunfishcode:sunfishcode/try-clone, r=joshtri…
matthiaskrgr Jan 25, 2022
cf70411
Rollup merge of #93064 - Aaron1011:provisional-dep-node, r=michaelwoe…
matthiaskrgr Jan 25, 2022
c8ede15
Rollup merge of #93118 - jackh726:param-heuristics-3, r=estebank
matthiaskrgr Jan 25, 2022
8dddc86
Rollup merge of #93144 - wesleywiser:uninhabited_type_code_cov2, r=tm…
matthiaskrgr Jan 25, 2022
677126c
Rollup merge of #93169 - CraftSpider:rustdoc-clean-inconsistency, r=G…
matthiaskrgr Jan 25, 2022
3d6f276
Rollup merge of #93175 - spastorino:negative-traits-coherence-new, r=…
matthiaskrgr Jan 25, 2022
c3ddca6
Rollup merge of #93251 - jsha:theme-radio, r=GuillaumeGomez
matthiaskrgr Jan 25, 2022
13b87d8
Rollup merge of #93269 - jacobbramley:dev/pauth-option-1, r=petrochenkov
matthiaskrgr Jan 25, 2022
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
Restructure the code leveraging in abilities more than modes
  • Loading branch information
spastorino committed Jan 22, 2022
commit e5f2fdb53939dc01ea6cad6e369c36aaa96f6e57
98 changes: 47 additions & 51 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::traits::util::impl_trait_ref_and_oblig;
use crate::traits::SkipLeakCheck;
use crate::traits::{
self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation,
SelectionContext,
PredicateObligations, SelectionContext,
};
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences};
Expand Down Expand Up @@ -137,12 +137,23 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
header
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
enum OverlapMode {
Stable,
WithNegative,
Strict,
}

impl OverlapMode {
fn use_negative_impl(&self) -> bool {
*self == OverlapMode::Strict || *self == OverlapMode::WithNegative
}

fn use_implicit_negative(&self) -> bool {
*self == OverlapMode::Stable || *self == OverlapMode::WithNegative
}
}

fn overlap_mode<'tcx>(tcx: TyCtxt<'tcx>, impl1_def_id: DefId, impl2_def_id: DefId) -> OverlapMode {
if tcx.has_attr(impl1_def_id, sym::rustc_strict_coherence)
!= tcx.has_attr(impl2_def_id, sym::rustc_strict_coherence)
Expand Down Expand Up @@ -190,6 +201,16 @@ fn overlap_within_probe<'cx, 'tcx>(
let infcx = selcx.infcx();
let tcx = infcx.tcx;

let overlap_mode = overlap_mode(tcx, impl1_def_id, impl2_def_id);

if overlap_mode.use_negative_impl() {
if negative_impl(selcx, impl1_def_id, impl2_def_id)
|| negative_impl(selcx, impl2_def_id, impl1_def_id)
{
return None;
}
}

// For the purposes of this check, we don't bring any placeholder
// types into scope; instead, we replace the generic types with
// fresh type variables, and hence we do our evaluations in an
Expand All @@ -199,29 +220,15 @@ fn overlap_within_probe<'cx, 'tcx>(
let impl1_header = with_fresh_ty_vars(selcx, param_env, impl1_def_id);
let impl2_header = with_fresh_ty_vars(selcx, param_env, impl2_def_id);

match overlap_mode(tcx, impl1_def_id, impl2_def_id) {
OverlapMode::Stable => {
if stable_disjoint(selcx, param_env, &impl1_header, impl2_header) {
return None;
}
}
OverlapMode::Strict => {
if strict_disjoint(selcx, impl1_def_id, impl2_def_id) {
return None;
}
debug!("overlap: impl1_header={:?}", impl1_header);
debug!("overlap: impl2_header={:?}", impl2_header);

// Equate for error reporting
let _ = selcx
.infcx()
.at(&ObligationCause::dummy(), param_env)
.eq_impl_headers(&impl1_header, &impl2_header);
}
OverlapMode::WithNegative => {
if stable_disjoint(selcx, param_env, &impl1_header, impl2_header)
|| strict_disjoint(selcx, impl1_def_id, impl2_def_id)
{
return None;
}
let obligations = equate_impl_headers(selcx, &impl1_header, &impl2_header)?;
debug!("overlap: unification check succeeded");

if overlap_mode.use_implicit_negative() {
if implicit_negative(selcx, param_env, &impl1_header, impl2_header, obligations) {
return None;
}
}

Expand All @@ -242,31 +249,29 @@ fn overlap_within_probe<'cx, 'tcx>(
Some(OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder })
}

fn equate_impl_headers<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
impl1_header: &ty::ImplHeader<'tcx>,
impl2_header: &ty::ImplHeader<'tcx>,
) -> Option<PredicateObligations<'tcx>> {
// Do `a` and `b` unify? If not, no overlap.
selcx
.infcx()
.at(&ObligationCause::dummy(), ty::ParamEnv::empty())
.eq_impl_headers(impl1_header, impl2_header)
.map(|infer_ok| infer_ok.obligations)
.ok()
}

/// Given impl1 and impl2 check if both impls can be satisfied by a common type (including
/// where-clauses) If so, return false, otherwise return true, they are disjoint.
fn stable_disjoint<'cx, 'tcx>(
fn implicit_negative<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
impl1_header: &ty::ImplHeader<'tcx>,
impl2_header: ty::ImplHeader<'tcx>,
obligations: PredicateObligations<'tcx>,
) -> bool {
debug!("overlap: impl1_header={:?}", impl1_header);
debug!("overlap: impl2_header={:?}", impl2_header);

// Do `a` and `b` unify? If not, no overlap.
let obligations = match selcx
.infcx()
.at(&ObligationCause::dummy(), param_env)
.eq_impl_headers(&impl1_header, &impl2_header)
{
Ok(InferOk { obligations, value: () }) => obligations,
Err(_) => {
return true;
}
};

debug!("overlap: unification check succeeded");

// There's no overlap if obligations are unsatisfiable or if the obligation negated is
// satisfied.
//
Expand Down Expand Up @@ -318,16 +323,7 @@ fn stable_disjoint<'cx, 'tcx>(

/// Given impl1 and impl2 check if both impls are never satisfied by a common type (including
/// where-clauses) If so, return true, they are disjoint and false otherwise.
fn strict_disjoint<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
impl1_def_id: DefId,
impl2_def_id: DefId,
) -> bool {
explicit_disjoint(selcx, impl1_def_id, impl2_def_id)
|| explicit_disjoint(selcx, impl2_def_id, impl1_def_id)
}

fn explicit_disjoint<'cx, 'tcx>(
fn negative_impl<'cx, 'tcx>(
selcx: &mut SelectionContext<'cx, 'tcx>,
impl1_def_id: DefId,
impl2_def_id: DefId,
Expand Down