Moved the Diverges struct to its own file

This commit is contained in:
Nicholas-Baron 2020-09-19 12:45:14 -07:00
parent b1e9379679
commit 428a8c6eae
2 changed files with 80 additions and 77 deletions

View File

@ -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 }
}
}

View File

@ -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;
@ -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};
@ -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;
@ -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,