Auto merge of #36814 - petrochenkov:def, r=eddyb

Refactoring/bugfixing around definitions for struct/variant constructors

 d917c364ad separates definitions for struct/variant constructors living in value namespace from struct/variant type definitions.

adfb37827b fixes cross-crate resolution of reexports reexporting half-items, like struct constructors without struct type or types without constructor. Such reexports can appear due to glob shadowing.
Resolution now is not affected by the order in which items and reexports are decoded from metadata (cc https://github.com/rust-lang/rust/issues/31337#issuecomment-183996263). `try_define` is not used during building reduced graph anymore.
500 lines of this PR are tests for this exotic situation, the remaining line diff count is actually negative! :)

c695d0c875 (and partially aabf132de0) moves most of pattern resolution checks from typeck to resolve (except those checking for associated items), uses the same wording for pattern resolution error messages from both typeck and resolve and makes the messages more precise.

11e3524e5a fixes seemingly incorrectly set `NON_ZERO_SIZED` attributes for struct/variant ctors in const eval.

4586fea253 eliminates `ty::VariantKind` in favor of `def::CtorKind`. The logic is that variant kinds are irrelevant for types, they make sense only when we deal with constructor functions/constants. Despite that `VariantDefData` still keeps a copy of `CtorKind`, but it's used only for various kinds of pretty-printing (and for storing in metadata).

aabf132de0 is mostly a cleanup of various impossible or improperly used definitions, and other small definition cleanups.

cc @jseyfried
r? @eddyb
This commit is contained in:
bors 2016-10-04 16:30:30 -07:00 committed by GitHub
commit fd065a8381
70 changed files with 1031 additions and 613 deletions

View File

@ -13,34 +13,46 @@ use util::nodemap::NodeMap;
use syntax::ast;
use hir;
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum CtorKind {
// Constructor function automatically created by a tuple struct/variant.
Fn,
// Constructor constant automatically created by a unit struct/variant.
Const,
// Unusable name in value namespace created by a struct variant.
Fictive,
}
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum Def {
Fn(DefId),
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
// Type namespace
Mod(DefId),
Static(DefId, bool /* is_mutbl */),
Const(DefId),
AssociatedConst(DefId),
Local(DefId),
Variant(DefId),
Struct(DefId), // DefId refers to NodeId of the struct itself
Union(DefId),
Enum(DefId),
Variant(DefId),
Trait(DefId),
TyAlias(DefId),
AssociatedTy(DefId),
Trait(DefId),
PrimTy(hir::PrimTy),
TyParam(DefId),
Upvar(DefId, // def id of closed over local
usize, // index in the freevars list of the closure
ast::NodeId), // expr node that creates the closure
SelfTy(Option<DefId> /* trait */, Option<DefId> /* impl */),
// If Def::Struct lives in type namespace it denotes a struct item and its DefId refers
// to NodeId of the struct itself.
// If Def::Struct lives in value namespace (e.g. tuple struct, unit struct expressions)
// it denotes a constructor and its DefId refers to NodeId of the struct's constructor.
Struct(DefId),
Union(DefId),
Label(ast::NodeId),
// Value namespace
Fn(DefId),
Const(DefId),
Static(DefId, bool /* is_mutbl */),
StructCtor(DefId, CtorKind), // DefId refers to NodeId of the struct's constructor
VariantCtor(DefId, CtorKind),
Method(DefId),
AssociatedConst(DefId),
Local(DefId),
Upvar(DefId, // def id of closed over local
usize, // index in the freevars list of the closure
ast::NodeId), // expr node that creates the closure
Label(ast::NodeId),
// Both namespaces
Err,
}
@ -93,18 +105,35 @@ pub type ExportMap = NodeMap<Vec<Export>>;
#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
pub struct Export {
pub name: ast::Name, // The name of the target.
pub def_id: DefId, // The definition of the target.
pub name: ast::Name, // The name of the target.
pub def: Def, // The definition of the target.
}
impl CtorKind {
pub fn from_ast(vdata: &ast::VariantData) -> CtorKind {
match *vdata {
ast::VariantData::Tuple(..) => CtorKind::Fn,
ast::VariantData::Unit(..) => CtorKind::Const,
ast::VariantData::Struct(..) => CtorKind::Fictive,
}
}
pub fn from_hir(vdata: &hir::VariantData) -> CtorKind {
match *vdata {
hir::VariantData::Tuple(..) => CtorKind::Fn,
hir::VariantData::Unit(..) => CtorKind::Const,
hir::VariantData::Struct(..) => CtorKind::Fictive,
}
}
}
impl Def {
pub fn def_id(&self) -> DefId {
match *self {
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
Def::Variant(id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(id) |
Def::TyParam(id) | Def::Struct(id) | Def::Union(id) | Def::Trait(id) |
Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) |
Def::Local(id) | Def::Upvar(id, ..) => {
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) | Def::TyAlias(id) |
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
Def::AssociatedConst(id) | Def::Local(id) | Def::Upvar(id, ..) => {
id
}
@ -123,10 +152,16 @@ impl Def {
Def::Mod(..) => "module",
Def::Static(..) => "static",
Def::Variant(..) => "variant",
Def::VariantCtor(.., CtorKind::Fn) => "tuple variant",
Def::VariantCtor(.., CtorKind::Const) => "unit variant",
Def::VariantCtor(.., CtorKind::Fictive) => "struct variant",
Def::Enum(..) => "enum",
Def::TyAlias(..) => "type",
Def::TyAlias(..) => "type alias",
Def::AssociatedTy(..) => "associated type",
Def::Struct(..) => "struct",
Def::StructCtor(.., CtorKind::Fn) => "tuple struct",
Def::StructCtor(.., CtorKind::Const) => "unit struct",
Def::StructCtor(.., CtorKind::Fictive) => bug!("impossible struct constructor"),
Def::Union(..) => "union",
Def::Trait(..) => "trait",
Def::Method(..) => "method",

View File

@ -44,8 +44,9 @@ use hir;
use hir::map::Definitions;
use hir::map::definitions::DefPathData;
use hir::def_id::{DefIndex, DefId};
use hir::def::{Def, PathResolution};
use hir::def::{Def, CtorKind, PathResolution};
use session::Session;
use lint;
use std::collections::BTreeMap;
use std::iter;
@ -855,10 +856,23 @@ impl<'a> LoweringContext<'a> {
})
}
PatKind::Lit(ref e) => hir::PatKind::Lit(self.lower_expr(e)),
PatKind::TupleStruct(ref pth, ref pats, ddpos) => {
hir::PatKind::TupleStruct(self.lower_path(pth),
pats.iter().map(|x| self.lower_pat(x)).collect(),
ddpos)
PatKind::TupleStruct(ref path, ref pats, ddpos) => {
match self.resolver.get_resolution(p.id).map(|d| d.base_def) {
Some(def @ Def::StructCtor(_, CtorKind::Const)) |
Some(def @ Def::VariantCtor(_, CtorKind::Const)) => {
// Temporarily lower `UnitVariant(..)` into `UnitVariant`
// for backward compatibility.
let msg = format!("expected tuple struct/variant, found {} `{}`",
def.kind_name(), path);
self.sess.add_lint(
lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
p.id, p.span, msg
);
hir::PatKind::Path(None, self.lower_path(path))
}
_ => hir::PatKind::TupleStruct(self.lower_path(path),
pats.iter().map(|x| self.lower_pat(x)).collect(), ddpos)
}
}
PatKind::Path(ref opt_qself, ref path) => {
let opt_qself = opt_qself.as_ref().map(|qself| {

View File

@ -58,7 +58,7 @@ pub fn pat_is_refutable(dm: &DefMap, pat: &hir::Pat) -> bool {
PatKind::Path(..) |
PatKind::Struct(..) => {
match dm.get(&pat.id).map(|d| d.full_def()) {
Some(Def::Variant(..)) => true,
Some(Def::Variant(..)) | Some(Def::VariantCtor(..)) => true,
_ => false
}
}
@ -173,10 +173,9 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec<DefId> {
PatKind::TupleStruct(..) |
PatKind::Path(..) |
PatKind::Struct(..) => {
match dm.get(&p.id) {
Some(&PathResolution { base_def: Def::Variant(id), .. }) => {
variants.push(id);
}
match dm.get(&p.id).map(|d| d.full_def()) {
Some(Def::Variant(id)) |
Some(Def::VariantCtor(id, ..)) => variants.push(id),
_ => ()
}
}

View File

@ -201,8 +201,6 @@ pub trait CrateStore<'tcx> {
-> Option<DefIndex>;
fn def_key(&self, def: DefId) -> hir_map::DefKey;
fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath>;
fn variant_kind(&self, def_id: DefId) -> Option<ty::VariantKind>;
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>;
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>;
fn item_children(&self, did: DefId) -> Vec<def::Export>;
@ -378,9 +376,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
fn relative_def_path(&self, def: DefId) -> Option<hir_map::DefPath> {
bug!("relative_def_path")
}
fn variant_kind(&self, def_id: DefId) -> Option<ty::VariantKind> { bug!("variant_kind") }
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
{ bug!("struct_ctor_def_id") }
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name> { bug!("struct_field_names") }
fn item_children(&self, did: DefId) -> Vec<def::Export> { bug!("item_children") }

View File

@ -106,9 +106,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
self.check_def_id(def.def_id());
}
_ if self.ignore_non_const_paths => (),
Def::PrimTy(_) => (),
Def::SelfTy(..) => (),
Def::Variant(variant_id) => {
Def::PrimTy(..) | Def::SelfTy(..) => (),
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {
self.check_def_id(enum_id);
}

View File

@ -1003,7 +1003,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
// the leaves of the pattern tree structure.
return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| {
match tcx.expect_def_or_none(pat.id) {
Some(Def::Variant(variant_did)) => {
Some(Def::Variant(variant_did)) |
Some(Def::VariantCtor(variant_did, ..)) => {
let enum_did = tcx.parent_def_id(variant_did).unwrap();
let downcast_cmt = if tcx.lookup_adt_def(enum_did).is_univariant() {
cmt_pat
@ -1015,12 +1016,14 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat);
delegate.matched_pat(pat, downcast_cmt, match_mode);
}
Some(Def::Struct(..)) | Some(Def::Union(..)) |
Some(Def::Struct(..)) | Some(Def::StructCtor(..)) | Some(Def::Union(..)) |
Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) => {
debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
delegate.matched_pat(pat, cmt_pat, match_mode);
}
_ => {}
None | Some(Def::Local(..)) |
Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {}
def => bug!("unexpected definition: {:?}", def)
}
}));
}

View File

@ -74,7 +74,7 @@ use hir::def_id::DefId;
use hir::map as ast_map;
use infer::InferCtxt;
use middle::const_qualif::ConstQualif;
use hir::def::Def;
use hir::def::{Def, CtorKind};
use ty::adjustment;
use ty::{self, Ty, TyCtxt};
@ -524,20 +524,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
id, expr_ty, def);
match def {
Def::Struct(..) | Def::Union(..) | Def::Variant(..) | Def::Const(..) |
Def::StructCtor(..) | Def::VariantCtor(..) | Def::Const(..) |
Def::AssociatedConst(..) | Def::Fn(..) | Def::Method(..) => {
Ok(self.cat_rvalue_node(id, span, expr_ty))
}
Def::Mod(_) |
Def::Trait(_) | Def::Enum(..) | Def::TyAlias(..) | Def::PrimTy(_) |
Def::TyParam(..) |
Def::Label(_) | Def::SelfTy(..) |
Def::AssociatedTy(..) => {
span_bug!(span, "Unexpected definition in \
memory categorization: {:?}", def);
}
Def::Static(_, mutbl) => {
Ok(Rc::new(cmt_ {
id:id,
@ -598,7 +589,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
}))
}
Def::Err => bug!("Def::Err in memory categorization")
def => span_bug!(span, "unexpected definition in memory categorization: {:?}", def)
}
}
@ -1077,7 +1068,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
// alone) because PatKind::Struct can also refer to variants.
let cmt = match self.tcx().expect_def_or_none(pat.id) {
Some(Def::Err) => return Err(()),
Some(Def::Variant(variant_did)) => {
Some(Def::Variant(variant_did)) |
Some(Def::VariantCtor(variant_did, ..)) => {
// univariant enums do not need downcasts
let enum_did = self.tcx().parent_def_id(variant_did).unwrap();
if !self.tcx().lookup_adt_def(enum_did).is_univariant() {
@ -1092,11 +1084,11 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
match pat.node {
PatKind::TupleStruct(_, ref subpats, ddpos) => {
let expected_len = match self.tcx().expect_def(pat.id) {
Def::Variant(def_id) => {
Def::VariantCtor(def_id, CtorKind::Fn) => {
let enum_def = self.tcx().parent_def_id(def_id).unwrap();
self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id).fields.len()
}
Def::Struct(..) => {
Def::StructCtor(_, CtorKind::Fn) => {
match self.pat_ty(&pat)?.sty {
ty::TyAdt(adt_def, _) => {
adt_def.struct_variant().fields.len()

View File

@ -617,12 +617,8 @@ pub fn check_path<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
&Option<DeprecationEntry>)) {
// Paths in import prefixes may have no resolution.
match tcx.expect_def_or_none(id) {
Some(Def::PrimTy(..)) => {}
Some(Def::SelfTy(..)) => {}
Some(def) => {
maybe_do_stability_check(tcx, def.def_id(), path.span, cb);
}
None => {}
None | Some(Def::PrimTy(..)) | Some(Def::SelfTy(..)) => {}
Some(def) => maybe_do_stability_check(tcx, def.def_id(), path.span, cb)
}
}
@ -631,12 +627,7 @@ pub fn check_path_list_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
cb: &mut FnMut(DefId, Span,
&Option<&Stability>,
&Option<DeprecationEntry>)) {
match tcx.expect_def(item.node.id) {
Def::PrimTy(..) => {}
def => {
maybe_do_stability_check(tcx, def.def_id(), item.span, cb);
}
}
maybe_do_stability_check(tcx, tcx.expect_def(item.node.id).def_id(), item.span, cb);
}
pub fn check_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pat: &hir::Pat,

View File

@ -15,6 +15,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors};
use rustc_data_structures::control_flow_graph::ControlFlowGraph;
use hir::def::CtorKind;
use hir::def_id::DefId;
use ty::subst::Substs;
use ty::{self, AdtDef, ClosureSubsts, Region, Ty};
@ -1140,10 +1141,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
ppaux::parameterized(fmt, substs, variant_def.did,
ppaux::Ns::Value, &[])?;
match variant_def.kind {
ty::VariantKind::Unit => Ok(()),
ty::VariantKind::Tuple => fmt_tuple(fmt, lvs),
ty::VariantKind::Struct => {
match variant_def.ctor_kind {
CtorKind::Const => Ok(()),
CtorKind::Fn => fmt_tuple(fmt, lvs),
CtorKind::Fictive => {
let mut struct_fmt = fmt.debug_struct("");
for (field, lv) in variant_def.fields.iter().zip(lvs) {
struct_fmt.field(&field.name.as_str(), lv);

View File

@ -20,7 +20,7 @@ pub use self::fold::TypeFoldable;
use dep_graph::{self, DepNode};
use hir::map as ast_map;
use middle;
use hir::def::{Def, PathResolution, ExportMap};
use hir::def::{Def, CtorKind, PathResolution, ExportMap};
use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
@ -1420,7 +1420,7 @@ pub struct VariantDefData<'tcx, 'container: 'tcx> {
pub name: Name, // struct's name if this is a struct
pub disr_val: Disr,
pub fields: Vec<FieldDefData<'tcx, 'container>>,
pub kind: VariantKind,
pub ctor_kind: CtorKind,
}
pub struct FieldDefData<'tcx, 'container: 'tcx> {
@ -1485,19 +1485,6 @@ impl<'tcx> serialize::UseSpecializedDecodable for AdtDef<'tcx> {}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum AdtKind { Struct, Union, Enum }
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum VariantKind { Struct, Tuple, Unit }
impl VariantKind {
pub fn from_variant_data(vdata: &hir::VariantData) -> Self {
match *vdata {
hir::VariantData::Struct(..) => VariantKind::Struct,
hir::VariantData::Tuple(..) => VariantKind::Tuple,
hir::VariantData::Unit(..) => VariantKind::Unit,
}
}
}
impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
did: DefId,
@ -1673,8 +1660,8 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
pub fn variant_of_def(&self, def: Def) -> &VariantDefData<'gcx, 'container> {
match def {
Def::Variant(vid) => self.variant_with_id(vid),
Def::Struct(..) | Def::Union(..) |
Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid),
Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
Def::TyAlias(..) | Def::AssociatedTy(..) => self.struct_variant(),
_ => bug!("unexpected def {:?} in variant_of_def", def)
}
@ -2332,11 +2319,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
// or variant or their constructors, panics otherwise.
pub fn expect_variant_def(self, def: Def) -> VariantDef<'tcx> {
match def {
Def::Variant(did) => {
Def::Variant(did) | Def::VariantCtor(did, ..) => {
let enum_did = self.parent_def_id(did).unwrap();
self.lookup_adt_def(enum_did).variant_with_id(did)
}
Def::Struct(did) | Def::Union(did) => {
Def::Struct(did) | Def::StructCtor(did, ..) | Def::Union(did) => {
self.lookup_adt_def(did).struct_variant()
}
_ => bug!("expect_variant_def used with unexpected def {:?}", def)

View File

@ -247,7 +247,7 @@ fn check_for_bindings_named_the_same_as_variants(cx: &MatchCheckCtxt, pat: &Pat)
if edef.is_enum() {
if let Def::Local(..) = cx.tcx.expect_def(p.id) {
if edef.variants.iter().any(|variant| {
variant.name == name.node && variant.kind == ty::VariantKind::Unit
variant.name == name.node && variant.ctor_kind == CtorKind::Const
}) {
let ty_path = cx.tcx.item_path_str(edef.did);
let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170,
@ -577,8 +577,8 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
ty::TyAdt(adt, _) => {
let v = ctor.variant_for_adt(adt);
match v.kind {
ty::VariantKind::Struct => {
match v.ctor_kind {
CtorKind::Fictive => {
let field_pats: hir::HirVec<_> = v.fields.iter()
.zip(pats)
.filter(|&(_, ref pat)| pat.node != PatKind::Wild)
@ -593,10 +593,10 @@ fn construct_witness<'a,'tcx>(cx: &MatchCheckCtxt<'a,'tcx>, ctor: &Constructor,
let has_more_fields = field_pats.len() < pats_len;
PatKind::Struct(def_to_path(cx.tcx, v.did), field_pats, has_more_fields)
}
ty::VariantKind::Tuple => {
CtorKind::Fn => {
PatKind::TupleStruct(def_to_path(cx.tcx, v.did), pats.collect(), None)
}
ty::VariantKind::Unit => {
CtorKind::Const => {
PatKind::Path(None, def_to_path(cx.tcx, v.did))
}
}
@ -801,8 +801,8 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat,
match pat.node {
PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) =>
match cx.tcx.expect_def(pat.id) {
Def::Variant(id) => vec![Variant(id)],
Def::Struct(..) | Def::Union(..) |
Def::Variant(id) | Def::VariantCtor(id, ..) => vec![Variant(id)],
Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
Def::TyAlias(..) | Def::AssociatedTy(..) => vec![Single],
Def::Const(..) | Def::AssociatedConst(..) =>
span_bug!(pat.span, "const pattern should've been rewritten"),
@ -913,10 +913,10 @@ pub fn specialize<'a, 'b, 'tcx>(
Def::Const(..) | Def::AssociatedConst(..) =>
span_bug!(pat_span, "const pattern should've \
been rewritten"),
Def::Variant(id) if *constructor != Variant(id) => None,
Def::Variant(..) | Def::Struct(..) => Some(Vec::new()),
def => span_bug!(pat_span, "specialize: unexpected \
definition {:?}", def),
Def::VariantCtor(id, CtorKind::Const) if *constructor != Variant(id) => None,
Def::VariantCtor(_, CtorKind::Const) |
Def::StructCtor(_, CtorKind::Const) => Some(Vec::new()),
def => span_bug!(pat_span, "specialize: unexpected definition: {:?}", def),
}
}
@ -925,8 +925,9 @@ pub fn specialize<'a, 'b, 'tcx>(
Def::Const(..) | Def::AssociatedConst(..) =>
span_bug!(pat_span, "const pattern should've \
been rewritten"),
Def::Variant(id) if *constructor != Variant(id) => None,
Def::Variant(..) | Def::Struct(..) => {
Def::VariantCtor(id, CtorKind::Fn) if *constructor != Variant(id) => None,
Def::VariantCtor(_, CtorKind::Fn) |
Def::StructCtor(_, CtorKind::Fn) => {
match ddpos {
Some(ddpos) => {
let mut pats: Vec<_> = args[..ddpos].iter().map(|p| {
@ -939,7 +940,7 @@ pub fn specialize<'a, 'b, 'tcx>(
None => Some(args.iter().map(|p| wpat(p)).collect())
}
}
_ => None
def => span_bug!(pat_span, "specialize: unexpected definition: {:?}", def),
}
}

View File

@ -19,7 +19,7 @@ use rustc::hir::map as ast_map;
use rustc::hir::map::blocks::FnLikeNode;
use rustc::middle::cstore::InlinedItem;
use rustc::traits;
use rustc::hir::def::{Def, PathResolution};
use rustc::hir::def::{Def, CtorKind, PathResolution};
use rustc::hir::def_id::DefId;
use rustc::hir::pat_util::def_to_path;
use rustc::ty::{self, Ty, TyCtxt};
@ -287,8 +287,8 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
entry.insert(PathResolution::new(def));
}
let path = match def {
Def::Struct(def_id) => def_to_path(tcx, def_id),
Def::Variant(variant_did) => def_to_path(tcx, variant_did),
Def::StructCtor(def_id, CtorKind::Fn) |
Def::VariantCtor(def_id, CtorKind::Fn) => def_to_path(tcx, def_id),
Def::Fn(..) | Def::Method(..) => return Ok(P(hir::Pat {
id: expr.id,
node: PatKind::Lit(P(expr.clone())),
@ -326,7 +326,8 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
hir::ExprPath(_, ref path) => {
match tcx.expect_def(expr.id) {
Def::Struct(..) | Def::Variant(..) => PatKind::Path(None, path.clone()),
Def::StructCtor(_, CtorKind::Const) |
Def::VariantCtor(_, CtorKind::Const) => PatKind::Path(None, path.clone()),
Def::Const(def_id) | Def::AssociatedConst(def_id) => {
let substs = Some(tcx.node_id_item_substs(expr.id).substs);
let (expr, _ty) = lookup_const_by_id(tcx, def_id, substs).unwrap();
@ -807,7 +808,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
signal!(e, NonConstPath);
}
},
Def::Variant(variant_def) => {
Def::VariantCtor(variant_def, ..) => {
if let Some(const_expr) = lookup_variant_by_id(tcx, variant_def) {
match eval_const_expr_partial(tcx, const_expr, ty_hint, None) {
Ok(val) => val,
@ -820,7 +821,7 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
signal!(e, UnimplementedConstVal("enum variants"));
}
}
Def::Struct(..) => {
Def::StructCtor(..) => {
ConstVal::Struct(e.id)
}
Def::Local(def_id) => {

View File

@ -611,11 +611,13 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> {
Def::Mod(..) |
Def::Static(..) |
Def::Variant(..) |
Def::VariantCtor(..) |
Def::Enum(..) |
Def::TyAlias(..) |
Def::AssociatedTy(..) |
Def::TyParam(..) |
Def::Struct(..) |
Def::StructCtor(..) |
Def::Union(..) |
Def::Trait(..) |
Def::Method(..) |

View File

@ -149,7 +149,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
self.dep_graph.read(DepNode::MetaData(def_id));
let mut result = vec![];
self.get_crate_data(def_id.krate)
.each_child_of_item(def_id.index, |child| result.push(child.def_id));
.each_child_of_item(def_id.index, |child| result.push(child.def.def_id()));
result
}
@ -342,18 +342,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
self.get_crate_data(def.krate).def_path(def.index)
}
fn variant_kind(&self, def_id: DefId) -> Option<ty::VariantKind>
{
self.dep_graph.read(DepNode::MetaData(def_id));
self.get_crate_data(def_id.krate).get_variant_kind(def_id.index)
}
fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option<DefId>
{
self.dep_graph.read(DepNode::MetaData(struct_def_id));
self.get_crate_data(struct_def_id.krate).get_struct_ctor_def_id(struct_def_id.index)
}
fn struct_field_names(&self, def: DefId) -> Vec<ast::Name>
{
self.dep_graph.read(DepNode::MetaData(def));
@ -566,7 +554,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
let mut bfs_queue = &mut VecDeque::new();
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: def::Export, parent: DefId| {
let child = child.def_id;
let child = child.def.def_id();
if self.visibility(child) != ty::Visibility::Public {
return;

View File

@ -22,7 +22,7 @@ use rustc::hir;
use rustc::hir::intravisit::IdRange;
use rustc::middle::cstore::{InlinedItem, LinkagePreference};
use rustc::hir::def::{self, Def};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
use rustc::middle::lang_items;
use rustc::ty::{self, Ty, TyCtxt};
@ -534,7 +534,7 @@ impl<'a, 'tcx> CrateMetadata {
name: self.item_name(item),
fields: fields,
disr_val: ConstInt::Infer(data.disr),
kind: data.kind,
ctor_kind: data.ctor_kind,
}, data.struct_ctor)
}
@ -670,10 +670,12 @@ impl<'a, 'tcx> CrateMetadata {
// FIXME(eddyb) Don't encode these in children.
EntryKind::ForeignMod => {
for child_index in child.children.decode(self) {
callback(def::Export {
def_id: self.local_def_id(child_index),
name: self.item_name(&self.entry(child_index))
});
if let Some(def) = self.get_def(child_index) {
callback(def::Export {
def: def,
name: self.item_name(&self.entry(child_index))
});
}
}
continue;
}
@ -683,11 +685,28 @@ impl<'a, 'tcx> CrateMetadata {
}
let def_key = child.def_key.decode(self);
if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
callback(def::Export {
def_id: self.local_def_id(child_index),
name: name
});
if let (Some(def), Some(name)) = (self.get_def(child_index),
def_key.disambiguated_data.data.get_opt_name()) {
callback(def::Export { def: def, name: name });
// For non-reexport structs and variants add their constructors to children.
// Reexport lists automatically contain constructors when necessary.
match def {
Def::Struct(..) => {
if let Some(ctor_def_id) = self.get_struct_ctor_def_id(child_index) {
let ctor_kind = self.get_ctor_kind(child_index);
let ctor_def = Def::StructCtor(ctor_def_id, ctor_kind);
callback(def::Export { def: ctor_def, name: name });
}
}
Def::Variant(def_id) => {
// Braced variants, unlike structs, generate unusable names in
// value namespace, they are reserved for possible future use.
let ctor_kind = self.get_ctor_kind(child_index);
let ctor_def = Def::VariantCtor(def_id, ctor_kind);
callback(def::Export { def: ctor_def, name: name });
}
_ => {}
}
}
}
}
@ -787,12 +806,12 @@ impl<'a, 'tcx> CrateMetadata {
self.entry(id).variances.decode(self).collect()
}
pub fn get_variant_kind(&self, node_id: DefIndex) -> Option<ty::VariantKind> {
pub fn get_ctor_kind(&self, node_id: DefIndex) -> CtorKind {
match self.entry(node_id).kind {
EntryKind::Struct(data) |
EntryKind::Union(data) |
EntryKind::Variant(data) => Some(data.decode(self).kind),
_ => None
EntryKind::Variant(data) => data.decode(self).ctor_kind,
_ => CtorKind::Fictive,
}
}

View File

@ -258,7 +258,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let def_id = variant.did;
let data = VariantData {
kind: variant.kind,
ctor_kind: variant.ctor_kind,
disr: variant.disr_val.to_u64_unchecked(),
struct_ctor: None
};
@ -406,17 +406,21 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId))
-> Entry<'tcx> {
let variant = self.tcx.lookup_adt_def(adt_def_id).struct_variant();
let tcx = self.tcx;
let variant = tcx.lookup_adt_def(adt_def_id).struct_variant();
let data = VariantData {
kind: variant.kind,
ctor_kind: variant.ctor_kind,
disr: variant.disr_val.to_u64_unchecked(),
struct_ctor: Some(def_id.index)
};
let struct_id = tcx.map.as_local_node_id(adt_def_id).unwrap();
let struct_vis = &tcx.map.expect_item(struct_id).vis;
Entry {
kind: EntryKind::Struct(self.lazy(&data)),
visibility: ty::Visibility::Public,
visibility: struct_vis.simplify(),
def_key: self.encode_def_key(def_id),
attributes: LazySeq::empty(),
children: LazySeq::empty(),
@ -671,7 +675,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
None
};
EntryKind::Struct(self.lazy(&VariantData {
kind: variant.kind,
ctor_kind: variant.ctor_kind,
disr: variant.disr_val.to_u64_unchecked(),
struct_ctor: struct_ctor
}))
@ -680,7 +684,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let variant = tcx.lookup_adt_def(def_id).struct_variant();
EntryKind::Union(self.lazy(&VariantData {
kind: variant.kind,
ctor_kind: variant.ctor_kind,
disr: variant.disr_val.to_u64_unchecked(),
struct_ctor: None
}))
@ -885,19 +889,12 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
hir::ItemStruct(ref struct_def, _) => {
self.encode_fields(def_id);
// If this is a tuple-like struct, encode the type of the constructor.
match self.tcx.lookup_adt_def(def_id).struct_variant().kind {
ty::VariantKind::Struct => {
// no value for structs like struct Foo { ... }
}
ty::VariantKind::Tuple | ty::VariantKind::Unit => {
// there is a value for structs like `struct
// Foo()` and `struct Foo`
let ctor_def_id = self.tcx.map.local_def_id(struct_def.id());
self.record(ctor_def_id,
EncodeContext::encode_struct_ctor,
(def_id, ctor_def_id));
}
// If the struct has a constructor, encode it.
if !struct_def.is_struct() {
let ctor_def_id = self.tcx.map.local_def_id(struct_def.id());
self.record(ctor_def_id,
EncodeContext::encode_struct_ctor,
(def_id, ctor_def_id));
}
}
hir::ItemUnion(..) => {

View File

@ -12,7 +12,7 @@ use astencode;
use index;
use rustc::hir;
use rustc::hir::def;
use rustc::hir::def::{self, CtorKind};
use rustc::hir::def_id::{DefIndex, DefId};
use rustc::middle::cstore::{LinkagePreference, NativeLibraryKind};
use rustc::middle::lang_items;
@ -261,7 +261,7 @@ pub struct FnData {
#[derive(RustcEncodable, RustcDecodable)]
pub struct VariantData {
pub kind: ty::VariantKind,
pub ctor_kind: CtorKind,
pub disr: u64,
/// If this is a struct's only variant, this

View File

@ -15,7 +15,7 @@ use hair::cx::Cx;
use hair::cx::block;
use hair::cx::to_ref::ToRef;
use rustc::hir::map;
use rustc::hir::def::Def;
use rustc::hir::def::{Def, CtorKind};
use rustc::middle::const_val::ConstVal;
use rustc_const_eval as const_eval;
use rustc::middle::region::CodeExtent;
@ -271,10 +271,10 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// Tuple-like ADTs are represented as ExprCall. We convert them here.
expr_ty.ty_adt_def().and_then(|adt_def|{
match cx.tcx.expect_def(fun.id) {
Def::Variant(variant_id) => {
Def::VariantCtor(variant_id, CtorKind::Fn) => {
Some((adt_def, adt_def.variant_index_with_id(variant_id)))
},
Def::Struct(..) => {
Def::StructCtor(_, CtorKind::Fn) => {
Some((adt_def, 0))
},
_ => None
@ -670,42 +670,25 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
// Otherwise there may be def_map borrow conflicts
let def = cx.tcx.expect_def(expr.id);
let def_id = match def {
// A regular function.
Def::Fn(def_id) | Def::Method(def_id) => def_id,
Def::Struct(def_id) => match cx.tcx.node_id_to_type(expr.id).sty {
// A tuple-struct constructor. Should only be reached if not called in the same
// expression.
ty::TyFnDef(..) => def_id,
// A unit struct which is used as a value. We return a completely different ExprKind
// here to account for this special case.
// A regular function, constructor function or a constant.
Def::Fn(def_id) | Def::Method(def_id) |
Def::StructCtor(def_id, CtorKind::Fn) |
Def::VariantCtor(def_id, CtorKind::Fn) |
Def::Const(def_id) | Def::AssociatedConst(def_id) => def_id,
Def::StructCtor(def_id, CtorKind::Const) |
Def::VariantCtor(def_id, CtorKind::Const) => match cx.tcx.node_id_to_type(expr.id).sty {
// A unit struct/variant which is used as a value.
// We return a completely different ExprKind here to account for this special case.
ty::TyAdt(adt_def, substs) => return ExprKind::Adt {
adt_def: adt_def,
variant_index: 0,
variant_index: adt_def.variant_index_with_id(def_id),
substs: substs,
fields: vec![],
base: None
base: None,
},
ref sty => bug!("unexpected sty: {:?}", sty)
},
Def::Variant(variant_id) => match cx.tcx.node_id_to_type(expr.id).sty {
// A variant constructor. Should only be reached if not called in the same
// expression.
ty::TyFnDef(..) => variant_id,
// A unit variant, similar special case to the struct case above.
ty::TyAdt(adt_def, substs) => {
let index = adt_def.variant_index_with_id(variant_id);
return ExprKind::Adt {
adt_def: adt_def,
substs: substs,
variant_index: index,
fields: vec![],
base: None
};
},
ref sty => bug!("unexpected sty: {:?}", sty)
},
Def::Const(def_id) |
Def::AssociatedConst(def_id) => def_id,
Def::Static(node_id, _) => return ExprKind::StaticRef {
id: node_id,

View File

@ -301,7 +301,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
subpatterns: Vec<FieldPattern<'tcx>>)
-> PatternKind<'tcx> {
match self.cx.tcx.expect_def(pat.id) {
Def::Variant(variant_id) => {
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
let enum_id = self.cx.tcx.parent_def_id(variant_id).unwrap();
let adt_def = self.cx.tcx.lookup_adt_def(enum_id);
if adt_def.variants.len() > 1 {
@ -315,7 +315,7 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> {
}
}
Def::Struct(..) | Def::Union(..) |
Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
Def::TyAlias(..) | Def::AssociatedTy(..) => {
PatternKind::Leaf { subpatterns: subpatterns }
}

View File

@ -12,7 +12,6 @@ use rustc::ty::TyCtxt;
use rustc::mir::repr::*;
use rustc::mir::transform::{MirPass, MirSource, Pass};
use rustc_data_structures::indexed_vec::Idx;
use rustc::ty::VariantKind;
pub struct Deaggregator;
@ -129,10 +128,7 @@ fn get_aggregate_statement_index<'a, 'tcx, 'b>(start: usize,
}
debug!("getting variant {:?}", variant);
debug!("for adt_def {:?}", adt_def);
let variant_def = &adt_def.variants[variant];
if variant_def.kind == VariantKind::Struct {
return Some(i);
}
return Some(i);
};
None
}

View File

@ -33,7 +33,7 @@ use rustc_const_eval::ErrKind::{ErroneousReferencedConstant, MiscBinaryOp, NonCo
use rustc_const_eval::ErrKind::UnresolvedPath;
use rustc_const_eval::EvalHint::ExprTypeChecked;
use rustc_const_math::{ConstMathErr, Op};
use rustc::hir::def::Def;
use rustc::hir::def::{Def, CtorKind};
use rustc::hir::def_id::DefId;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::mem_categorization as mc;
@ -489,20 +489,12 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
}
hir::ExprPath(..) => {
match v.tcx.expect_def(e.id) {
Def::Variant(..) => {
// Count the discriminator or function pointer.
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
}
Def::Struct(..) => {
if let ty::TyFnDef(..) = node_ty.sty {
// Count the function pointer.
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
}
}
Def::Fn(..) | Def::Method(..) => {
// Count the function pointer.
Def::VariantCtor(_, CtorKind::Const) => {
// Size is determined by the whole enum, may be non-zero.
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
}
Def::VariantCtor(..) | Def::StructCtor(..) |
Def::Fn(..) | Def::Method(..) => {}
Def::Static(..) => {
match v.mode {
Mode::Static | Mode::StaticMut => {}
@ -539,9 +531,9 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
}
// The callee is an arbitrary expression, it doesn't necessarily have a definition.
let is_const = match v.tcx.expect_def_or_none(callee.id) {
Some(Def::Struct(..)) => true,
Some(Def::Variant(..)) => {
// Count the discriminator.
Some(Def::StructCtor(_, CtorKind::Fn)) |
Some(Def::VariantCtor(_, CtorKind::Fn)) => {
// `NON_ZERO_SIZED` is about the call result, not about the ctor itself.
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
true
}

View File

@ -14,7 +14,7 @@
use rustc::dep_graph::DepNode;
use rustc::hir::map as ast_map;
use rustc::session::{CompileResult, Session};
use rustc::hir::def::{Def, DefMap};
use rustc::hir::def::{Def, CtorKind, DefMap};
use rustc::util::nodemap::NodeMap;
use syntax::ast;
@ -272,7 +272,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
// affect the specific variant used, but we need to check
// the whole enum definition to see what expression that
// might be (if any).
Some(Def::Variant(variant_id)) => {
Some(Def::VariantCtor(variant_id, CtorKind::Const)) => {
if let Some(variant_id) = self.ast_map.as_local_node_id(variant_id) {
let variant = self.ast_map.expect_variant(variant_id);
let enum_id = self.ast_map.get_parent(variant_id);
@ -283,7 +283,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> {
} else {
span_bug!(e.span,
"`check_static_recursion` found \
non-enum in Def::Variant");
non-enum in Def::VariantCtor");
}
}
}

View File

@ -28,7 +28,7 @@ extern crate syntax_pos;
use rustc::dep_graph::DepNode;
use rustc::hir::{self, PatKind};
use rustc::hir::def::{self, Def};
use rustc::hir::def::{self, Def, CtorKind};
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{self, Visitor};
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@ -286,7 +286,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
if self.prev_level.is_some() {
if let Some(exports) = self.export_map.get(&id) {
for export in exports {
if let Some(node_id) = self.tcx.map.as_local_node_id(export.def_id) {
if let Some(node_id) = self.tcx.map.as_local_node_id(export.def.def_id()) {
self.update(node_id, Some(AccessLevel::Exported));
}
}
@ -454,36 +454,25 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
}
}
hir::ExprPath(..) => {
if let Def::Struct(..) = self.tcx.expect_def(expr.id) {
let expr_ty = self.tcx.expr_ty(expr);
let def = match expr_ty.sty {
ty::TyFnDef(.., &ty::BareFnTy { sig: ty::Binder(ty::FnSig {
output: ty, ..
}), ..}) => ty,
_ => expr_ty
}.ty_adt_def().unwrap();
let private_indexes : Vec<_> = def.struct_variant().fields.iter().enumerate()
.filter(|&(_,f)| {
!f.vis.is_accessible_from(self.curitem, &self.tcx.map)
}).map(|(n,&_)|n).collect();
if let def @ Def::StructCtor(_, CtorKind::Fn) = self.tcx.expect_def(expr.id) {
let adt_def = self.tcx.expect_variant_def(def);
let private_indexes = adt_def.fields.iter().enumerate().filter(|&(_, field)| {
!field.vis.is_accessible_from(self.curitem, &self.tcx.map)
}).map(|(i, _)| i).collect::<Vec<_>>();
if !private_indexes.is_empty() {
let mut error = struct_span_err!(self.tcx.sess, expr.span, E0450,
"cannot invoke tuple struct constructor \
with private fields");
with private fields");
error.span_label(expr.span,
&format!("cannot construct with a private field"));
if let Some(def_id) = self.tcx.map.as_local_node_id(def.did) {
if let Some(hir::map::NodeItem(node)) = self.tcx.map.find(def_id) {
if let hir::Item_::ItemStruct(ref tuple_data, _) = node.node {
for i in private_indexes {
error.span_label(tuple_data.fields()[i].span,
&format!("private field declared here"));
}
if let Some(node_id) = self.tcx.map.as_local_node_id(adt_def.did) {
let node = self.tcx.map.find(node_id);
if let Some(hir::map::NodeStructCtor(vdata)) = node {
for i in private_indexes {
error.span_label(vdata.fields()[i].span,
&format!("private field declared here"));
}
}
}

View File

@ -24,7 +24,6 @@ use {resolve_error, resolve_struct_error, ResolutionError};
use rustc::middle::cstore::LoadedMacroKind;
use rustc::hir::def::*;
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
use rustc::hir::map::DefPathData;
use rustc::ty;
use std::cell::Cell;
@ -78,6 +77,12 @@ impl<'b> Resolver<'b> {
})
}
fn insert_field_names(&mut self, def_id: DefId, field_names: Vec<Name>) {
if !field_names.is_empty() {
self.field_names.insert(def_id, field_names);
}
}
/// Constructs the reduced graph for one item.
fn build_reduced_graph_for_item(&mut self, item: &Item, expansion: Mark) {
let parent = self.current_module;
@ -297,32 +302,31 @@ impl<'b> Resolver<'b> {
// If this is a tuple or unit struct, define a name
// in the value namespace as well.
if !struct_def.is_struct() {
let def = Def::Struct(self.definitions.local_def_id(struct_def.id()));
self.define(parent, name, ValueNS, (def, sp, vis));
let ctor_def = Def::StructCtor(self.definitions.local_def_id(struct_def.id()),
CtorKind::from_ast(struct_def));
self.define(parent, name, ValueNS, (ctor_def, sp, vis));
}
// Record the def ID and fields of this struct.
let field_names = struct_def.fields().iter().enumerate().map(|(index, field)| {
// Record field names for error reporting.
let field_names = struct_def.fields().iter().filter_map(|field| {
self.resolve_visibility(&field.vis);
field.ident.map(|ident| ident.name)
.unwrap_or_else(|| token::intern(&index.to_string()))
}).collect();
let item_def_id = self.definitions.local_def_id(item.id);
self.structs.insert(item_def_id, field_names);
self.insert_field_names(item_def_id, field_names);
}
ItemKind::Union(ref vdata, _) => {
let def = Def::Union(self.definitions.local_def_id(item.id));
self.define(parent, name, TypeNS, (def, sp, vis));
// Record the def ID and fields of this union.
let field_names = vdata.fields().iter().enumerate().map(|(index, field)| {
// Record field names for error reporting.
let field_names = vdata.fields().iter().filter_map(|field| {
self.resolve_visibility(&field.vis);
field.ident.map(|ident| ident.name)
.unwrap_or_else(|| token::intern(&index.to_string()))
}).collect();
let item_def_id = self.definitions.local_def_id(item.id);
self.structs.insert(item_def_id, field_names);
self.insert_field_names(item_def_id, field_names);
}
ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => {}
@ -347,17 +351,18 @@ impl<'b> Resolver<'b> {
parent: Module<'b>,
vis: ty::Visibility) {
let name = variant.node.name.name;
if variant.node.data.is_struct() {
// Not adding fields for variants as they are not accessed with a self receiver
let variant_def_id = self.definitions.local_def_id(variant.node.data.id());
self.structs.insert(variant_def_id, Vec::new());
}
let def_id = self.definitions.local_def_id(variant.node.data.id());
// Variants are always treated as importable to allow them to be glob used.
// All variants are defined in both type and value namespaces as future-proofing.
let def = Def::Variant(self.definitions.local_def_id(variant.node.data.id()));
self.define(parent, name, ValueNS, (def, variant.span, vis));
// Define a name in the type namespace.
let def = Def::Variant(def_id);
self.define(parent, name, TypeNS, (def, variant.span, vis));
// Define a constructor name in the value namespace.
// Braced variants, unlike structs, generate unusable names in
// value namespace, they are reserved for possible future use.
let ctor_kind = CtorKind::from_ast(&variant.node.data);
let ctor_def = Def::VariantCtor(def_id, ctor_kind);
self.define(parent, name, ValueNS, (ctor_def, variant.span, vis));
}
/// Constructs the reduced graph for one foreign item.
@ -395,15 +400,9 @@ impl<'b> Resolver<'b> {
/// Builds the reduced graph for a single item in an external crate.
fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>,
child: Export) {
let def_id = child.def_id;
let name = child.name;
let def = if let Some(def) = self.session.cstore.describe_def(def_id) {
def
} else {
return;
};
let def = child.def;
let def_id = def.def_id();
let vis = if parent.is_trait() {
ty::Visibility::Public
} else {
@ -411,83 +410,56 @@ impl<'b> Resolver<'b> {
};
match def {
Def::Mod(_) | Def::Enum(..) => {
debug!("(building reduced graph for external crate) building module {} {:?}",
name, vis);
Def::Mod(..) | Def::Enum(..) => {
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
self.define(parent, name, TypeNS, (module, DUMMY_SP, vis));
}
Def::Variant(variant_id) => {
debug!("(building reduced graph for external crate) building variant {}", name);
// Variants are always treated as importable to allow them to be glob used.
// All variants are defined in both type and value namespaces as future-proofing.
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
if self.session.cstore.variant_kind(variant_id) == Some(ty::VariantKind::Struct) {
// Not adding fields for variants as they are not accessed with a self receiver
self.structs.insert(variant_id, Vec::new());
}
Def::Variant(..) => {
self.define(parent, name, TypeNS, (def, DUMMY_SP, vis));
}
Def::VariantCtor(..) => {
self.define(parent, name, ValueNS, (def, DUMMY_SP, vis));
}
Def::Fn(..) |
Def::Static(..) |
Def::Const(..) |
Def::AssociatedConst(..) |
Def::Method(..) => {
debug!("(building reduced graph for external crate) building value (fn/static) {}",
name);
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
self.define(parent, name, ValueNS, (def, DUMMY_SP, vis));
}
Def::Trait(_) => {
debug!("(building reduced graph for external crate) building type {}", name);
// If this is a trait, add all the trait item names to the trait
// info.
Def::Trait(..) => {
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
self.define(parent, name, TypeNS, (module, DUMMY_SP, vis));
// If this is a trait, add all the trait item names to the trait info.
let trait_item_def_ids = self.session.cstore.impl_or_trait_items(def_id);
for &trait_item_def in &trait_item_def_ids {
let trait_item_name =
self.session.cstore.def_key(trait_item_def)
.disambiguated_data.data.get_opt_name()
.expect("opt_item_name returned None for trait");
debug!("(building reduced graph for external crate) ... adding trait item \
'{}'",
trait_item_name);
for trait_item_def_id in trait_item_def_ids {
let trait_item_name = self.session.cstore.def_key(trait_item_def_id)
.disambiguated_data.data.get_opt_name()
.expect("opt_item_name returned None for trait");
self.trait_item_map.insert((trait_item_name, def_id), false);
}
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
}
Def::TyAlias(..) | Def::AssociatedTy(..) => {
debug!("(building reduced graph for external crate) building type {}", name);
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
self.define(parent, name, TypeNS, (def, DUMMY_SP, vis));
}
Def::Struct(_)
if self.session.cstore.def_key(def_id).disambiguated_data.data !=
DefPathData::StructCtor
=> {
debug!("(building reduced graph for external crate) building type and value for {}",
name);
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
if let Some(ctor_def_id) = self.session.cstore.struct_ctor_def_id(def_id) {
let def = Def::Struct(ctor_def_id);
let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis));
}
Def::Struct(..) => {
self.define(parent, name, TypeNS, (def, DUMMY_SP, vis));
// Record the def ID and fields of this struct.
let fields = self.session.cstore.struct_field_names(def_id);
self.structs.insert(def_id, fields);
// Record field names for error reporting.
let field_names = self.session.cstore.struct_field_names(def_id);
self.insert_field_names(def_id, field_names);
}
Def::Union(_) => {
let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis));
Def::StructCtor(..) => {
self.define(parent, name, ValueNS, (def, DUMMY_SP, vis));
}
Def::Union(..) => {
self.define(parent, name, TypeNS, (def, DUMMY_SP, vis));
// Record the def ID and fields of this union.
let fields = self.session.cstore.struct_field_names(def_id);
self.structs.insert(def_id, fields);
// Record field names for error reporting.
let field_names = self.session.cstore.struct_field_names(def_id);
self.insert_field_names(def_id, field_names);
}
Def::Struct(..) => {}
Def::Local(..) |
Def::PrimTy(..) |
Def::TyParam(..) |
@ -495,7 +467,7 @@ impl<'b> Resolver<'b> {
Def::Label(..) |
Def::SelfTy(..) |
Def::Err => {
bug!("didn't expect `{:?}`", def);
bug!("unexpected definition: {:?}", def);
}
}
}

View File

@ -485,7 +485,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
E0531,
"unresolved {} `{}`",
expected_what,
path.segments.last().unwrap().identifier)
path)
}
ResolutionError::PatPathUnexpected(expected_what, found_what, path) => {
struct_span_err!(resolver.session,
@ -494,7 +494,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
"expected {}, found {} `{}`",
expected_what,
found_what,
path.segments.last().unwrap().identifier)
path)
}
}
}
@ -924,7 +924,8 @@ impl<'a> NameBinding<'a> {
fn is_variant(&self) -> bool {
match self.kind {
NameBindingKind::Def(Def::Variant(..)) => true,
NameBindingKind::Def(Def::Variant(..)) |
NameBindingKind::Def(Def::VariantCtor(..)) => true,
_ => false,
}
}
@ -1005,7 +1006,9 @@ pub struct Resolver<'a> {
trait_item_map: FnvHashMap<(Name, DefId), bool /* is static method? */>,
structs: FnvHashMap<DefId, Vec<Name>>,
// Names of fields of an item `DefId` accessible with dot syntax.
// Used for hints during error reporting.
field_names: FnvHashMap<DefId, Vec<Name>>,
// All imports known to succeed or fail.
determined_imports: Vec<&'a ImportDirective<'a>>,
@ -1217,7 +1220,7 @@ impl<'a> Resolver<'a> {
prelude: None,
trait_item_map: FnvHashMap(),
structs: FnvHashMap(),
field_names: FnvHashMap(),
determined_imports: Vec::new(),
indeterminate_imports: Vec::new(),
@ -2373,15 +2376,16 @@ impl<'a> Resolver<'a> {
let always_binding = !pat_src.is_refutable() || opt_pat.is_some() ||
bmode != BindingMode::ByValue(Mutability::Immutable);
match def {
Def::Struct(..) | Def::Variant(..) |
Def::Const(..) | Def::AssociatedConst(..) if !always_binding => {
// A constant, unit variant, etc pattern.
Def::StructCtor(_, CtorKind::Const) |
Def::VariantCtor(_, CtorKind::Const) |
Def::Const(..) if !always_binding => {
// A unit struct/variant or constant pattern.
let name = ident.node.name;
self.record_use(name, ValueNS, binding.unwrap(), ident.span);
Some(PathResolution::new(def))
}
Def::Struct(..) | Def::Variant(..) |
Def::Const(..) | Def::AssociatedConst(..) | Def::Static(..) => {
Def::StructCtor(..) | Def::VariantCtor(..) |
Def::Const(..) | Def::Static(..) => {
// A fresh binding that shadows something unacceptable.
resolve_error(
self,
@ -2398,7 +2402,7 @@ impl<'a> Resolver<'a> {
}
def => {
span_bug!(ident.span, "unexpected definition for an \
identifier in pattern {:?}", def);
identifier in pattern: {:?}", def);
}
}
}).unwrap_or_else(|| {
@ -2408,23 +2412,29 @@ impl<'a> Resolver<'a> {
self.record_def(pat.id, resolution);
}
PatKind::TupleStruct(ref path, ..) => {
PatKind::TupleStruct(ref path, ref pats, ddpos) => {
self.resolve_pattern_path(pat.id, None, path, ValueNS, |def| {
match def {
Def::Struct(..) | Def::Variant(..) => true,
Def::StructCtor(_, CtorKind::Fn) |
Def::VariantCtor(_, CtorKind::Fn) => true,
// `UnitVariant(..)` is accepted for backward compatibility.
Def::StructCtor(_, CtorKind::Const) |
Def::VariantCtor(_, CtorKind::Const)
if pats.is_empty() && ddpos.is_some() => true,
_ => false,
}
}, "variant or struct");
}, "tuple struct/variant");
}
PatKind::Path(ref qself, ref path) => {
self.resolve_pattern_path(pat.id, qself.as_ref(), path, ValueNS, |def| {
match def {
Def::Struct(..) | Def::Variant(..) |
Def::StructCtor(_, CtorKind::Const) |
Def::VariantCtor(_, CtorKind::Const) |
Def::Const(..) | Def::AssociatedConst(..) => true,
_ => false,
}
}, "variant, struct or constant");
}, "unit struct/variant or constant");
}
PatKind::Struct(ref path, ..) => {
@ -2776,10 +2786,9 @@ impl<'a> Resolver<'a> {
// Look for a field with the same name in the current self_type.
if let Some(resolution) = self.def_map.get(&node_id) {
match resolution.base_def {
Def::Enum(did) | Def::TyAlias(did) | Def::Union(did) |
Def::Struct(did) | Def::Variant(did) if resolution.depth == 0 => {
if let Some(fields) = self.structs.get(&did) {
if fields.iter().any(|&field_name| name == field_name) {
Def::Struct(did) | Def::Union(did) if resolution.depth == 0 => {
if let Some(field_names) = self.field_names.get(&did) {
if field_names.iter().any(|&field_name| name == field_name) {
return Field;
}
}
@ -2846,13 +2855,11 @@ impl<'a> Resolver<'a> {
if let Some(path_res) = self.resolve_possibly_assoc_item(expr.id,
maybe_qself.as_ref(), path, ValueNS) {
// Check if struct variant
let is_struct_variant = if let Def::Variant(variant_id) = path_res.base_def {
self.structs.contains_key(&variant_id)
} else {
false
let is_struct_variant = match path_res.base_def {
Def::VariantCtor(_, CtorKind::Fictive) => true,
_ => false,
};
if is_struct_variant {
let _ = self.structs.contains_key(&path_res.base_def.def_id());
let path_name = path_names_to_string(path, 0);
let mut err = resolve_struct_error(self,
@ -2885,9 +2892,6 @@ impl<'a> Resolver<'a> {
}
} else {
// Be helpful if the name refers to a struct
// (The pattern matching def_tys where the id is in self.structs
// matches on regular structs while excluding tuple- and enum-like
// structs, which wouldn't result in this error.)
let path_name = path_names_to_string(path, 0);
let type_res = self.with_no_errors(|this| {
this.resolve_path(expr.id, path, 0, TypeNS)

View File

@ -797,7 +797,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
(binding.is_import() || binding.is_extern_crate()) {
let def = binding.def();
if def != Def::Err {
reexports.push(Export { name: name, def_id: def.def_id() });
reexports.push(Export { name: name, def: def });
}
}

View File

@ -271,12 +271,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
}
}
// looks up anything, not just a type
fn lookup_type_ref(&self, ref_id: NodeId) -> Option<DefId> {
fn lookup_def_id(&self, ref_id: NodeId) -> Option<DefId> {
self.tcx.expect_def_or_none(ref_id).and_then(|def| {
match def {
Def::PrimTy(..) => None,
Def::SelfTy(..) => None,
Def::PrimTy(..) | Def::SelfTy(..) => None,
def => Some(def.def_id()),
}
})
@ -303,10 +301,10 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
}.lower(self.tcx));
}
Def::Struct(..) |
Def::Variant(..) |
Def::Union(..) |
Def::Enum(..) |
Def::TyAlias(..) |
Def::AssociatedTy(..) |
Def::Trait(_) => {
self.dumper.type_ref(TypeRefData {
span: sub_span.expect("No span found for type ref"),
@ -316,11 +314,9 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
}.lower(self.tcx));
}
Def::Static(..) |
Def::Const(_) |
Def::AssociatedConst(..) |
Def::Local(..) |
Def::Variant(..) |
Def::Upvar(..) => {
Def::Const(..) |
Def::StructCtor(..) |
Def::VariantCtor(..) => {
self.dumper.variable_ref(VariableRefData {
span: sub_span.expect("No span found for var ref"),
ref_id: def_id,
@ -335,10 +331,14 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
scope: scope
}.lower(self.tcx));
}
Def::Local(..) |
Def::Upvar(..) |
Def::SelfTy(..) |
Def::Label(_) |
Def::TyParam(..) |
Def::Method(..) |
Def::AssociatedTy(..) |
Def::AssociatedConst(..) |
Def::PrimTy(_) |
Def::Err => {
span_bug!(span,
@ -422,7 +422,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
None => {
if let Some(NodeItem(item)) = self.tcx.map.get_if_local(id) {
if let hir::ItemImpl(_, _, _, _, ref ty, _) = item.node {
trait_id = self.lookup_type_ref(ty.id);
trait_id = self.lookup_def_id(ty.id);
}
}
}
@ -805,7 +805,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
};
let trait_ref = &trait_ref.trait_ref;
if let Some(id) = self.lookup_type_ref(trait_ref.ref_id) {
if let Some(id) = self.lookup_def_id(trait_ref.ref_id) {
let sub_span = self.span.sub_span_for_type_name(trait_ref.path.span);
if !self.span.filter_generated(sub_span, trait_ref.path.span) {
self.dumper.type_ref(TypeRefData {
@ -924,13 +924,19 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
}
}
}
Def::Local(..) |
Def::Static(..) |
Def::Fn(..) |
Def::Const(..) |
Def::Static(..) |
Def::StructCtor(..) |
Def::VariantCtor(..) |
Def::AssociatedConst(..) |
Def::Local(..) |
Def::Upvar(..) |
Def::Struct(..) |
Def::Union(..) |
Def::Variant(..) |
Def::Fn(..) => self.write_sub_paths_truncated(path, false),
Def::TyAlias(..) |
Def::AssociatedTy(..) => self.write_sub_paths_truncated(path, false),
_ => {}
}
}
@ -1163,7 +1169,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
match use_item.node {
ast::ViewPathSimple(ident, ref path) => {
let sub_span = self.span.span_for_last_ident(path.span);
let mod_id = match self.lookup_type_ref(item.id) {
let mod_id = match self.lookup_def_id(item.id) {
Some(def_id) => {
let scope = self.cur_scope;
self.process_def_kind(item.id, path.span, sub_span, def_id, scope);
@ -1221,7 +1227,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
for plid in list {
let scope = self.cur_scope;
let id = plid.node.id;
if let Some(def_id) = self.lookup_type_ref(id) {
if let Some(def_id) = self.lookup_def_id(id) {
let span = plid.span;
self.process_def_kind(id, span, Some(span), def_id, scope);
}
@ -1316,7 +1322,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
self.process_macro_use(t.span, t.id);
match t.node {
ast::TyKind::Path(_, ref path) => {
if let Some(id) = self.lookup_type_ref(t.id) {
if let Some(id) = self.lookup_def_id(t.id) {
let sub_span = self.span.sub_span_for_type_name(t.span);
if !self.span.filter_generated(sub_span, t.span) {
self.dumper.type_ref(TypeRefData {
@ -1486,14 +1492,12 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
}.lower(self.tcx));
}
}
Def::Variant(..) | Def::Enum(..) |
Def::TyAlias(..) | Def::Struct(..) => {
Def::StructCtor(..) | Def::VariantCtor(..) |
Def::Const(..) | Def::AssociatedConst(..) |
Def::Struct(..) | Def::Variant(..) |
Def::TyAlias(..) | Def::AssociatedTy(..) => {
paths_to_process.push((id, p.clone(), Some(ref_kind)))
}
// FIXME(nrc) what are these doing here?
Def::Static(..) |
Def::Const(..) |
Def::AssociatedConst(..) => {}
def => error!("unexpected definition kind when processing collected paths: {:?}",
def),
}

View File

@ -507,7 +507,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
Def::Static(..) |
Def::Const(..) |
Def::AssociatedConst(..) |
Def::Variant(..) => {
Def::StructCtor(..) |
Def::VariantCtor(..) => {
Some(Data::VariableRefData(VariableRefData {
name: self.span_utils.snippet(sub_span.unwrap()),
span: sub_span.unwrap(),
@ -516,9 +517,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
}))
}
Def::Struct(def_id) |
Def::Variant(def_id, ..) |
Def::Union(def_id) |
Def::Enum(def_id) |
Def::TyAlias(def_id) |
Def::AssociatedTy(def_id) |
Def::Trait(def_id) |
Def::TyParam(def_id) => {
Some(Data::TypeRefData(TypeRefData {
@ -572,7 +575,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
qualname: String::new() // FIXME: generate the real qualname
}))
}
_ => None,
Def::PrimTy(..) |
Def::SelfTy(..) |
Def::Label(..) |
Def::Err => None,
}
}

View File

@ -24,6 +24,7 @@ use session::Session;
use llvm::{self, ValueRef};
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DILexicalBlock};
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::DefId;
use rustc::ty::subst::Substs;
use rustc::hir;
@ -1076,10 +1077,6 @@ struct StructMemberDescriptionFactory<'tcx> {
impl<'tcx> StructMemberDescriptionFactory<'tcx> {
fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
-> Vec<MemberDescription> {
if self.variant.kind == ty::VariantKind::Unit {
return Vec::new();
}
let field_size = if self.is_simd {
let fty = monomorphize::field_ty(cx.tcx(),
self.substs,
@ -1093,7 +1090,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
};
self.variant.fields.iter().enumerate().map(|(i, f)| {
let name = if self.variant.kind == ty::VariantKind::Tuple {
let name = if self.variant.ctor_kind == CtorKind::Fn {
format!("__{}", i)
} else {
f.name.to_string()
@ -1387,12 +1384,12 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
// For the metadata of the wrapper struct, we need to create a
// MemberDescription of the struct's single field.
let sole_struct_member_description = MemberDescription {
name: match non_null_variant.kind {
ty::VariantKind::Tuple => "__0".to_string(),
ty::VariantKind::Struct => {
name: match non_null_variant.ctor_kind {
CtorKind::Fn => "__0".to_string(),
CtorKind::Fictive => {
non_null_variant.fields[0].name.to_string()
}
ty::VariantKind::Unit => bug!()
CtorKind::Const => bug!()
},
llvm_type: non_null_llvm_type,
type_metadata: non_null_type_metadata,
@ -1579,16 +1576,16 @@ fn describe_enum_variant<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
containing_scope);
// Get the argument names from the enum variant info
let mut arg_names: Vec<_> = match variant.kind {
ty::VariantKind::Unit => vec![],
ty::VariantKind::Tuple => {
let mut arg_names: Vec<_> = match variant.ctor_kind {
CtorKind::Const => vec![],
CtorKind::Fn => {
variant.fields
.iter()
.enumerate()
.map(|(i, _)| format!("__{}", i))
.collect()
}
ty::VariantKind::Struct => {
CtorKind::Fictive => {
variant.fields
.iter()
.map(|f| f.name.to_string())

View File

@ -8,12 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use hir::def::Def;
use rustc::hir::{self, PatKind};
use rustc::hir::def::{Def, CtorKind};
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
use rustc::infer::{self, InferOk, TypeOrigin};
use hir::pat_util::EnumerateAndAdjustIterator;
use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference, VariantKind};
use rustc::ty::{self, Ty, TypeFoldable, LvaluePreference};
use check::{FnCtxt, Expectation};
use lint;
use util::nodemap::FnvHashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
@ -23,9 +23,6 @@ use syntax::codemap::Spanned;
use syntax::ptr::P;
use syntax_pos::Span;
use rustc::hir::{self, PatKind};
use rustc::hir::print as pprust;
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn check_pat(&self, pat: &'gcx hir::Pat, expected: Ty<'tcx>) {
let tcx = self.tcx;
@ -516,10 +513,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
expected: Ty<'tcx>) -> Ty<'tcx>
{
let tcx = self.tcx;
let report_unexpected_def = || {
let report_unexpected_def = |def: Def| {
span_err!(tcx.sess, pat.span, E0533,
"`{}` does not name a unit variant, unit struct or a constant",
pprust::path_to_string(path));
"expected unit struct/variant or constant, found {} `{}`",
def.kind_name(), path);
};
// Resolve the path and check the definition for errors.
@ -531,18 +528,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
return tcx.types.err;
}
Def::Method(..) => {
report_unexpected_def();
report_unexpected_def(def);
return tcx.types.err;
}
Def::Variant(..) | Def::Struct(..) => {
let variant = tcx.expect_variant_def(def);
if variant.kind != VariantKind::Unit {
report_unexpected_def();
return tcx.types.err;
}
}
Def::VariantCtor(_, CtorKind::Const) |
Def::StructCtor(_, CtorKind::Const) |
Def::Const(..) | Def::AssociatedConst(..) => {} // OK
_ => bug!("unexpected pattern definition {:?}", def)
_ => bug!("unexpected pattern definition: {:?}", def)
}
// Type check the path.
@ -564,17 +556,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.check_pat(&pat, tcx.types.err);
}
};
let report_unexpected_def = |is_lint| {
let msg = format!("`{}` does not name a tuple variant or a tuple struct",
pprust::path_to_string(path));
if is_lint {
tcx.sess.add_lint(lint::builtin::MATCH_OF_UNIT_VARIANT_VIA_PAREN_DOTDOT,
pat.id, pat.span, msg);
} else {
struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
.span_label(pat.span, &format!("not a tuple variant or struct")).emit();
on_error();
}
let report_unexpected_def = |def: Def| {
let msg = format!("expected tuple struct/variant, found {} `{}`",
def.kind_name(), path);
struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg)
.span_label(pat.span, &format!("not a tuple variant or struct")).emit();
on_error();
};
// Resolve the path and check the definition for errors.
@ -585,33 +572,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
on_error();
return tcx.types.err;
}
Def::Const(..) | Def::AssociatedConst(..) | Def::Method(..) => {
report_unexpected_def(false);
Def::AssociatedConst(..) | Def::Method(..) => {
report_unexpected_def(def);
return tcx.types.err;
}
Def::Variant(..) | Def::Struct(..) => {
Def::VariantCtor(_, CtorKind::Fn) |
Def::StructCtor(_, CtorKind::Fn) => {
tcx.expect_variant_def(def)
}
_ => bug!("unexpected pattern definition {:?}", def)
_ => bug!("unexpected pattern definition: {:?}", def)
};
if variant.kind == VariantKind::Unit && subpats.is_empty() && ddpos.is_some() {
// Matching unit structs with tuple variant patterns (`UnitVariant(..)`)
// is allowed for backward compatibility.
report_unexpected_def(true);
} else if variant.kind != VariantKind::Tuple {
report_unexpected_def(false);
return tcx.types.err;
}
// Type check the path.
let pat_ty = self.instantiate_value_path(segments, opt_ty, def, pat.span, pat.id);
let pat_ty = if pat_ty.is_fn() {
// Replace constructor type with constructed type for tuple struct patterns.
tcx.no_late_bound_regions(&pat_ty.fn_ret()).unwrap()
} else {
// Leave the type as is for unit structs (backward compatibility).
pat_ty
};
// Replace constructor type with constructed type for tuple struct patterns.
let pat_ty = tcx.no_late_bound_regions(&pat_ty.fn_ret()).expect("expected fn type");
self.demand_eqtype(pat.span, expected, pat_ty);
// Type check subpatterns.
@ -626,16 +601,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.check_pat(&subpat, field_ty);
}
} else {
let subpats_ending = if subpats.len() == 1 {
""
} else {
"s"
};
let fields_ending = if variant.fields.len() == 1 {
""
} else {
"s"
};
let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
let fields_ending = if variant.fields.len() == 1 { "" } else { "s" };
struct_span_err!(tcx.sess, pat.span, E0023,
"this pattern has {} field{}, but the corresponding {} has {} field{}",
subpats.len(), subpats_ending, def.kind_name(),

View File

@ -451,27 +451,26 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> {
fn handle_external_def(ccx: &CrateCtxt,
traits: &mut AllTraitsVec,
external_mods: &mut FnvHashSet<DefId>,
def_id: DefId) {
match ccx.tcx.sess.cstore.describe_def(def_id) {
Some(Def::Trait(_)) => {
def: Def) {
let def_id = def.def_id();
match def {
Def::Trait(..) => {
traits.push(TraitInfo::new(def_id));
}
Some(Def::Mod(_)) => {
Def::Mod(..) => {
if !external_mods.insert(def_id) {
return;
}
for child in ccx.tcx.sess.cstore.item_children(def_id) {
handle_external_def(ccx, traits, external_mods, child.def_id)
handle_external_def(ccx, traits, external_mods, child.def)
}
}
_ => {}
}
}
for cnum in ccx.tcx.sess.cstore.crates() {
handle_external_def(ccx, &mut traits, &mut external_mods, DefId {
krate: cnum,
index: CRATE_DEF_INDEX
});
let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
handle_external_def(ccx, &mut traits, &mut external_mods, Def::Mod(def_id));
}
*ccx.all_traits.borrow_mut() = Some(traits);

View File

@ -83,7 +83,7 @@ use self::TupleArgumentsFlag::*;
use astconv::{AstConv, ast_region_to_region, PathParamMode};
use dep_graph::DepNode;
use fmt_macros::{Parser, Piece, Position};
use hir::def::{Def, PathResolution};
use hir::def::{Def, CtorKind, PathResolution};
use hir::def_id::{DefId, LOCAL_CRATE};
use hir::pat_util;
use rustc::infer::{self, InferCtxt, InferOk, TypeOrigin, TypeTrace, type_variable};
@ -3020,7 +3020,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
while let Some((base_t, autoderefs)) = autoderef.next() {
let field = match base_t.sty {
ty::TyAdt(base_def, substs) if base_def.is_struct() => {
tuple_like = base_def.struct_variant().kind == ty::VariantKind::Tuple;
tuple_like = base_def.struct_variant().ctor_kind == CtorKind::Fn;
if !tuple_like { continue }
debug!("tuple struct named {:?}", base_t);
@ -3245,7 +3245,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
Def::Struct(type_did) | Def::Union(type_did) => {
Some((type_did, self.tcx.expect_variant_def(def)))
}
Def::TyAlias(did) => {
Def::TyAlias(did) | Def::AssociatedTy(did) => {
match self.tcx.opt_lookup_item_type(did).map(|scheme| &scheme.ty.sty) {
Some(&ty::TyAdt(adt, _)) if !adt.is_enum() => {
Some((did, adt.struct_variant()))
@ -3257,7 +3257,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
if let Some((def_id, variant)) = variant {
if variant.kind == ty::VariantKind::Tuple &&
if variant.ctor_kind == CtorKind::Fn &&
!self.tcx.sess.features.borrow().relaxed_adts {
emit_feature_err(&self.tcx.sess.parse_sess,
"relaxed_adts", span, GateIssue::Language,
@ -4064,34 +4064,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
//
// There are basically four cases to consider:
//
// 1. Reference to a *type*, such as a struct or enum:
// 1. Reference to a constructor of enum variant or struct:
//
// mod a { struct Foo<T> { ... } }
//
// Because we don't allow types to be declared within one
// another, a path that leads to a type will always look like
// `a::b::Foo<T>` where `a` and `b` are modules. This implies
// that only the final segment can have type parameters, and
// they are located in the TypeSpace.
//
// *Note:* Generally speaking, references to types don't
// actually pass through this function, but rather the
// `ast_ty_to_ty` function in `astconv`. However, in the case
// of struct patterns (and maybe literals) we do invoke
// `instantiate_value_path` to get the general type of an instance of
// a struct. (In these cases, there are actually no type
// parameters permitted at present, but perhaps we will allow
// them in the future.)
//
// 1b. Reference to an enum variant or tuple-like struct:
//
// struct foo<T>(...)
// enum E<T> { foo(...) }
// struct Foo<T>(...)
// enum E<T> { Foo(...) }
//
// In these cases, the parameters are declared in the type
// space.
//
// 2. Reference to a *fn item*:
// 2. Reference to a fn item or a free constant:
//
// fn foo<T>() { }
//
@ -4100,7 +4081,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// type parameters. However, in this case, those parameters are
// declared on a value, and hence are in the `FnSpace`.
//
// 3. Reference to a *method*:
// 3. Reference to a method or an associated constant:
//
// impl<A> SomeStruct<A> {
// fn foo<B>(...)
@ -4112,15 +4093,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// `SomeStruct::<A>`, contains parameters in TypeSpace, and the
// final segment, `foo::<B>` contains parameters in fn space.
//
// 4. Reference to an *associated const*:
// 4. Reference to a local variable
//
// impl<A> AnotherStruct<A> {
// const FOO: B = BAR;
// }
//
// The path in this case will look like
// `a::b::AnotherStruct::<A>::FOO`, so the penultimate segment
// only will have parameters in TypeSpace.
// Local variables can't have any type parameters.
//
// The first step then is to categorize the segments appropriately.
@ -4130,14 +4105,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let mut type_segment = None;
let mut fn_segment = None;
match def {
// Case 1 and 1b. Reference to a *type* or *enum variant*.
Def::Struct(def_id) |
Def::Union(def_id) |
Def::Variant(def_id) |
Def::Enum(def_id) |
Def::TyAlias(def_id) |
Def::AssociatedTy(def_id) |
Def::Trait(def_id) => {
// Case 1. Reference to a struct/variant constructor.
Def::StructCtor(def_id, ..) |
Def::VariantCtor(def_id, ..) => {
// Everything but the final segment should have no
// parameters at all.
let mut generics = self.tcx.lookup_generics(def_id);
@ -4180,17 +4150,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
fn_segment = Some((segments.last().unwrap(), generics));
}
// Other cases. Various nonsense that really shouldn't show up
// here. If they do, an error will have been reported
// elsewhere. (I hope)
Def::Mod(..) |
Def::PrimTy(..) |
Def::SelfTy(..) |
Def::TyParam(..) |
Def::Local(..) |
Def::Label(..) |
Def::Upvar(..) |
Def::Err => {}
// Case 4. Local variable, no generics.
Def::Local(..) | Def::Upvar(..) => {}
_ => bug!("unexpected definition: {:?}", def),
}
// In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but

View File

@ -68,7 +68,6 @@ use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
use rustc::ty::subst::Substs;
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
use rustc::ty::{self, AdtKind, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
use rustc::ty::{VariantKind};
use rustc::ty::util::IntTypeExt;
use rscope::*;
use rustc::dep_graph::DepNode;
@ -87,7 +86,7 @@ use syntax::parse::token::keywords;
use syntax_pos::Span;
use rustc::hir::{self, intravisit, map as hir_map, print as pprust};
use rustc::hir::def::Def;
use rustc::hir::def::{Def, CtorKind};
use rustc::hir::def_id::DefId;
///////////////////////////////////////////////////////////////////////////
@ -987,9 +986,9 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let tcx = ccx.tcx;
let def_id = tcx.map.local_def_id(ctor_id);
generics_of_def_id(ccx, def_id);
let ctor_ty = match variant.kind {
VariantKind::Unit | VariantKind::Struct => scheme.ty,
VariantKind::Tuple => {
let ctor_ty = match variant.ctor_kind {
CtorKind::Fictive | CtorKind::Const => scheme.ty,
CtorKind::Fn => {
let inputs: Vec<_> =
variant.fields
.iter()
@ -1066,7 +1065,7 @@ fn convert_struct_variant<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
name: name,
disr_val: disr_val,
fields: fields,
kind: VariantKind::from_variant_data(def),
ctor_kind: CtorKind::from_hir(def),
}
}

View File

@ -15,11 +15,10 @@ use std::iter::once;
use syntax::ast;
use rustc::hir;
use rustc::hir::def::Def;
use rustc::hir::def::{Def, CtorKind};
use rustc::hir::def_id::DefId;
use rustc::hir::map::DefPathData;
use rustc::hir::print as pprust;
use rustc::ty::{self, TyCtxt, VariantKind};
use rustc::ty::{self, TyCtxt};
use rustc::util::nodemap::FnvHashSet;
use rustc_const_eval::lookup_const_by_id;
@ -81,9 +80,7 @@ fn try_inline_def<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
record_extern_fqn(cx, did, clean::TypeKind::Function);
clean::FunctionItem(build_external_function(cx, tcx, did))
}
Def::Struct(did)
// If this is a struct constructor, we skip it
if tcx.def_key(did).disambiguated_data.data != DefPathData::StructCtor => {
Def::Struct(did) => {
record_extern_fqn(cx, did, clean::TypeKind::Struct);
ret.extend(build_impls(cx, tcx, did));
clean::StructItem(build_struct(cx, tcx, did))
@ -105,7 +102,10 @@ fn try_inline_def<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
// Assume that the enum type is reexported next to the variant, and
// variants don't show up in documentation specially.
Def::Variant(..) => return Some(Vec::new()),
// Similarly, consider that struct type is reexported next to its constructor.
Def::Variant(..) |
Def::VariantCtor(..) |
Def::StructCtor(..) => return Some(Vec::new()),
Def::Mod(did) => {
record_extern_fqn(cx, did, clean::TypeKind::Module);
clean::ModuleItem(build_module(cx, tcx, did))
@ -114,7 +114,7 @@ fn try_inline_def<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
record_extern_fqn(cx, did, clean::TypeKind::Static);
clean::StaticItem(build_static(cx, tcx, did, mtbl))
}
Def::Const(did) | Def::AssociatedConst(did) => {
Def::Const(did) => {
record_extern_fqn(cx, did, clean::TypeKind::Const);
clean::ConstantItem(build_const(cx, tcx, did))
}
@ -219,10 +219,10 @@ fn build_struct<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
let variant = tcx.lookup_adt_def(did).struct_variant();
clean::Struct {
struct_type: match variant.kind {
VariantKind::Struct => doctree::Plain,
VariantKind::Tuple => doctree::Tuple,
VariantKind::Unit => doctree::Unit,
struct_type: match variant.ctor_kind {
CtorKind::Fictive => doctree::Plain,
CtorKind::Fn => doctree::Tuple,
CtorKind::Const => doctree::Unit,
},
generics: (t.generics, &predicates).clean(cx),
fields: variant.fields.clean(cx),
@ -498,12 +498,11 @@ fn build_module<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
// visit each node at most once.
let mut visited = FnvHashSet();
for item in tcx.sess.cstore.item_children(did) {
if tcx.sess.cstore.visibility(item.def_id) == ty::Visibility::Public {
if !visited.insert(item.def_id) { continue }
if let Some(def) = tcx.sess.cstore.describe_def(item.def_id) {
if let Some(i) = try_inline_def(cx, tcx, def) {
items.extend(i)
}
let def_id = item.def.def_id();
if tcx.sess.cstore.visibility(def_id) == ty::Visibility::Public {
if !visited.insert(def_id) { continue }
if let Some(i) = try_inline_def(cx, tcx, item.def) {
items.extend(i)
}
}
}

View File

@ -32,7 +32,7 @@ use syntax_pos::{self, DUMMY_SP, Pos};
use rustc_trans::back::link;
use rustc::middle::privacy::AccessLevels;
use rustc::middle::resolve_lifetime::DefRegion::*;
use rustc::hir::def::Def;
use rustc::hir::def::{Def, CtorKind};
use rustc::hir::def_id::{self, DefId, DefIndex, CRATE_DEF_INDEX};
use rustc::hir::print as pprust;
use rustc::ty::subst::Substs;
@ -237,7 +237,7 @@ impl Clean<ExternalCrate> for CrateNum {
let root = DefId { krate: self.0, index: CRATE_DEF_INDEX };
cx.tcx_opt().map(|tcx| {
for item in tcx.sess.cstore.item_children(root) {
let attrs = inline::load_attrs(cx, tcx, item.def_id);
let attrs = inline::load_attrs(cx, tcx, item.def.def_id());
PrimitiveType::find(&attrs).map(|prim| primitives.push(prim));
}
});
@ -2032,14 +2032,14 @@ impl Clean<Item> for doctree::Variant {
impl<'tcx> Clean<Item> for ty::VariantDefData<'tcx, 'static> {
fn clean(&self, cx: &DocContext) -> Item {
let kind = match self.kind {
ty::VariantKind::Unit => VariantKind::CLike,
ty::VariantKind::Tuple => {
let kind = match self.ctor_kind {
CtorKind::Const => VariantKind::CLike,
CtorKind::Fn => {
VariantKind::Tuple(
self.fields.iter().map(|f| f.unsubst_ty().clean(cx)).collect()
)
}
ty::VariantKind::Struct => {
CtorKind::Fictive => {
VariantKind::Struct(VariantStruct {
struct_type: doctree::Plain,
fields_stripped: false,

View File

@ -66,11 +66,12 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
pub fn visit_mod(&mut self, def_id: DefId) {
for item in self.cstore.item_children(def_id) {
self.visit_item(item.def_id);
self.visit_item(item.def);
}
}
fn visit_item(&mut self, def_id: DefId) {
fn visit_item(&mut self, def: Def) {
let def_id = def.def_id();
let vis = self.cstore.visibility(def_id);
let inherited_item_level = if vis == Visibility::Public {
self.prev_level
@ -80,7 +81,7 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> {
let item_level = self.update(def_id, inherited_item_level);
if let Some(Def::Mod(_)) = self.cstore.describe_def(def_id) {
if let Def::Mod(..) = def {
let orig_level = self.prev_level;
self.prev_level = item_level;

View File

@ -8,7 +8,13 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
enum Foo { B { i: u32 } }
#![feature(associated_consts)]
enum Foo {}
impl Foo {
const B: u8 = 0;
}
fn bar(foo: Foo) -> u32 {
match foo {

View File

@ -0,0 +1,78 @@
// 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.
#![feature(item_like_imports, relaxed_adts)]
pub mod c {
pub struct S {}
pub struct TS();
pub struct US;
pub enum E {
V {},
TV(),
UV,
}
pub struct Item;
}
pub mod xm1 {
pub use ::c::*;
pub type S = ::c::Item;
}
pub mod xm2 {
pub use ::c::*;
pub const S: ::c::Item = ::c::Item;
}
pub mod xm3 {
pub use ::c::*;
pub type TS = ::c::Item;
}
pub mod xm4 {
pub use ::c::*;
pub const TS: ::c::Item = ::c::Item;
}
pub mod xm5 {
pub use ::c::*;
pub type US = ::c::Item;
}
pub mod xm6 {
pub use ::c::*;
pub const US: ::c::Item = ::c::Item;
}
pub mod xm7 {
pub use ::c::E::*;
pub type V = ::c::Item;
}
pub mod xm8 {
pub use ::c::E::*;
pub const V: ::c::Item = ::c::Item;
}
pub mod xm9 {
pub use ::c::E::*;
pub type TV = ::c::Item;
}
pub mod xmA {
pub use ::c::E::*;
pub const TV: ::c::Item = ::c::Item;
}
pub mod xmB {
pub use ::c::E::*;
pub type UV = ::c::Item;
}
pub mod xmC {
pub use ::c::E::*;
pub const UV: ::c::Item = ::c::Item;
}

View File

@ -0,0 +1,85 @@
// 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.
// FIXME: Remove when `item_like_imports` is stabilized.
#![feature(relaxed_adts)]
pub mod c {
pub struct S {}
pub struct TS();
pub struct US;
pub enum E {
V {},
TV(),
UV,
}
pub struct Item;
}
pub mod proxy {
pub use c::*;
pub use c::E::*;
}
pub mod xm1 {
pub use ::proxy::*;
pub type S = ::c::Item;
}
pub mod xm2 {
pub use ::proxy::*;
pub const S: ::c::Item = ::c::Item;
}
pub mod xm3 {
pub use ::proxy::*;
pub type TS = ::c::Item;
}
pub mod xm4 {
pub use ::proxy::*;
pub const TS: ::c::Item = ::c::Item;
}
pub mod xm5 {
pub use ::proxy::*;
pub type US = ::c::Item;
}
pub mod xm6 {
pub use ::proxy::*;
pub const US: ::c::Item = ::c::Item;
}
pub mod xm7 {
pub use ::proxy::*;
pub type V = ::c::Item;
}
pub mod xm8 {
pub use ::proxy::*;
pub const V: ::c::Item = ::c::Item;
}
pub mod xm9 {
pub use ::proxy::*;
pub type TV = ::c::Item;
}
pub mod xmA {
pub use ::proxy::*;
pub const TV: ::c::Item = ::c::Item;
}
pub mod xmB {
pub use ::proxy::*;
pub type UV = ::c::Item;
}
pub mod xmC {
pub use ::proxy::*;
pub const UV: ::c::Item = ::c::Item;
}

View File

@ -12,6 +12,6 @@ mod foo { pub struct bar; }
fn main() {
let bar = 5;
//~^ ERROR let bindings cannot shadow structs
//~^ ERROR let bindings cannot shadow unit structs
use foo::bar;
}

View File

@ -32,13 +32,13 @@ fn main() {
}
match e3 {
E::Empty3 => ()
//~^ ERROR `E::Empty3` does not name a unit variant, unit struct or a constant
//~^ ERROR expected unit struct/variant or constant, found struct variant `E::Empty3`
}
match xe1 {
XEmpty1 => () // Not an error, `XEmpty1` is interpreted as a new binding
}
match xe3 {
XE::XEmpty3 => ()
//~^ ERROR `XE::XEmpty3` does not name a unit variant, unit struct or a constant
//~^ ERROR expected unit struct/variant or constant, found struct variant `XE::XEmpty3`
}
}

View File

@ -24,15 +24,15 @@ fn main() {
let xe1 = XEmpty1 {};
match e1 {
Empty1() => () //~ ERROR unresolved variant or struct `Empty1`
Empty1() => () //~ ERROR unresolved tuple struct/variant `Empty1`
}
match xe1 {
XEmpty1() => () //~ ERROR unresolved variant or struct `XEmpty1`
XEmpty1() => () //~ ERROR unresolved tuple struct/variant `XEmpty1`
}
match e1 {
Empty1(..) => () //~ ERROR unresolved variant or struct `Empty1`
Empty1(..) => () //~ ERROR unresolved tuple struct/variant `Empty1`
}
match xe1 {
XEmpty1(..) => () //~ ERROR unresolved variant or struct `XEmpty1`
XEmpty1(..) => () //~ ERROR unresolved tuple struct/variant `XEmpty1`
}
}

View File

@ -26,15 +26,19 @@ fn main() {
let xe3 = XE::XEmpty3 {};
match e3 {
E::Empty3() => () //~ ERROR `E::Empty3` does not name a tuple variant or a tuple struct
E::Empty3() => ()
//~^ ERROR expected tuple struct/variant, found struct variant `E::Empty3`
}
match xe3 {
XE::XEmpty3() => () //~ ERROR `XE::XEmpty3` does not name a tuple variant or a tuple struct
XE::XEmpty3() => ()
//~^ ERROR expected tuple struct/variant, found struct variant `XE::XEmpty3`
}
match e3 {
E::Empty3(..) => () //~ ERROR `E::Empty3` does not name a tuple variant or a tuple struct
E::Empty3(..) => ()
//~^ ERROR expected tuple struct/variant, found struct variant `E::Empty3`
}
match xe3 {
XE::XEmpty3(..) => () //~ ERROR `XE::XEmpty3` does not name a tuple variant or a tuple
XE::XEmpty3(..) => ()
//~^ ERROR expected tuple struct/variant, found struct variant `XE::XEmpty3
}
}

View File

@ -31,17 +31,19 @@ fn main() {
let xe5 = XE::XEmpty5();
match e2 {
Empty2 => () //~ ERROR `Empty2` does not name a unit variant, unit struct or a constant
Empty2 => () //~ ERROR match bindings cannot shadow tuple structs
}
match xe6 {
XEmpty6 => () //~ ERROR `XEmpty6` does not name a unit variant, unit struct or a constant
XEmpty6 => () //~ ERROR match bindings cannot shadow tuple structs
}
match e4 {
E::Empty4 => () //~ ERROR `E::Empty4` does not name a unit variant, unit struct or a
E::Empty4 => ()
//~^ ERROR expected unit struct/variant or constant, found tuple variant `E::Empty4`
}
match xe5 {
XE::XEmpty5 => (), //~ ERROR `XE::XEmpty5` does not name a unit variant, unit struct or a
XE::XEmpty5 => (),
//~^ ERROR expected unit struct/variant or constant, found tuple variant `XE::XEmpty5`
_ => {},
}
}

View File

@ -31,21 +31,22 @@ fn main() {
let xe4 = XE::XEmpty4;
match e2 {
Empty2(..) => () //~ ERROR `Empty2` does not name a tuple variant or a tuple struct
Empty2(..) => () //~ ERROR expected tuple struct/variant, found unit struct `Empty2`
//~^ WARNING hard error
}
match xe2 {
XEmpty2(..) => () //~ ERROR `XEmpty2` does not name a tuple variant or a tuple struct
XEmpty2(..) => () //~ ERROR expected tuple struct/variant, found unit struct `XEmpty2`
//~^ WARNING hard error
}
match e4 {
E::Empty4(..) => () //~ ERROR `E::Empty4` does not name a tuple variant or a tuple struct
E::Empty4(..) => () //~ ERROR expected tuple struct/variant, found unit variant `E::Empty4`
//~^ WARNING hard error
}
match xe4 {
XE::XEmpty4(..) => (), //~ ERROR `XE::XEmpty4` does not name a tuple variant or a tuple
//~^ WARNING hard error
XE::XEmpty4(..) => (),
//~^ ERROR expected tuple struct/variant, found unit variant `XE::XEmpty4`
//~| WARNING hard error
_ => {},
}
}

View File

@ -23,7 +23,6 @@ enum E {
Empty4
}
// remove attribute after warning cycle and promoting warnings to errors
fn main() {
let e2 = Empty2;
let e4 = E::Empty4;
@ -31,17 +30,21 @@ fn main() {
let xe4 = XE::XEmpty4;
match e2 {
Empty2() => () //~ ERROR `Empty2` does not name a tuple variant or a tuple struct
Empty2() => ()
//~^ ERROR expected tuple struct/variant, found unit struct `Empty2`
}
match xe2 {
XEmpty2() => () //~ ERROR `XEmpty2` does not name a tuple variant or a tuple struct
XEmpty2() => ()
//~^ ERROR expected tuple struct/variant, found unit struct `XEmpty2`
}
match e4 {
E::Empty4() => () //~ ERROR `E::Empty4` does not name a tuple variant or a tuple struct
E::Empty4() => ()
//~^ ERROR expected tuple struct/variant, found unit variant `E::Empty4`
}
match xe4 {
XE::XEmpty4() => (), //~ ERROR `XE::XEmpty4` does not name a tuple variant or a tuple
XE::XEmpty4() => (),
//~^ ERROR expected tuple struct/variant, found unit variant `XE::XEmpty4`
_ => {},
}
}

View File

@ -11,5 +11,5 @@
struct hello(isize);
fn main() {
let hello = 0; //~ERROR let bindings cannot shadow structs
let hello = 0; //~ERROR let bindings cannot shadow tuple structs
}

View File

@ -9,5 +9,5 @@
// except according to those terms.
fn main() {
let a(1) = 13; //~ ERROR unresolved variant or struct `a`
let a(1) = 13; //~ ERROR unresolved tuple struct/variant `a`
}

View File

@ -13,7 +13,7 @@ fn foo(_: usize) -> Foo { Foo(false) }
fn main() {
match Foo(true) {
foo(x) //~ ERROR expected variant or struct, found function `foo`
foo(x) //~ ERROR expected tuple struct/variant, found function `foo`
=> ()
}
}

View File

@ -12,6 +12,6 @@ mod foo { pub fn bar() {} }
fn main() {
match () {
foo::bar => {} //~ ERROR expected variant, struct or constant, found function `bar`
foo::bar => {} //~ ERROR expected unit struct/variant or constant, found function `foo::bar`
}
}

View File

@ -13,7 +13,7 @@ pub static X: usize = 1;
fn main() {
match 1 {
self::X => { },
//~^ ERROR expected variant, struct or constant, found static `X`
//~^ ERROR expected unit struct/variant or constant, found static `self::X`
_ => { },
}
}

View File

@ -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 tuple variant or a tuple struct
//~^ ERROR expected tuple struct/variant, found struct variant `FooB`
}
}

View File

@ -10,7 +10,7 @@
fn main() {
match Some(1) {
None @ _ => {} //~ ERROR match bindings cannot shadow variants
None @ _ => {} //~ ERROR match bindings cannot shadow unit variants
};
const C: u8 = 1;
match 1 {

View File

@ -14,7 +14,9 @@ fn main() {
let u = A { x: 1 }; //~ ERROR `A` does not name a struct or a struct variant
let v = u32 { x: 1 }; //~ ERROR `u32` does not name a struct or a struct variant
match () {
A { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found module `A`
u32 { x: 1 } => {} //~ ERROR expected variant, struct or type alias, found builtin type `u32
A { x: 1 } => {}
//~^ ERROR expected variant, struct or type alias, found module `A`
u32 { x: 1 } => {}
//~^ ERROR expected variant, struct or type alias, found builtin type `u32`
}
}

View File

@ -21,6 +21,7 @@ impl S {
}
fn main() {
if let C1(..) = 0 {} //~ ERROR expected variant or struct, found constant `C1`
if let S::C2(..) = 0 {} //~ ERROR `S::C2` does not name a tuple variant or a tuple struct
if let C1(..) = 0 {} //~ ERROR expected tuple struct/variant, found constant `C1`
if let S::C2(..) = 0 {}
//~^ ERROR expected tuple struct/variant, found associated constant `S::C2`
}

View File

@ -18,12 +18,12 @@ struct S;
fn main() {
match Foo::Baz {
Foo::Bar => {}
//~^ ERROR `Foo::Bar` does not name a unit variant, unit struct or a constant
//~^ ERROR expected unit struct/variant or constant, found tuple variant `Foo::Bar`
_ => {}
}
match S {
S(()) => {}
//~^ ERROR `S` does not name a tuple variant or a tuple struct
//~^ ERROR expected tuple struct/variant, found unit struct `S`
}
}

View File

@ -12,6 +12,6 @@ struct S(u8);
const C: S = S(10);
fn main() {
let C(a) = S(11); //~ ERROR expected variant or struct, found constant `C`
let C(..) = S(11); //~ ERROR expected variant or struct, found constant `C`
let C(a) = S(11); //~ ERROR expected tuple struct/variant, found constant `C`
let C(..) = S(11); //~ ERROR expected tuple struct/variant, found constant `C`
}

View File

@ -11,7 +11,7 @@
fn main() {
let z = match 3 {
x(1) => x(1) //~ ERROR unresolved variant or struct `x`
x(1) => x(1) //~ ERROR unresolved tuple struct/variant `x`
//~^ ERROR unresolved name `x`
};
assert!(z == 3);

View File

@ -20,7 +20,7 @@ fn main() {
color::rgb(_, _, _) => { }
color::cmyk(_, _, _, _) => { }
color::no_color(_) => { }
//~^ ERROR `color::no_color` does not name a tuple variant or a tuple struct
//~^ ERROR expected tuple struct/variant, found unit variant `color::no_color`
}
}
}

View File

@ -18,7 +18,7 @@ fn main() {
fn foo(c: color) {
match c {
color::rgb(_, _) => { }
//~^ ERROR this pattern has 2 fields, but the corresponding variant has 3 fields
//~^ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields
color::cmyk(_, _, _, _) => { }
color::no_color => { }
}

View File

@ -22,13 +22,13 @@ impl MyTrait for Foo {}
fn main() {
match 0u32 {
Foo::bar => {} //~ ERROR `Foo::bar` does not name a unit variant, unit struct or a constant
Foo::bar => {} //~ ERROR expected unit struct/variant or constant, found method `Foo::bar`
}
match 0u32 {
<Foo>::bar => {} //~ ERROR `bar` does not name a unit variant, unit struct or a constant
<Foo>::bar => {} //~ ERROR expected unit struct/variant or constant, found method `bar`
}
match 0u32 {
<Foo>::trait_bar => {}
//~^ ERROR `trait_bar` does not name a unit variant, unit struct or a constant
//~^ ERROR expected unit struct/variant or constant, found method `trait_bar`
}
}

View File

@ -19,6 +19,6 @@ impl MyTrait for Foo {}
fn main() {
match 0u32 {
<Foo as MyTrait>::trait_bar => {}
//~^ ERROR expected variant, struct or constant, found method `trait_bar`
//~^ ERROR expected unit struct/variant or constant, found method `MyTrait::trait_bar`
}
}

View File

@ -11,7 +11,7 @@
use std::option::*;
fn main() {
let None: isize = 42; //~ ERROR let bindings cannot shadow variants
let None: isize = 42; //~ ERROR let bindings cannot shadow unit variants
log(debug, None);
//~^ ERROR unresolved name `debug`
//~| ERROR unresolved name `log`

View File

@ -0,0 +1,167 @@
// 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.
// aux-build:namespace-mix-new.rs
#![feature(item_like_imports, relaxed_adts)]
extern crate namespace_mix_new;
use namespace_mix_new::*;
mod c {
pub struct S {}
pub struct TS();
pub struct US;
pub enum E {
V {},
TV(),
UV,
}
pub struct Item;
}
// Use something emitting the type argument name, e.g. unsatisfied bound.
trait Impossible {}
fn check<T: Impossible>(_: T) {}
mod m1 {
pub use ::c::*;
pub type S = ::c::Item;
}
mod m2 {
pub use ::c::*;
pub const S: ::c::Item = ::c::Item;
}
fn f12() {
check(m1::S{}); //~ ERROR c::Item
check(m1::S); //~ ERROR unresolved name
check(m2::S{}); //~ ERROR c::S
check(m2::S); //~ ERROR c::Item
}
fn xf12() {
check(xm1::S{}); //~ ERROR c::Item
check(xm1::S); //~ ERROR unresolved name
check(xm2::S{}); //~ ERROR c::S
check(xm2::S); //~ ERROR c::Item
}
mod m3 {
pub use ::c::*;
pub type TS = ::c::Item;
}
mod m4 {
pub use ::c::*;
pub const TS: ::c::Item = ::c::Item;
}
fn f34() {
check(m3::TS{}); //~ ERROR c::Item
check(m3::TS); //~ ERROR c::TS
check(m4::TS{}); //~ ERROR c::TS
check(m4::TS); //~ ERROR c::Item
}
fn xf34() {
check(xm3::TS{}); //~ ERROR c::Item
check(xm3::TS); //~ ERROR c::TS
check(xm4::TS{}); //~ ERROR c::TS
check(xm4::TS); //~ ERROR c::Item
}
mod m5 {
pub use ::c::*;
pub type US = ::c::Item;
}
mod m6 {
pub use ::c::*;
pub const US: ::c::Item = ::c::Item;
}
fn f56() {
check(m5::US{}); //~ ERROR c::Item
check(m5::US); //~ ERROR c::US
check(m6::US{}); //~ ERROR c::US
check(m6::US); //~ ERROR c::Item
}
fn xf56() {
check(xm5::US{}); //~ ERROR c::Item
check(xm5::US); //~ ERROR c::US
check(xm6::US{}); //~ ERROR c::US
check(xm6::US); //~ ERROR c::Item
}
mod m7 {
pub use ::c::E::*;
pub type V = ::c::Item;
}
mod m8 {
pub use ::c::E::*;
pub const V: ::c::Item = ::c::Item;
}
fn f78() {
check(m7::V{}); //~ ERROR c::Item
check(m7::V); //~ ERROR name of a struct or struct variant
check(m8::V{}); //~ ERROR c::E
check(m8::V); //~ ERROR c::Item
}
fn xf78() {
check(xm7::V{}); //~ ERROR c::Item
check(xm7::V); //~ ERROR name of a struct or struct variant
check(xm8::V{}); //~ ERROR c::E
check(xm8::V); //~ ERROR c::Item
}
mod m9 {
pub use ::c::E::*;
pub type TV = ::c::Item;
}
mod mA {
pub use ::c::E::*;
pub const TV: ::c::Item = ::c::Item;
}
fn f9A() {
check(m9::TV{}); //~ ERROR c::Item
check(m9::TV); //~ ERROR c::E
check(mA::TV{}); //~ ERROR c::E
check(mA::TV); //~ ERROR c::Item
}
fn xf9A() {
check(xm9::TV{}); //~ ERROR c::Item
check(xm9::TV); //~ ERROR c::E
check(xmA::TV{}); //~ ERROR c::E
check(xmA::TV); //~ ERROR c::Item
}
mod mB {
pub use ::c::E::*;
pub type UV = ::c::Item;
}
mod mC {
pub use ::c::E::*;
pub const UV: ::c::Item = ::c::Item;
}
fn fBC() {
check(mB::UV{}); //~ ERROR c::Item
check(mB::UV); //~ ERROR c::E
check(mC::UV{}); //~ ERROR c::E
check(mC::UV); //~ ERROR c::Item
}
fn xfBC() {
check(xmB::UV{}); //~ ERROR c::Item
check(xmB::UV); //~ ERROR c::E
check(xmC::UV{}); //~ ERROR c::E
check(xmC::UV); //~ ERROR c::Item
}
fn main() {}

View File

@ -0,0 +1,174 @@
// 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.
// FIXME: Remove when `item_like_imports` is stabilized.
// aux-build:namespace-mix-old.rs
#![feature(relaxed_adts)]
extern crate namespace_mix_old;
use namespace_mix_old::{xm1, xm2, xm3, xm4, xm5, xm6, xm7, xm8, xm9, xmA, xmB, xmC};
mod c {
pub struct S {}
pub struct TS();
pub struct US;
pub enum E {
V {},
TV(),
UV,
}
pub struct Item;
}
mod proxy {
pub use c::*;
pub use c::E::*;
}
// Use something emitting the type argument name, e.g. unsatisfied bound.
trait Impossible {}
fn check<T: Impossible>(_: T) {}
mod m1 {
pub use ::proxy::*;
pub type S = ::c::Item;
}
mod m2 {
pub use ::proxy::*;
pub const S: ::c::Item = ::c::Item;
}
fn f12() {
check(m1::S{}); //~ ERROR c::Item
check(m1::S); //~ ERROR unresolved name
check(m2::S{}); //~ ERROR c::S
check(m2::S); //~ ERROR c::Item
}
fn xf12() {
check(xm1::S{}); //~ ERROR c::Item
check(xm1::S); //~ ERROR unresolved name
check(xm2::S{}); //~ ERROR c::S
check(xm2::S); //~ ERROR c::Item
}
mod m3 {
pub use ::proxy::*;
pub type TS = ::c::Item;
}
mod m4 {
pub use ::proxy::*;
pub const TS: ::c::Item = ::c::Item;
}
fn f34() {
check(m3::TS{}); //~ ERROR c::Item
check(m3::TS); //~ ERROR c::TS
check(m4::TS{}); //~ ERROR c::TS
check(m4::TS); //~ ERROR c::Item
}
fn xf34() {
check(xm3::TS{}); //~ ERROR c::Item
check(xm3::TS); //~ ERROR c::TS
check(xm4::TS{}); //~ ERROR c::TS
check(xm4::TS); //~ ERROR c::Item
}
mod m5 {
pub use ::proxy::*;
pub type US = ::c::Item;
}
mod m6 {
pub use ::proxy::*;
pub const US: ::c::Item = ::c::Item;
}
fn f56() {
check(m5::US{}); //~ ERROR c::Item
check(m5::US); //~ ERROR c::US
check(m6::US{}); //~ ERROR c::US
check(m6::US); //~ ERROR c::Item
}
fn xf56() {
check(xm5::US{}); //~ ERROR c::Item
check(xm5::US); //~ ERROR c::US
check(xm6::US{}); //~ ERROR c::US
check(xm6::US); //~ ERROR c::Item
}
mod m7 {
pub use ::proxy::*;
pub type V = ::c::Item;
}
mod m8 {
pub use ::proxy::*;
pub const V: ::c::Item = ::c::Item;
}
fn f78() {
check(m7::V{}); //~ ERROR c::Item
check(m7::V); //~ ERROR name of a struct or struct variant
check(m8::V{}); //~ ERROR c::E
check(m8::V); //~ ERROR c::Item
}
fn xf78() {
check(xm7::V{}); //~ ERROR c::Item
check(xm7::V); //~ ERROR name of a struct or struct variant
check(xm8::V{}); //~ ERROR c::E
check(xm8::V); //~ ERROR c::Item
}
mod m9 {
pub use ::proxy::*;
pub type TV = ::c::Item;
}
mod mA {
pub use ::proxy::*;
pub const TV: ::c::Item = ::c::Item;
}
fn f9A() {
check(m9::TV{}); //~ ERROR c::Item
check(m9::TV); //~ ERROR c::E
check(mA::TV{}); //~ ERROR c::E
check(mA::TV); //~ ERROR c::Item
}
fn xf9A() {
check(xm9::TV{}); //~ ERROR c::Item
check(xm9::TV); //~ ERROR c::E
check(xmA::TV{}); //~ ERROR c::E
check(xmA::TV); //~ ERROR c::Item
}
mod mB {
pub use ::proxy::*;
pub type UV = ::c::Item;
}
mod mC {
pub use ::proxy::*;
pub const UV: ::c::Item = ::c::Item;
}
fn fBC() {
check(mB::UV{}); //~ ERROR c::Item
check(mB::UV); //~ ERROR c::E
check(mC::UV{}); //~ ERROR c::E
check(mC::UV); //~ ERROR c::Item
}
fn xfBC() {
check(xmB::UV{}); //~ ERROR c::Item
check(xmB::UV); //~ ERROR c::E
check(xmC::UV{}); //~ ERROR c::E
check(xmC::UV); //~ ERROR c::Item
}
fn main() {}

View File

@ -11,5 +11,5 @@
struct foo(usize);
fn main() {
let (foo, _) = (2, 3); //~ ERROR let bindings cannot shadow structs
let (foo, _) = (2, 3); //~ ERROR let bindings cannot shadow tuple structs
}

View File

@ -20,9 +20,9 @@ fn main() {
}
match S(1, 2, 3) {
S(1, 2, 3, 4) => {}
//~^ ERROR this pattern has 4 fields, but the corresponding struct has 3 fields
//~^ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields
S(1, 2, .., 3, 4) => {}
//~^ ERROR this pattern has 4 fields, but the corresponding struct has 3 fields
//~^ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields
_ => {}
}
}

View File

@ -25,7 +25,7 @@ fn f(_c: char) {}
fn main() {
match A::B(1, 2) {
A::B(_, _, _) => (), //~ ERROR this pattern has 3 fields, but
A::D(_) => (), //~ ERROR `A::D` does not name a tuple variant or a tuple struct
A::D(_) => (), //~ ERROR expected tuple struct/variant, found unit variant `A::D`
_ => ()
}
match 'c' {

View File

@ -28,7 +28,7 @@ impl S {
fn main() {
match 10 {
<S as Tr>::A::f::<u8> => {}
//~^ ERROR `Tr::A::f<u8>` does not name a unit variant, unit struct or a constant
//~^ ERROR expected unit struct/variant or constant, found method `Tr::A::f<u8>`
0 ... <S as Tr>::A::f::<u8> => {} //~ ERROR only char and numeric types are allowed in range
}
}

View File

@ -39,7 +39,7 @@ fn main() {
foo::<static_priv_by_default::m>();
//~^ ERROR: enum `m` is private
foo::<static_priv_by_default::n>();
//~^ ERROR: type `n` is private
//~^ ERROR: type alias `n` is private
// public items in a private mod should be inaccessible
static_priv_by_default::foo::a;