Rename empty/bang to never
Split Ty::is_empty method into is_never and is_uninhabited
This commit is contained in:
parent
f0a8b6d43f
commit
fadabe08f5
76 changed files with 161 additions and 150 deletions
|
@ -703,24 +703,24 @@ mod impls {
|
||||||
// that supports `!`
|
// that supports `!`
|
||||||
macro_rules! not_stage0 {
|
macro_rules! not_stage0 {
|
||||||
() => {
|
() => {
|
||||||
#[unstable(feature = "bang_type", issue = "35121")]
|
#[unstable(feature = "never_type", issue = "35121")]
|
||||||
impl PartialEq for ! {
|
impl PartialEq for ! {
|
||||||
fn eq(&self, _: &!) -> bool {
|
fn eq(&self, _: &!) -> bool {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "bang_type", issue = "35121")]
|
#[unstable(feature = "never_type", issue = "35121")]
|
||||||
impl Eq for ! {}
|
impl Eq for ! {}
|
||||||
|
|
||||||
#[unstable(feature = "bang_type", issue = "35121")]
|
#[unstable(feature = "never_type", issue = "35121")]
|
||||||
impl PartialOrd for ! {
|
impl PartialOrd for ! {
|
||||||
fn partial_cmp(&self, _: &!) -> Option<Ordering> {
|
fn partial_cmp(&self, _: &!) -> Option<Ordering> {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "bang_type", issue = "35121")]
|
#[unstable(feature = "never_type", issue = "35121")]
|
||||||
impl Ord for ! {
|
impl Ord for ! {
|
||||||
fn cmp(&self, _: &!) -> Ordering {
|
fn cmp(&self, _: &!) -> Ordering {
|
||||||
*self
|
*self
|
||||||
|
|
|
@ -1367,14 +1367,14 @@ fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperEx
|
||||||
// that supports `!`
|
// that supports `!`
|
||||||
macro_rules! not_stage0 {
|
macro_rules! not_stage0 {
|
||||||
() => {
|
() => {
|
||||||
#[unstable(feature = "bang_type", issue = "35121")]
|
#[unstable(feature = "never_type", issue = "35121")]
|
||||||
impl Debug for ! {
|
impl Debug for ! {
|
||||||
fn fmt(&self, _: &mut Formatter) -> Result {
|
fn fmt(&self, _: &mut Formatter) -> Result {
|
||||||
*self
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[unstable(feature = "bang_type", issue = "35121")]
|
#[unstable(feature = "never_type", issue = "35121")]
|
||||||
impl Display for ! {
|
impl Display for ! {
|
||||||
fn fmt(&self, _: &mut Formatter) -> Result {
|
fn fmt(&self, _: &mut Formatter) -> Result {
|
||||||
*self
|
*self
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
#![feature(question_mark)]
|
#![feature(question_mark)]
|
||||||
|
|
||||||
// NOTE: remove the cfg_attr next snapshot
|
// NOTE: remove the cfg_attr next snapshot
|
||||||
#![cfg_attr(not(stage0), feature(bang_type))]
|
#![cfg_attr(not(stage0), feature(never_type))]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
|
@ -379,7 +379,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
|
||||||
|
|
||||||
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
|
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
|
||||||
let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
|
let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
|
||||||
if fn_ty.fn_ret().0.is_empty(self.tcx) {
|
// FIXME(canndrew): This is_never should probably be an is_uninhabited.
|
||||||
|
if fn_ty.fn_ret().0.is_never() {
|
||||||
self.add_unreachable_node()
|
self.add_unreachable_node()
|
||||||
} else {
|
} else {
|
||||||
ret
|
ret
|
||||||
|
|
|
@ -353,7 +353,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
TyEmpty => node,
|
TyNever => node,
|
||||||
TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
|
TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
|
||||||
TyPath(qself, path) => {
|
TyPath(qself, path) => {
|
||||||
let qself = qself.map(|QSelf { ty, position }| {
|
let qself = qself.map(|QSelf { ty, position }| {
|
||||||
|
|
|
@ -403,7 +403,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
|
||||||
walk_list!(visitor, visit_lifetime, opt_lifetime);
|
walk_list!(visitor, visit_lifetime, opt_lifetime);
|
||||||
visitor.visit_ty(&mutable_type.ty)
|
visitor.visit_ty(&mutable_type.ty)
|
||||||
}
|
}
|
||||||
TyEmpty => {},
|
TyNever => {},
|
||||||
TyTup(ref tuple_element_types) => {
|
TyTup(ref tuple_element_types) => {
|
||||||
walk_list!(visitor, visit_ty, tuple_element_types);
|
walk_list!(visitor, visit_ty, tuple_element_types);
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,7 +270,7 @@ impl<'a> LoweringContext<'a> {
|
||||||
decl: self.lower_fn_decl(&f.decl),
|
decl: self.lower_fn_decl(&f.decl),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
Empty => hir::TyEmpty,
|
Never => hir::TyNever,
|
||||||
Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect()),
|
Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect()),
|
||||||
Paren(ref ty) => {
|
Paren(ref ty) => {
|
||||||
return self.lower_ty(ty);
|
return self.lower_ty(ty);
|
||||||
|
|
|
@ -1122,8 +1122,8 @@ pub enum Ty_ {
|
||||||
TyRptr(Option<Lifetime>, MutTy),
|
TyRptr(Option<Lifetime>, MutTy),
|
||||||
/// A bare function (e.g. `fn(usize) -> bool`)
|
/// A bare function (e.g. `fn(usize) -> bool`)
|
||||||
TyBareFn(P<BareFnTy>),
|
TyBareFn(P<BareFnTy>),
|
||||||
/// The empty type (`!`)
|
/// The never type (`!`)
|
||||||
TyEmpty,
|
TyNever,
|
||||||
/// A tuple (`(A, B, C, D,...)`)
|
/// A tuple (`(A, B, C, D,...)`)
|
||||||
TyTup(HirVec<P<Ty>>),
|
TyTup(HirVec<P<Ty>>),
|
||||||
/// A path (`module::module::...::Type`), optionally
|
/// A path (`module::module::...::Type`), optionally
|
||||||
|
|
|
@ -504,7 +504,7 @@ impl<'a> State<'a> {
|
||||||
self.print_opt_lifetime(lifetime)?;
|
self.print_opt_lifetime(lifetime)?;
|
||||||
self.print_mt(mt)?;
|
self.print_mt(mt)?;
|
||||||
}
|
}
|
||||||
hir::TyEmpty => {
|
hir::TyNever => {
|
||||||
word(&mut self.s, "!")?;
|
word(&mut self.s, "!")?;
|
||||||
},
|
},
|
||||||
hir::TyTup(ref elts) => {
|
hir::TyTup(ref elts) => {
|
||||||
|
|
|
@ -168,7 +168,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
|
||||||
ty::TyTrait(..) |
|
ty::TyTrait(..) |
|
||||||
ty::TyStruct(..) |
|
ty::TyStruct(..) |
|
||||||
ty::TyClosure(..) |
|
ty::TyClosure(..) |
|
||||||
ty::TyEmpty |
|
ty::TyNever |
|
||||||
ty::TyTuple(..) |
|
ty::TyTuple(..) |
|
||||||
ty::TyProjection(..) |
|
ty::TyProjection(..) |
|
||||||
ty::TyParam(..) |
|
ty::TyParam(..) |
|
||||||
|
|
|
@ -717,7 +717,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||||
let adj = infcx.adjustments().get(&expr.id).map(|x| x.clone());
|
let adj = infcx.adjustments().get(&expr.id).map(|x| x.clone());
|
||||||
if let Some(adjustment) = adj {
|
if let Some(adjustment) = adj {
|
||||||
match adjustment {
|
match adjustment {
|
||||||
adjustment::AdjustEmptyToAny(..) |
|
adjustment::AdjustNeverToAny(..) |
|
||||||
adjustment::AdjustReifyFnPointer |
|
adjustment::AdjustReifyFnPointer |
|
||||||
adjustment::AdjustUnsafeFnPointer |
|
adjustment::AdjustUnsafeFnPointer |
|
||||||
adjustment::AdjustMutToConstPointer => {
|
adjustment::AdjustMutToConstPointer => {
|
||||||
|
|
|
@ -1111,8 +1111,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
hir::ExprCall(ref f, ref args) => {
|
hir::ExprCall(ref f, ref args) => {
|
||||||
|
// FIXME(canndrew): This is_never should really be an is_uninhabited
|
||||||
let diverges = !self.ir.tcx.is_method_call(expr.id) &&
|
let diverges = !self.ir.tcx.is_method_call(expr.id) &&
|
||||||
self.ir.tcx.expr_ty_adjusted(&f).fn_ret().0.is_empty(self.ir.tcx);
|
self.ir.tcx.expr_ty_adjusted(&f).fn_ret().0.is_never();
|
||||||
let succ = if diverges {
|
let succ = if diverges {
|
||||||
self.s.exit_ln
|
self.s.exit_ln
|
||||||
} else {
|
} else {
|
||||||
|
@ -1125,7 +1126,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||||
hir::ExprMethodCall(_, _, ref args) => {
|
hir::ExprMethodCall(_, _, ref args) => {
|
||||||
let method_call = ty::MethodCall::expr(expr.id);
|
let method_call = ty::MethodCall::expr(expr.id);
|
||||||
let method_ty = self.ir.tcx.tables.borrow().method_map[&method_call].ty;
|
let method_ty = self.ir.tcx.tables.borrow().method_map[&method_call].ty;
|
||||||
let succ = if method_ty.fn_ret().0.is_empty(self.ir.tcx) {
|
// FIXME(canndrew): This is_never should really be an is_uninhabited
|
||||||
|
let succ = if method_ty.fn_ret().0.is_never() {
|
||||||
self.s.exit_ln
|
self.s.exit_ln
|
||||||
} else {
|
} else {
|
||||||
succ
|
succ
|
||||||
|
|
|
@ -451,7 +451,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
||||||
self.cat_expr_autoderefd(expr, autoderefs)
|
self.cat_expr_autoderefd(expr, autoderefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
adjustment::AdjustEmptyToAny(..) |
|
adjustment::AdjustNeverToAny(..) |
|
||||||
adjustment::AdjustReifyFnPointer |
|
adjustment::AdjustReifyFnPointer |
|
||||||
adjustment::AdjustUnsafeFnPointer |
|
adjustment::AdjustUnsafeFnPointer |
|
||||||
adjustment::AdjustMutToConstPointer |
|
adjustment::AdjustMutToConstPointer |
|
||||||
|
|
|
@ -253,7 +253,7 @@ fn ty_is_local_constructor(tcx: TyCtxt, ty: Ty, infer_is_local: InferIsLocal)->
|
||||||
ty::TySlice(..) |
|
ty::TySlice(..) |
|
||||||
ty::TyRawPtr(..) |
|
ty::TyRawPtr(..) |
|
||||||
ty::TyRef(..) |
|
ty::TyRef(..) |
|
||||||
ty::TyEmpty |
|
ty::TyNever |
|
||||||
ty::TyTuple(..) |
|
ty::TyTuple(..) |
|
||||||
ty::TyParam(..) |
|
ty::TyParam(..) |
|
||||||
ty::TyProjection(..) => {
|
ty::TyProjection(..) => {
|
||||||
|
|
|
@ -212,7 +212,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
ty::TyProjection(..) => Some(13),
|
ty::TyProjection(..) => Some(13),
|
||||||
ty::TyParam(..) => Some(14),
|
ty::TyParam(..) => Some(14),
|
||||||
ty::TyAnon(..) => Some(15),
|
ty::TyAnon(..) => Some(15),
|
||||||
ty::TyEmpty => Some(16),
|
ty::TyNever => Some(16),
|
||||||
ty::TyInfer(..) | ty::TyError => None
|
ty::TyInfer(..) | ty::TyError => None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1772,7 +1772,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
|
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
|
||||||
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyRawPtr(..) |
|
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyRawPtr(..) |
|
||||||
ty::TyChar | ty::TyBox(_) | ty::TyRef(..) |
|
ty::TyChar | ty::TyBox(_) | ty::TyRef(..) |
|
||||||
ty::TyArray(..) | ty::TyClosure(..) | ty::TyEmpty |
|
ty::TyArray(..) | ty::TyClosure(..) | ty::TyNever |
|
||||||
ty::TyError => {
|
ty::TyError => {
|
||||||
// safe for everything
|
// safe for everything
|
||||||
Where(ty::Binder(Vec::new()))
|
Where(ty::Binder(Vec::new()))
|
||||||
|
@ -1820,7 +1820,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) |
|
ty::TyInfer(ty::IntVar(_)) | ty::TyInfer(ty::FloatVar(_)) |
|
||||||
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
|
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
|
||||||
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar |
|
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar |
|
||||||
ty::TyRawPtr(..) | ty::TyError | ty::TyEmpty |
|
ty::TyRawPtr(..) | ty::TyError | ty::TyNever |
|
||||||
ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
|
ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
|
||||||
Where(ty::Binder(Vec::new()))
|
Where(ty::Binder(Vec::new()))
|
||||||
}
|
}
|
||||||
|
@ -1886,7 +1886,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
ty::TyError |
|
ty::TyError |
|
||||||
ty::TyInfer(ty::IntVar(_)) |
|
ty::TyInfer(ty::IntVar(_)) |
|
||||||
ty::TyInfer(ty::FloatVar(_)) |
|
ty::TyInfer(ty::FloatVar(_)) |
|
||||||
ty::TyEmpty |
|
ty::TyNever |
|
||||||
ty::TyChar => {
|
ty::TyChar => {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
pub use self::AutoAdjustment::*;
|
pub use self::AutoAdjustment::*;
|
||||||
pub use self::AutoRef::*;
|
pub use self::AutoRef::*;
|
||||||
|
|
||||||
use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeVariants};
|
use ty::{self, Ty, TyCtxt, TypeAndMut, TypeFoldable};
|
||||||
use ty::LvaluePreference::{NoPreference};
|
use ty::LvaluePreference::{NoPreference};
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
@ -21,7 +21,7 @@ use hir;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub enum AutoAdjustment<'tcx> {
|
pub enum AutoAdjustment<'tcx> {
|
||||||
AdjustEmptyToAny(Ty<'tcx>), // go from ! to any type
|
AdjustNeverToAny(Ty<'tcx>), // go from ! to any type
|
||||||
AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type
|
AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type
|
||||||
AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer
|
AdjustUnsafeFnPointer, // go from a safe fn pointer to an unsafe fn pointer
|
||||||
AdjustMutToConstPointer, // go from a mut raw pointer to a const raw pointer
|
AdjustMutToConstPointer, // go from a mut raw pointer to a const raw pointer
|
||||||
|
@ -107,10 +107,7 @@ pub struct AutoDerefRef<'tcx> {
|
||||||
impl<'tcx> AutoAdjustment<'tcx> {
|
impl<'tcx> AutoAdjustment<'tcx> {
|
||||||
pub fn is_identity(&self) -> bool {
|
pub fn is_identity(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
AdjustEmptyToAny(ty) => match ty.sty {
|
AdjustNeverToAny(ty) => ty.is_never(),
|
||||||
TypeVariants::TyEmpty => true,
|
|
||||||
_ => false,
|
|
||||||
},
|
|
||||||
AdjustReifyFnPointer |
|
AdjustReifyFnPointer |
|
||||||
AdjustUnsafeFnPointer |
|
AdjustUnsafeFnPointer |
|
||||||
AdjustMutToConstPointer => false,
|
AdjustMutToConstPointer => false,
|
||||||
|
@ -159,7 +156,7 @@ impl<'a, 'gcx, 'tcx> ty::TyS<'tcx> {
|
||||||
return match adjustment {
|
return match adjustment {
|
||||||
Some(adjustment) => {
|
Some(adjustment) => {
|
||||||
match *adjustment {
|
match *adjustment {
|
||||||
AdjustEmptyToAny(ref ty) => ty,
|
AdjustNeverToAny(ref ty) => ty,
|
||||||
|
|
||||||
AdjustReifyFnPointer => {
|
AdjustReifyFnPointer => {
|
||||||
match self.sty {
|
match self.sty {
|
||||||
|
|
|
@ -185,7 +185,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
||||||
|
|
||||||
// Scalar and unique types are sendable, and durable
|
// Scalar and unique types are sendable, and durable
|
||||||
ty::TyInfer(ty::FreshIntTy(_)) | ty::TyInfer(ty::FreshFloatTy(_)) |
|
ty::TyInfer(ty::FreshIntTy(_)) | ty::TyInfer(ty::FreshFloatTy(_)) |
|
||||||
ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyEmpty |
|
ty::TyBool | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) | ty::TyNever |
|
||||||
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar => {
|
ty::TyFnDef(..) | ty::TyFnPtr(_) | ty::TyChar => {
|
||||||
TC::None
|
TC::None
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,7 +190,7 @@ pub struct CommonTypes<'tcx> {
|
||||||
pub u64: Ty<'tcx>,
|
pub u64: Ty<'tcx>,
|
||||||
pub f32: Ty<'tcx>,
|
pub f32: Ty<'tcx>,
|
||||||
pub f64: Ty<'tcx>,
|
pub f64: Ty<'tcx>,
|
||||||
pub empty: Ty<'tcx>,
|
pub never: Ty<'tcx>,
|
||||||
pub err: Ty<'tcx>,
|
pub err: Ty<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ impl<'tcx> CommonTypes<'tcx> {
|
||||||
CommonTypes {
|
CommonTypes {
|
||||||
bool: mk(TyBool),
|
bool: mk(TyBool),
|
||||||
char: mk(TyChar),
|
char: mk(TyChar),
|
||||||
empty: mk(TyEmpty),
|
never: mk(TyNever),
|
||||||
err: mk(TyError),
|
err: mk(TyError),
|
||||||
isize: mk(TyInt(ast::IntTy::Is)),
|
isize: mk(TyInt(ast::IntTy::Is)),
|
||||||
i8: mk(TyInt(ast::IntTy::I8)),
|
i8: mk(TyInt(ast::IntTy::I8)),
|
||||||
|
@ -977,7 +977,7 @@ macro_rules! sty_debug_print {
|
||||||
for &Interned(t) in tcx.interners.type_.borrow().iter() {
|
for &Interned(t) in tcx.interners.type_.borrow().iter() {
|
||||||
let variant = match t.sty {
|
let variant = match t.sty {
|
||||||
ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) |
|
ty::TyBool | ty::TyChar | ty::TyInt(..) | ty::TyUint(..) |
|
||||||
ty::TyFloat(..) | ty::TyStr | ty::TyEmpty => continue,
|
ty::TyFloat(..) | ty::TyStr | ty::TyNever => continue,
|
||||||
ty::TyError => /* unimportant */ continue,
|
ty::TyError => /* unimportant */ continue,
|
||||||
$(ty::$variant(..) => &mut $variant,)*
|
$(ty::$variant(..) => &mut $variant,)*
|
||||||
};
|
};
|
||||||
|
|
|
@ -214,7 +214,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
|
||||||
fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
|
fn sort_string(&self, tcx: TyCtxt<'a, 'gcx, 'lcx>) -> String {
|
||||||
match self.sty {
|
match self.sty {
|
||||||
ty::TyBool | ty::TyChar | ty::TyInt(_) |
|
ty::TyBool | ty::TyChar | ty::TyInt(_) |
|
||||||
ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyEmpty => self.to_string(),
|
ty::TyUint(_) | ty::TyFloat(_) | ty::TyStr | ty::TyNever => self.to_string(),
|
||||||
ty::TyTuple(ref tys) if tys.is_empty() => self.to_string(),
|
ty::TyTuple(ref tys) if tys.is_empty() => self.to_string(),
|
||||||
|
|
||||||
ty::TyEnum(def, _) => format!("enum `{}`", tcx.item_path_str(def.did)),
|
ty::TyEnum(def, _) => format!("enum `{}`", tcx.item_path_str(def.did)),
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub enum SimplifiedType {
|
||||||
StrSimplifiedType,
|
StrSimplifiedType,
|
||||||
VecSimplifiedType,
|
VecSimplifiedType,
|
||||||
PtrSimplifiedType,
|
PtrSimplifiedType,
|
||||||
EmptySimplifiedType,
|
NeverSimplifiedType,
|
||||||
TupleSimplifiedType(usize),
|
TupleSimplifiedType(usize),
|
||||||
TraitSimplifiedType(DefId),
|
TraitSimplifiedType(DefId),
|
||||||
StructSimplifiedType(DefId),
|
StructSimplifiedType(DefId),
|
||||||
|
@ -82,7 +82,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
ty::TyClosure(def_id, _) => {
|
ty::TyClosure(def_id, _) => {
|
||||||
Some(ClosureSimplifiedType(def_id))
|
Some(ClosureSimplifiedType(def_id))
|
||||||
}
|
}
|
||||||
ty::TyEmpty => Some(EmptySimplifiedType),
|
ty::TyNever => Some(NeverSimplifiedType),
|
||||||
ty::TyTuple(ref tys) => {
|
ty::TyTuple(ref tys) => {
|
||||||
Some(TupleSimplifiedType(tys.len()))
|
Some(TupleSimplifiedType(tys.len()))
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ impl FlagComputation {
|
||||||
&ty::TyInt(_) |
|
&ty::TyInt(_) |
|
||||||
&ty::TyFloat(_) |
|
&ty::TyFloat(_) |
|
||||||
&ty::TyUint(_) |
|
&ty::TyUint(_) |
|
||||||
&ty::TyEmpty |
|
&ty::TyNever |
|
||||||
&ty::TyStr => {
|
&ty::TyStr => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -349,7 +349,7 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
|
||||||
ty::TyAnon(..) |
|
ty::TyAnon(..) |
|
||||||
ty::TyInfer(_) |
|
ty::TyInfer(_) |
|
||||||
ty::TyError |
|
ty::TyError |
|
||||||
ty::TyEmpty |
|
ty::TyNever |
|
||||||
ty::TyFloat(_) => None,
|
ty::TyFloat(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -795,8 +795,8 @@ impl<'a, 'gcx, 'tcx> Layout {
|
||||||
ty::TyFloat(FloatTy::F64) => Scalar { value: F64, non_zero: false },
|
ty::TyFloat(FloatTy::F64) => Scalar { value: F64, non_zero: false },
|
||||||
ty::TyFnPtr(_) => Scalar { value: Pointer, non_zero: true },
|
ty::TyFnPtr(_) => Scalar { value: Pointer, non_zero: true },
|
||||||
|
|
||||||
// The empty type.
|
// The never type.
|
||||||
ty::TyEmpty => Univariant { variant: Struct::new(dl, false), non_zero: false },
|
ty::TyNever => Univariant { variant: Struct::new(dl, false), non_zero: false },
|
||||||
|
|
||||||
// Potentially-fat pointers.
|
// Potentially-fat pointers.
|
||||||
ty::TyBox(pointee) |
|
ty::TyBox(pointee) |
|
||||||
|
|
|
@ -1853,7 +1853,7 @@ impl<'a, 'tcx> AdtDefData<'tcx, 'tcx> {
|
||||||
let result = match ty.sty {
|
let result = match ty.sty {
|
||||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
||||||
TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
||||||
TyArray(..) | TyClosure(..) | TyEmpty => {
|
TyArray(..) | TyClosure(..) | TyNever => {
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
ty::TyInt(..) | // OutlivesScalar
|
ty::TyInt(..) | // OutlivesScalar
|
||||||
ty::TyUint(..) | // OutlivesScalar
|
ty::TyUint(..) | // OutlivesScalar
|
||||||
ty::TyFloat(..) | // OutlivesScalar
|
ty::TyFloat(..) | // OutlivesScalar
|
||||||
ty::TyEmpty | // ...
|
ty::TyNever | // ...
|
||||||
ty::TyEnum(..) | // OutlivesNominalType
|
ty::TyEnum(..) | // OutlivesNominalType
|
||||||
ty::TyStruct(..) | // OutlivesNominalType
|
ty::TyStruct(..) | // OutlivesNominalType
|
||||||
ty::TyBox(..) | // OutlivesNominalType (ish)
|
ty::TyBox(..) | // OutlivesNominalType (ish)
|
||||||
|
|
|
@ -453,7 +453,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
||||||
Ok(tcx.types.err)
|
Ok(tcx.types.err)
|
||||||
}
|
}
|
||||||
|
|
||||||
(&ty::TyEmpty, _) |
|
(&ty::TyNever, _) |
|
||||||
(&ty::TyChar, _) |
|
(&ty::TyChar, _) |
|
||||||
(&ty::TyBool, _) |
|
(&ty::TyBool, _) |
|
||||||
(&ty::TyInt(_), _) |
|
(&ty::TyInt(_), _) |
|
||||||
|
|
|
@ -486,7 +486,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||||
ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)),
|
ty::TyAnon(did, substs) => ty::TyAnon(did, substs.fold_with(folder)),
|
||||||
ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
|
ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
|
||||||
ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
|
ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
|
||||||
ty::TyParam(..) | ty::TyEmpty => self.sty.clone(),
|
ty::TyParam(..) | ty::TyNever => self.sty.clone(),
|
||||||
};
|
};
|
||||||
folder.tcx().mk_ty(sty)
|
folder.tcx().mk_ty(sty)
|
||||||
}
|
}
|
||||||
|
@ -515,7 +515,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
||||||
ty::TyAnon(_, ref substs) => substs.visit_with(visitor),
|
ty::TyAnon(_, ref substs) => substs.visit_with(visitor),
|
||||||
ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
|
ty::TyBool | ty::TyChar | ty::TyStr | ty::TyInt(_) |
|
||||||
ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
|
ty::TyUint(_) | ty::TyFloat(_) | ty::TyError | ty::TyInfer(_) |
|
||||||
ty::TyParam(..) | ty::TyEmpty => false,
|
ty::TyParam(..) | ty::TyNever => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,8 +158,8 @@ pub enum TypeVariants<'tcx> {
|
||||||
/// `|a| a`.
|
/// `|a| a`.
|
||||||
TyClosure(DefId, ClosureSubsts<'tcx>),
|
TyClosure(DefId, ClosureSubsts<'tcx>),
|
||||||
|
|
||||||
/// The empty type `!`
|
/// The never type `!`
|
||||||
TyEmpty,
|
TyNever,
|
||||||
|
|
||||||
/// A tuple type. For example, `(i32, bool)`.
|
/// A tuple type. For example, `(i32, bool)`.
|
||||||
TyTuple(&'tcx [Ty<'tcx>]),
|
TyTuple(&'tcx [Ty<'tcx>]),
|
||||||
|
@ -894,14 +894,22 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self, cx: TyCtxt) -> bool {
|
pub fn is_never(&self) -> bool {
|
||||||
// FIXME(#24885): be smarter here
|
match self.sty {
|
||||||
|
TyNever => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_uninhabited(&self, cx: TyCtxt) -> bool {
|
||||||
|
// FIXME(#24885): be smarter here, the AdtDefData::is_empty method could easily be made
|
||||||
|
// more complete.
|
||||||
match self.sty {
|
match self.sty {
|
||||||
TyEnum(def, _) | TyStruct(def, _) => def.is_empty(),
|
TyEnum(def, _) | TyStruct(def, _) => def.is_empty(),
|
||||||
TyEmpty => true,
|
TyNever => true,
|
||||||
TyTuple(ref tys) => tys.iter().any(|ty| ty.is_empty(cx)),
|
TyTuple(ref tys) => tys.iter().any(|ty| ty.is_uninhabited(cx)),
|
||||||
// FIXME (canndrew): this line breaks core::fmt
|
// FIXME (canndrew): this line breaks core::fmt
|
||||||
//TyRef(_, ref tm) => tm.ty.is_empty(cx),
|
//TyRef(_, ref tm) => tm.ty.is_uninhabited(cx),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1225,7 +1233,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
||||||
TyArray(_, _) |
|
TyArray(_, _) |
|
||||||
TySlice(_) |
|
TySlice(_) |
|
||||||
TyRawPtr(_) |
|
TyRawPtr(_) |
|
||||||
TyEmpty |
|
TyNever |
|
||||||
TyTuple(_) |
|
TyTuple(_) |
|
||||||
TyParam(_) |
|
TyParam(_) |
|
||||||
TyInfer(_) |
|
TyInfer(_) |
|
||||||
|
|
|
@ -485,7 +485,7 @@ impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx> {
|
||||||
self.def_id(data.trait_ref.def_id);
|
self.def_id(data.trait_ref.def_id);
|
||||||
self.hash(data.item_name.as_str());
|
self.hash(data.item_name.as_str());
|
||||||
}
|
}
|
||||||
TyEmpty |
|
TyNever |
|
||||||
TyBool |
|
TyBool |
|
||||||
TyChar |
|
TyChar |
|
||||||
TyStr |
|
TyStr |
|
||||||
|
@ -551,7 +551,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
||||||
|
|
||||||
// Fast-path for primitive types
|
// Fast-path for primitive types
|
||||||
let result = match self.sty {
|
let result = match self.sty {
|
||||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | TyEmpty |
|
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | TyNever |
|
||||||
TyRawPtr(..) | TyFnDef(..) | TyFnPtr(_) | TyRef(_, TypeAndMut {
|
TyRawPtr(..) | TyFnDef(..) | TyFnPtr(_) | TyRef(_, TypeAndMut {
|
||||||
mutbl: hir::MutImmutable, ..
|
mutbl: hir::MutImmutable, ..
|
||||||
}) => Some(false),
|
}) => Some(false),
|
||||||
|
@ -597,7 +597,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
|
||||||
let result = match self.sty {
|
let result = match self.sty {
|
||||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
||||||
TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
TyBox(..) | TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) |
|
||||||
TyArray(..) | TyTuple(..) | TyClosure(..) | TyEmpty => Some(true),
|
TyArray(..) | TyTuple(..) | TyClosure(..) | TyNever => Some(true),
|
||||||
|
|
||||||
TyStr | TyTrait(..) | TySlice(_) => Some(false),
|
TyStr | TyTrait(..) | TySlice(_) => Some(false),
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ pub fn walk_shallow<'tcx>(ty: Ty<'tcx>) -> IntoIter<Ty<'tcx>> {
|
||||||
fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
|
fn push_subtypes<'tcx>(stack: &mut Vec<Ty<'tcx>>, parent_ty: Ty<'tcx>) {
|
||||||
match parent_ty.sty {
|
match parent_ty.sty {
|
||||||
ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) |
|
ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) | ty::TyFloat(_) |
|
||||||
ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyEmpty | ty::TyError => {
|
ty::TyStr | ty::TyInfer(_) | ty::TyParam(_) | ty::TyNever | ty::TyError => {
|
||||||
}
|
}
|
||||||
ty::TyBox(ty) | ty::TyArray(ty, _) | ty::TySlice(ty) => {
|
ty::TyBox(ty) | ty::TyArray(ty, _) | ty::TySlice(ty) => {
|
||||||
stack.push(ty);
|
stack.push(ty);
|
||||||
|
|
|
@ -321,7 +321,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
||||||
ty::TyFloat(..) |
|
ty::TyFloat(..) |
|
||||||
ty::TyError |
|
ty::TyError |
|
||||||
ty::TyStr |
|
ty::TyStr |
|
||||||
ty::TyEmpty |
|
ty::TyNever |
|
||||||
ty::TyParam(_) => {
|
ty::TyParam(_) => {
|
||||||
// WfScalar, WfParameter, etc
|
// WfScalar, WfParameter, etc
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ use ty::subst::{self, Subst};
|
||||||
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
|
use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
|
||||||
use ty::{TyBool, TyChar, TyStruct, TyEnum};
|
use ty::{TyBool, TyChar, TyStruct, TyEnum};
|
||||||
use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
|
use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
|
||||||
use ty::{TyParam, TyRawPtr, TyRef, TyEmpty, TyTuple};
|
use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple};
|
||||||
use ty::TyClosure;
|
use ty::TyClosure;
|
||||||
use ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
|
use ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
|
||||||
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
use ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
|
@ -422,8 +422,8 @@ impl<'tcx, 'container> fmt::Debug for ty::AdtDefData<'tcx, 'container> {
|
||||||
impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> {
|
impl<'tcx> fmt::Debug for ty::adjustment::AutoAdjustment<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
ty::adjustment::AdjustEmptyToAny(ref target) => {
|
ty::adjustment::AdjustNeverToAny(ref target) => {
|
||||||
write!(f, "AdjustEmptyToAny({:?})", target)
|
write!(f, "AdjustNeverToAny({:?})", target)
|
||||||
}
|
}
|
||||||
ty::adjustment::AdjustReifyFnPointer => {
|
ty::adjustment::AdjustReifyFnPointer => {
|
||||||
write!(f, "AdjustReifyFnPointer")
|
write!(f, "AdjustReifyFnPointer")
|
||||||
|
@ -843,7 +843,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
|
||||||
}
|
}
|
||||||
write!(f, "{}", tm)
|
write!(f, "{}", tm)
|
||||||
}
|
}
|
||||||
TyEmpty => write!(f, "!"),
|
TyNever => write!(f, "!"),
|
||||||
TyTuple(ref tys) => {
|
TyTuple(ref tys) => {
|
||||||
write!(f, "(")?;
|
write!(f, "(")?;
|
||||||
let mut tys = tys.iter();
|
let mut tys = tys.iter();
|
||||||
|
|
|
@ -215,17 +215,17 @@ fn check_expr(cx: &mut MatchCheckCtxt, ex: &hir::Expr) {
|
||||||
// Check for empty enum, because is_useful only works on inhabited types.
|
// Check for empty enum, because is_useful only works on inhabited types.
|
||||||
let pat_ty = cx.tcx.node_id_to_type(scrut.id);
|
let pat_ty = cx.tcx.node_id_to_type(scrut.id);
|
||||||
if inlined_arms.is_empty() {
|
if inlined_arms.is_empty() {
|
||||||
if !pat_ty.is_empty(cx.tcx) {
|
if !pat_ty.is_uninhabited(cx.tcx) {
|
||||||
// We know the type is inhabited, so this must be wrong
|
// We know the type is inhabited, so this must be wrong
|
||||||
let mut err = struct_span_err!(cx.tcx.sess, ex.span, E0002,
|
let mut err = struct_span_err!(cx.tcx.sess, ex.span, E0002,
|
||||||
"non-exhaustive patterns: type {} is non-empty",
|
"non-exhaustive patterns: type {} is inhabited",
|
||||||
pat_ty);
|
pat_ty);
|
||||||
span_help!(&mut err, ex.span,
|
span_help!(&mut err, ex.span,
|
||||||
"Please ensure that all possible cases are being handled; \
|
"Please ensure that all possible cases are being handled; \
|
||||||
possibly adding wildcards or more match arms.");
|
possibly adding wildcards or more match arms.");
|
||||||
err.emit();
|
err.emit();
|
||||||
}
|
}
|
||||||
// If the type *is* empty, it's vacuously exhaustive
|
// If the type *is* uninhabited, it's vacuously exhaustive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -523,7 +523,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
// Primitive types with a stable representation.
|
// Primitive types with a stable representation.
|
||||||
ty::TyBool | ty::TyInt(..) | ty::TyUint(..) |
|
ty::TyBool | ty::TyInt(..) | ty::TyUint(..) |
|
||||||
ty::TyFloat(..) | ty::TyEmpty => FfiSafe,
|
ty::TyFloat(..) | ty::TyNever => FfiSafe,
|
||||||
|
|
||||||
ty::TyBox(..) => {
|
ty::TyBox(..) => {
|
||||||
FfiUnsafe("found Rust type Box<_> in foreign module, \
|
FfiUnsafe("found Rust type Box<_> in foreign module, \
|
||||||
|
|
|
@ -133,7 +133,7 @@ impl LateLintPass for UnusedResults {
|
||||||
let t = cx.tcx.expr_ty(&expr);
|
let t = cx.tcx.expr_ty(&expr);
|
||||||
let warned = match t.sty {
|
let warned = match t.sty {
|
||||||
ty::TyTuple(ref tys) if tys.is_empty() => return,
|
ty::TyTuple(ref tys) if tys.is_empty() => return,
|
||||||
ty::TyEmpty => return,
|
ty::TyNever => return,
|
||||||
ty::TyBool => return,
|
ty::TyBool => return,
|
||||||
ty::TyStruct(def, _) |
|
ty::TyStruct(def, _) |
|
||||||
ty::TyEnum(def, _) => {
|
ty::TyEnum(def, _) => {
|
||||||
|
|
|
@ -645,8 +645,8 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
adjustment::AdjustEmptyToAny(ref ty) => {
|
adjustment::AdjustNeverToAny(ref ty) => {
|
||||||
this.emit_enum_variant("AdjustEmptyToAny", 5, 1, |this| {
|
this.emit_enum_variant("AdjustNeverToAny", 5, 1, |this| {
|
||||||
this.emit_enum_variant_arg(0, |this| Ok(this.emit_ty(ecx, ty)))
|
this.emit_enum_variant_arg(0, |this| Ok(this.emit_ty(ecx, ty)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1024,7 +1024,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||||
self.read_enum("AutoAdjustment", |this| {
|
self.read_enum("AutoAdjustment", |this| {
|
||||||
let variants = ["AdjustReifyFnPointer", "AdjustUnsafeFnPointer",
|
let variants = ["AdjustReifyFnPointer", "AdjustUnsafeFnPointer",
|
||||||
"AdjustMutToConstPointer", "AdjustDerefRef",
|
"AdjustMutToConstPointer", "AdjustDerefRef",
|
||||||
"AdjustEmptyToAny"];
|
"AdjustNeverToAny"];
|
||||||
this.read_enum_variant(&variants, |this, i| {
|
this.read_enum_variant(&variants, |this, i| {
|
||||||
Ok(match i {
|
Ok(match i {
|
||||||
1 => adjustment::AdjustReifyFnPointer,
|
1 => adjustment::AdjustReifyFnPointer,
|
||||||
|
@ -1042,7 +1042,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||||
Ok(this.read_ty(dcx))
|
Ok(this.read_ty(dcx))
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
|
|
||||||
adjustment::AdjustEmptyToAny(ty)
|
adjustment::AdjustNeverToAny(ty)
|
||||||
}
|
}
|
||||||
_ => bug!("bad enum variant for adjustment::AutoAdjustment")
|
_ => bug!("bad enum variant for adjustment::AutoAdjustment")
|
||||||
})
|
})
|
||||||
|
|
|
@ -311,7 +311,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
match self.next() {
|
match self.next() {
|
||||||
'b' => return tcx.types.bool,
|
'b' => return tcx.types.bool,
|
||||||
'!' => return tcx.types.empty,
|
'!' => return tcx.types.never,
|
||||||
'i' => { /* eat the s of is */ self.next(); return tcx.types.isize },
|
'i' => { /* eat the s of is */ self.next(); return tcx.types.isize },
|
||||||
'u' => { /* eat the s of us */ self.next(); return tcx.types.usize },
|
'u' => { /* eat the s of us */ self.next(); return tcx.types.usize },
|
||||||
'M' => {
|
'M' => {
|
||||||
|
|
|
@ -74,7 +74,7 @@ pub fn enc_ty<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>, t: Ty<'tcx
|
||||||
match t.sty {
|
match t.sty {
|
||||||
ty::TyBool => { write!(w, "b"); }
|
ty::TyBool => { write!(w, "b"); }
|
||||||
ty::TyChar => { write!(w, "c"); }
|
ty::TyChar => { write!(w, "c"); }
|
||||||
ty::TyEmpty => { write!(w, "!"); }
|
ty::TyNever => { write!(w, "!"); }
|
||||||
ty::TyInt(t) => {
|
ty::TyInt(t) => {
|
||||||
match t {
|
match t {
|
||||||
ast::IntTy::Is => write!(w, "is"),
|
ast::IntTy::Is => write!(w, "is"),
|
||||||
|
|
|
@ -96,7 +96,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
ExprKind::LogicalOp { .. } |
|
ExprKind::LogicalOp { .. } |
|
||||||
ExprKind::Box { .. } |
|
ExprKind::Box { .. } |
|
||||||
ExprKind::Cast { .. } |
|
ExprKind::Cast { .. } |
|
||||||
ExprKind::EmptyToAny { .. } |
|
ExprKind::NeverToAny { .. } |
|
||||||
ExprKind::ReifyFnPointer { .. } |
|
ExprKind::ReifyFnPointer { .. } |
|
||||||
ExprKind::UnsafeFnPointer { .. } |
|
ExprKind::UnsafeFnPointer { .. } |
|
||||||
ExprKind::Unsize { .. } |
|
ExprKind::Unsize { .. } |
|
||||||
|
|
|
@ -219,7 +219,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
ExprKind::Block { .. } |
|
ExprKind::Block { .. } |
|
||||||
ExprKind::Match { .. } |
|
ExprKind::Match { .. } |
|
||||||
ExprKind::If { .. } |
|
ExprKind::If { .. } |
|
||||||
ExprKind::EmptyToAny { .. } |
|
ExprKind::NeverToAny { .. } |
|
||||||
ExprKind::Loop { .. } |
|
ExprKind::Loop { .. } |
|
||||||
ExprKind::LogicalOp { .. } |
|
ExprKind::LogicalOp { .. } |
|
||||||
ExprKind::Call { .. } |
|
ExprKind::Call { .. } |
|
||||||
|
|
|
@ -56,7 +56,7 @@ impl Category {
|
||||||
ExprKind::LogicalOp { .. } |
|
ExprKind::LogicalOp { .. } |
|
||||||
ExprKind::If { .. } |
|
ExprKind::If { .. } |
|
||||||
ExprKind::Match { .. } |
|
ExprKind::Match { .. } |
|
||||||
ExprKind::EmptyToAny { .. } |
|
ExprKind::NeverToAny { .. } |
|
||||||
ExprKind::Call { .. } =>
|
ExprKind::Call { .. } =>
|
||||||
Some(Category::Rvalue(RvalueFunc::Into)),
|
Some(Category::Rvalue(RvalueFunc::Into)),
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
ExprKind::Match { discriminant, arms } => {
|
ExprKind::Match { discriminant, arms } => {
|
||||||
this.match_expr(destination, expr_span, block, discriminant, arms)
|
this.match_expr(destination, expr_span, block, discriminant, arms)
|
||||||
}
|
}
|
||||||
ExprKind::EmptyToAny { source } => {
|
ExprKind::NeverToAny { source } => {
|
||||||
let source = this.hir.mirror(source);
|
let source = this.hir.mirror(source);
|
||||||
let is_call = match source.kind {
|
let is_call = match source.kind {
|
||||||
ExprKind::Call { .. } => true,
|
ExprKind::Call { .. } => true,
|
||||||
|
@ -209,7 +209,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
||||||
ExprKind::Call { ty, fun, args } => {
|
ExprKind::Call { ty, fun, args } => {
|
||||||
let diverges = match ty.sty {
|
let diverges = match ty.sty {
|
||||||
ty::TyFnDef(_, _, ref f) | ty::TyFnPtr(ref f) => {
|
ty::TyFnDef(_, _, ref f) | ty::TyFnPtr(ref f) => {
|
||||||
f.sig.0.output.is_empty(this.hir.tcx())
|
// FIXME(canndrew): This is_never should probably be an is_uninhabited
|
||||||
|
f.sig.0.output.is_never()
|
||||||
}
|
}
|
||||||
_ => false
|
_ => false
|
||||||
};
|
};
|
||||||
|
|
|
@ -60,13 +60,13 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
|
||||||
kind: ExprKind::UnsafeFnPointer { source: expr.to_ref() },
|
kind: ExprKind::UnsafeFnPointer { source: expr.to_ref() },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Some(&ty::adjustment::AdjustEmptyToAny(..)) => {
|
Some(&ty::adjustment::AdjustNeverToAny(..)) => {
|
||||||
let adjusted_ty = cx.tcx.expr_ty_adjusted(self);
|
let adjusted_ty = cx.tcx.expr_ty_adjusted(self);
|
||||||
expr = Expr {
|
expr = Expr {
|
||||||
temp_lifetime: temp_lifetime,
|
temp_lifetime: temp_lifetime,
|
||||||
ty: adjusted_ty,
|
ty: adjusted_ty,
|
||||||
span: self.span,
|
span: self.span,
|
||||||
kind: ExprKind::EmptyToAny { source: expr.to_ref() },
|
kind: ExprKind::NeverToAny { source: expr.to_ref() },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Some(&ty::adjustment::AdjustMutToConstPointer) => {
|
Some(&ty::adjustment::AdjustMutToConstPointer) => {
|
||||||
|
|
|
@ -139,7 +139,7 @@ pub enum ExprKind<'tcx> {
|
||||||
Cast {
|
Cast {
|
||||||
source: ExprRef<'tcx>,
|
source: ExprRef<'tcx>,
|
||||||
},
|
},
|
||||||
EmptyToAny {
|
NeverToAny {
|
||||||
source: ExprRef<'tcx>,
|
source: ExprRef<'tcx>,
|
||||||
},
|
},
|
||||||
ReifyFnPointer {
|
ReifyFnPointer {
|
||||||
|
|
|
@ -492,7 +492,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
if !sig.output.is_empty(tcx) {
|
// FIXME(canndrew): This is_never should probably be an is_uninhabited
|
||||||
|
if !sig.output.is_never() {
|
||||||
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
|
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -632,7 +632,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
|
||||||
fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr) {
|
fn check_adjustments<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr) {
|
||||||
match v.tcx.tables.borrow().adjustments.get(&e.id) {
|
match v.tcx.tables.borrow().adjustments.get(&e.id) {
|
||||||
None |
|
None |
|
||||||
Some(&ty::adjustment::AdjustEmptyToAny(..)) |
|
Some(&ty::adjustment::AdjustNeverToAny(..)) |
|
||||||
Some(&ty::adjustment::AdjustReifyFnPointer) |
|
Some(&ty::adjustment::AdjustReifyFnPointer) |
|
||||||
Some(&ty::adjustment::AdjustUnsafeFnPointer) |
|
Some(&ty::adjustment::AdjustUnsafeFnPointer) |
|
||||||
Some(&ty::adjustment::AdjustMutToConstPointer) => {}
|
Some(&ty::adjustment::AdjustMutToConstPointer) => {}
|
||||||
|
|
|
@ -1593,7 +1593,7 @@ fn trans_match_inner<'blk, 'tcx>(scope_cx: Block<'blk, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let t = node_id_type(bcx, discr_expr.id);
|
let t = node_id_type(bcx, discr_expr.id);
|
||||||
let chk = if t.is_empty(tcx) {
|
let chk = if t.is_uninhabited(tcx) {
|
||||||
Unreachable
|
Unreachable
|
||||||
} else {
|
} else {
|
||||||
Infallible
|
Infallible
|
||||||
|
|
|
@ -712,7 +712,8 @@ fn trans_call_inner<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if output.is_empty(bcx.tcx()) {
|
// FIXME(canndrew): This is_never should really be an is_uninhabited
|
||||||
|
if output.is_never() {
|
||||||
Unreachable(bcx);
|
Unreachable(bcx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -753,7 +753,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
|
||||||
ty::TyRef(..) |
|
ty::TyRef(..) |
|
||||||
ty::TyFnDef(..) |
|
ty::TyFnDef(..) |
|
||||||
ty::TyFnPtr(_) |
|
ty::TyFnPtr(_) |
|
||||||
ty::TyEmpty |
|
ty::TyNever |
|
||||||
ty::TyTrait(_) => {
|
ty::TyTrait(_) => {
|
||||||
/* nothing to do */
|
/* nothing to do */
|
||||||
}
|
}
|
||||||
|
|
|
@ -558,7 +558,7 @@ impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
|
||||||
abi: Abi::C,
|
abi: Abi::C,
|
||||||
sig: ty::Binder(ty::FnSig {
|
sig: ty::Binder(ty::FnSig {
|
||||||
inputs: vec![tcx.mk_mut_ptr(tcx.types.u8)],
|
inputs: vec![tcx.mk_mut_ptr(tcx.types.u8)],
|
||||||
output: tcx.types.empty,
|
output: tcx.types.never,
|
||||||
variadic: false
|
variadic: false
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -34,7 +34,7 @@ use type_of;
|
||||||
use value::Value;
|
use value::Value;
|
||||||
use Disr;
|
use Disr;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::adjustment::{AdjustEmptyToAny, AdjustDerefRef, AdjustReifyFnPointer};
|
use rustc::ty::adjustment::{AdjustNeverToAny, AdjustDerefRef, AdjustReifyFnPointer};
|
||||||
use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
|
use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::cast::{CastTy,IntTy};
|
use rustc::ty::cast::{CastTy,IntTy};
|
||||||
|
@ -348,7 +348,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
&cx.tcx().expr_ty_adjusted(e));
|
&cx.tcx().expr_ty_adjusted(e));
|
||||||
let opt_adj = cx.tcx().tables.borrow().adjustments.get(&e.id).cloned();
|
let opt_adj = cx.tcx().tables.borrow().adjustments.get(&e.id).cloned();
|
||||||
match opt_adj {
|
match opt_adj {
|
||||||
Some(AdjustEmptyToAny(..)) => span_bug!(e.span, "const expression of type ! encountered"),
|
Some(AdjustNeverToAny(..)) => span_bug!(e.span, "const expression of type ! encountered"),
|
||||||
Some(AdjustReifyFnPointer) => {
|
Some(AdjustReifyFnPointer) => {
|
||||||
match ety.sty {
|
match ety.sty {
|
||||||
ty::TyFnDef(def_id, substs, _) => {
|
ty::TyFnDef(def_id, substs, _) => {
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl<'tcx> TypeMap<'tcx> {
|
||||||
unique_type_id.push('{');
|
unique_type_id.push('{');
|
||||||
|
|
||||||
match type_.sty {
|
match type_.sty {
|
||||||
ty::TyEmpty |
|
ty::TyNever |
|
||||||
ty::TyBool |
|
ty::TyBool |
|
||||||
ty::TyChar |
|
ty::TyChar |
|
||||||
ty::TyStr |
|
ty::TyStr |
|
||||||
|
@ -695,7 +695,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
|
|
||||||
let sty = &t.sty;
|
let sty = &t.sty;
|
||||||
let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
|
let MetadataCreationResult { metadata, already_stored_in_typemap } = match *sty {
|
||||||
ty::TyEmpty |
|
ty::TyNever |
|
||||||
ty::TyBool |
|
ty::TyBool |
|
||||||
ty::TyChar |
|
ty::TyChar |
|
||||||
ty::TyInt(_) |
|
ty::TyInt(_) |
|
||||||
|
@ -912,7 +912,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
debug!("basic_type_metadata: {:?}", t);
|
debug!("basic_type_metadata: {:?}", t);
|
||||||
|
|
||||||
let (name, encoding) = match t.sty {
|
let (name, encoding) = match t.sty {
|
||||||
ty::TyEmpty => ("!", DW_ATE_unsigned),
|
ty::TyNever => ("!", DW_ATE_unsigned),
|
||||||
ty::TyTuple(ref elements) if elements.is_empty() =>
|
ty::TyTuple(ref elements) if elements.is_empty() =>
|
||||||
("()", DW_ATE_unsigned),
|
("()", DW_ATE_unsigned),
|
||||||
ty::TyBool => ("bool", DW_ATE_boolean),
|
ty::TyBool => ("bool", DW_ATE_boolean),
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
ty::TyBool => output.push_str("bool"),
|
ty::TyBool => output.push_str("bool"),
|
||||||
ty::TyChar => output.push_str("char"),
|
ty::TyChar => output.push_str("char"),
|
||||||
ty::TyStr => output.push_str("str"),
|
ty::TyStr => output.push_str("str"),
|
||||||
ty::TyEmpty => output.push_str("!"),
|
ty::TyNever => output.push_str("!"),
|
||||||
ty::TyInt(int_ty) => output.push_str(int_ty.ty_to_string()),
|
ty::TyInt(int_ty) => output.push_str(int_ty.ty_to_string()),
|
||||||
ty::TyUint(uint_ty) => output.push_str(uint_ty.ty_to_string()),
|
ty::TyUint(uint_ty) => output.push_str(uint_ty.ty_to_string()),
|
||||||
ty::TyFloat(float_ty) => output.push_str(float_ty.ty_to_string()),
|
ty::TyFloat(float_ty) => output.push_str(float_ty.ty_to_string()),
|
||||||
|
|
|
@ -111,7 +111,8 @@ pub fn declare_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, name: &str,
|
||||||
let fty = FnType::new(ccx, abi, &sig, &[]);
|
let fty = FnType::new(ccx, abi, &sig, &[]);
|
||||||
let llfn = declare_raw_fn(ccx, name, fty.cconv, fty.llvm_type(ccx));
|
let llfn = declare_raw_fn(ccx, name, fty.cconv, fty.llvm_type(ccx));
|
||||||
|
|
||||||
if sig.output.is_empty(ccx.tcx()) {
|
// FIXME(canndrew): This is_never should really be an is_uninhabited
|
||||||
|
if sig.output.is_never() {
|
||||||
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
|
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ use tvec;
|
||||||
use type_of;
|
use type_of;
|
||||||
use value::Value;
|
use value::Value;
|
||||||
use Disr;
|
use Disr;
|
||||||
use rustc::ty::adjustment::{AdjustEmptyToAny, AdjustDerefRef, AdjustReifyFnPointer};
|
use rustc::ty::adjustment::{AdjustNeverToAny, AdjustDerefRef, AdjustReifyFnPointer};
|
||||||
use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
|
use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
|
||||||
use rustc::ty::adjustment::CustomCoerceUnsized;
|
use rustc::ty::adjustment::CustomCoerceUnsized;
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
|
@ -348,7 +348,7 @@ fn adjustment_required<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
match adjustment {
|
match adjustment {
|
||||||
AdjustEmptyToAny(..) => true,
|
AdjustNeverToAny(..) => true,
|
||||||
AdjustReifyFnPointer => true,
|
AdjustReifyFnPointer => true,
|
||||||
AdjustUnsafeFnPointer | AdjustMutToConstPointer => {
|
AdjustUnsafeFnPointer | AdjustMutToConstPointer => {
|
||||||
// purely a type-level thing
|
// purely a type-level thing
|
||||||
|
@ -381,7 +381,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
debug!("unadjusted datum for expr {:?}: {:?} adjustment={:?}",
|
debug!("unadjusted datum for expr {:?}: {:?} adjustment={:?}",
|
||||||
expr, datum, adjustment);
|
expr, datum, adjustment);
|
||||||
match adjustment {
|
match adjustment {
|
||||||
AdjustEmptyToAny(ref target) => {
|
AdjustNeverToAny(ref target) => {
|
||||||
let mono_target = bcx.monomorphize(target);
|
let mono_target = bcx.monomorphize(target);
|
||||||
let llty = type_of::type_of(bcx.ccx(), mono_target);
|
let llty = type_of::type_of(bcx.ccx(), mono_target);
|
||||||
let dummy = C_undef(llty.ptr_to());
|
let dummy = C_undef(llty.ptr_to());
|
||||||
|
|
|
@ -412,7 +412,7 @@ pub fn push_unique_type_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
ty::TyBool => output.push_str("bool"),
|
ty::TyBool => output.push_str("bool"),
|
||||||
ty::TyChar => output.push_str("char"),
|
ty::TyChar => output.push_str("char"),
|
||||||
ty::TyStr => output.push_str("str"),
|
ty::TyStr => output.push_str("str"),
|
||||||
ty::TyEmpty => output.push_str("!"),
|
ty::TyNever => output.push_str("!"),
|
||||||
ty::TyInt(ast::IntTy::Is) => output.push_str("isize"),
|
ty::TyInt(ast::IntTy::Is) => output.push_str("isize"),
|
||||||
ty::TyInt(ast::IntTy::I8) => output.push_str("i8"),
|
ty::TyInt(ast::IntTy::I8) => output.push_str("i8"),
|
||||||
ty::TyInt(ast::IntTy::I16) => output.push_str("i16"),
|
ty::TyInt(ast::IntTy::I16) => output.push_str("i16"),
|
||||||
|
|
|
@ -64,7 +64,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
|
||||||
ty::TyInt(t) => Type::int_from_ty(cx, t),
|
ty::TyInt(t) => Type::int_from_ty(cx, t),
|
||||||
ty::TyUint(t) => Type::uint_from_ty(cx, t),
|
ty::TyUint(t) => Type::uint_from_ty(cx, t),
|
||||||
ty::TyFloat(t) => Type::float_from_ty(cx, t),
|
ty::TyFloat(t) => Type::float_from_ty(cx, t),
|
||||||
ty::TyEmpty => Type::nil(cx),
|
ty::TyNever => Type::nil(cx),
|
||||||
|
|
||||||
ty::TyBox(ty) |
|
ty::TyBox(ty) |
|
||||||
ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
|
ty::TyRef(_, ty::TypeAndMut{ty, ..}) |
|
||||||
|
@ -250,7 +250,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
|
||||||
ty::TyInt(t) => Type::int_from_ty(cx, t),
|
ty::TyInt(t) => Type::int_from_ty(cx, t),
|
||||||
ty::TyUint(t) => Type::uint_from_ty(cx, t),
|
ty::TyUint(t) => Type::uint_from_ty(cx, t),
|
||||||
ty::TyFloat(t) => Type::float_from_ty(cx, t),
|
ty::TyFloat(t) => Type::float_from_ty(cx, t),
|
||||||
ty::TyEmpty => Type::nil(cx),
|
ty::TyNever => Type::nil(cx),
|
||||||
ty::TyEnum(def, ref substs) => {
|
ty::TyEnum(def, ref substs) => {
|
||||||
// Only create the named struct, but don't fill it in. We
|
// Only create the named struct, but don't fill it in. We
|
||||||
// fill it in *after* placing it into the type cache. This
|
// fill it in *after* placing it into the type cache. This
|
||||||
|
|
|
@ -1700,8 +1700,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
||||||
let t = self.ast_ty_to_ty(rscope1, &mt.ty);
|
let t = self.ast_ty_to_ty(rscope1, &mt.ty);
|
||||||
tcx.mk_ref(tcx.mk_region(r), ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
|
tcx.mk_ref(tcx.mk_region(r), ty::TypeAndMut {ty: t, mutbl: mt.mutbl})
|
||||||
}
|
}
|
||||||
hir::TyEmpty => {
|
hir::TyNever => {
|
||||||
tcx.types.empty
|
tcx.types.never
|
||||||
},
|
},
|
||||||
hir::TyTup(ref fields) => {
|
hir::TyTup(ref fields) => {
|
||||||
let flds = fields.iter()
|
let flds = fields.iter()
|
||||||
|
|
|
@ -68,8 +68,8 @@ use rustc::traits::{self, ObligationCause};
|
||||||
use rustc::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef};
|
use rustc::ty::adjustment::{AutoAdjustment, AutoDerefRef, AdjustDerefRef};
|
||||||
use rustc::ty::adjustment::{AutoPtr, AutoUnsafe, AdjustReifyFnPointer};
|
use rustc::ty::adjustment::{AutoPtr, AutoUnsafe, AdjustReifyFnPointer};
|
||||||
use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
|
use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
|
||||||
use rustc::ty::adjustment::AdjustEmptyToAny;
|
use rustc::ty::adjustment::AdjustNeverToAny;
|
||||||
use rustc::ty::{self, TypeVariants, LvaluePreference, TypeAndMut, Ty};
|
use rustc::ty::{self, LvaluePreference, TypeAndMut, Ty};
|
||||||
use rustc::ty::fold::TypeFoldable;
|
use rustc::ty::fold::TypeFoldable;
|
||||||
use rustc::ty::error::TypeError;
|
use rustc::ty::error::TypeError;
|
||||||
use rustc::ty::relate::RelateResult;
|
use rustc::ty::relate::RelateResult;
|
||||||
|
@ -168,8 +168,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
||||||
return self.identity(b);
|
return self.identity(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let TypeVariants::TyEmpty = a.sty {
|
if a.is_never() {
|
||||||
return Ok((b, AdjustEmptyToAny(b)));
|
return Ok((b, AdjustNeverToAny(b)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Consider coercing the subtype to a DST
|
// Consider coercing the subtype to a DST
|
||||||
|
|
|
@ -433,7 +433,7 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'b, 'gcx, 'tcx>(
|
||||||
// We still need to ensure all referenced data is safe.
|
// We still need to ensure all referenced data is safe.
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) |
|
ty::TyBool | ty::TyChar | ty::TyInt(_) | ty::TyUint(_) |
|
||||||
ty::TyFloat(_) | ty::TyStr | ty::TyEmpty => {
|
ty::TyFloat(_) | ty::TyStr | ty::TyNever => {
|
||||||
// primitive - definitely safe
|
// primitive - definitely safe
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &hir::ForeignItem) {
|
||||||
};
|
};
|
||||||
(n_tps, inputs, output)
|
(n_tps, inputs, output)
|
||||||
} else if &name[..] == "abort" || &name[..] == "unreachable" {
|
} else if &name[..] == "abort" || &name[..] == "unreachable" {
|
||||||
(0, Vec::new(), tcx.types.empty)
|
(0, Vec::new(), tcx.types.never)
|
||||||
} else {
|
} else {
|
||||||
let (n_tps, inputs, output) = match &name[..] {
|
let (n_tps, inputs, output) = match &name[..] {
|
||||||
"breakpoint" => (0, Vec::new(), tcx.mk_nil()),
|
"breakpoint" => (0, Vec::new(), tcx.mk_nil()),
|
||||||
|
|
|
@ -93,7 +93,7 @@ use rustc::traits::{self, Reveal};
|
||||||
use rustc::ty::{GenericPredicates, TypeScheme};
|
use rustc::ty::{GenericPredicates, TypeScheme};
|
||||||
use rustc::ty::{ParamTy, ParameterEnvironment};
|
use rustc::ty::{ParamTy, ParameterEnvironment};
|
||||||
use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
|
use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
|
||||||
use rustc::ty::{self, ToPolyTraitRef, Ty, TypeVariants, TyCtxt, Visibility};
|
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, Visibility};
|
||||||
use rustc::ty::{MethodCall, MethodCallee};
|
use rustc::ty::{MethodCall, MethodCallee};
|
||||||
use rustc::ty::adjustment;
|
use rustc::ty::adjustment;
|
||||||
use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
|
use rustc::ty::fold::{BottomUpFolder, TypeFoldable};
|
||||||
|
@ -1556,8 +1556,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn write_ty_expr(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
|
pub fn write_ty_expr(&self, node_id: ast::NodeId, ty: Ty<'tcx>) {
|
||||||
self.write_ty(node_id, ty);
|
self.write_ty(node_id, ty);
|
||||||
if let TypeVariants::TyEmpty = ty.sty {
|
if ty.is_never() {
|
||||||
self.write_adjustment(node_id, adjustment::AdjustEmptyToAny(self.next_diverging_ty_var()));
|
self.write_adjustment(node_id, adjustment::AdjustNeverToAny(self.next_diverging_ty_var()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1732,8 +1732,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
self.write_ty(node_id, self.tcx.mk_nil());
|
self.write_ty(node_id, self.tcx.mk_nil());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_empty(&self, node_id: ast::NodeId) {
|
pub fn write_never(&self, node_id: ast::NodeId) {
|
||||||
self.write_ty_expr(node_id, self.tcx.types.empty);
|
self.write_ty_expr(node_id, self.tcx.types.never);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_error(&self, node_id: ast::NodeId) {
|
pub fn write_error(&self, node_id: ast::NodeId) {
|
||||||
|
@ -1793,7 +1793,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
|
pub fn expr_ty(&self, ex: &hir::Expr) -> Ty<'tcx> {
|
||||||
if let Some(&adjustment::AdjustEmptyToAny(ref t))
|
if let Some(&adjustment::AdjustNeverToAny(ref t))
|
||||||
= self.tables.borrow().adjustments.get(&ex.id) {
|
= self.tables.borrow().adjustments.get(&ex.id) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -1977,7 +1977,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
if self.type_var_diverges(resolved) {
|
if self.type_var_diverges(resolved) {
|
||||||
debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
|
debug!("default_type_parameters: defaulting `{:?}` to `!` because it diverges",
|
||||||
resolved);
|
resolved);
|
||||||
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.empty);
|
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.never);
|
||||||
} else {
|
} else {
|
||||||
match self.type_is_unconstrained_numeric(resolved) {
|
match self.type_is_unconstrained_numeric(resolved) {
|
||||||
UnconstrainedInt => {
|
UnconstrainedInt => {
|
||||||
|
@ -2051,7 +2051,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
for ty in &unsolved_variables {
|
for ty in &unsolved_variables {
|
||||||
let resolved = self.resolve_type_vars_if_possible(ty);
|
let resolved = self.resolve_type_vars_if_possible(ty);
|
||||||
if self.type_var_diverges(resolved) {
|
if self.type_var_diverges(resolved) {
|
||||||
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.empty);
|
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.never);
|
||||||
} else {
|
} else {
|
||||||
match self.type_is_unconstrained_numeric(resolved) {
|
match self.type_is_unconstrained_numeric(resolved) {
|
||||||
UnconstrainedInt | UnconstrainedFloat => {
|
UnconstrainedInt | UnconstrainedFloat => {
|
||||||
|
@ -2109,7 +2109,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| {
|
let _ = self.commit_if_ok(|_: &infer::CombinedSnapshot| {
|
||||||
for ty in &unbound_tyvars {
|
for ty in &unbound_tyvars {
|
||||||
if self.type_var_diverges(ty) {
|
if self.type_var_diverges(ty) {
|
||||||
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.empty);
|
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.never);
|
||||||
} else {
|
} else {
|
||||||
match self.type_is_unconstrained_numeric(ty) {
|
match self.type_is_unconstrained_numeric(ty) {
|
||||||
UnconstrainedInt => {
|
UnconstrainedInt => {
|
||||||
|
@ -2205,7 +2205,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
// reporting for more then one conflict.
|
// reporting for more then one conflict.
|
||||||
for ty in &unbound_tyvars {
|
for ty in &unbound_tyvars {
|
||||||
if self.type_var_diverges(ty) {
|
if self.type_var_diverges(ty) {
|
||||||
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.empty);
|
self.demand_eqtype(syntax_pos::DUMMY_SP, *ty, self.tcx.types.never);
|
||||||
} else {
|
} else {
|
||||||
match self.type_is_unconstrained_numeric(ty) {
|
match self.type_is_unconstrained_numeric(ty) {
|
||||||
UnconstrainedInt => {
|
UnconstrainedInt => {
|
||||||
|
@ -2610,9 +2610,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(&arg_ty) = self.tables.borrow().node_types.get(&arg.id) {
|
if let Some(&arg_ty) = self.tables.borrow().node_types.get(&arg.id) {
|
||||||
|
// FIXME(canndrew): This is_never should probably be an is_uninhabited
|
||||||
any_diverges = any_diverges ||
|
any_diverges = any_diverges ||
|
||||||
self.type_var_diverges(arg_ty) ||
|
self.type_var_diverges(arg_ty) ||
|
||||||
arg_ty.is_empty(self.tcx);
|
arg_ty.is_never();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if any_diverges && !warned {
|
if any_diverges && !warned {
|
||||||
|
@ -3485,8 +3486,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
}
|
}
|
||||||
self.write_nil(id);
|
self.write_nil(id);
|
||||||
}
|
}
|
||||||
hir::ExprBreak(_) => { self.write_empty(id); }
|
hir::ExprBreak(_) => { self.write_never(id); }
|
||||||
hir::ExprAgain(_) => { self.write_empty(id); }
|
hir::ExprAgain(_) => { self.write_never(id); }
|
||||||
hir::ExprRet(ref expr_opt) => {
|
hir::ExprRet(ref expr_opt) => {
|
||||||
if let Some(ref e) = *expr_opt {
|
if let Some(ref e) = *expr_opt {
|
||||||
self.check_expr_coercable_to_type(&e, self.ret_ty);
|
self.check_expr_coercable_to_type(&e, self.ret_ty);
|
||||||
|
@ -3504,7 +3505,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.write_empty(id);
|
self.write_never(id);
|
||||||
}
|
}
|
||||||
hir::ExprAssign(ref lhs, ref rhs) => {
|
hir::ExprAssign(ref lhs, ref rhs) => {
|
||||||
self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
|
self.check_expr_with_lvalue_pref(&lhs, PreferMutLvalue);
|
||||||
|
@ -3546,7 +3547,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
hir::ExprLoop(ref body, _) => {
|
hir::ExprLoop(ref body, _) => {
|
||||||
self.check_block_no_value(&body);
|
self.check_block_no_value(&body);
|
||||||
if !may_break(tcx, expr.id, &body) {
|
if !may_break(tcx, expr.id, &body) {
|
||||||
self.write_empty(id);
|
self.write_never(id);
|
||||||
} else {
|
} else {
|
||||||
self.write_nil(id);
|
self.write_nil(id);
|
||||||
}
|
}
|
||||||
|
@ -4002,9 +4003,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
"unreachable statement".to_string());
|
"unreachable statement".to_string());
|
||||||
warned = true;
|
warned = true;
|
||||||
}
|
}
|
||||||
|
// FIXME(canndrew): This is_never should probably be an is_uninhabited
|
||||||
any_diverges = any_diverges ||
|
any_diverges = any_diverges ||
|
||||||
self.type_var_diverges(s_ty) ||
|
self.type_var_diverges(s_ty) ||
|
||||||
s_ty.is_empty(self.tcx);
|
s_ty.is_never();
|
||||||
any_err = any_err || s_ty.references_error();
|
any_err = any_err || s_ty.references_error();
|
||||||
}
|
}
|
||||||
match blk.expr {
|
match blk.expr {
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> {
|
||||||
let id = self.id;
|
let id = self.id;
|
||||||
let span = self.span;
|
let span = self.span;
|
||||||
self.inherited.enter(|inh| {
|
self.inherited.enter(|inh| {
|
||||||
let fcx = FnCtxt::new(&inh, inh.ccx.tcx.types.empty, id);
|
let fcx = FnCtxt::new(&inh, inh.ccx.tcx.types.never, id);
|
||||||
let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor {
|
let wf_tys = f(&fcx, &mut CheckTypeWellFormedVisitor {
|
||||||
ccx: fcx.ccx,
|
ccx: fcx.ccx,
|
||||||
code: code
|
code: code
|
||||||
|
|
|
@ -378,8 +378,8 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||||
|
|
||||||
Some(adjustment) => {
|
Some(adjustment) => {
|
||||||
let resolved_adjustment = match adjustment {
|
let resolved_adjustment = match adjustment {
|
||||||
adjustment::AdjustEmptyToAny(ty) => {
|
adjustment::AdjustNeverToAny(ty) => {
|
||||||
adjustment::AdjustEmptyToAny(self.resolve(&ty, reason))
|
adjustment::AdjustNeverToAny(self.resolve(&ty, reason))
|
||||||
}
|
}
|
||||||
|
|
||||||
adjustment::AdjustReifyFnPointer => {
|
adjustment::AdjustReifyFnPointer => {
|
||||||
|
|
|
@ -24,7 +24,7 @@ use rustc::ty::{ImplOrTraitItemId, ConstTraitItemId};
|
||||||
use rustc::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment};
|
use rustc::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment};
|
||||||
use rustc::ty::{Ty, TyBool, TyChar, TyEnum, TyError};
|
use rustc::ty::{Ty, TyBool, TyChar, TyEnum, TyError};
|
||||||
use rustc::ty::{TyParam, TyRawPtr};
|
use rustc::ty::{TyParam, TyRawPtr};
|
||||||
use rustc::ty::{TyRef, TyStruct, TyTrait, TyEmpty, TyTuple};
|
use rustc::ty::{TyRef, TyStruct, TyTrait, TyNever, TyTuple};
|
||||||
use rustc::ty::{TyStr, TyArray, TySlice, TyFloat, TyInfer, TyInt};
|
use rustc::ty::{TyStr, TyArray, TySlice, TyFloat, TyInfer, TyInt};
|
||||||
use rustc::ty::{TyUint, TyClosure, TyBox, TyFnDef, TyFnPtr};
|
use rustc::ty::{TyUint, TyClosure, TyBox, TyFnDef, TyFnPtr};
|
||||||
use rustc::ty::{TyProjection, TyAnon};
|
use rustc::ty::{TyProjection, TyAnon};
|
||||||
|
@ -84,7 +84,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
|
||||||
|
|
||||||
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
|
||||||
TyStr | TyArray(..) | TySlice(..) | TyFnDef(..) | TyFnPtr(_) |
|
TyStr | TyArray(..) | TySlice(..) | TyFnDef(..) | TyFnPtr(_) |
|
||||||
TyTuple(..) | TyParam(..) | TyError | TyEmpty |
|
TyTuple(..) | TyParam(..) | TyError | TyNever |
|
||||||
TyRawPtr(_) | TyRef(_, _) | TyProjection(..) => {
|
TyRawPtr(_) | TyRef(_, _) | TyProjection(..) => {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -322,7 +322,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty::TyBool |
|
ty::TyBool |
|
||||||
ty::TyChar | ty::TyInt(_) | ty::TyUint(_) |
|
ty::TyChar | ty::TyInt(_) | ty::TyUint(_) |
|
||||||
ty::TyFloat(_) | ty::TyStr | ty::TyEmpty => {
|
ty::TyFloat(_) | ty::TyStr | ty::TyNever => {
|
||||||
/* leaf type -- noop */
|
/* leaf type -- noop */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1459,8 +1459,7 @@ pub enum Type {
|
||||||
Tuple(Vec<Type>),
|
Tuple(Vec<Type>),
|
||||||
Vector(Box<Type>),
|
Vector(Box<Type>),
|
||||||
FixedVector(Box<Type>, String),
|
FixedVector(Box<Type>, String),
|
||||||
/// aka TyBot
|
Never,
|
||||||
Bottom,
|
|
||||||
Unique(Box<Type>),
|
Unique(Box<Type>),
|
||||||
RawPointer(Mutability, Box<Type>),
|
RawPointer(Mutability, Box<Type>),
|
||||||
BorrowedRef {
|
BorrowedRef {
|
||||||
|
@ -1671,7 +1670,7 @@ impl Clean<Type> for hir::Ty {
|
||||||
fn clean(&self, cx: &DocContext) -> Type {
|
fn clean(&self, cx: &DocContext) -> Type {
|
||||||
use rustc::hir::*;
|
use rustc::hir::*;
|
||||||
match self.node {
|
match self.node {
|
||||||
TyEmpty => Bottom,
|
TyNever => Never,
|
||||||
TyPtr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)),
|
TyPtr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)),
|
||||||
TyRptr(ref l, ref m) =>
|
TyRptr(ref l, ref m) =>
|
||||||
BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx),
|
BorrowedRef {lifetime: l.clean(cx), mutability: m.mutbl.clean(cx),
|
||||||
|
@ -1780,7 +1779,7 @@ impl Clean<Type> for hir::Ty {
|
||||||
impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
||||||
fn clean(&self, cx: &DocContext) -> Type {
|
fn clean(&self, cx: &DocContext) -> Type {
|
||||||
match self.sty {
|
match self.sty {
|
||||||
ty::TyEmpty => Bottom,
|
ty::TyNever => Never,
|
||||||
ty::TyBool => Primitive(Bool),
|
ty::TyBool => Primitive(Bool),
|
||||||
ty::TyChar => Primitive(Char),
|
ty::TyChar => Primitive(Char),
|
||||||
ty::TyInt(ast::IntTy::Is) => Primitive(Isize),
|
ty::TyInt(ast::IntTy::Is) => Primitive(Isize),
|
||||||
|
|
|
@ -492,7 +492,7 @@ impl fmt::Display for clean::Type {
|
||||||
primitive_link(f, clean::PrimitiveType::Array,
|
primitive_link(f, clean::PrimitiveType::Array,
|
||||||
&format!("; {}]", Escape(s)))
|
&format!("; {}]", Escape(s)))
|
||||||
}
|
}
|
||||||
clean::Bottom => f.write_str("!"),
|
clean::Never => f.write_str("!"),
|
||||||
clean::RawPointer(m, ref t) => {
|
clean::RawPointer(m, ref t) => {
|
||||||
match **t {
|
match **t {
|
||||||
clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => {
|
clean::Generic(_) | clean::ResolvedPath {is_generic: true, ..} => {
|
||||||
|
|
|
@ -1358,8 +1358,8 @@ pub enum TyKind {
|
||||||
Rptr(Option<Lifetime>, MutTy),
|
Rptr(Option<Lifetime>, MutTy),
|
||||||
/// A bare function (e.g. `fn(usize) -> bool`)
|
/// A bare function (e.g. `fn(usize) -> bool`)
|
||||||
BareFn(P<BareFnTy>),
|
BareFn(P<BareFnTy>),
|
||||||
/// The empty type (`!`)
|
/// The never type (`!`)
|
||||||
Empty,
|
Never,
|
||||||
/// A tuple (`(A, B, C, D,...)`)
|
/// A tuple (`(A, B, C, D,...)`)
|
||||||
Tup(Vec<P<Ty>> ),
|
Tup(Vec<P<Ty>> ),
|
||||||
/// A path (`module::module::...::Type`), optionally
|
/// A path (`module::module::...::Type`), optionally
|
||||||
|
|
|
@ -287,7 +287,7 @@ declare_features! (
|
||||||
(active, relaxed_adts, "1.12.0", Some(35626)),
|
(active, relaxed_adts, "1.12.0", Some(35626)),
|
||||||
|
|
||||||
// The `!` type
|
// The `!` type
|
||||||
(active, bang_type, "1.13.0", Some(35121))
|
(active, never_type, "1.13.0", Some(35121))
|
||||||
);
|
);
|
||||||
|
|
||||||
declare_features! (
|
declare_features! (
|
||||||
|
@ -966,8 +966,8 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
|
||||||
gate_feature_post!(&self, conservative_impl_trait, ty.span,
|
gate_feature_post!(&self, conservative_impl_trait, ty.span,
|
||||||
"`impl Trait` is experimental");
|
"`impl Trait` is experimental");
|
||||||
}
|
}
|
||||||
ast::TyKind::Empty => {
|
ast::TyKind::Never => {
|
||||||
gate_feature_post!(&self, bang_type, ty.span,
|
gate_feature_post!(&self, never_type, ty.span,
|
||||||
"The `!` type is experimental");
|
"The `!` type is experimental");
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -978,7 +978,7 @@ impl<'a> Visitor for PostExpansionVisitor<'a> {
|
||||||
fn visit_fn_ret_ty(&mut self, ret_ty: &ast::FunctionRetTy) {
|
fn visit_fn_ret_ty(&mut self, ret_ty: &ast::FunctionRetTy) {
|
||||||
if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty {
|
if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty {
|
||||||
match output_ty.node {
|
match output_ty.node {
|
||||||
ast::TyKind::Empty => return,
|
ast::TyKind::Never => return,
|
||||||
_ => (),
|
_ => (),
|
||||||
};
|
};
|
||||||
visit::walk_ty(self, output_ty)
|
visit::walk_ty(self, output_ty)
|
||||||
|
|
|
@ -373,7 +373,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
|
||||||
decl: fld.fold_fn_decl(decl)
|
decl: fld.fold_fn_decl(decl)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
TyKind::Empty => node,
|
TyKind::Never => node,
|
||||||
TyKind::Tup(tys) => TyKind::Tup(tys.move_map(|ty| fld.fold_ty(ty))),
|
TyKind::Tup(tys) => TyKind::Tup(tys.move_map(|ty| fld.fold_ty(ty))),
|
||||||
TyKind::Paren(ty) => TyKind::Paren(fld.fold_ty(ty)),
|
TyKind::Paren(ty) => TyKind::Paren(fld.fold_ty(ty)),
|
||||||
TyKind::Path(qself, path) => {
|
TyKind::Path(qself, path) => {
|
||||||
|
|
|
@ -1396,7 +1396,7 @@ impl<'a> Parser<'a> {
|
||||||
TyKind::Tup(ts)
|
TyKind::Tup(ts)
|
||||||
}
|
}
|
||||||
} else if self.eat(&token::Not) {
|
} else if self.eat(&token::Not) {
|
||||||
TyKind::Empty
|
TyKind::Never
|
||||||
} else if self.check(&token::BinOp(token::Star)) {
|
} else if self.check(&token::BinOp(token::Star)) {
|
||||||
// STAR POINTER (bare pointer?)
|
// STAR POINTER (bare pointer?)
|
||||||
self.bump();
|
self.bump();
|
||||||
|
|
|
@ -976,7 +976,7 @@ impl<'a> State<'a> {
|
||||||
try!(self.print_opt_lifetime(lifetime));
|
try!(self.print_opt_lifetime(lifetime));
|
||||||
try!(self.print_mt(mt));
|
try!(self.print_mt(mt));
|
||||||
}
|
}
|
||||||
ast::TyKind::Empty => {
|
ast::TyKind::Never => {
|
||||||
word(&mut self.s, "!")?;
|
word(&mut self.s, "!")?;
|
||||||
},
|
},
|
||||||
ast::TyKind::Tup(ref elts) => {
|
ast::TyKind::Tup(ref elts) => {
|
||||||
|
|
|
@ -323,7 +323,7 @@ pub fn walk_ty<V: Visitor>(visitor: &mut V, typ: &Ty) {
|
||||||
walk_list!(visitor, visit_lifetime, opt_lifetime);
|
walk_list!(visitor, visit_lifetime, opt_lifetime);
|
||||||
visitor.visit_ty(&mutable_type.ty)
|
visitor.visit_ty(&mutable_type.ty)
|
||||||
}
|
}
|
||||||
TyKind::Empty => {},
|
TyKind::Never => {},
|
||||||
TyKind::Tup(ref tuple_element_types) => {
|
TyKind::Tup(ref tuple_element_types) => {
|
||||||
walk_list!(visitor, visit_ty, tuple_element_types);
|
walk_list!(visitor, visit_ty, tuple_element_types);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,7 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#![feature(bang_type)]
|
#![feature(never_type)]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// error-pattern:explicit
|
// error-pattern:explicit
|
||||||
fn main() {
|
fn main() {
|
Loading…
Add table
Add a link
Reference in a new issue