1
Fork 0

remove defaulting to unit

Types will no longer default to `()`, instead always defaulting to `!`.
This disables the associated warning and removes the flag from TyTuple
This commit is contained in:
Andrew Cann 2018-01-21 13:33:21 +08:00
parent fab632f975
commit 9b15ddb29e
57 changed files with 107 additions and 243 deletions

View file

@ -886,9 +886,8 @@ for ty::TypeVariants<'gcx>
TyGeneratorWitness(types) => { TyGeneratorWitness(types) => {
types.hash_stable(hcx, hasher) types.hash_stable(hcx, hasher)
} }
TyTuple(inner_tys, from_diverging_type_var) => { TyTuple(inner_tys) => {
inner_tys.hash_stable(hcx, hasher); inner_tys.hash_stable(hcx, hasher);
from_diverging_type_var.hash_stable(hcx, hasher);
} }
TyProjection(ref projection_ty) => { TyProjection(ref projection_ty) => {
projection_ty.hash_stable(hcx, hasher); projection_ty.hash_stable(hcx, hasher);

View file

@ -173,12 +173,6 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for FullTypeResolver<'a, 'gcx, 'tcx>
ty::TyInfer(_) => { ty::TyInfer(_) => {
bug!("Unexpected type in full type resolver: {:?}", t); 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) t.super_fold_with(self)
} }

View file

@ -151,13 +151,6 @@ declare_lint! {
"lints that have been renamed or removed" "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! { declare_lint! {
pub SAFE_EXTERN_STATICS, pub SAFE_EXTERN_STATICS,
Deny, Deny,
@ -304,7 +297,6 @@ impl LintPass for HardwiredLints {
INVALID_TYPE_PARAM_DEFAULT, INVALID_TYPE_PARAM_DEFAULT,
CONST_ERR, CONST_ERR,
RENAMED_AND_REMOVED_LINTS, RENAMED_AND_REMOVED_LINTS,
RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
SAFE_EXTERN_STATICS, SAFE_EXTERN_STATICS,
SAFE_PACKED_BORROWS, SAFE_PACKED_BORROWS,
PATTERNS_IN_FNS_WITHOUT_BODY, PATTERNS_IN_FNS_WITHOUT_BODY,

View file

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

View file

@ -155,7 +155,7 @@ impl<'tcx> Rvalue<'tcx> {
let lhs_ty = lhs.ty(local_decls, tcx); let lhs_ty = lhs.ty(local_decls, tcx);
let rhs_ty = rhs.ty(local_decls, tcx); let rhs_ty = rhs.ty(local_decls, tcx);
let ty = op.ty(tcx, lhs_ty, rhs_ty); 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::Not, ref operand) |
Rvalue::UnaryOp(UnOp::Neg, ref operand) => { Rvalue::UnaryOp(UnOp::Neg, ref operand) => {
@ -178,10 +178,7 @@ impl<'tcx> Rvalue<'tcx> {
tcx.mk_array(ty, ops.len() as u64) tcx.mk_array(ty, ops.len() as u64)
} }
AggregateKind::Tuple => { AggregateKind::Tuple => {
tcx.mk_tup( tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx)))
ops.iter().map(|op| op.ty(local_decls, tcx)),
false
)
} }
AggregateKind::Adt(def, _, substs, _) => { AggregateKind::Adt(def, _, substs, _) => {
tcx.type_of(def.did).subst(tcx, substs) tcx.type_of(def.did).subst(tcx, substs)

View file

@ -729,14 +729,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 }).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 { 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<_>>(), .map(|_| ArgKind::empty()).collect::<Vec<_>>(),
_ => vec![ArgKind::empty()], _ => vec![ArgKind::empty()],
}; };
let expected = match expected_trait_ref.skip_binder().substs.type_at(1).sty { 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 { .map(|t| match t.sty {
ty::TypeVariants::TyTuple(ref tys, _) => ArgKind::Tuple( ty::TypeVariants::TyTuple(ref tys) => ArgKind::Tuple(
Some(span), Some(span),
tys.iter() tys.iter()
.map(|ty| ("_".to_owned(), format!("{}", ty.sty))) .map(|ty| ("_".to_owned(), format!("{}", ty.sty)))
@ -986,7 +986,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>, fn build_fn_sig_string<'a, 'gcx, 'tcx>(tcx: ty::TyCtxt<'a, 'gcx, 'tcx>,
trait_ref: &ty::TraitRef<'tcx>) -> String { trait_ref: &ty::TraitRef<'tcx>) -> String {
let inputs = trait_ref.substs.type_at(1); 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( tcx.mk_fn_sig(
inputs.iter().map(|&x| x), inputs.iter().map(|&x| x),
tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })), tcx.mk_infer(ty::TyVar(ty::TyVid { index: 0 })),
@ -1422,7 +1422,7 @@ impl ArgKind {
/// argument. This has no name (`_`) and no source spans.. /// argument. This has no name (`_`) and no source spans..
pub fn from_expected_ty(t: Ty<'_>) -> ArgKind { pub fn from_expected_ty(t: Ty<'_>) -> ArgKind {
match t.sty { match t.sty {
ty::TyTuple(ref tys, _) => ArgKind::Tuple( ty::TyTuple(ref tys) => ArgKind::Tuple(
None, None,
tys.iter() tys.iter()
.map(|ty| ("_".to_owned(), format!("{}", ty.sty))) .map(|ty| ("_".to_owned(), format!("{}", ty.sty)))

View file

@ -330,11 +330,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
if data.is_global() { if data.is_global() {
// no type variables present, can use evaluation for better caching. // no type variables present, can use evaluation for better caching.
// FIXME: consider caching errors too. // FIXME: consider caching errors too.
if if selcx.evaluate_obligation_conservatively(&obligation) {
// 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) {
debug!("selecting trait `{:?}` at depth {} evaluated to holds", debug!("selecting trait `{:?}` at depth {} evaluated to holds",
data, obligation.recursion_depth); data, obligation.recursion_depth);
return Ok(Some(vec![])) return Ok(Some(vec![]))

View file

@ -53,7 +53,6 @@ use std::mem;
use std::rc::Rc; use std::rc::Rc;
use syntax::abi::Abi; use syntax::abi::Abi;
use hir; use hir;
use lint;
use util::nodemap::{FxHashMap, FxHashSet}; use util::nodemap::{FxHashMap, FxHashSet};
@ -526,54 +525,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
debug!("select({:?})", obligation); debug!("select({:?})", obligation);
assert!(!obligation.predicate.has_escaping_regions()); assert!(!obligation.predicate.has_escaping_regions());
let tcx = self.tcx();
let stack = self.push_stack(TraitObligationStackList::empty(), obligation); let stack = self.push_stack(TraitObligationStackList::empty(), obligation);
let ret = match self.candidate_from_obligation(&stack)? { let ret = match self.candidate_from_obligation(&stack)? {
None => None, None => None,
Some(candidate) => Some(self.confirm_candidate(obligation, candidate)?) Some(candidate) => Some(self.confirm_candidate(obligation, candidate)?)
}; };
// Test whether this is a `()` which was produced by defaulting a
// diverging type variable with `!` disabled. If so, we may need
// to raise a warning.
if obligation.predicate.skip_binder().self_ty().is_defaulted_unit() {
let mut raise_warning = true;
// Don't raise a warning if the trait is implemented for ! and only
// permits a trivial implementation for !. This stops us warning
// about (for example) `(): Clone` becoming `!: Clone` because such
// a switch can't cause code to stop compiling or execute
// differently.
let mut never_obligation = obligation.clone();
let def_id = never_obligation.predicate.skip_binder().trait_ref.def_id;
never_obligation.predicate = never_obligation.predicate.map_bound(|mut trait_pred| {
// Swap out () with ! so we can check if the trait is impld for !
{
let trait_ref = &mut trait_pred.trait_ref;
let unit_substs = trait_ref.substs;
let mut never_substs = Vec::with_capacity(unit_substs.len());
never_substs.push(tcx.types.never.into());
never_substs.extend(&unit_substs[1..]);
trait_ref.substs = tcx.intern_substs(&never_substs);
}
trait_pred
});
if let Ok(Some(..)) = self.select(&never_obligation) {
if !tcx.trait_relevant_for_never(def_id) {
// The trait is also implemented for ! and the resulting
// implementation cannot actually be invoked in any way.
raise_warning = false;
}
}
if raise_warning {
tcx.lint_node(lint::builtin::RESOLVE_TRAIT_ON_DEFAULTED_UNIT,
obligation.cause.body_id,
obligation.cause.span,
&format!("code relies on type inference rules which are likely \
to change"));
}
}
Ok(ret) Ok(ret)
} }
@ -1929,7 +1886,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
} }
// (.., T) -> (.., U). // (.., T) -> (.., U).
(&ty::TyTuple(tys_a, _), &ty::TyTuple(tys_b, _)) => { (&ty::TyTuple(tys_a), &ty::TyTuple(tys_b)) => {
tys_a.len() == tys_b.len() tys_a.len() == tys_b.len()
} }
@ -2068,7 +2025,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) | ty::TyForeign(..) => Never, ty::TyStr | ty::TySlice(_) | ty::TyDynamic(..) | ty::TyForeign(..) => Never,
ty::TyTuple(tys, _) => { ty::TyTuple(tys) => {
Where(ty::Binder(tys.last().into_iter().cloned().collect())) Where(ty::Binder(tys.last().into_iter().cloned().collect()))
} }
@ -2122,7 +2079,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
Where(ty::Binder(vec![element_ty])) Where(ty::Binder(vec![element_ty]))
} }
ty::TyTuple(tys, _) => { ty::TyTuple(tys) => {
// (*) binder moved here // (*) binder moved here
Where(ty::Binder(tys.to_vec())) Where(ty::Binder(tys.to_vec()))
} }
@ -2215,7 +2172,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
vec![element_ty] vec![element_ty]
} }
ty::TyTuple(ref tys, _) => { ty::TyTuple(ref tys) => {
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
tys.to_vec() tys.to_vec()
} }
@ -3004,7 +2961,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
} }
// (.., T) -> (.., U). // (.., T) -> (.., U).
(&ty::TyTuple(tys_a, _), &ty::TyTuple(tys_b, _)) => { (&ty::TyTuple(tys_a), &ty::TyTuple(tys_b)) => {
assert_eq!(tys_a.len(), tys_b.len()); assert_eq!(tys_a.len(), tys_b.len());
// The last field of the tuple has to exist. // The last field of the tuple has to exist.
@ -3017,7 +2974,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
// Check that the source tuple with the target's // Check that the source tuple with the target's
// last element is equal to the target. // last element is equal to the target.
let new_tuple = tcx.mk_tup(a_mid.iter().chain(Some(b_last)), false); let new_tuple = tcx.mk_tup(a_mid.iter().chain(Some(b_last)));
let InferOk { obligations, .. } = let InferOk { obligations, .. } =
self.infcx.at(&obligation.cause, obligation.param_env) self.infcx.at(&obligation.cause, obligation.param_env)
.eq(target, new_tuple) .eq(target, new_tuple)

View file

@ -503,7 +503,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
let arguments_tuple = match tuple_arguments { let arguments_tuple = match tuple_arguments {
TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
TupleArgumentsFlag::Yes => TupleArgumentsFlag::Yes =>
self.intern_tup(sig.skip_binder().inputs(), false), self.intern_tup(sig.skip_binder().inputs()),
}; };
let trait_ref = ty::TraitRef { let trait_ref = ty::TraitRef {
def_id: fn_trait_def_id, def_id: fn_trait_def_id,

View file

@ -2014,7 +2014,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> { pub fn coerce_closure_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
let converted_sig = sig.map_bound(|s| { let converted_sig = sig.map_bound(|s| {
let params_iter = match s.inputs()[0].sty { let params_iter = match s.inputs()[0].sty {
ty::TyTuple(params, _) => { ty::TyTuple(params) => {
params.into_iter().cloned() params.into_iter().cloned()
} }
_ => bug!(), _ => bug!(),
@ -2134,25 +2134,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
self.mk_ty(TySlice(ty)) self.mk_ty(TySlice(ty))
} }
pub fn intern_tup(self, ts: &[Ty<'tcx>], defaulted: bool) -> Ty<'tcx> { pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> {
self.mk_ty(TyTuple(self.intern_type_list(ts), defaulted)) self.mk_ty(TyTuple(self.intern_type_list(ts)))
} }
pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I, pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I) -> I::Output {
defaulted: bool) -> I::Output { iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts))))
iter.intern_with(|ts| self.mk_ty(TyTuple(self.intern_type_list(ts), defaulted)))
} }
pub fn mk_nil(self) -> Ty<'tcx> { pub fn mk_nil(self) -> Ty<'tcx> {
self.intern_tup(&[], false) self.intern_tup(&[])
}
pub fn mk_diverging_default(self) -> Ty<'tcx> {
if self.features().never_type {
self.types.never
} else {
self.intern_tup(&[], true)
}
} }
pub fn mk_bool(self) -> Ty<'tcx> { pub fn mk_bool(self) -> Ty<'tcx> {

View file

@ -177,7 +177,7 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
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::TyNever => 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::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)), ty::TyAdt(def, _) => format!("{} `{}`", def.descr(), tcx.item_path_str(def.did)),
ty::TyForeign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)), ty::TyForeign(def_id) => format!("extern type `{}`", tcx.item_path_str(def_id)),

View file

@ -97,7 +97,7 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len())) Some(GeneratorWitnessSimplifiedType(tys.skip_binder().len()))
} }
ty::TyNever => Some(NeverSimplifiedType), ty::TyNever => Some(NeverSimplifiedType),
ty::TyTuple(ref tys, _) => { ty::TyTuple(ref tys) => {
Some(TupleSimplifiedType(tys.len())) Some(TupleSimplifiedType(tys.len()))
} }
ty::TyFnPtr(ref f) => { ty::TyFnPtr(ref f) => {

View file

@ -179,10 +179,7 @@ impl FlagComputation {
self.add_ty(m.ty); self.add_ty(m.ty);
} }
&ty::TyTuple(ref ts, is_default) => { &ty::TyTuple(ref ts) => {
if is_default {
self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX);
}
self.add_tys(&ts[..]); self.add_tys(&ts[..]);
} }

View file

@ -256,7 +256,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
}, },
TyNever => DefIdForest::full(tcx), TyNever => DefIdForest::full(tcx),
TyTuple(ref tys, _) => { TyTuple(ref tys) => {
DefIdForest::union(tcx, tys.iter().map(|ty| { DefIdForest::union(tcx, tys.iter().map(|ty| {
ty.uninhabited_from(visited, tcx) ty.uninhabited_from(visited, tcx)
})) }))

View file

@ -355,9 +355,9 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
ty::TyRawPtr(mt) | ty::TyRawPtr(mt) |
ty::TyRef(_, mt) => characteristic_def_id_of_type(mt.ty), ty::TyRef(_, mt) => characteristic_def_id_of_type(mt.ty),
ty::TyTuple(ref tys, _) => tys.iter() ty::TyTuple(ref tys) => tys.iter()
.filter_map(|ty| characteristic_def_id_of_type(ty)) .filter_map(|ty| characteristic_def_id_of_type(ty))
.next(), .next(),
ty::TyFnDef(def_id, _) | ty::TyFnDef(def_id, _) |
ty::TyClosure(def_id, _) | ty::TyClosure(def_id, _) |

View file

@ -1318,7 +1318,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
StructKind::AlwaysSized)? StructKind::AlwaysSized)?
} }
ty::TyTuple(tys, _) => { ty::TyTuple(tys) => {
let kind = if tys.len() == 0 { let kind = if tys.len() == 0 {
StructKind::AlwaysSized StructKind::AlwaysSized
} else { } else {
@ -2243,7 +2243,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
substs.field_tys(def_id, tcx).nth(i).unwrap() substs.field_tys(def_id, tcx).nth(i).unwrap()
} }
ty::TyTuple(tys, _) => tys[i], ty::TyTuple(tys) => tys[i],
// SIMD vector types. // SIMD vector types.
ty::TyAdt(def, ..) if def.repr.simd() => { ty::TyAdt(def, ..) if def.repr.simd() => {

View file

@ -2046,7 +2046,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
vec![ty] vec![ty]
} }
TyTuple(ref tys, _) => { TyTuple(ref tys) => {
match tys.last() { match tys.last() {
None => vec![], None => vec![],
Some(ty) => self.sized_constraint_for_ty(tcx, ty) Some(ty) => self.sized_constraint_for_ty(tcx, ty)

View file

@ -529,11 +529,10 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
Ok(tcx.mk_slice(t)) Ok(tcx.mk_slice(t))
} }
(&ty::TyTuple(as_, a_defaulted), &ty::TyTuple(bs, b_defaulted)) => (&ty::TyTuple(as_), &ty::TyTuple(bs)) =>
{ {
if as_.len() == bs.len() { if as_.len() == bs.len() {
let defaulted = a_defaulted || b_defaulted; Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)))?)
Ok(tcx.mk_tup(as_.iter().zip(bs).map(|(a, b)| relation.relate(a, b)), defaulted)?)
} else if !(as_.is_empty() || bs.is_empty()) { } else if !(as_.is_empty() || bs.is_empty()) {
Err(TypeError::TupleSize( Err(TypeError::TupleSize(
expected_found(relation, &as_.len(), &bs.len()))) expected_found(relation, &as_.len(), &bs.len())))

View file

@ -869,7 +869,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)), ty::TyAdt(tid, substs) => ty::TyAdt(tid, substs.fold_with(folder)),
ty::TyDynamic(ref trait_ty, ref region) => ty::TyDynamic(ref trait_ty, ref region) =>
ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)), ty::TyDynamic(trait_ty.fold_with(folder), region.fold_with(folder)),
ty::TyTuple(ts, defaulted) => ty::TyTuple(ts.fold_with(folder), defaulted), ty::TyTuple(ts) => ty::TyTuple(ts.fold_with(folder)),
ty::TyFnDef(def_id, substs) => { ty::TyFnDef(def_id, substs) => {
ty::TyFnDef(def_id, substs.fold_with(folder)) ty::TyFnDef(def_id, substs.fold_with(folder))
} }
@ -908,7 +908,7 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
ty::TyAdt(_, substs) => substs.visit_with(visitor), ty::TyAdt(_, substs) => substs.visit_with(visitor),
ty::TyDynamic(ref trait_ty, ref reg) => ty::TyDynamic(ref trait_ty, ref reg) =>
trait_ty.visit_with(visitor) || reg.visit_with(visitor), trait_ty.visit_with(visitor) || reg.visit_with(visitor),
ty::TyTuple(ts, _) => ts.visit_with(visitor), ty::TyTuple(ts) => ts.visit_with(visitor),
ty::TyFnDef(_, substs) => substs.visit_with(visitor), ty::TyFnDef(_, substs) => substs.visit_with(visitor),
ty::TyFnPtr(ref f) => f.visit_with(visitor), ty::TyFnPtr(ref f) => f.visit_with(visitor),
ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor), ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),

View file

@ -148,11 +148,7 @@ pub enum TypeVariants<'tcx> {
TyNever, TyNever,
/// A tuple type. For example, `(i32, bool)`. /// A tuple type. For example, `(i32, bool)`.
/// The bool indicates whether this is a unit tuple and was created by TyTuple(&'tcx Slice<Ty<'tcx>>),
/// defaulting a diverging type variable with feature(never_type) disabled.
/// It's only purpose is for raising future-compatibility warnings for when
/// diverging type variables start defaulting to ! instead of ().
TyTuple(&'tcx Slice<Ty<'tcx>>, bool),
/// The projection of an associated type. For example, /// The projection of an associated type. For example,
/// `<T as Trait<..>>::N`. /// `<T as Trait<..>>::N`.
@ -1274,7 +1270,7 @@ impl RegionKind {
impl<'a, 'gcx, 'tcx> TyS<'tcx> { impl<'a, 'gcx, 'tcx> TyS<'tcx> {
pub fn is_nil(&self) -> bool { pub fn is_nil(&self) -> bool {
match self.sty { match self.sty {
TyTuple(ref tys, _) => tys.is_empty(), TyTuple(ref tys) => tys.is_empty(),
_ => false, _ => false,
} }
} }
@ -1286,15 +1282,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
} }
} }
/// Test whether this is a `()` which was produced by defaulting a
/// diverging type variable with feature(never_type) disabled.
pub fn is_defaulted_unit(&self) -> bool {
match self.sty {
TyTuple(_, true) => true,
_ => false,
}
}
pub fn is_primitive(&self) -> bool { pub fn is_primitive(&self) -> bool {
match self.sty { match self.sty {
TyBool | TyChar | TyInt(_) | TyUint(_) | TyFloat(_) => true, TyBool | TyChar | TyInt(_) | TyUint(_) | TyFloat(_) => true,

View file

@ -269,7 +269,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// Don't use `non_enum_variant`, this may be a univariant enum. // Don't use `non_enum_variant`, this may be a univariant enum.
adt.variants[0].fields.get(i).map(|f| f.ty(self, substs)) adt.variants[0].fields.get(i).map(|f| f.ty(self, substs))
} }
(&TyTuple(ref v, _), None) => v.get(i).cloned(), (&TyTuple(ref v), None) => v.get(i).cloned(),
_ => None, _ => None,
} }
} }
@ -307,7 +307,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
} }
} }
ty::TyTuple(tys, _) => { ty::TyTuple(tys) => {
if let Some((&last_ty, _)) = tys.split_last() { if let Some((&last_ty, _)) = tys.split_last() {
ty = last_ty; ty = last_ty;
} else { } else {
@ -344,7 +344,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
break; break;
} }
}, },
(&TyTuple(a_tys, _), &TyTuple(b_tys, _)) (&TyTuple(a_tys), &TyTuple(b_tys))
if a_tys.len() == b_tys.len() => { if a_tys.len() == b_tys.len() => {
if let Some(a_last) = a_tys.last() { if let Some(a_last) = a_tys.last() {
a = a_last; a = a_last;
@ -709,9 +709,8 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
TyGeneratorWitness(tys) => { TyGeneratorWitness(tys) => {
self.hash(tys.skip_binder().len()); self.hash(tys.skip_binder().len());
} }
TyTuple(tys, defaulted) => { TyTuple(tys) => {
self.hash(tys.len()); self.hash(tys.len());
self.hash(defaulted);
} }
TyParam(p) => { TyParam(p) => {
self.hash(p.idx); self.hash(p.idx);
@ -838,7 +837,7 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
-> Representability -> Representability
{ {
match ty.sty { match ty.sty {
TyTuple(ref ts, _) => { TyTuple(ref ts) => {
// Find non representable // Find non representable
fold_repr(ts.iter().map(|ty| { fold_repr(ts.iter().map(|ty| {
is_type_structurally_recursive(tcx, sp, seen, representable_cache, ty) is_type_structurally_recursive(tcx, sp, seen, representable_cache, ty)
@ -1106,7 +1105,7 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// state transformation pass // state transformation pass
ty::TyGenerator(..) => true, ty::TyGenerator(..) => true,
ty::TyTuple(ref tys, _) => tys.iter().cloned().any(needs_drop), ty::TyTuple(ref tys) => tys.iter().cloned().any(needs_drop),
// unions don't have destructors regardless of the child types // unions don't have destructors regardless of the child types
ty::TyAdt(def, _) if def.is_union() => false, ty::TyAdt(def, _) if def.is_union() => false,

View file

@ -125,7 +125,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
ty::TyGeneratorWitness(ts) => { ty::TyGeneratorWitness(ts) => {
stack.extend(ts.skip_binder().iter().cloned().rev()); stack.extend(ts.skip_binder().iter().cloned().rev());
} }
ty::TyTuple(ts, _) => { ty::TyTuple(ts) => {
stack.extend(ts.iter().cloned().rev()); stack.extend(ts.iter().cloned().rev());
} }
ty::TyFnDef(_, substs) => { ty::TyFnDef(_, substs) => {

View file

@ -275,7 +275,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
self.compute_const(len); self.compute_const(len);
} }
ty::TyTuple(ref tys, _) => { ty::TyTuple(ref tys) => {
if let Some((_last, rest)) = tys.split_last() { if let Some((_last, rest)) = tys.split_last() {
for elem in rest { for elem in rest {
self.require_sized(elem, traits::TupleElem); self.require_sized(elem, traits::TupleElem);

View file

@ -340,7 +340,7 @@ impl PrintContext {
if !verbose && fn_trait_kind.is_some() && projections.len() == 1 { if !verbose && fn_trait_kind.is_some() && projections.len() == 1 {
let projection_ty = projections[0].ty; let projection_ty = projections[0].ty;
if let TyTuple(ref args, _) = substs.type_at(1).sty { if let TyTuple(ref args) = substs.type_at(1).sty {
return self.fn_sig(f, args, false, projection_ty); return self.fn_sig(f, args, false, projection_ty);
} }
} }
@ -1013,7 +1013,7 @@ define_print! {
tm.print(f, cx) tm.print(f, cx)
} }
TyNever => 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();
if let Some(&ty) = tys.next() { if let Some(&ty) = tys.next() {

View file

@ -287,7 +287,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
} }
pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> { pub fn t_pair(&self, ty1: Ty<'tcx>, ty2: Ty<'tcx>) -> Ty<'tcx> {
self.infcx.tcx.intern_tup(&[ty1, ty2], false) self.infcx.tcx.intern_tup(&[ty1, ty2])
} }
pub fn t_param(&self, index: u32) -> Ty<'tcx> { pub fn t_param(&self, index: u32) -> Ty<'tcx> {
@ -593,8 +593,8 @@ fn walk_ty() {
let tcx = env.infcx.tcx; let tcx = env.infcx.tcx;
let int_ty = tcx.types.isize; let int_ty = tcx.types.isize;
let usize_ty = tcx.types.usize; let usize_ty = tcx.types.usize;
let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty], false); let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]);
let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty], false); let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]);
let walked: Vec<_> = tup2_ty.walk().collect(); let walked: Vec<_> = tup2_ty.walk().collect();
assert_eq!(walked, assert_eq!(walked,
[tup2_ty, tup1_ty, int_ty, usize_ty, int_ty, usize_ty, tup1_ty, int_ty, [tup2_ty, tup1_ty, int_ty, usize_ty, int_ty, usize_ty, tup1_ty, int_ty,
@ -608,8 +608,8 @@ fn walk_ty_skip_subtree() {
let tcx = env.infcx.tcx; let tcx = env.infcx.tcx;
let int_ty = tcx.types.isize; let int_ty = tcx.types.isize;
let usize_ty = tcx.types.usize; let usize_ty = tcx.types.usize;
let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty], false); let tup1_ty = tcx.intern_tup(&[int_ty, usize_ty, int_ty, usize_ty]);
let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty], false); let tup2_ty = tcx.intern_tup(&[tup1_ty, tup1_ty, usize_ty]);
// types we expect to see (in order), plus a boolean saying // types we expect to see (in order), plus a boolean saying
// whether to skip the subtree. // whether to skip the subtree.

View file

@ -234,11 +234,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>", reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
epoch: None, epoch: None,
}, },
FutureIncompatibleInfo {
id: LintId::of(RESOLVE_TRAIT_ON_DEFAULTED_UNIT),
reference: "issue #39216 <https://github.com/rust-lang/rust/issues/39216>",
epoch: None,
},
FutureIncompatibleInfo { FutureIncompatibleInfo {
id: LintId::of(MISSING_FRAGMENT_SPECIFIER), id: LintId::of(MISSING_FRAGMENT_SPECIFIER),
reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>", reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",

View file

@ -58,7 +58,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
let t = cx.tables.expr_ty(&expr); let t = cx.tables.expr_ty(&expr);
let ty_warned = match t.sty { let ty_warned = match t.sty {
ty::TyTuple(ref tys, _) if tys.is_empty() => return, ty::TyTuple(ref tys) if tys.is_empty() => return,
ty::TyNever => return, ty::TyNever => return,
ty::TyAdt(def, _) => { ty::TyAdt(def, _) => {
if def.variants.is_empty() { if def.variants.is_empty() {

View file

@ -789,7 +789,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
} else { } else {
format!("{}", def.non_enum_variant().fields[field.index()].name) format!("{}", def.non_enum_variant().fields[field.index()].name)
}, },
ty::TyTuple(_, _) => format!("{}", field.index()), ty::TyTuple(_) => format!("{}", field.index()),
ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => { ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => {
self.describe_field_from_ty(&tnm.ty, field) self.describe_field_from_ty(&tnm.ty, field)
} }

View file

@ -542,7 +542,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
}), }),
}; };
} }
ty::TyTuple(tys, _) => { ty::TyTuple(tys) => {
return match tys.get(field.index()) { return match tys.get(field.index()) {
Some(&ty) => Ok(ty), Some(&ty) => Ok(ty),
None => Err(FieldAccessError::OutOfRange { None => Err(FieldAccessError::OutOfRange {

View file

@ -635,7 +635,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
let (&output, tuplized_inputs) = inputs_and_output.split_last().unwrap(); let (&output, tuplized_inputs) = inputs_and_output.split_last().unwrap();
assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs"); assert_eq!(tuplized_inputs.len(), 1, "multiple closure inputs");
let inputs = match tuplized_inputs[0].sty { let inputs = match tuplized_inputs[0].sty {
ty::TyTuple(inputs, _) => inputs, ty::TyTuple(inputs) => inputs,
_ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]), _ => bug!("closure inputs not a tuple: {:?}", tuplized_inputs[0]),
}; };

View file

@ -298,7 +298,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source_info = self.source_info(span); let source_info = self.source_info(span);
let bool_ty = self.hir.bool_ty(); let bool_ty = self.hir.bool_ty();
if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() { if self.hir.check_overflow() && op.is_checkable() && ty.is_integral() {
let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty], false); let result_tup = self.hir.tcx().intern_tup(&[ty, bool_ty]);
let result_value = self.temp(result_tup, span); let result_value = self.temp(result_tup, span);
self.cfg.push_assign(block, source_info, self.cfg.push_assign(block, source_info,

View file

@ -227,7 +227,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
let arg_tys = args.iter().map(|e| cx.tables().expr_ty_adjusted(e)); let arg_tys = args.iter().map(|e| cx.tables().expr_ty_adjusted(e));
let tupled_args = Expr { let tupled_args = Expr {
ty: cx.tcx.mk_tup(arg_tys, false), ty: cx.tcx.mk_tup(arg_tys),
temp_lifetime, temp_lifetime,
span: expr.span, span: expr.span,
kind: ExprKind::Tuple { fields: args.iter().map(ToRef::to_ref).collect() }, kind: ExprKind::Tuple { fields: args.iter().map(ToRef::to_ref).collect() },

View file

@ -877,7 +877,7 @@ fn pat_constructors<'tcx>(_cx: &mut MatchCheckCtxt,
fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> u64 { fn constructor_arity(_cx: &MatchCheckCtxt, ctor: &Constructor, ty: Ty) -> u64 {
debug!("constructor_arity({:#?}, {:?})", ctor, ty); debug!("constructor_arity({:#?}, {:?})", ctor, ty);
match ty.sty { match ty.sty {
ty::TyTuple(ref fs, _) => fs.len() as u64, ty::TyTuple(ref fs) => fs.len() as u64,
ty::TySlice(..) | ty::TyArray(..) => match *ctor { ty::TySlice(..) | ty::TyArray(..) => match *ctor {
Slice(length) => length, Slice(length) => length,
ConstantValue(_) => 0, ConstantValue(_) => 0,
@ -901,7 +901,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
{ {
debug!("constructor_sub_pattern_tys({:#?}, {:?})", ctor, ty); debug!("constructor_sub_pattern_tys({:#?}, {:?})", ctor, ty);
match ty.sty { match ty.sty {
ty::TyTuple(ref fs, _) => fs.into_iter().map(|t| *t).collect(), ty::TyTuple(ref fs) => fs.into_iter().map(|t| *t).collect(),
ty::TySlice(ty) | ty::TyArray(ty, _) => match *ctor { ty::TySlice(ty) | ty::TyArray(ty, _) => match *ctor {
Slice(length) => (0..length).map(|_| ty).collect(), Slice(length) => (0..length).map(|_| ty).collect(),
ConstantValue(_) => vec![], ConstantValue(_) => vec![],

View file

@ -449,7 +449,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
PatKind::Tuple(ref subpatterns, ddpos) => { PatKind::Tuple(ref subpatterns, ddpos) => {
let ty = self.tables.node_id_to_type(pat.hir_id); let ty = self.tables.node_id_to_type(pat.hir_id);
match ty.sty { match ty.sty {
ty::TyTuple(ref tys, _) => { ty::TyTuple(ref tys) => {
let subpatterns = let subpatterns =
subpatterns.iter() subpatterns.iter()
.enumerate_and_adjust(tys.len(), ddpos) .enumerate_and_adjust(tys.len(), ddpos)
@ -879,7 +879,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
subpatterns: adt_subpatterns(struct_var.fields.len(), None), subpatterns: adt_subpatterns(struct_var.fields.len(), None),
} }
} }
ty::TyTuple(fields, _) => { ty::TyTuple(fields) => {
PatternKind::Leaf { PatternKind::Leaf {
subpatterns: adt_subpatterns(fields.len(), None), subpatterns: adt_subpatterns(fields.len(), None),
} }

View file

@ -234,7 +234,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
// Second argument must be a tuple matching the argument list of sig // Second argument must be a tuple matching the argument list of sig
let snd_ty = real_sig.inputs_and_output[1]; let snd_ty = real_sig.inputs_and_output[1];
match snd_ty.sty { match snd_ty.sty {
ty::TyTuple(tys, _) if sig.inputs().len() == tys.len() => ty::TyTuple(tys) if sig.inputs().len() == tys.len() =>
if sig.inputs().iter().zip(tys).all(|(ty, real_ty)| check_ty_compat(ty, real_ty)) { if sig.inputs().iter().zip(tys).all(|(ty, real_ty)| check_ty_compat(ty, real_ty)) {
return Ok(true) return Ok(true)
}, },

View file

@ -281,7 +281,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
self.push_def_path(adt_def.did, output); self.push_def_path(adt_def.did, output);
self.push_type_params(substs, iter::empty(), output); self.push_type_params(substs, iter::empty(), output);
}, },
ty::TyTuple(component_types, _) => { ty::TyTuple(component_types) => {
output.push('('); output.push('(');
for &component_type in component_types { for &component_type in component_types {
self.push_type_name(component_type, output); self.push_type_name(component_type, output);

View file

@ -312,7 +312,7 @@ fn build_clone_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
substs.upvar_tys(def_id, tcx) substs.upvar_tys(def_id, tcx)
) )
} }
ty::TyTuple(tys, _) => builder.tuple_like_shim(dest, src, tys.iter().cloned()), ty::TyTuple(tys) => builder.tuple_like_shim(dest, src, tys.iter().cloned()),
_ => { _ => {
bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty) bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty)
} }

View file

@ -599,7 +599,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
assert!(args.next().is_none()); assert!(args.next().is_none());
let tuple = Place::Local(tuple); let tuple = Place::Local(tuple);
let tuple_tys = if let ty::TyTuple(s, _) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty { let tuple_tys = if let ty::TyTuple(s) = tuple.ty(caller_mir, tcx).to_ty(tcx).sty {
s s
} else { } else {
bug!("Closure arguments are not passed as a tuple"); bug!("Closure arguments are not passed as a tuple");

View file

@ -788,7 +788,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect(); let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect();
self.open_drop_for_tuple(&tys) self.open_drop_for_tuple(&tys)
} }
ty::TyTuple(tys, _) => { ty::TyTuple(tys) => {
self.open_drop_for_tuple(tys) self.open_drop_for_tuple(tys)
} }
ty::TyAdt(def, _) if def.is_box() => { ty::TyAdt(def, _) if def.is_box() => {

View file

@ -722,7 +722,7 @@ impl<'a, 'tcx> FnType<'tcx> {
assert!(!sig.variadic && extra_args.is_empty()); assert!(!sig.variadic && extra_args.is_empty());
match sig.inputs().last().unwrap().sty { match sig.inputs().last().unwrap().sty {
ty::TyTuple(ref tupled_arguments, _) => { ty::TyTuple(ref tupled_arguments) => {
inputs = &sig.inputs()[0..sig.inputs().len() - 1]; inputs = &sig.inputs()[0..sig.inputs().len() - 1];
tupled_arguments tupled_arguments
} }

View file

@ -362,7 +362,7 @@ fn subroutine_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
// return type // return type
signature_metadata.push(match signature.output().sty { signature_metadata.push(match signature.output().sty {
ty::TyTuple(ref tys, _) if tys.is_empty() => ptr::null_mut(), ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
_ => type_metadata(cx, signature.output(), span) _ => type_metadata(cx, signature.output(), span)
}); });
@ -533,7 +533,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
ty::TyFloat(_) => { ty::TyFloat(_) => {
MetadataCreationResult::new(basic_type_metadata(cx, t), false) MetadataCreationResult::new(basic_type_metadata(cx, t), false)
} }
ty::TyTuple(ref elements, _) if elements.is_empty() => { ty::TyTuple(ref elements) if elements.is_empty() => {
MetadataCreationResult::new(basic_type_metadata(cx, t), false) MetadataCreationResult::new(basic_type_metadata(cx, t), false)
} }
ty::TyArray(typ, _) | ty::TyArray(typ, _) |
@ -621,7 +621,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
usage_site_span).finalize(cx) usage_site_span).finalize(cx)
} }
}, },
ty::TyTuple(ref elements, _) => { ty::TyTuple(ref elements) => {
prepare_tuple_metadata(cx, prepare_tuple_metadata(cx,
t, t,
&elements[..], &elements[..],
@ -731,7 +731,7 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
let (name, encoding) = match t.sty { let (name, encoding) = match t.sty {
ty::TyNever => ("!", 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),
ty::TyChar => ("char", DW_ATE_unsigned_char), ty::TyChar => ("char", DW_ATE_unsigned_char),

View file

@ -312,7 +312,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
// Return type -- llvm::DIBuilder wants this at index 0 // Return type -- llvm::DIBuilder wants this at index 0
signature.push(match sig.output().sty { signature.push(match sig.output().sty {
ty::TyTuple(ref tys, _) if tys.is_empty() => ptr::null_mut(), ty::TyTuple(ref tys) if tys.is_empty() => ptr::null_mut(),
_ => type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP) _ => type_metadata(cx, sig.output(), syntax_pos::DUMMY_SP)
}); });
@ -351,7 +351,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
} }
if sig.abi == Abi::RustCall && !sig.inputs().is_empty() { if sig.abi == Abi::RustCall && !sig.inputs().is_empty() {
if let ty::TyTuple(args, _) = sig.inputs()[sig.inputs().len() - 1].sty { if let ty::TyTuple(args) = sig.inputs()[sig.inputs().len() - 1].sty {
for &argument_type in args { for &argument_type in args {
signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP)); signature.push(type_metadata(cx, argument_type, syntax_pos::DUMMY_SP));
} }

View file

@ -53,7 +53,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
push_item_name(cx, def.did, qualified, output); push_item_name(cx, def.did, qualified, output);
push_type_params(cx, substs, output); push_type_params(cx, substs, output);
}, },
ty::TyTuple(component_types, _) => { ty::TyTuple(component_types) => {
output.push('('); output.push('(');
for &component_type in component_types { for &component_type in component_types {
push_debuginfo_type_name(cx, component_type, true, output); push_debuginfo_type_name(cx, component_type, true, output);

View file

@ -710,7 +710,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
let layout = cx.layout_of(cx.tcx.intern_tup(&[ let layout = cx.layout_of(cx.tcx.intern_tup(&[
cx.tcx.mk_mut_ptr(cx.tcx.types.u8), cx.tcx.mk_mut_ptr(cx.tcx.types.u8),
cx.tcx.types.i32 cx.tcx.types.i32
], false)); ]));
let slot = PlaceRef::alloca(bx, layout, "personalityslot"); let slot = PlaceRef::alloca(bx, layout, "personalityslot");
self.personality_slot = Some(slot); self.personality_slot = Some(slot);
slot slot

View file

@ -448,7 +448,7 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
let arg_ty = fx.monomorphize(&arg_decl.ty); let arg_ty = fx.monomorphize(&arg_decl.ty);
let tupled_arg_tys = match arg_ty.sty { let tupled_arg_tys = match arg_ty.sty {
ty::TyTuple(ref tys, _) => tys, ty::TyTuple(ref tys) => tys,
_ => bug!("spread argument isn't a tuple?!") _ => bug!("spread argument isn't a tuple?!")
}; };

View file

@ -399,7 +399,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
lhs.immediate(), rhs.immediate(), lhs.immediate(), rhs.immediate(),
lhs.layout.ty); lhs.layout.ty);
let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty); let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty);
let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool], false); let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool]);
let operand = OperandRef { let operand = OperandRef {
val: result, val: result,
layout: bx.cx.layout_of(operand_ty) layout: bx.cx.layout_of(operand_ty)

View file

@ -1050,7 +1050,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
tcx.types.never tcx.types.never
}, },
hir::TyTup(ref fields) => { hir::TyTup(ref fields) => {
tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t)), false) tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(&t)))
} }
hir::TyBareFn(ref bf) => { hir::TyBareFn(ref bf) => {
require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span); require_c_abi_if_variadic(tcx, &bf.decl, bf.abi, ast_ty.span);

View file

@ -319,7 +319,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let mut expected_len = elements.len(); let mut expected_len = elements.len();
if ddpos.is_some() { if ddpos.is_some() {
// Require known type only when `..` is present // Require known type only when `..` is present
if let ty::TyTuple(ref tys, _) = if let ty::TyTuple(ref tys) =
self.structurally_resolved_type(pat.span, expected).sty { self.structurally_resolved_type(pat.span, expected).sty {
expected_len = tys.len(); expected_len = tys.len();
} }
@ -332,7 +332,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
ty::UniverseIndex::ROOT, ty::UniverseIndex::ROOT,
TypeVariableOrigin::TypeInference(pat.span))); TypeVariableOrigin::TypeInference(pat.span)));
let element_tys = tcx.mk_type_list(element_tys_iter); let element_tys = tcx.mk_type_list(element_tys_iter);
let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys, false)); let pat_ty = tcx.mk_ty(ty::TyTuple(element_tys));
self.demand_eqtype(pat.span, expected, pat_ty); self.demand_eqtype(pat.span, expected, pat_ty);
for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) {
self.check_pat_walk(elem, &element_tys[i], def_bm, true); self.check_pat_walk(elem, &element_tys[i], def_bm, true);

View file

@ -115,7 +115,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
} }
} }
} }
ty::TyTuple(fields, _) => match fields.last() { ty::TyTuple(fields) => match fields.last() {
None => Some(PointerKind::Thin), None => Some(PointerKind::Thin),
Some(f) => self.pointer_kind(f, span)? Some(f) => self.pointer_kind(f, span)?
}, },

View file

@ -140,7 +140,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// the `closures` table. // the `closures` table.
let sig = bound_sig.map_bound(|sig| { let sig = bound_sig.map_bound(|sig| {
self.tcx.mk_fn_sig( self.tcx.mk_fn_sig(
iter::once(self.tcx.intern_tup(sig.inputs(), false)), iter::once(self.tcx.intern_tup(sig.inputs())),
sig.output(), sig.output(),
sig.variadic, sig.variadic,
sig.unsafety, sig.unsafety,
@ -312,7 +312,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
); );
let input_tys = match arg_param_ty.sty { let input_tys = match arg_param_ty.sty {
ty::TyTuple(tys, _) => tys.into_iter(), ty::TyTuple(tys) => tys.into_iter(),
_ => { _ => {
return None; return None;
} }

View file

@ -87,7 +87,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
"cxchg" | "cxchgweak" => (1, vec![tcx.mk_mut_ptr(param(0)), "cxchg" | "cxchgweak" => (1, vec![tcx.mk_mut_ptr(param(0)),
param(0), param(0),
param(0)], param(0)],
tcx.intern_tup(&[param(0), tcx.types.bool], false)), tcx.intern_tup(&[param(0), tcx.types.bool])),
"load" => (1, vec![tcx.mk_imm_ptr(param(0))], "load" => (1, vec![tcx.mk_imm_ptr(param(0))],
param(0)), param(0)),
"store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], "store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)],
@ -281,7 +281,7 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" =>
(1, vec![param(0), param(0)], (1, vec![param(0), param(0)],
tcx.intern_tup(&[param(0), tcx.types.bool], false)), tcx.intern_tup(&[param(0), tcx.types.bool])),
"unchecked_div" | "unchecked_rem" => "unchecked_div" | "unchecked_rem" =>
(1, vec![param(0), param(0)], param(0)), (1, vec![param(0), param(0)], param(0)),
@ -441,7 +441,7 @@ fn match_intrinsic_type_to_type<'a, 'tcx>(
match *expected { match *expected {
Void => match t.sty { Void => match t.sty {
ty::TyTuple(ref v, _) if v.is_empty() => {}, ty::TyTuple(ref v) if v.is_empty() => {},
_ => simple_error(&format!("`{}`", t), "()"), _ => simple_error(&format!("`{}`", t), "()"),
}, },
// (The width we pass to LLVM doesn't concern the type checker.) // (The width we pass to LLVM doesn't concern the type checker.)
@ -515,7 +515,7 @@ fn match_intrinsic_type_to_type<'a, 'tcx>(
} }
Aggregate(_flatten, ref expected_contents) => { Aggregate(_flatten, ref expected_contents) => {
match t.sty { match t.sty {
ty::TyTuple(contents, _) => { ty::TyTuple(contents) => {
if contents.len() != expected_contents.len() { if contents.len() != expected_contents.len() {
simple_error(&format!("tuple with length {}", contents.len()), simple_error(&format!("tuple with length {}", contents.len()),
&format!("tuple with length {}", expected_contents.len())); &format!("tuple with length {}", expected_contents.len()));

View file

@ -2160,8 +2160,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
} }
// Tries to apply a fallback to `ty` if it is an unsolved variable. // Tries to apply a fallback to `ty` if it is an unsolved variable.
// Non-numerics get replaced with ! or () (depending on whether // Non-numerics get replaced with !, unconstrained ints with i32,
// feature(never_type) is enabled), unconstrained ints with i32,
// unconstrained floats with f64. // unconstrained floats with f64.
// Fallback becomes very dubious if we have encountered type-checking errors. // Fallback becomes very dubious if we have encountered type-checking errors.
// In that case, fallback to TyError. // In that case, fallback to TyError.
@ -2174,7 +2173,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
_ if self.is_tainted_by_errors() => self.tcx().types.err, _ if self.is_tainted_by_errors() => self.tcx().types.err,
UnconstrainedInt => self.tcx.types.i32, UnconstrainedInt => self.tcx.types.i32,
UnconstrainedFloat => self.tcx.types.f64, UnconstrainedFloat => self.tcx.types.f64,
Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(), Neither if self.type_var_diverges(ty) => self.tcx.types.never,
Neither => return Neither => return
}; };
debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback); debug!("default_type_parameters: defaulting `{:?}` to `{:?}`", ty, fallback);
@ -2438,7 +2437,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let err_inputs = match tuple_arguments { let err_inputs = match tuple_arguments {
DontTupleArguments => err_inputs, DontTupleArguments => err_inputs,
TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..], false)], TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])],
}; };
self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr, self.check_argument_types(sp, expr_sp, &err_inputs[..], &[], args_no_rcvr,
@ -2531,16 +2530,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let formal_tys = if tuple_arguments == TupleArguments { let formal_tys = if tuple_arguments == TupleArguments {
let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]); let tuple_type = self.structurally_resolved_type(sp, fn_inputs[0]);
match tuple_type.sty { match tuple_type.sty {
ty::TyTuple(arg_types, _) if arg_types.len() != args.len() => { ty::TyTuple(arg_types) if arg_types.len() != args.len() => {
parameter_count_error(tcx.sess, sp, expr_sp, arg_types.len(), args.len(), parameter_count_error(tcx.sess, sp, expr_sp, arg_types.len(), args.len(),
"E0057", false, def_span, false); "E0057", false, def_span, false);
expected_arg_tys = &[]; expected_arg_tys = &[];
self.err_args(args.len()) self.err_args(args.len())
} }
ty::TyTuple(arg_types, _) => { ty::TyTuple(arg_types) => {
expected_arg_tys = match expected_arg_tys.get(0) { expected_arg_tys = match expected_arg_tys.get(0) {
Some(&ty) => match ty.sty { Some(&ty) => match ty.sty {
ty::TyTuple(ref tys, _) => &tys, ty::TyTuple(ref tys) => &tys,
_ => &[] _ => &[]
}, },
None => &[] None => &[]
@ -3193,7 +3192,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
None None
} }
} }
ty::TyTuple(ref v, _) => { ty::TyTuple(ref v) => {
tuple_like = true; tuple_like = true;
v.get(idx.node).cloned() v.get(idx.node).cloned()
} }
@ -4060,7 +4059,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let flds = expected.only_has_type(self).and_then(|ty| { let flds = expected.only_has_type(self).and_then(|ty| {
let ty = self.resolve_type_vars_with_obligations(ty); let ty = self.resolve_type_vars_with_obligations(ty);
match ty.sty { match ty.sty {
ty::TyTuple(ref flds, _) => Some(&flds[..]), ty::TyTuple(ref flds) => Some(&flds[..]),
_ => None _ => None
} }
}); });
@ -4078,7 +4077,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}; };
t t
}); });
let tuple = tcx.mk_tup(elt_ts_iter, false); let tuple = tcx.mk_tup(elt_ts_iter);
if tuple.references_error() { if tuple.references_error() {
tcx.types.err tcx.types.err
} else { } else {

View file

@ -287,7 +287,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
self.add_constraints_from_mt(current, mt, variance); self.add_constraints_from_mt(current, mt, variance);
} }
ty::TyTuple(subtys, _) => { ty::TyTuple(subtys) => {
for &subty in subtys { for &subty in subtys {
self.add_constraints_from_ty(current, subty, variance); self.add_constraints_from_ty(current, subty, variance);
} }

View file

@ -1322,7 +1322,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: boo
Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => { Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => {
assert_eq!(types.len(), 1); assert_eq!(types.len(), 1);
let inputs = match types[0].sty { let inputs = match types[0].sty {
ty::TyTuple(ref tys, _) => tys.iter().map(|t| t.clean(cx)).collect(), ty::TyTuple(ref tys) => tys.iter().map(|t| t.clean(cx)).collect(),
_ => { _ => {
return PathParameters::AngleBracketed { return PathParameters::AngleBracketed {
lifetimes, lifetimes,
@ -1334,7 +1334,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: boo
let output = None; let output = None;
// FIXME(#20299) return type comes from a projection now // FIXME(#20299) return type comes from a projection now
// match types[1].sty { // match types[1].sty {
// ty::TyTuple(ref v, _) if v.is_empty() => None, // -> () // ty::TyTuple(ref v) if v.is_empty() => None, // -> ()
// _ => Some(types[1].clean(cx)) // _ => Some(types[1].clean(cx))
// }; // };
PathParameters::Parenthesized { PathParameters::Parenthesized {
@ -1377,7 +1377,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
// collect any late bound regions // collect any late bound regions
let mut late_bounds = vec![]; let mut late_bounds = vec![];
for ty_s in self.input_types().skip(1) { for ty_s in self.input_types().skip(1) {
if let ty::TyTuple(ts, _) = ty_s.sty { if let ty::TyTuple(ts) = ty_s.sty {
for &ty_s in ts { for &ty_s in ts {
if let ty::TyRef(ref reg, _) = ty_s.sty { if let ty::TyRef(ref reg, _) = ty_s.sty {
if let &ty::RegionKind::ReLateBound(..) = *reg { if let &ty::RegionKind::ReLateBound(..) = *reg {
@ -2731,7 +2731,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
Never Never
} }
} }
ty::TyTuple(ref t, _) => Tuple(t.clean(cx)), ty::TyTuple(ref t) => Tuple(t.clean(cx)),
ty::TyProjection(ref data) => data.clean(cx), ty::TyProjection(ref data) => data.clean(cx),

View file

@ -1,38 +0,0 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![allow(unused)]
trait Deserialize: Sized {
fn deserialize() -> Result<Self, String>;
}
impl Deserialize for () {
fn deserialize() -> Result<(), String> {
Ok(())
}
}
trait ImplementedForUnitButNotNever {}
impl ImplementedForUnitButNotNever for () {}
fn foo<T: ImplementedForUnitButNotNever>(_t: T) {}
fn smeg() {
let _x = return;
foo(_x);
//~^ ERROR code relies on type
//~| WARNING previously accepted
}
fn main() {
smeg();
}

View file

@ -31,5 +31,5 @@ trait Add<RHS=Self> {
fn ice<A>(a: A) { fn ice<A>(a: A) {
let r = loop {}; let r = loop {};
r = r + a; r = r + a;
//~^ ERROR the trait bound `(): Add<A>` is not satisfied //~^ ERROR the trait bound `!: Add<A>` is not satisfied
} }

View file

@ -1,8 +1,8 @@
error[E0277]: the trait bound `(): Add<A>` is not satisfied error[E0277]: the trait bound `!: Add<A>` is not satisfied
--> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:33:11 --> $DIR/associated-types-ICE-when-projecting-out-of-err.rs:33:11
| |
LL | r = r + a; LL | r = r + a;
| ^ the trait `Add<A>` is not implemented for `()` | ^ the trait `Add<A>` is not implemented for `!`
error: aborting due to previous error error: aborting due to previous error