Skip to content

bool::implies and bool::implied_by #188

@GoldsteinE

Description

@GoldsteinE

Proposal

Problem statement

There’s no clean way to express boolean implication: you need to resort to something like !a || b.

Motivation, use-cases

Happens kind of a lot, but it may be unclear whether a.implies(b) or !a || b is more clear in each concrete use case.

Some examples from rustc:

https://github.com/rust-lang/rust/blob/f63ccaf25f74151a5d8ce057904cd944074b01d2/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs#L451

if !expected.is_box() || found.is_box()

https://github.com/rust-lang/rust/blob/f63ccaf25f74151a5d8ce057904cd944074b01d2/compiler/rustc_expand/src/config.rs#L444

attrs.iter().all(|attr| !is_cfg(attr) || self.cfg_true(attr))

https://github.com/rust-lang/rust/blob/f63ccaf25f74151a5d8ce057904cd944074b01d2/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs#L44

!clone_or_copy_needed || is_copy(cx, in_ty)

Solution sketches

impl bool {
    fn implies(self, other: Self) -> Self {
        !self || other
    }

    fn implied_by(self, other: Self) -> Self {
        self || !other
    }

    // Or maybe (to preserve laziness)
    fn implies(self, other: impl FnOnce() -> Self) -> Self {
        !self || other()
    }

    fn implied_by(self, other: impl FnOnce() -> Self) -> Self {
        self || !other()
    }
}

Links and related work

Some languages have implication function or operator, e.g. Racket.

Rust has <=, which works like boolean implication but looks like implication backwards, which is kinda confusing.

What happens now?

This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions