Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilise feature(never_type). Introduce feature(exhaustive_patterns) #47630

Merged
merged 14 commits into from
Mar 15, 2018
8 changes: 4 additions & 4 deletions src/libcore/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -882,24 +882,24 @@ mod impls {

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

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

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

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

#[unstable(feature = "never_type", issue = "35121")]
#[stable(feature = "never_type", since = "1.26.0")]
impl Ord for ! {
fn cmp(&self, _: &!) -> Ordering {
*self
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1579,14 +1579,14 @@ macro_rules! fmt_refs {

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

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

#[unstable(feature = "never_type", issue = "35121")]
#[stable(feature = "never_type", since = "1.26.0")]
impl Display for ! {
fn fmt(&self, _: &mut Formatter) -> Result {
*self
Expand Down
3 changes: 2 additions & 1 deletion src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
#![feature(iterator_repeat_with)]
#![feature(lang_items)]
#![feature(link_llvm_intrinsics)]
#![feature(never_type)]
#![feature(exhaustive_patterns)]
#![feature(no_core)]
#![feature(on_unimplemented)]
#![feature(optin_builtin_traits)]
Expand All @@ -103,6 +103,7 @@
#![feature(unwind_attributes)]

#![cfg_attr(stage0, allow(unused_attributes))]
#![cfg_attr(stage0, feature(never_type))]

#[prelude_import]
#[allow(unused)]
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/ich/impls_ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -886,9 +886,8 @@ for ty::TypeVariants<'gcx>
TyGeneratorWitness(types) => {
types.hash_stable(hcx, hasher)
}
TyTuple(inner_tys, from_diverging_type_var) => {
TyTuple(inner_tys) => {
inner_tys.hash_stable(hcx, hasher);
from_diverging_type_var.hash_stable(hcx, hasher);
}
TyProjection(ref projection_ty) => {
projection_ty.hash_stable(hcx, hasher);
Expand Down
8 changes: 1 addition & 7 deletions src/librustc/infer/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,12 +609,6 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
bug!("encountered a canonical type during canonicalization")
}

// Replace a `()` that "would've fallen back" to `!` with just `()`.
ty::TyTuple(ref tys, true) => {
assert!(tys.is_empty());
self.tcx().mk_nil()
}

ty::TyClosure(..)
| ty::TyGenerator(..)
| ty::TyGeneratorWitness(..)
Expand All @@ -634,7 +628,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
| ty::TyFnPtr(_)
| ty::TyDynamic(..)
| ty::TyNever
| ty::TyTuple(_, false)
| ty::TyTuple(..)
| ty::TyProjection(..)
| ty::TyForeign(..)
| ty::TyParam(..)
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/infer/outlives/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
// get solved *here*.
match fulfill_cx.select_all_or_error(self) {
Ok(()) => (),
Err(errors) => self.report_fulfillment_errors(&errors, None),
Err(errors) => self.report_fulfillment_errors(&errors, None, false),
}

implied_bounds
Expand Down
6 changes: 0 additions & 6 deletions src/librustc/infer/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
ty::TyInfer(_) => {
bug!("Unexpected type in full type resolver: {:?}", t);
}
ty::TyTuple(tys, true) => {
// Un-default defaulted tuples - we are going to a
// different infcx, and the default will just cause
// pollution.
self.tcx().intern_tup(tys, false)
}
_ => {
t.super_fold_with(self)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
#![feature(match_default_bindings)]
#![feature(macro_lifetime_matcher)]
#![feature(macro_vis_matcher)]
#![feature(never_type)]
#![feature(exhaustive_patterns)]
#![feature(non_exhaustive)]
#![feature(nonzero)]
#![feature(proc_macro_internals)]
Expand Down
15 changes: 0 additions & 15 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,6 @@ declare_lint! {
"lints that have been renamed or removed"
}

declare_lint! {
pub RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
Deny,
"attempt to resolve a trait on an expression whose type cannot be inferred but which \
currently defaults to ()"
}

declare_lint! {
pub SAFE_EXTERN_STATICS,
Deny,
Expand Down Expand Up @@ -237,12 +230,6 @@ declare_lint! {
"detect mut variables which don't need to be mutable"
}

declare_lint! {
pub COERCE_NEVER,
Deny,
"detect coercion to !"
}

declare_lint! {
pub SINGLE_USE_LIFETIME,
Allow,
Expand Down Expand Up @@ -304,7 +291,6 @@ impl LintPass for HardwiredLints {
INVALID_TYPE_PARAM_DEFAULT,
CONST_ERR,
RENAMED_AND_REMOVED_LINTS,
RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
SAFE_EXTERN_STATICS,
SAFE_PACKED_BORROWS,
PATTERNS_IN_FNS_WITHOUT_BODY,
Expand All @@ -318,7 +304,6 @@ impl LintPass for HardwiredLints {
DEPRECATED,
UNUSED_UNSAFE,
UNUSED_MUT,
COERCE_NEVER,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we also need to register that these lints are removed. Like so:

store.register_removed("extra_requirement_in_impl",
"converted into hard error, see https://github.com/rust-lang/rust/issues/37166");

Presumably something like:

    store.register_removed("coerce_never",
        "converted into hard error, see https://github.com/rust-lang/rust/issues/XXX");
    store.register_removed("resolve_trait_on_defaulted_unit",
        "converted into hard error, see https://github.com/rust-lang/rust/issues/XXX");

SINGLE_USE_LIFETIME,
TYVAR_BEHIND_RAW_POINTER,
ELIDED_LIFETIME_IN_PATH,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
PatKind::Tuple(ref subpats, ddpos) => {
// (p1, ..., pN)
let expected_len = match self.pat_ty(&pat)?.sty {
ty::TyTuple(ref tys, _) => tys.len(),
ty::TyTuple(ref tys) => tys.len(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so happy to see that _ go =)

ref ty => span_bug!(pat.span, "tuple pattern unexpected type {:?}", ty),
};
for (i, subpat) in subpats.iter().enumerate_and_adjust(expected_len, ddpos) {
Expand Down
7 changes: 2 additions & 5 deletions src/librustc/mir/tcx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ impl<'tcx> Rvalue<'tcx> {
let lhs_ty = lhs.ty(local_decls, tcx);
let rhs_ty = rhs.ty(local_decls, tcx);
let ty = op.ty(tcx, lhs_ty, rhs_ty);
tcx.intern_tup(&[ty, tcx.types.bool], false)
tcx.intern_tup(&[ty, tcx.types.bool])
}
Rvalue::UnaryOp(UnOp::Not, ref operand) |
Rvalue::UnaryOp(UnOp::Neg, ref operand) => {
Expand All @@ -178,10 +178,7 @@ impl<'tcx> Rvalue<'tcx> {
tcx.mk_array(ty, ops.len() as u64)
}
AggregateKind::Tuple => {
tcx.mk_tup(
ops.iter().map(|op| op.ty(local_decls, tcx)),
false
)
tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx)))
}
AggregateKind::Adt(def, _, substs, _) => {
tcx.type_of(def.did).subst(tcx, substs)
Expand Down
56 changes: 46 additions & 10 deletions src/librustc/traits/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ use syntax_pos::{DUMMY_SP, Span};
impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
pub fn report_fulfillment_errors(&self,
errors: &Vec<FulfillmentError<'tcx>>,
body_id: Option<hir::BodyId>) {
body_id: Option<hir::BodyId>,
fallback_has_occurred: bool) {
#[derive(Debug)]
struct ErrorDescriptor<'tcx> {
predicate: ty::Predicate<'tcx>,
Expand Down Expand Up @@ -107,7 +108,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {

for (error, suppressed) in errors.iter().zip(is_suppressed) {
if !suppressed {
self.report_fulfillment_error(error, body_id);
self.report_fulfillment_error(error, body_id, fallback_has_occurred);
}
}
}
Expand Down Expand Up @@ -151,11 +152,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}

fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>,
body_id: Option<hir::BodyId>) {
body_id: Option<hir::BodyId>,
fallback_has_occurred: bool) {
debug!("report_fulfillment_errors({:?})", error);
match error.code {
FulfillmentErrorCode::CodeSelectionError(ref e) => {
self.report_selection_error(&error.obligation, e);
self.report_selection_error(&error.obligation, e, fallback_has_occurred);
}
FulfillmentErrorCode::CodeProjectionError(ref e) => {
self.report_projection_error(&error.obligation, e);
Expand Down Expand Up @@ -533,7 +535,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {

pub fn report_selection_error(&self,
obligation: &PredicateObligation<'tcx>,
error: &SelectionError<'tcx>)
error: &SelectionError<'tcx>,
fallback_has_occurred: bool)
{
let span = obligation.cause.span;

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

// If this error is due to `!: Trait` not implemented but `(): Trait` is
// implemented, and fallback has occured, then it could be due to a
// variable that used to fallback to `()` now falling back to `!`. Issue a
// note informing about the change in behaviour.
if trait_predicate.skip_binder().self_ty().is_never()
&& fallback_has_occurred
{
let predicate = trait_predicate.map_bound(|mut trait_pred| {
{
let trait_ref = &mut trait_pred.trait_ref;
let never_substs = trait_ref.substs;
let mut unit_substs = Vec::with_capacity(never_substs.len());
unit_substs.push(self.tcx.mk_nil().into());
unit_substs.extend(&never_substs[1..]);
trait_ref.substs = self.tcx.intern_substs(&unit_substs);
}
trait_pred
});
let unit_obligation = Obligation {
predicate: ty::Predicate::Trait(predicate),
.. obligation.clone()
};
let mut selcx = SelectionContext::new(self);
if selcx.evaluate_obligation(&unit_obligation) {
err.note("the trait is implemented for `()`. \
Possibly this error has been caused by changes to \
Rust's type-inference algorithm \
(see: https://github.com/rust-lang/rust/issues/48950 \
for more info). Consider whether you meant to use the \
type `()` here instead.");
}
}

err
}

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

let found = match found_trait_ref.skip_binder().substs.type_at(1).sty {
ty::TyTuple(ref tys, _) => tys.iter()
ty::TyTuple(ref tys) => tys.iter()
.map(|_| ArgKind::empty()).collect::<Vec<_>>(),
_ => vec![ArgKind::empty()],
};
let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty {
ty::TyTuple(ref tys, _) => tys.iter()
ty::TyTuple(ref tys) => tys.iter()
.map(|t| match t.sty {
ty::TypeVariants::TyTuple(ref tys, _) => ArgKind::Tuple(
ty::TypeVariants::TyTuple(ref tys) => ArgKind::Tuple(
Some(span),
tys.iter()
.map(|ty| ("_".to_owned(), format!("{}", ty.sty)))
Expand Down Expand Up @@ -986,7 +1022,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
trait_ref: &ty::TraitRef<'tcx>) -> String {
let inputs = trait_ref.substs.type_at(1);
let sig = if let ty::TyTuple(inputs, _) = inputs.sty {
let sig = if let ty::TyTuple(inputs) = inputs.sty {
tcx.mk_fn_sig(
inputs.iter().map(|&x| x),
tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
Expand Down Expand Up @@ -1422,7 +1458,7 @@ impl ArgKind {
/// argument. This has no name (`_`) and no source spans..
pub fn from_expected_ty(t: Ty<'_>) -> ArgKind {
match t.sty {
ty::TyTuple(ref tys, _) => ArgKind::Tuple(
ty::TyTuple(ref tys) => ArgKind::Tuple(
None,
tys.iter()
.map(|ty| ("_".to_owned(), format!("{}", ty.sty)))
Expand Down
6 changes: 1 addition & 5 deletions src/librustc/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,11 +330,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
if data.is_global() {
// no type variables present, can use evaluation for better caching.
// FIXME: consider caching errors too.
if
// make defaulted unit go through the slow path for better warnings,
// please remove this when the warnings are removed.
!trait_obligation.predicate.skip_binder().self_ty().is_defaulted_unit() &&
selcx.evaluate_obligation_conservatively(&obligation) {
if selcx.evaluate_obligation_conservatively(&obligation) {
debug!("selecting trait `{:?}` at depth {} evaluated to holds",
data, obligation.recursion_depth);
return Ok(Some(vec![]))
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
) {
Ok(predicates) => predicates,
Err(errors) => {
infcx.report_fulfillment_errors(&errors, None);
infcx.report_fulfillment_errors(&errors, None, false);
// An unnormalized env is better than nothing.
return elaborated_env;
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/traits/query/dropck_outlives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ fn trivial_dropck_outlives<'cx, 'tcx>(tcx: TyCtxt<'cx, '_, 'tcx>, ty: Ty<'tcx>)

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