Skip to content

Commit 428a8c6

Browse files
Moved the Diverges struct to its own file
1 parent b1e9379 commit 428a8c6

File tree

2 files changed

+80
-77
lines changed

2 files changed

+80
-77
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
use rustc_span::source_map::DUMMY_SP;
2+
use rustc_span::{self, Span};
3+
use std::{cmp, ops};
4+
5+
/// Tracks whether executing a node may exit normally (versus
6+
/// return/break/panic, which "diverge", leaving dead code in their
7+
/// wake). Tracked semi-automatically (through type variables marked
8+
/// as diverging), with some manual adjustments for control-flow
9+
/// primitives (approximating a CFG).
10+
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
11+
pub enum Diverges {
12+
/// Potentially unknown, some cases converge,
13+
/// others require a CFG to determine them.
14+
Maybe,
15+
16+
/// Definitely known to diverge and therefore
17+
/// not reach the next sibling or its parent.
18+
Always {
19+
/// The `Span` points to the expression
20+
/// that caused us to diverge
21+
/// (e.g. `return`, `break`, etc).
22+
span: Span,
23+
/// In some cases (e.g. a `match` expression
24+
/// where all arms diverge), we may be
25+
/// able to provide a more informative
26+
/// message to the user.
27+
/// If this is `None`, a default message
28+
/// will be generated, which is suitable
29+
/// for most cases.
30+
custom_note: Option<&'static str>,
31+
},
32+
33+
/// Same as `Always` but with a reachability
34+
/// warning already emitted.
35+
WarnedAlways,
36+
}
37+
38+
// Convenience impls for combining `Diverges`.
39+
40+
impl ops::BitAnd for Diverges {
41+
type Output = Self;
42+
fn bitand(self, other: Self) -> Self {
43+
cmp::min(self, other)
44+
}
45+
}
46+
47+
impl ops::BitOr for Diverges {
48+
type Output = Self;
49+
fn bitor(self, other: Self) -> Self {
50+
cmp::max(self, other)
51+
}
52+
}
53+
54+
impl ops::BitAndAssign for Diverges {
55+
fn bitand_assign(&mut self, other: Self) {
56+
*self = *self & other;
57+
}
58+
}
59+
60+
impl ops::BitOrAssign for Diverges {
61+
fn bitor_assign(&mut self, other: Self) {
62+
*self = *self | other;
63+
}
64+
}
65+
66+
impl Diverges {
67+
/// Creates a `Diverges::Always` with the provided `span` and the default note message.
68+
pub(super) fn always(span: Span) -> Diverges {
69+
Diverges::Always { span, custom_note: None }
70+
}
71+
72+
pub(super) fn is_always(self) -> bool {
73+
// Enum comparison ignores the
74+
// contents of fields, so we just
75+
// fill them in with garbage here.
76+
self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
77+
}
78+
}

compiler/rustc_typeck/src/check/mod.rs

Lines changed: 2 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ mod closure;
7070
pub mod coercion;
7171
mod compare_method;
7272
pub mod demand;
73+
mod diverges;
7374
pub mod dropck;
7475
mod expr;
7576
mod fn_ctxt;
@@ -86,6 +87,7 @@ mod upvar;
8687
mod wfcheck;
8788
pub mod writeback;
8889

90+
pub use diverges::Diverges;
8991
pub use fn_ctxt::FnCtxt;
9092
pub use inherited::{Inherited, InheritedBuilder};
9193

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

127129
use std::cell::{Ref, RefCell, RefMut};
128-
use std::cmp;
129-
use std::ops::{self};
130130

131131
use crate::require_c_abi_if_c_variadic;
132132
use crate::util::common::indenter;
@@ -326,81 +326,6 @@ pub enum PlaceOp {
326326
Index,
327327
}
328328

329-
/// Tracks whether executing a node may exit normally (versus
330-
/// return/break/panic, which "diverge", leaving dead code in their
331-
/// wake). Tracked semi-automatically (through type variables marked
332-
/// as diverging), with some manual adjustments for control-flow
333-
/// primitives (approximating a CFG).
334-
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
335-
pub enum Diverges {
336-
/// Potentially unknown, some cases converge,
337-
/// others require a CFG to determine them.
338-
Maybe,
339-
340-
/// Definitely known to diverge and therefore
341-
/// not reach the next sibling or its parent.
342-
Always {
343-
/// The `Span` points to the expression
344-
/// that caused us to diverge
345-
/// (e.g. `return`, `break`, etc).
346-
span: Span,
347-
/// In some cases (e.g. a `match` expression
348-
/// where all arms diverge), we may be
349-
/// able to provide a more informative
350-
/// message to the user.
351-
/// If this is `None`, a default message
352-
/// will be generated, which is suitable
353-
/// for most cases.
354-
custom_note: Option<&'static str>,
355-
},
356-
357-
/// Same as `Always` but with a reachability
358-
/// warning already emitted.
359-
WarnedAlways,
360-
}
361-
362-
// Convenience impls for combining `Diverges`.
363-
364-
impl ops::BitAnd for Diverges {
365-
type Output = Self;
366-
fn bitand(self, other: Self) -> Self {
367-
cmp::min(self, other)
368-
}
369-
}
370-
371-
impl ops::BitOr for Diverges {
372-
type Output = Self;
373-
fn bitor(self, other: Self) -> Self {
374-
cmp::max(self, other)
375-
}
376-
}
377-
378-
impl ops::BitAndAssign for Diverges {
379-
fn bitand_assign(&mut self, other: Self) {
380-
*self = *self & other;
381-
}
382-
}
383-
384-
impl ops::BitOrAssign for Diverges {
385-
fn bitor_assign(&mut self, other: Self) {
386-
*self = *self | other;
387-
}
388-
}
389-
390-
impl Diverges {
391-
/// Creates a `Diverges::Always` with the provided `span` and the default note message.
392-
fn always(span: Span) -> Diverges {
393-
Diverges::Always { span, custom_note: None }
394-
}
395-
396-
fn is_always(self) -> bool {
397-
// Enum comparison ignores the
398-
// contents of fields, so we just
399-
// fill them in with garbage here.
400-
self >= Diverges::Always { span: DUMMY_SP, custom_note: None }
401-
}
402-
}
403-
404329
pub struct BreakableCtxt<'tcx> {
405330
may_break: bool,
406331

0 commit comments

Comments
 (0)