Skip to content

Commit 5ebf748

Browse files
committed
Auto merge of #47630 - canndrew:exhaustive-patterns, r=nikomatsakis
Stabilise feature(never_type). Introduce feature(exhaustive_patterns) This stabilizes `!`, removing the feature gate as well as the old defaulting-to-`()` behavior. The pattern exhaustiveness checks which were covered by `feature(never_type)` have been moved behind a new `feature(exhaustive_patterns)` gate.
2 parents 521d91c + a8a0c69 commit 5ebf748

File tree

147 files changed

+295
-547
lines changed

Some content is hidden

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

147 files changed

+295
-547
lines changed

src/libcore/cmp.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -882,24 +882,24 @@ mod impls {
882882

883883
ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
884884

885-
#[unstable(feature = "never_type", issue = "35121")]
885+
#[stable(feature = "never_type", since = "1.26.0")]
886886
impl PartialEq for ! {
887887
fn eq(&self, _: &!) -> bool {
888888
*self
889889
}
890890
}
891891

892-
#[unstable(feature = "never_type", issue = "35121")]
892+
#[stable(feature = "never_type", since = "1.26.0")]
893893
impl Eq for ! {}
894894

895-
#[unstable(feature = "never_type", issue = "35121")]
895+
#[stable(feature = "never_type", since = "1.26.0")]
896896
impl PartialOrd for ! {
897897
fn partial_cmp(&self, _: &!) -> Option<Ordering> {
898898
*self
899899
}
900900
}
901901

902-
#[unstable(feature = "never_type", issue = "35121")]
902+
#[stable(feature = "never_type", since = "1.26.0")]
903903
impl Ord for ! {
904904
fn cmp(&self, _: &!) -> Ordering {
905905
*self

src/libcore/fmt/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1711,14 +1711,14 @@ macro_rules! fmt_refs {
17111711

17121712
fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp }
17131713

1714-
#[unstable(feature = "never_type", issue = "35121")]
1714+
#[stable(feature = "never_type", since = "1.26.0")]
17151715
impl Debug for ! {
17161716
fn fmt(&self, _: &mut Formatter) -> Result {
17171717
*self
17181718
}
17191719
}
17201720

1721-
#[unstable(feature = "never_type", issue = "35121")]
1721+
#[stable(feature = "never_type", since = "1.26.0")]
17221722
impl Display for ! {
17231723
fn fmt(&self, _: &mut Formatter) -> Result {
17241724
*self

src/libcore/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
#![feature(iterator_repeat_with)]
8686
#![feature(lang_items)]
8787
#![feature(link_llvm_intrinsics)]
88-
#![feature(never_type)]
88+
#![feature(exhaustive_patterns)]
8989
#![feature(no_core)]
9090
#![feature(on_unimplemented)]
9191
#![feature(optin_builtin_traits)]
@@ -103,6 +103,7 @@
103103
#![feature(unwind_attributes)]
104104

105105
#![cfg_attr(stage0, allow(unused_attributes))]
106+
#![cfg_attr(stage0, feature(never_type))]
106107

107108
#[prelude_import]
108109
#[allow(unused)]

src/librustc/ich/impls_ty.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -886,9 +886,8 @@ for ty::TypeVariants<'gcx>
886886
TyGeneratorWitness(types) => {
887887
types.hash_stable(hcx, hasher)
888888
}
889-
TyTuple(inner_tys, from_diverging_type_var) => {
889+
TyTuple(inner_tys) => {
890890
inner_tys.hash_stable(hcx, hasher);
891-
from_diverging_type_var.hash_stable(hcx, hasher);
892891
}
893892
TyProjection(ref projection_ty) => {
894893
projection_ty.hash_stable(hcx, hasher);

src/librustc/infer/canonical.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -609,12 +609,6 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
609609
bug!("encountered a canonical type during canonicalization")
610610
}
611611

612-
// Replace a `()` that "would've fallen back" to `!` with just `()`.
613-
ty::TyTuple(ref tys, true) => {
614-
assert!(tys.is_empty());
615-
self.tcx().mk_nil()
616-
}
617-
618612
ty::TyClosure(..)
619613
| ty::TyGenerator(..)
620614
| ty::TyGeneratorWitness(..)
@@ -634,7 +628,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
634628
| ty::TyFnPtr(_)
635629
| ty::TyDynamic(..)
636630
| ty::TyNever
637-
| ty::TyTuple(_, false)
631+
| ty::TyTuple(..)
638632
| ty::TyProjection(..)
639633
| ty::TyForeign(..)
640634
| ty::TyParam(..)

src/librustc/infer/outlives/bounds.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
151151
// get solved *here*.
152152
match fulfill_cx.select_all_or_error(self) {
153153
Ok(()) => (),
154-
Err(errors) => self.report_fulfillment_errors(&errors, None),
154+
Err(errors) => self.report_fulfillment_errors(&errors, None, false),
155155
}
156156

157157
implied_bounds

src/librustc/infer/resolve.rs

-6
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
173173
ty::TyInfer(_) => {
174174
bug!("Unexpected type in full type resolver: {:?}", t);
175175
}
176-
ty::TyTuple(tys, true) => {
177-
// Un-default defaulted tuples - we are going to a
178-
// different infcx, and the default will just cause
179-
// pollution.
180-
self.tcx().intern_tup(tys, false)
181-
}
182176
_ => {
183177
t.super_fold_with(self)
184178
}

src/librustc/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
#![feature(match_default_bindings)]
6161
#![feature(macro_lifetime_matcher)]
6262
#![feature(macro_vis_matcher)]
63-
#![feature(never_type)]
63+
#![feature(exhaustive_patterns)]
6464
#![feature(non_exhaustive)]
6565
#![feature(nonzero)]
6666
#![feature(proc_macro_internals)]

src/librustc/lint/builtin.rs

-15
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,6 @@ declare_lint! {
151151
"lints that have been renamed or removed"
152152
}
153153

154-
declare_lint! {
155-
pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
156-
Deny,
157-
"attempt to resolve a trait on an expression whose type cannot be inferred but which \
158-
currently defaults to ()"
159-
}
160-
161154
declare_lint! {
162155
pub SAFE_EXTERN_STATICS,
163156
Deny,
@@ -237,12 +230,6 @@ declare_lint! {
237230
"detect mut variables which don't need to be mutable"
238231
}
239232

240-
declare_lint! {
241-
pub COERCE_NEVER,
242-
Deny,
243-
"detect coercion to !"
244-
}
245-
246233
declare_lint! {
247234
pub SINGLE_USE_LIFETIME,
248235
Allow,
@@ -304,7 +291,6 @@ impl LintPass for HardwiredLints {
304291
INVALID_TYPE_PARAM_DEFAULT,
305292
CONST_ERR,
306293
RENAMED_AND_REMOVED_LINTS,
307-
RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
308294
SAFE_EXTERN_STATICS,
309295
SAFE_PACKED_BORROWS,
310296
PATTERNS_IN_FNS_WITHOUT_BODY,
@@ -318,7 +304,6 @@ impl LintPass for HardwiredLints {
318304
DEPRECATED,
319305
UNUSED_UNSAFE,
320306
UNUSED_MUT,
321-
COERCE_NEVER,
322307
SINGLE_USE_LIFETIME,
323308
TYVAR_BEHIND_RAW_POINTER,
324309
ELIDED_LIFETIME_IN_PATH,

src/librustc/middle/mem_categorization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
12981298
PatKind::Tuple(ref subpats, ddpos) => {
12991299
// (p1, ..., pN)
13001300
let expected_len = match self.pat_ty(&pat)?.sty {
1301-
ty::TyTuple(ref tys, _) => tys.len(),
1301+
ty::TyTuple(ref tys) => tys.len(),
13021302
ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
13031303
};
13041304
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {

src/librustc/mir/tcx.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl<'tcx> Rvalue<'tcx> {
155155
let lhs_ty = lhs.ty(local_decls, tcx);
156156
let rhs_ty = rhs.ty(local_decls, tcx);
157157
let ty = op.ty(tcx, lhs_ty, rhs_ty);
158-
tcx.intern_tup(&[ty, tcx.types.bool], false)
158+
tcx.intern_tup(&[ty, tcx.types.bool])
159159
}
160160
Rvalue::UnaryOp(UnOp::Not, ref operand) |
161161
Rvalue::UnaryOp(UnOp::Neg, ref operand) => {
@@ -178,10 +178,7 @@ impl<'tcx> Rvalue<'tcx> {
178178
tcx.mk_array(ty, ops.len() as u64)
179179
}
180180
AggregateKind::Tuple => {
181-
tcx.mk_tup(
182-
ops.iter().map(|op| op.ty(local_decls, tcx)),
183-
false
184-
)
181+
tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx)))
185182
}
186183
AggregateKind::Adt(def, _, substs, _) => {
187184
tcx.type_of(def.did).subst(tcx, substs)

src/librustc/traits/error_reporting.rs

+46-10
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ use syntax_pos::{DUMMY_SP, Span};
4747
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
4848
pub fn report_fulfillment_errors(&self,
4949
errors: &Vec<FulfillmentError<'tcx>>,
50-
body_id: Option<hir::BodyId>) {
50+
body_id: Option<hir::BodyId>,
51+
fallback_has_occurred: bool) {
5152
#[derive(Debug)]
5253
struct ErrorDescriptor<'tcx> {
5354
predicate: ty::Predicate<'tcx>,
@@ -107,7 +108,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
107108

108109
for (error, suppressed) in errors.iter().zip(is_suppressed) {
109110
if !suppressed {
110-
self.report_fulfillment_error(error, body_id);
111+
self.report_fulfillment_error(error, body_id, fallback_has_occurred);
111112
}
112113
}
113114
}
@@ -151,11 +152,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
151152
}
152153

153154
fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>,
154-
body_id: Option<hir::BodyId>) {
155+
body_id: Option<hir::BodyId>,
156+
fallback_has_occurred: bool) {
155157
debug!("report_fulfillment_errors({:?})", error);
156158
match error.code {
157159
FulfillmentErrorCode::CodeSelectionError(ref e) => {
158-
self.report_selection_error(&error.obligation, e);
160+
self.report_selection_error(&error.obligation, e, fallback_has_occurred);
159161
}
160162
FulfillmentErrorCode::CodeProjectionError(ref e) => {
161163
self.report_projection_error(&error.obligation, e);
@@ -533,7 +535,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
533535

534536
pub fn report_selection_error(&self,
535537
obligation: &PredicateObligation<'tcx>,
536-
error: &SelectionError<'tcx>)
538+
error: &SelectionError<'tcx>,
539+
fallback_has_occurred: bool)
537540
{
538541
let span = obligation.cause.span;
539542

@@ -619,6 +622,39 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
619622
self.report_similar_impl_candidates(impl_candidates, &mut err);
620623
}
621624

625+
// If this error is due to `!: Trait` not implemented but `(): Trait` is
626+
// implemented, and fallback has occured, then it could be due to a
627+
// variable that used to fallback to `()` now falling back to `!`. Issue a
628+
// note informing about the change in behaviour.
629+
if trait_predicate.skip_binder().self_ty().is_never()
630+
&& fallback_has_occurred
631+
{
632+
let predicate = trait_predicate.map_bound(|mut trait_pred| {
633+
{
634+
let trait_ref = &mut trait_pred.trait_ref;
635+
let never_substs = trait_ref.substs;
636+
let mut unit_substs = Vec::with_capacity(never_substs.len());
637+
unit_substs.push(self.tcx.mk_nil().into());
638+
unit_substs.extend(&never_substs[1..]);
639+
trait_ref.substs = self.tcx.intern_substs(&unit_substs);
640+
}
641+
trait_pred
642+
});
643+
let unit_obligation = Obligation {
644+
predicate: ty::Predicate::Trait(predicate),
645+
.. obligation.clone()
646+
};
647+
let mut selcx = SelectionContext::new(self);
648+
if selcx.evaluate_obligation(&unit_obligation) {
649+
err.note("the trait is implemented for `()`. \
650+
Possibly this error has been caused by changes to \
651+
Rust's type-inference algorithm \
652+
(see: https://github.com/rust-lang/rust/issues/48950 \
653+
for more info). Consider whether you meant to use the \
654+
type `()` here instead.");
655+
}
656+
}
657+
622658
err
623659
}
624660

@@ -729,14 +765,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
729765
}).map(|sp| self.tcx.sess.codemap().def_span(sp)); // the sp could be an fn def
730766

731767
let found = match found_trait_ref.skip_binder().substs.type_at(1).sty {
732-
ty::TyTuple(ref tys, _) => tys.iter()
768+
ty::TyTuple(ref tys) => tys.iter()
733769
.map(|_| ArgKind::empty()).collect::<Vec<_>>(),
734770
_ => vec![ArgKind::empty()],
735771
};
736772
let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty {
737-
ty::TyTuple(ref tys, _) => tys.iter()
773+
ty::TyTuple(ref tys) => tys.iter()
738774
.map(|t| match t.sty {
739-
ty::TypeVariants::TyTuple(ref tys, _) => ArgKind::Tuple(
775+
ty::TypeVariants::TyTuple(ref tys) => ArgKind::Tuple(
740776
Some(span),
741777
tys.iter()
742778
.map(|ty| ("_".to_owned(), format!("{}", ty.sty)))
@@ -986,7 +1022,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
9861022
fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
9871023
trait_ref: &ty::TraitRef<'tcx>) -> String {
9881024
let inputs = trait_ref.substs.type_at(1);
989-
let sig = if let ty::TyTuple(inputs, _) = inputs.sty {
1025+
let sig = if let ty::TyTuple(inputs) = inputs.sty {
9901026
tcx.mk_fn_sig(
9911027
inputs.iter().map(|&x| x),
9921028
tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
@@ -1422,7 +1458,7 @@ impl ArgKind {
14221458
/// argument. This has no name (`_`) and no source spans..
14231459
pub fn from_expected_ty(t: Ty<'_>) -> ArgKind {
14241460
match t.sty {
1425-
ty::TyTuple(ref tys, _) => ArgKind::Tuple(
1461+
ty::TyTuple(ref tys) => ArgKind::Tuple(
14261462
None,
14271463
tys.iter()
14281464
.map(|ty| ("_".to_owned(), format!("{}", ty.sty)))

src/librustc/traits/fulfill.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -330,11 +330,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
330330
if data.is_global() {
331331
// no type variables present, can use evaluation for better caching.
332332
// FIXME: consider caching errors too.
333-
if
334-
// make defaulted unit go through the slow path for better warnings,
335-
// please remove this when the warnings are removed.
336-
!trait_obligation.predicate.skip_binder().self_ty().is_defaulted_unit() &&
337-
selcx.evaluate_obligation_conservatively(&obligation) {
333+
if selcx.evaluate_obligation_conservatively(&obligation) {
338334
debug!("selecting trait `{:?}` at depth {} evaluated to holds",
339335
data, obligation.recursion_depth);
340336
return Ok(Some(vec![]))

src/librustc/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
580580
) {
581581
Ok(predicates) => predicates,
582582
Err(errors) => {
583-
infcx.report_fulfillment_errors(&errors, None);
583+
infcx.report_fulfillment_errors(&errors, None, false);
584584
// An unnormalized env is better than nothing.
585585
return elaborated_env;
586586
}

src/librustc/traits/query/dropck_outlives.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ fn trivial_dropck_outlives<'cx, 'tcx>(tcx: TyCtxt<'cx, '_, 'tcx>, ty: Ty<'tcx>)
236236

237237
// (T1..Tn) and closures have same properties as T1..Tn --
238238
// check if *any* of those are trivial.
239-
ty::TyTuple(ref tys, _) => tys.iter().cloned().all(|t| trivial_dropck_outlives(tcx, t)),
239+
ty::TyTuple(ref tys) => tys.iter().cloned().all(|t| trivial_dropck_outlives(tcx, t)),
240240
ty::TyClosure(def_id, ref substs) => substs
241241
.upvar_tys(def_id, tcx)
242242
.all(|t| trivial_dropck_outlives(tcx, t)),

0 commit comments

Comments
 (0)