Skip to content

Commit e25542c

Browse files
authored
Auto merge of #35162 - canndrew:bang_type_coerced, r=nikomatsakis
Implement the `!` type This implements the never type (`!`) and hides it behind the feature gate `#[feature(never_type)]`. With the feature gate off, things should build as normal (although some error messages may be different). With the gate on, `!` is usable as a type and diverging type variables (ie. types that are unconstrained by anything in the code) will default to `!` instead of `()`.
2 parents 197be89 + f59f1f0 commit e25542c

File tree

128 files changed

+899
-705
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

128 files changed

+899
-705
lines changed

src/libcore/cmp.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,39 @@ mod impls {
699699

700700
ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
701701

702+
// Note: This macro is a temporary hack that can be remove once we are building with a compiler
703+
// that supports `!`
704+
macro_rules! not_stage0 {
705+
() => {
706+
#[unstable(feature = "never_type", issue = "35121")]
707+
impl PartialEq for ! {
708+
fn eq(&self, _: &!) -> bool {
709+
*self
710+
}
711+
}
712+
713+
#[unstable(feature = "never_type", issue = "35121")]
714+
impl Eq for ! {}
715+
716+
#[unstable(feature = "never_type", issue = "35121")]
717+
impl PartialOrd for ! {
718+
fn partial_cmp(&self, _: &!) -> Option<Ordering> {
719+
*self
720+
}
721+
}
722+
723+
#[unstable(feature = "never_type", issue = "35121")]
724+
impl Ord for ! {
725+
fn cmp(&self, _: &!) -> Ordering {
726+
*self
727+
}
728+
}
729+
}
730+
}
731+
732+
#[cfg(not(stage0))]
733+
not_stage0!();
734+
702735
// & pointers
703736

704737
#[stable(feature = "rust1", since = "1.0.0")]

src/libcore/fmt/mod.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,29 @@ macro_rules! fmt_refs {
13631363

13641364
fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp }
13651365

1366+
// Note: This macro is a temporary hack that can be remove once we are building with a compiler
1367+
// that supports `!`
1368+
macro_rules! not_stage0 {
1369+
() => {
1370+
#[unstable(feature = "never_type", issue = "35121")]
1371+
impl Debug for ! {
1372+
fn fmt(&self, _: &mut Formatter) -> Result {
1373+
*self
1374+
}
1375+
}
1376+
1377+
#[unstable(feature = "never_type", issue = "35121")]
1378+
impl Display for ! {
1379+
fn fmt(&self, _: &mut Formatter) -> Result {
1380+
*self
1381+
}
1382+
}
1383+
}
1384+
}
1385+
1386+
#[cfg(not(stage0))]
1387+
not_stage0!();
1388+
13661389
#[stable(feature = "rust1", since = "1.0.0")]
13671390
impl Debug for bool {
13681391
fn fmt(&self, f: &mut Formatter) -> Result {

src/libcore/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@
8888
#![feature(unboxed_closures)]
8989
#![feature(question_mark)]
9090

91+
// NOTE: remove the cfg_attr next snapshot
92+
#![cfg_attr(not(stage0), feature(never_type))]
93+
9194
#[macro_use]
9295
mod macros;
9396

src/librustc/cfg/construct.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
379379

380380
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
381381
let ret = self.straightline(call_expr, func_or_rcvr_exit, args);
382-
if fn_ty.fn_ret().diverges() {
382+
// FIXME(canndrew): This is_never should probably be an is_uninhabited.
383+
if fn_ty.fn_ret().0.is_never() {
383384
self.add_unreachable_node()
384385
} else {
385386
ret

src/librustc/hir/fold.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
353353
}
354354
}))
355355
}
356+
TyNever => node,
356357
TyTup(tys) => TyTup(tys.move_map(|ty| fld.fold_ty(ty))),
357358
TyPath(qself, path) => {
358359
let qself = qself.map(|QSelf { ty, position }| {
@@ -515,7 +516,6 @@ pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
515516
output: match output {
516517
Return(ty) => Return(fld.fold_ty(ty)),
517518
DefaultReturn(span) => DefaultReturn(span),
518-
NoReturn(span) => NoReturn(span),
519519
},
520520
variadic: variadic,
521521
}

src/librustc/hir/intravisit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
403403
walk_list!(visitor, visit_lifetime, opt_lifetime);
404404
visitor.visit_ty(&mutable_type.ty)
405405
}
406+
TyNever => {},
406407
TyTup(ref tuple_element_types) => {
407408
walk_list!(visitor, visit_ty, tuple_element_types);
408409
}

src/librustc/hir/lowering.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ impl<'a> LoweringContext<'a> {
270270
decl: self.lower_fn_decl(&f.decl),
271271
}))
272272
}
273+
Never => hir::TyNever,
273274
Tup(ref tys) => hir::TyTup(tys.iter().map(|ty| self.lower_ty(ty)).collect()),
274275
Paren(ref ty) => {
275276
return self.lower_ty(ty);
@@ -402,7 +403,6 @@ impl<'a> LoweringContext<'a> {
402403
output: match decl.output {
403404
FunctionRetTy::Ty(ref ty) => hir::Return(self.lower_ty(ty)),
404405
FunctionRetTy::Default(span) => hir::DefaultReturn(span),
405-
FunctionRetTy::None(span) => hir::NoReturn(span),
406406
},
407407
variadic: decl.variadic,
408408
})

src/librustc/hir/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,7 @@ pub struct BareFnTy {
11121112
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
11131113
/// The different kinds of types recognized by the compiler
11141114
pub enum Ty_ {
1115+
/// A variable length array (`[T]`)
11151116
TyVec(P<Ty>),
11161117
/// A fixed length array (`[T; n]`)
11171118
TyFixedLengthVec(P<Ty>, P<Expr>),
@@ -1121,6 +1122,8 @@ pub enum Ty_ {
11211122
TyRptr(Option<Lifetime>, MutTy),
11221123
/// A bare function (e.g. `fn(usize) -> bool`)
11231124
TyBareFn(P<BareFnTy>),
1125+
/// The never type (`!`)
1126+
TyNever,
11241127
/// A tuple (`(A, B, C, D,...)`)
11251128
TyTup(HirVec<P<Ty>>),
11261129
/// A path (`module::module::...::Type`), optionally
@@ -1283,9 +1286,6 @@ impl fmt::Debug for ImplPolarity {
12831286

12841287
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
12851288
pub enum FunctionRetTy {
1286-
/// Functions with return type `!`that always
1287-
/// raise an error or exit (i.e. never return to the caller)
1288-
NoReturn(Span),
12891289
/// Return type is not specified.
12901290
///
12911291
/// Functions default to `()` and
@@ -1299,7 +1299,6 @@ pub enum FunctionRetTy {
12991299
impl FunctionRetTy {
13001300
pub fn span(&self) -> Span {
13011301
match *self {
1302-
NoReturn(span) => span,
13031302
DefaultReturn(span) => span,
13041303
Return(ref ty) => ty.span,
13051304
}

src/librustc/hir/print.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,9 @@ impl<'a> State<'a> {
504504
self.print_opt_lifetime(lifetime)?;
505505
self.print_mt(mt)?;
506506
}
507+
hir::TyNever => {
508+
word(&mut self.s, "!")?;
509+
},
507510
hir::TyTup(ref elts) => {
508511
self.popen()?;
509512
self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty))?;
@@ -1959,10 +1962,6 @@ impl<'a> State<'a> {
19591962
self.maybe_print_comment(ty.span.lo)
19601963
}
19611964
hir::DefaultReturn(..) => unreachable!(),
1962-
hir::NoReturn(span) => {
1963-
self.word_nbsp("!")?;
1964-
self.maybe_print_comment(span.lo)
1965-
}
19661965
}
19671966
}
19681967

@@ -2195,7 +2194,6 @@ impl<'a> State<'a> {
21952194
self.ibox(indent_unit)?;
21962195
self.word_space("->")?;
21972196
match decl.output {
2198-
hir::NoReturn(_) => self.word_nbsp("!")?,
21992197
hir::DefaultReturn(..) => unreachable!(),
22002198
hir::Return(ref ty) => self.print_type(&ty)?,
22012199
}

src/librustc/infer/error_reporting.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1326,7 +1326,6 @@ impl<'a, 'gcx, 'tcx> Rebuilder<'a, 'gcx, 'tcx> {
13261326
self.rebuild_arg_ty_or_output(&ret_ty, lifetime, anon_nums, region_names)
13271327
),
13281328
hir::DefaultReturn(span) => hir::DefaultReturn(span),
1329-
hir::NoReturn(span) => hir::NoReturn(span)
13301329
}
13311330
}
13321331

0 commit comments

Comments
 (0)