Skip to content

Commit

Permalink
Moved the Diverges struct to its own file
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicholas-Baron committed Sep 21, 2020
1 parent b1e9379 commit 428a8c6
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 77 deletions.
78 changes: 78 additions & 0 deletions compiler/rustc_typeck/src/check/diverges.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use rustc_span::source_map::DUMMY_SP;
use rustc_span::{self, Span};
use std::{cmp, ops};

/// Tracks whether executing a node may exit normally (versus
/// return/break/panic, which "diverge", leaving dead code in their
/// wake). Tracked semi-automatically (through type variables marked
/// as diverging), with some manual adjustments for control-flow
/// primitives (approximating a CFG).
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Diverges {
/// Potentially unknown, some cases converge,
/// others require a CFG to determine them.
Maybe,

/// Definitely known to diverge and therefore
/// not reach the next sibling or its parent.
Always {
/// The `Span` points to the expression
/// that caused us to diverge
/// (e.g. `return`, `break`, etc).
span: Span,
/// In some cases (e.g. a `match` expression
/// where all arms diverge), we may be
/// able to provide a more informative
/// message to the user.
/// If this is `None`, a default message
/// will be generated, which is suitable
/// for most cases.
custom_note: Option<&'static str>,
},

/// Same as `Always` but with a reachability
/// warning already emitted.
WarnedAlways,
}

// Convenience impls for combining `Diverges`.

impl ops::BitAnd for Diverges {
type Output = Self;
fn bitand(self, other: Self) -> Self {
cmp::min(self, other)
}
}

impl ops::BitOr for Diverges {
type Output = Self;
fn bitor(self, other: Self) -> Self {
cmp::max(self, other)
}
}

impl ops::BitAndAssign for Diverges {
fn bitand_assign(&mut self, other: Self) {
*self = *self & other;
}
}

impl ops::BitOrAssign for Diverges {
fn bitor_assign(&mut self, other: Self) {
*self = *self | other;
}
}

impl Diverges {
/// Creates a `Diverges::Always` with the provided `span` and the default note message.
pub(super) fn always(span: Span) -> Diverges {
Diverges::Always { span, custom_note: None }
}

pub(super) fn is_always(self) -> bool {
// Enum comparison ignores the
// contents of fields, so we just
// fill them in with garbage here.
self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
}
}
79 changes: 2 additions & 77 deletions compiler/rustc_typeck/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ mod closure;
pub mod coercion;
mod compare_method;
pub mod demand;
mod diverges;
pub mod dropck;
mod expr;
mod fn_ctxt;
Expand All @@ -86,6 +87,7 @@ mod upvar;
mod wfcheck;
pub mod writeback;

pub use diverges::Diverges;
pub use fn_ctxt::FnCtxt;
pub use inherited::{Inherited, InheritedBuilder};

Expand Down Expand Up @@ -125,8 +127,6 @@ use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
use rustc_trait_selection::traits::{self, ObligationCauseCode};

use std::cell::{Ref, RefCell, RefMut};
use std::cmp;
use std::ops::{self};

use crate::require_c_abi_if_c_variadic;
use crate::util::common::indenter;
Expand Down Expand Up @@ -326,81 +326,6 @@ pub enum PlaceOp {
Index,
}

/// Tracks whether executing a node may exit normally (versus
/// return/break/panic, which "diverge", leaving dead code in their
/// wake). Tracked semi-automatically (through type variables marked
/// as diverging), with some manual adjustments for control-flow
/// primitives (approximating a CFG).
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Diverges {
/// Potentially unknown, some cases converge,
/// others require a CFG to determine them.
Maybe,

/// Definitely known to diverge and therefore
/// not reach the next sibling or its parent.
Always {
/// The `Span` points to the expression
/// that caused us to diverge
/// (e.g. `return`, `break`, etc).
span: Span,
/// In some cases (e.g. a `match` expression
/// where all arms diverge), we may be
/// able to provide a more informative
/// message to the user.
/// If this is `None`, a default message
/// will be generated, which is suitable
/// for most cases.
custom_note: Option<&'static str>,
},

/// Same as `Always` but with a reachability
/// warning already emitted.
WarnedAlways,
}

// Convenience impls for combining `Diverges`.

impl ops::BitAnd for Diverges {
type Output = Self;
fn bitand(self, other: Self) -> Self {
cmp::min(self, other)
}
}

impl ops::BitOr for Diverges {
type Output = Self;
fn bitor(self, other: Self) -> Self {
cmp::max(self, other)
}
}

impl ops::BitAndAssign for Diverges {
fn bitand_assign(&mut self, other: Self) {
*self = *self & other;
}
}

impl ops::BitOrAssign for Diverges {
fn bitor_assign(&mut self, other: Self) {
*self = *self | other;
}
}

impl Diverges {
/// Creates a `Diverges::Always` with the provided `span` and the default note message.
fn always(span: Span) -> Diverges {
Diverges::Always { span, custom_note: None }
}

fn is_always(self) -> bool {
// Enum comparison ignores the
// contents of fields, so we just
// fill them in with garbage here.
self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
}
}

pub struct BreakableCtxt<'tcx> {
may_break: bool,

Expand Down

0 comments on commit 428a8c6

Please sign in to comment.