diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 28ad5edbd2db7..f3a2aa519465c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2374,6 +2374,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.intern_tup(&[]) } + pub fn mk_diverging_default(self) -> Ty<'tcx> { + if self.features().never_type { + self.types.never + } else { + self.intern_tup(&[]) + } + } + pub fn mk_bool(self) -> Ty<'tcx> { self.mk_ty(TyBool) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index ca35153d571db..acde10a639693 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2217,7 +2217,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } // Tries to apply a fallback to `ty` if it is an unsolved variable. - // Non-numerics get replaced with !, unconstrained ints with i32, + // Non-numerics get replaced with ! or () (depending on whether + // feature(never_type) is enabled, unconstrained ints with i32, // unconstrained floats with f64. // Fallback becomes very dubious if we have encountered type-checking errors. // In that case, fallback to TyError. @@ -2231,7 +2232,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ if self.is_tainted_by_errors() => self.tcx().types.err, UnconstrainedInt => self.tcx.types.i32, UnconstrainedFloat => self.tcx.types.f64, - Neither if self.type_var_diverges(ty) => self.tcx.types.never, + Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(), Neither => return false, }; debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback); diff --git a/src/test/compile-fail/defaulted-never-note.rs b/src/test/compile-fail/defaulted-never-note.rs index 798544f164932..ac8ac85824edc 100644 --- a/src/test/compile-fail/defaulted-never-note.rs +++ b/src/test/compile-fail/defaulted-never-note.rs @@ -8,6 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// We need to opt inot the `!` feature in order to trigger the +// requirement that this is testing. +#![feature(never_type)] + #![allow(unused)] trait Deserialize: Sized { diff --git a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs index 052575de4c267..75b60aa8d10b7 100644 --- a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs +++ b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.rs @@ -31,5 +31,5 @@ trait Add { fn ice(a: A) { let r = loop {}; r = r + a; - //~^ ERROR the trait bound `!: Add` is not satisfied + //~^ ERROR the trait bound `(): Add` is not satisfied } diff --git a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr index c22a645385ade..7924ab7444406 100644 --- a/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr +++ b/src/test/ui/associated-types-ICE-when-projecting-out-of-err.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `!: Add` is not satisfied +error[E0277]: the trait bound `(): Add` is not satisfied --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:33:11 | LL | r = r + a; - | ^ the trait `Add` is not implemented for `!` + | ^ the trait `Add` is not implemented for `()` error: aborting due to previous error