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

Fix various bugs around empty structs and patterns #29383

Merged
merged 4 commits into from
Nov 28, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/librustc/middle/intrinsicck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,11 +225,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
intravisit::walk_fn(self, fk, fd, b, s);
self.param_envs.pop();
}
FnKind::Closure(..) => {
FnKind::Closure => {
intravisit::walk_fn(self, fk, fd, b, s);
}
}

}

fn visit_expr(&mut self, expr: &hir::Expr) {
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 @@ -1424,7 +1424,7 @@ impl<'tcx> cmt_<'tcx> {
NonAliasable
}

Categorization::StaticItem(..) => {
Categorization::StaticItem => {
if self.mutbl.is_mutable() {
FreelyAliasable(AliasableStaticMut)
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
this.walk_fn(fk, fd, b, s)
})
}
FnKind::Closure(..) => {
FnKind::Closure => {
self.walk_fn(fk, fd, b, s)
}
}
Expand Down Expand Up @@ -479,7 +479,7 @@ impl<'a> LifetimeContext<'a> {
self.visit_generics(&sig.generics);
self.visit_explicit_self(&sig.explicit_self);
}
FnKind::Closure(..) => {
FnKind::Closure => {
intravisit::walk_fn_decl(self, fd);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>,
ty::TyInt(..) |
ty::TyUint(..) |
ty::TyFloat(..) |
ty::TyStr(..) |
ty::TyStr |
ty::TyBareFn(..) |
ty::TyArray(..) |
ty::TySlice(..) |
Expand Down
10 changes: 5 additions & 5 deletions src/librustc/middle/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1563,7 +1563,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}

match other {
&ObjectCandidate(..) |
&ObjectCandidate |
&ParamCandidate(_) | &ProjectionCandidate => match victim {
&DefaultImplCandidate(..) => {
self.tcx().sess.bug(
Expand All @@ -1572,16 +1572,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
&ImplCandidate(..) |
&ClosureCandidate(..) |
&FnPointerCandidate(..) |
&BuiltinObjectCandidate(..) |
&BuiltinUnsizeCandidate(..) |
&FnPointerCandidate |
&BuiltinObjectCandidate |
&BuiltinUnsizeCandidate |
&DefaultImplObjectCandidate(..) |
&BuiltinCandidate(..) => {
// We have a where-clause so don't go around looking
// for impls.
true
}
&ObjectCandidate(..) |
&ObjectCandidate |
&ProjectionCandidate => {
// Arbitrarily give param candidates priority
// over projection and object candidates.
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/ty/outlives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,21 +188,21 @@ fn compute_components<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
// the type and then visits the types that are lexically
// contained within. (The comments refer to relevant rules
// from RFC1214.)
ty::TyBool(..) | // OutlivesScalar
ty::TyChar(..) | // OutlivesScalar
ty::TyBool | // OutlivesScalar
ty::TyChar | // OutlivesScalar
ty::TyInt(..) | // OutlivesScalar
ty::TyUint(..) | // OutlivesScalar
ty::TyFloat(..) | // OutlivesScalar
ty::TyEnum(..) | // OutlivesNominalType
ty::TyStruct(..) | // OutlivesNominalType
ty::TyBox(..) | // OutlivesNominalType (ish)
ty::TyStr(..) | // OutlivesScalar (ish)
ty::TyStr | // OutlivesScalar (ish)
ty::TyArray(..) | // ...
ty::TySlice(..) | // ...
ty::TyRawPtr(..) | // ...
ty::TyRef(..) | // OutlivesReference
ty::TyTuple(..) | // ...
ty::TyError(..) => {
ty::TyError => {
push_region_constraints(out, ty.regions());
for subty in ty.walk_shallow() {
compute_components(infcx, subty, out);
Expand Down
16 changes: 8 additions & 8 deletions src/librustc_borrowck/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,14 +540,14 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
ol, old_loan_msg)
}

euv::OverloadedOperator(..) |
euv::AddrOf(..) |
euv::AutoRef(..) |
euv::AutoUnsafe(..) |
euv::ClosureInvocation(..) |
euv::ForLoop(..) |
euv::RefBinding(..) |
euv::MatchDiscriminant(..) => {
euv::OverloadedOperator |
euv::AddrOf |
euv::AutoRef |
euv::AutoUnsafe |
euv::ClosureInvocation |
euv::ForLoop |
euv::RefBinding |
euv::MatchDiscriminant => {
format!("previous borrow of `{}` occurs here{}",
ol, old_loan_msg)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
self.extend(result, &cmt, LpInterior(i.cleaned()))
}

Categorization::StaticItem(..) => {
Categorization::StaticItem => {
Safe
}

Expand Down
6 changes: 3 additions & 3 deletions src/librustc_borrowck/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -942,8 +942,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
"consider changing this closure to take self by mutable reference");
}
}
mc::AliasableStatic(..) |
mc::AliasableStaticMut(..) => {
mc::AliasableStatic |
mc::AliasableStaticMut => {
span_err!(
self.tcx.sess, span, E0388,
"{} in a static location", prefix);
Expand Down Expand Up @@ -998,7 +998,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
pub fn note_and_explain_bckerr(&self, err: BckError<'tcx>) {
let code = err.code;
match code {
err_mutbl(..) => {
err_mutbl => {
match err.cmt.note {
mc::NoteClosureEnv(upvar_id) | mc::NoteUpvarRef(upvar_id) => {
// If this is an `Fn` closure, it simply can't mutate upvars.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/matches/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
candidate: &mut Candidate<'pat, 'tcx>)
-> Result<BasicBlock, MatchPair<'pat, 'tcx>> {
match *match_pair.pattern.kind {
PatternKind::Wild(..) => {
PatternKind::Wild => {
// nothing left to do
Ok(block)
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/hair/cx/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
}
ty::TyEnum(adt, substs) => {
match cx.tcx.def_map.borrow()[&self.id].full_def() {
def::DefVariant(enum_id, variant_id, true) => {
def::DefVariant(enum_id, variant_id, _) => {
debug_assert!(adt.did == enum_id);
let index = adt.variant_index_with_id(variant_id);
let field_refs = field_refs(&adt.variants[index], fields);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
self.visit_explicit_self(&sig.explicit_self);
MethodRibKind
}
FnKind::Closure(..) => ClosureRibKind(node_id),
FnKind::Closure => ClosureRibKind(node_id),
};
self.resolve_function(rib_kind, declaration, block);
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/trans/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ pub fn sizing_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) -> Typ
}
}

ty::TyProjection(..) | ty::TyInfer(..) | ty::TyParam(..) | ty::TyError(..) => {
ty::TyProjection(..) | ty::TyInfer(..) | ty::TyParam(..) | ty::TyError => {
cx.sess().bug(&format!("fictitious type {:?} in sizing_type_of()",
t))
}
Expand Down Expand Up @@ -451,7 +451,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
ty::TyInfer(..) => cx.sess().bug("type_of with TyInfer"),
ty::TyProjection(..) => cx.sess().bug("type_of with TyProjection"),
ty::TyParam(..) => cx.sess().bug("type_of with ty_param"),
ty::TyError(..) => cx.sess().bug("type_of with TyError"),
ty::TyError => cx.sess().bug("type_of with TyError"),
};

debug!("--> mapped t={:?} to llty={}",
Expand Down
84 changes: 61 additions & 23 deletions src/librustc_typeck/check/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use check::{check_expr_with_lvalue_pref};
use check::{instantiate_path, resolve_ty_and_def_ufcs, structurally_resolved_type};
use require_same_types;
use util::nodemap::FnvHashMap;
use session::Session;

use std::cmp;
use std::collections::hash_map::Entry::{Occupied, Vacant};
Expand Down Expand Up @@ -136,6 +137,12 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
}
hir::PatEnum(..) | hir::PatIdent(..)
if pat_is_resolved_const(&tcx.def_map.borrow(), pat) => {
if let hir::PatEnum(ref path, ref subpats) = pat.node {
if !(subpats.is_some() && subpats.as_ref().unwrap().is_empty()) {
bad_struct_kind_err(tcx.sess, pat.span, path, false);
return;
}
}
let const_did = tcx.def_map.borrow().get(&pat.id).unwrap().def_id();
let const_scheme = tcx.lookup_item_type(const_did);
assert!(const_scheme.generics.is_empty());
Expand Down Expand Up @@ -192,11 +199,12 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
}
hir::PatIdent(_, ref path, _) => {
let path = hir_util::ident_to_path(path.span, path.node);
check_pat_enum(pcx, pat, &path, Some(&[]), expected);
check_pat_enum(pcx, pat, &path, Some(&[]), expected, false);
}
hir::PatEnum(ref path, ref subpats) => {
let subpats = subpats.as_ref().map(|v| &v[..]);
check_pat_enum(pcx, pat, path, subpats, expected);
let is_tuple_struct_pat = !(subpats.is_some() && subpats.unwrap().is_empty());
check_pat_enum(pcx, pat, path, subpats, expected, is_tuple_struct_pat);
}
hir::PatQPath(ref qself, ref path) => {
let self_ty = fcx.to_ty(&qself.ty);
Expand Down Expand Up @@ -572,11 +580,19 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx hir::Pat,
fcx.write_substs(pat.id, ty::ItemSubsts { substs: item_substs.clone() });
}

// This function exists due to the warning "diagnostic code E0164 already used"
fn bad_struct_kind_err(sess: &Session, span: Span, path: &hir::Path, is_warning: bool) {
let name = pprust::path_to_string(path);
span_err_or_warn!(is_warning, sess, span, E0164,
"`{}` does not name a tuple variant or a tuple struct", name);
}

pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
pat: &hir::Pat,
path: &hir::Path,
subpats: Option<&'tcx [P<hir::Pat>]>,
expected: Ty<'tcx>)
expected: Ty<'tcx>,
is_tuple_struct_pat: bool)
{
// Typecheck the path.
let fcx = pcx.fcx;
Expand Down Expand Up @@ -618,25 +634,52 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
path_scheme, &ctor_predicates,
opt_ty, def, pat.span, pat.id);

let report_bad_struct_kind = |is_warning| {
bad_struct_kind_err(tcx.sess, pat.span, path, is_warning);
fcx.write_error(pat.id);

if let Some(subpats) = subpats {
for pat in subpats {
check_pat(pcx, &**pat, tcx.types.err);
}
}
};

// If we didn't have a fully resolved path to start with, we had an
// associated const, and we should quit now, since the rest of this
// function uses checks specific to structs and enums.
if path_res.depth != 0 {
let pat_ty = fcx.node_ty(pat.id);
demand::suptype(fcx, pat.span, expected, pat_ty);
if is_tuple_struct_pat {
report_bad_struct_kind(false);
} else {
let pat_ty = fcx.node_ty(pat.id);
demand::suptype(fcx, pat.span, expected, pat_ty);
}
return;
}

let pat_ty = fcx.node_ty(pat.id);
demand::eqtype(fcx, pat.span, expected, pat_ty);


let real_path_ty = fcx.node_ty(pat.id);
let (arg_tys, kind_name): (Vec<_>, &'static str) = match real_path_ty.sty {
ty::TyEnum(enum_def, expected_substs)
if def == def::DefVariant(enum_def.did, def.def_id(), false) =>
{
let variant = enum_def.variant_of_def(def);
if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
// Matching unit variants with tuple variant patterns (`UnitVariant(..)`)
// is allowed for backward compatibility.
let is_special_case = variant.kind() == ty::VariantKind::Unit;
report_bad_struct_kind(is_special_case);
if !is_special_case {
return
} else {
span_note!(tcx.sess, pat.span,
"this warning will become a HARD ERROR in a future release. \
See RFC 218 for details.");
}
}
(variant.fields
.iter()
.map(|f| fcx.instantiate_type_scheme(pat.span,
Expand All @@ -646,26 +689,21 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
"variant")
}
ty::TyStruct(struct_def, expected_substs) => {
(struct_def.struct_variant()
.fields
.iter()
.map(|f| fcx.instantiate_type_scheme(pat.span,
expected_substs,
&f.unsubst_ty()))
.collect(),
let variant = struct_def.struct_variant();
if is_tuple_struct_pat && variant.kind() != ty::VariantKind::Tuple {
report_bad_struct_kind(false);
return;
}
(variant.fields
.iter()
.map(|f| fcx.instantiate_type_scheme(pat.span,
expected_substs,
&f.unsubst_ty()))
.collect(),
"struct")
}
_ => {
let name = pprust::path_to_string(path);
span_err!(tcx.sess, pat.span, E0164,
"`{}` does not name a non-struct variant or a tuple struct", name);
fcx.write_error(pat.id);

if let Some(subpats) = subpats {
for pat in subpats {
check_pat(pcx, &**pat, tcx.types.err);
}
}
report_bad_struct_kind(false);
return;
}
};
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
(impl_def_id, substs, ref_obligations)
}

ObjectCandidate(..) |
ObjectCandidate |
TraitCandidate |
WhereClauseCandidate(..) => {
// These have no additional conditions to check.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
-> Option<(ty::AdtDef<'tcx>, ty::VariantDef<'tcx>)>
{
let (adt, variant) = match def {
def::DefVariant(enum_id, variant_id, true) => {
def::DefVariant(enum_id, variant_id, _) => {
let adt = self.tcx().lookup_adt_def(enum_id);
(adt, adt.variant_with_id(variant_id))
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_typeck/coherence/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
}

TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
TyStr(..) | TyArray(..) | TySlice(..) | TyBareFn(..) | TyTuple(..) |
TyStr | TyArray(..) | TySlice(..) | TyBareFn(..) | TyTuple(..) |
TyParam(..) | TyError |
TyRawPtr(_) | TyRef(_, _) | TyProjection(..) => {
None
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ impl Clean<Option<Lifetime>> for ty::Region {
ty::ReScope(..) |
ty::ReVar(..) |
ty::ReSkolemized(..) |
ty::ReEmpty(..) => None
ty::ReEmpty => None
}
}
}
Expand Down Expand Up @@ -1609,7 +1609,7 @@ impl Clean<Type> for hir::Ty {
TyPolyTraitRef(ref bounds) => {
PolyTraitRef(bounds.clean(cx))
},
TyInfer(..) => {
TyInfer => {
Infer
},
TyTypeof(..) => {
Expand Down
Loading