diff --git a/src/librustc/middle/intrinsicck.rs b/src/librustc/middle/intrinsicck.rs index 11a28c0b5ea9a..48d7f44063ec3 100644 --- a/src/librustc/middle/intrinsicck.rs +++ b/src/librustc/middle/intrinsicck.rs @@ -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) { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index d8031e3134d5c..70ef112efbaab 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -1424,7 +1424,7 @@ impl<'tcx> cmt_<'tcx> { NonAliasable } - Categorization::StaticItem(..) => { + Categorization::StaticItem => { if self.mutbl.is_mutable() { FreelyAliasable(AliasableStaticMut) } else { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 1452cf2cd7667..4425a24590c83 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -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) } } @@ -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); } } diff --git a/src/librustc/middle/traits/coherence.rs b/src/librustc/middle/traits/coherence.rs index 56dc259b1c2f0..76428ca6d9035 100644 --- a/src/librustc/middle/traits/coherence.rs +++ b/src/librustc/middle/traits/coherence.rs @@ -300,7 +300,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(..) | diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index e73f0cafb0449..0b0f6c0b998fc 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -1563,7 +1563,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } match other { - &ObjectCandidate(..) | + &ObjectCandidate | &ParamCandidate(_) | &ProjectionCandidate => match victim { &DefaultImplCandidate(..) => { self.tcx().sess.bug( @@ -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. diff --git a/src/librustc/middle/ty/outlives.rs b/src/librustc/middle/ty/outlives.rs index 9a2570d710d38..ea092ed977eda 100644 --- a/src/librustc/middle/ty/outlives.rs +++ b/src/librustc/middle/ty/outlives.rs @@ -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); diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index cec0cf18fb72a..f6bb51a26adc9 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -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) } diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index 426da7809d843..e7ce93972633b 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -101,7 +101,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { self.extend(result, &cmt, LpInterior(i.cleaned())) } - Categorization::StaticItem(..) => { + Categorization::StaticItem => { Safe } diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs index a9a7b34df12c4..162c91ee4e9b5 100644 --- a/src/librustc_borrowck/borrowck/mod.rs +++ b/src/librustc_borrowck/borrowck/mod.rs @@ -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); @@ -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. diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index e69a04322c201..b9637addccf69 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -66,7 +66,7 @@ impl<'a,'tcx> Builder<'a,'tcx> { candidate: &mut Candidate<'pat, 'tcx>) -> Result> { match *match_pair.pattern.kind { - PatternKind::Wild(..) => { + PatternKind::Wild => { // nothing left to do Ok(block) } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index c546a264be1bb..3380b3a6c1484 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -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); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c2fb921c891db..b161d7f33307e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -619,7 +619,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); } diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs index 1e371a1697010..e65a212e41b13 100644 --- a/src/librustc_trans/trans/type_of.rs +++ b/src/librustc_trans/trans/type_of.rs @@ -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)) } @@ -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={}", diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 5ffe34d61bf7d..1053919be53fe 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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}; @@ -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()); @@ -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); @@ -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]>, - expected: Ty<'tcx>) + expected: Ty<'tcx>, + is_tuple_struct_pat: bool) { // Typecheck the path. let fcx = pcx.fcx; @@ -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, @@ -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; } }; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 59790d7226556..ed819d46041e6 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -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. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f81161addd918..ed8bb6a962509 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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)) } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 4c81c807ebd38..cdbfda40813b4 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -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 diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a1b3d88f083f2..4ea834cce2d88 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -774,7 +774,7 @@ impl Clean> for ty::Region { ty::ReScope(..) | ty::ReVar(..) | ty::ReSkolemized(..) | - ty::ReEmpty(..) => None + ty::ReEmpty => None } } } @@ -1607,7 +1607,7 @@ impl Clean for hir::Ty { TyPolyTraitRef(ref bounds) => { PolyTraitRef(bounds.clean(cx)) }, - TyInfer(..) => { + TyInfer => { Infer }, TyTypeof(..) => { diff --git a/src/test/compile-fail/empty-struct-braces-gate-2.rs b/src/test/compile-fail/empty-struct-braces-gate-2.rs index c1b73bdc96a8f..b2d44301eed8d 100644 --- a/src/test/compile-fail/empty-struct-braces-gate-2.rs +++ b/src/test/compile-fail/empty-struct-braces-gate-2.rs @@ -20,8 +20,7 @@ enum E { fn main() { let e2: Empty2 = Empty2 {}; //~ ERROR empty structs and enum variants with braces are unstable let e2: Empty2 = Empty2; - // Issue #28692 - // let e5: E = E::Empty5 {}; // ERROR empty structs and enum variants with braces are unstable + let e5: E = E::Empty5 {}; //~ ERROR empty structs and enum variants with braces are unstable let e5: E = E::Empty5; match e2 { @@ -33,17 +32,15 @@ fn main() { match e2 { Empty2 { .. } => {} //~ ERROR empty structs and enum variants with braces are unstable } - // Issue #28692 - // match e5 { - // E::Empty5 {} => {} // ERROR empty structs and enum variants with braces are unstable - // } + match e5 { + E::Empty5 {} => {} //~ ERROR empty structs and enum variants with braces are unstable + } match e5 { E::Empty5 => {} } - // Issue #28692 - // match e5 { - // E::Empty5 { .. } => {} // ERROR empty structs and enum variants with braces are unstable - // } + match e5 { + E::Empty5 { .. } => {} //~ ERROR empty structs and enum variants with braces are unstable + } let e22 = Empty2 { ..e2 }; //~ ERROR empty structs and enum variants with braces are unstable } diff --git a/src/test/compile-fail/empty-struct-braces-pat-1.rs b/src/test/compile-fail/empty-struct-braces-pat-1.rs index e095f69ed7da6..6a6c3f16c04af 100644 --- a/src/test/compile-fail/empty-struct-braces-pat-1.rs +++ b/src/test/compile-fail/empty-struct-braces-pat-1.rs @@ -10,7 +10,6 @@ // Can't use empty braced struct as constant pattern -#![deny(warnings)] #![feature(braced_empty_structs)] struct Empty1 {} @@ -23,11 +22,10 @@ fn main() { let e1 = Empty1 {}; let e2 = E::Empty2 {}; - // Issue #28692 - // match e1 { - // Empty1 => () // ERROR incorrect error - // } + match e1 { + Empty1 => () // Not an error, `Empty1` is interpreted as a new binding + } match e2 { - E::Empty2 => () //~ ERROR `E::Empty2` does not name a non-struct variant or a tuple struct + E::Empty2 => () //~ ERROR `E::Empty2` does not name a tuple variant or a tuple struct } } diff --git a/src/test/compile-fail/empty-struct-braces-pat-2.rs b/src/test/compile-fail/empty-struct-braces-pat-2.rs index 0e7152ec89a81..d98d64b712a8b 100644 --- a/src/test/compile-fail/empty-struct-braces-pat-2.rs +++ b/src/test/compile-fail/empty-struct-braces-pat-2.rs @@ -14,13 +14,8 @@ struct Empty1 {} -enum E { - Empty2 {} -} - fn main() { let e1 = Empty1 {}; - let e2 = E::Empty2 {}; // Rejected by parser as yet // match e1 { @@ -29,11 +24,4 @@ fn main() { match e1 { Empty1(..) => () //~ ERROR unresolved enum variant, struct or const `Empty1` } - // Issue #28692 - // match e2 { - // E::Empty2() => () // ERROR unresolved enum variant, struct or const `Empty2` - // } - // match e2 { - // E::Empty2(..) => () // ERROR unresolved enum variant, struct or const `Empty2` - // } } diff --git a/src/test/compile-fail/empty-struct-braces-pat-3.rs b/src/test/compile-fail/empty-struct-braces-pat-3.rs new file mode 100644 index 0000000000000..9fae203f3894d --- /dev/null +++ b/src/test/compile-fail/empty-struct-braces-pat-3.rs @@ -0,0 +1,29 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Can't use empty braced struct as enum pattern + +#![feature(braced_empty_structs)] + +enum E { + Empty2 {} +} + +fn main() { + let e2 = E::Empty2 {}; + + // Rejected by parser as yet + // match e2 { + // E::Empty2() => () // ERROR `E::Empty2` does not name a tuple variant or a tuple struct + // } + match e2 { + E::Empty2(..) => () //~ ERROR `E::Empty2` does not name a tuple variant or a tuple struct + } +} diff --git a/src/test/compile-fail/empty-struct-unit-pat.rs b/src/test/compile-fail/empty-struct-unit-pat.rs index 966a2780f9f8c..6cb9a3f007f0c 100644 --- a/src/test/compile-fail/empty-struct-unit-pat.rs +++ b/src/test/compile-fail/empty-struct-unit-pat.rs @@ -12,8 +12,6 @@ #![feature(braced_empty_structs)] -FIXME //~ ERROR expected item, found `FIXME` - struct Empty1; enum E { @@ -24,17 +22,18 @@ fn main() { let e1 = Empty1; let e2 = E::Empty2; - // Issue #28692 - // match e1 { - // Empty1() => () // ERROR variable `Empty1` should have a snake case name - // } + // Rejected by parser as yet // match e1 { - // Empty1(..) => () // ERROR variable `Empty1` should have a snake case name - // } - // match e2 { - // E::Empty2() => () // ERROR variable `Empty2` should have a snake case name + // Empty1() => () // ERROR `Empty1` does not name a tuple variant or a tuple struct // } + match e1 { + Empty1(..) => () //~ ERROR `Empty1` does not name a tuple variant or a tuple struct + } + // Rejected by parser as yet // match e2 { - // E::Empty2(..) => () // ERROR variable `Empty2` should have a snake case name + // E::Empty2() => () // ERROR `E::Empty2` does not name a tuple variant or a tuple struct // } + match e2 { + E::Empty2(..) => () //~ WARN `E::Empty2` does not name a tuple variant or a tuple struct + } } diff --git a/src/test/compile-fail/issue-19086.rs b/src/test/compile-fail/issue-19086.rs index 692018594571e..56452449d4ee1 100644 --- a/src/test/compile-fail/issue-19086.rs +++ b/src/test/compile-fail/issue-19086.rs @@ -18,6 +18,6 @@ fn main() { let f = FooB { x: 3, y: 4 }; match f { FooB(a, b) => println!("{} {}", a, b), -//~^ ERROR `FooB` does not name a non-struct variant or a tuple struct +//~^ ERROR `FooB` does not name a tuple variant or a tuple struct } } diff --git a/src/test/compile-fail/issue-27831.rs b/src/test/compile-fail/issue-27831.rs index 3cdb370f0e94c..ff2846dc705bb 100644 --- a/src/test/compile-fail/issue-27831.rs +++ b/src/test/compile-fail/issue-27831.rs @@ -26,7 +26,7 @@ fn main() { let Bar { .. } = x; //~ ERROR empty structs and enum variants with braces are unstable match Enum::Bar { - Enum::Bar { .. } //~ ERROR `Enum::Bar` does not name a struct + Enum::Bar { .. } //~ ERROR empty structs and enum variants with braces are unstable => {} Enum::Foo { .. } //~ ERROR `Enum::Foo` does not name a struct => {} diff --git a/src/test/compile-fail/issue-28992-empty.rs b/src/test/compile-fail/issue-28992-empty.rs new file mode 100644 index 0000000000000..f7d53ba23daf5 --- /dev/null +++ b/src/test/compile-fail/issue-28992-empty.rs @@ -0,0 +1,26 @@ +// Copyright 2015 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Can't use constants as tuple struct patterns + +#![feature(associated_consts)] + +const C1: i32 = 0; + +struct S; + +impl S { + const C2: i32 = 0; +} + +fn main() { + if let C1(..) = 0 {} //~ ERROR `C1` does not name a tuple variant or a tuple struct + if let S::C2(..) = 0 {} //~ ERROR `S::C2` does not name a tuple variant or a tuple struct +} diff --git a/src/test/compile-fail/match-pattern-field-mismatch-2.rs b/src/test/compile-fail/match-pattern-field-mismatch-2.rs index e63ddf6c7fd9b..17debdabb61f0 100644 --- a/src/test/compile-fail/match-pattern-field-mismatch-2.rs +++ b/src/test/compile-fail/match-pattern-field-mismatch-2.rs @@ -21,6 +21,7 @@ fn main() { color::cmyk(_, _, _, _) => { } color::no_color(_) => { } //~^ ERROR this pattern has 1 field, but the corresponding variant has no fields + //~^^ WARN `color::no_color` does not name a tuple variant or a tuple struct } } } diff --git a/src/test/compile-fail/move-fragments-2.rs b/src/test/compile-fail/move-fragments-2.rs index 1171755c95354..15c28ec2713e9 100644 --- a/src/test/compile-fail/move-fragments-2.rs +++ b/src/test/compile-fail/move-fragments-2.rs @@ -32,7 +32,7 @@ pub fn test_match_partial(p: Lonely) { //~^ ERROR parent_of_fragments: `$(local p)` //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Zero)` match p { - Zero(..) => {} + Zero => {} _ => {} } } @@ -44,7 +44,7 @@ pub fn test_match_full(p: Lonely) { //~| ERROR assigned_leaf_path: `($(local p) as Lonely::One)` //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Two)` match p { - Zero(..) => {} + Zero => {} One(..) => {} Two(..) => {} } @@ -59,7 +59,7 @@ pub fn test_match_bind_one(p: Lonely) { //~| ERROR assigned_leaf_path: `($(local p) as Lonely::Two)` //~| ERROR assigned_leaf_path: `$(local data)` match p { - Zero(..) => {} + Zero => {} One(data) => {} Two(..) => {} } @@ -78,7 +78,7 @@ pub fn test_match_bind_many(p: Lonely) { //~| ERROR assigned_leaf_path: `$(local left)` //~| ERROR assigned_leaf_path: `$(local right)` match p { - Zero(..) => {} + Zero => {} One(data) => {} Two(left, right) => {} } diff --git a/src/test/compile-fail/move-fragments-3.rs b/src/test/compile-fail/move-fragments-3.rs index 34b34471f4f69..a1152333900a0 100644 --- a/src/test/compile-fail/move-fragments-3.rs +++ b/src/test/compile-fail/move-fragments-3.rs @@ -38,7 +38,7 @@ pub fn test_match_bind_and_underscore(p: Lonely) { //~| ERROR assigned_leaf_path: `$(local left)` match p { - Zero(..) => {} + Zero => {} One(_) => {} // <-- does not fragment `($(local p) as One)` ... diff --git a/src/test/compile-fail/pattern-error-continue.rs b/src/test/compile-fail/pattern-error-continue.rs index aa7202574abfc..1721d1f0ae11c 100644 --- a/src/test/compile-fail/pattern-error-continue.rs +++ b/src/test/compile-fail/pattern-error-continue.rs @@ -26,6 +26,7 @@ fn main() { match A::B(1, 2) { A::B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but A::D(_) => (), //~ ERROR this pattern has 1 field, but + //~^ WARN `A::D` does not name a tuple variant or a tuple struct _ => () } match 'c' { diff --git a/src/test/run-pass/empty-struct-braces.rs b/src/test/run-pass/empty-struct-braces.rs index f2fbf2dd337e7..80ea1bc3a0e49 100644 --- a/src/test/run-pass/empty-struct-braces.rs +++ b/src/test/run-pass/empty-struct-braces.rs @@ -30,7 +30,7 @@ fn main() { let e3: Empty3 = Empty3 {}; let e3: Empty3 = Empty3; let e4: E = E::Empty4 {}; - // let e5: E = E::Empty5 {}; // Issue #28692 + let e5: E = E::Empty5 {}; let e5: E = E::Empty5; match e1 { @@ -46,11 +46,10 @@ fn main() { E::Empty4 {} => {} _ => {} } - // Issue #28692 - // match e5 { - // E::Empty5 {} => {} - // _ => {} - // } + match e5 { + E::Empty5 {} => {} + _ => {} + } match e1 { Empty1 { .. } => {} @@ -65,11 +64,10 @@ fn main() { E::Empty4 { .. } => {} _ => {} } - // Issue #28692 - // match e5 { - // E::Empty5 { .. } => {} - // _ => {} - // } + match e5 { + E::Empty5 { .. } => {} + _ => {} + } match e2 { Empty2 => {} diff --git a/src/test/run-pass/issue-14308.rs b/src/test/run-pass/issue-14308.rs index a61cb18faa65a..74936411da2c9 100644 --- a/src/test/run-pass/issue-14308.rs +++ b/src/test/run-pass/issue-14308.rs @@ -10,7 +10,6 @@ struct A(isize); -struct B; fn main() { let x = match A(3) { @@ -22,12 +21,4 @@ fn main() { A(..) => 2 }; assert_eq!(x, 2); - - // This next test uses a (..) wildcard match on a nullary struct. - // There's no particularly good reason to support this, but it's currently allowed, - // and this makes sure it doesn't ICE or break LLVM. - let x = match B { - B(..) => 3 - }; - assert_eq!(x, 3); } diff --git a/src/test/run-pass/issue-1701.rs b/src/test/run-pass/issue-1701.rs index 3a2e46c62b079..49ee99b22a120 100644 --- a/src/test/run-pass/issue-1701.rs +++ b/src/test/run-pass/issue-1701.rs @@ -20,7 +20,7 @@ fn noise(a: animal) -> Option { animal::cat(..) => { Some("meow".to_string()) } animal::dog(..) => { Some("woof".to_string()) } animal::rabbit(..) => { None } - animal::tiger(..) => { Some("roar".to_string()) } + animal::tiger => { Some("roar".to_string()) } } }