Unreserve braced enum variants in value namespace

This commit is contained in:
Vadim Petrochenkov 2022-10-25 20:15:15 +04:00
parent 1cbc45942d
commit 7a5376d23c
71 changed files with 364 additions and 642 deletions

View file

@ -2664,7 +2664,7 @@ impl VariantData {
} }
/// Return the `NodeId` of this variant's constructor, if it has one. /// Return the `NodeId` of this variant's constructor, if it has one.
pub fn ctor_id(&self) -> Option<NodeId> { pub fn ctor_node_id(&self) -> Option<NodeId> {
match *self { match *self {
VariantData::Struct(..) => None, VariantData::Struct(..) => None,
VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id), VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),

View file

@ -350,7 +350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} else { } else {
def.non_enum_variant() def.non_enum_variant()
}; };
if !including_tuple_field.0 && variant.ctor_kind == CtorKind::Fn { if !including_tuple_field.0 && variant.ctor_kind() == Some(CtorKind::Fn) {
return None; return None;
} }
Some(variant.fields[field.index()].name.to_string()) Some(variant.fields[field.index()].name.to_string())

View file

@ -998,7 +998,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
.iter() .iter()
.enumerate() .enumerate()
.map(|(i, f)| { .map(|(i, f)| {
let field_name = if variant_def.ctor_kind == CtorKind::Fn { let field_name = if variant_def.ctor_kind() == Some(CtorKind::Fn) {
// This is a tuple struct // This is a tuple struct
tuple_field_name(i) tuple_field_name(i)
} else { } else {

View file

@ -269,7 +269,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
|cx, struct_type_di_node| { |cx, struct_type_di_node| {
(0..variant_layout.fields.count()) (0..variant_layout.fields.count())
.map(|field_index| { .map(|field_index| {
let field_name = if variant_def.ctor_kind != CtorKind::Fn { let field_name = if variant_def.ctor_kind() != Some(CtorKind::Fn) {
// Fields have names // Fields have names
Cow::from(variant_def.fields[field_index].name.as_str()) Cow::from(variant_def.fields[field_index].name.as_str())
} else { } else {

View file

@ -28,8 +28,6 @@ pub enum CtorKind {
Fn, Fn,
/// Constructor constant automatically created by a unit struct/variant. /// Constructor constant automatically created by a unit struct/variant.
Const, Const,
/// Unusable name in value namespace created by a struct variant.
Fictive,
} }
/// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`. /// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`.
@ -132,13 +130,9 @@ impl DefKind {
DefKind::Variant => "variant", DefKind::Variant => "variant",
DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant", DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant",
DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant", DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant",
DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive) => "struct variant",
DefKind::Struct => "struct", DefKind::Struct => "struct",
DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => {
panic!("impossible struct constructor")
}
DefKind::OpaqueTy => "opaque type", DefKind::OpaqueTy => "opaque type",
DefKind::ImplTraitPlaceholder => "opaque type in trait", DefKind::ImplTraitPlaceholder => "opaque type in trait",
DefKind::TyAlias => "type alias", DefKind::TyAlias => "type alias",
@ -562,19 +556,11 @@ impl<T> PerNS<Option<T>> {
} }
impl CtorKind { impl CtorKind {
pub fn from_ast(vdata: &ast::VariantData) -> CtorKind { pub fn from_ast(vdata: &ast::VariantData) -> Option<(CtorKind, NodeId)> {
match *vdata { match *vdata {
ast::VariantData::Tuple(..) => CtorKind::Fn, ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)),
ast::VariantData::Unit(..) => CtorKind::Const, ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)),
ast::VariantData::Struct(..) => CtorKind::Fictive, ast::VariantData::Struct(..) => None,
}
}
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,
} }
} }
} }

View file

@ -2913,20 +2913,29 @@ impl<'hir> VariantData<'hir> {
} }
} }
/// Return the `LocalDefId` of this variant's constructor, if it has one. pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> {
pub fn ctor_def_id(&self) -> Option<LocalDefId> {
match *self { match *self {
VariantData::Struct(_, _) => None, VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)),
VariantData::Tuple(_, _, def_id) | VariantData::Unit(_, def_id) => Some(def_id), VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)),
VariantData::Struct(..) => None,
} }
} }
#[inline]
pub fn ctor_kind(&self) -> Option<CtorKind> {
self.ctor().map(|(kind, ..)| kind)
}
/// Return the `HirId` of this variant's constructor, if it has one. /// Return the `HirId` of this variant's constructor, if it has one.
#[inline]
pub fn ctor_hir_id(&self) -> Option<HirId> { pub fn ctor_hir_id(&self) -> Option<HirId> {
match *self { self.ctor().map(|(_, hir_id, _)| hir_id)
VariantData::Struct(_, _) => None, }
VariantData::Tuple(_, hir_id, _) | VariantData::Unit(hir_id, _) => Some(hir_id),
} /// Return the `LocalDefId` of this variant's constructor, if it has one.
#[inline]
pub fn ctor_def_id(&self) -> Option<LocalDefId> {
self.ctor().map(|(.., def_id)| def_id)
} }
} }

View file

@ -1165,7 +1165,7 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) {
} }
if def.repr().int.is_none() { if def.repr().int.is_none() {
let is_unit = |var: &ty::VariantDef| matches!(var.ctor_kind, CtorKind::Const); let is_unit = |var: &ty::VariantDef| matches!(var.ctor_kind(), Some(CtorKind::Const));
let has_disr = |var: &ty::VariantDef| matches!(var.discr, ty::VariantDiscr::Explicit(_)); let has_disr = |var: &ty::VariantDef| matches!(var.discr, ty::VariantDiscr::Explicit(_));
let has_non_units = def.variants().iter().any(|var| !is_unit(var)); let has_non_units = def.variants().iter().any(|var| !is_unit(var));

View file

@ -24,7 +24,6 @@ use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::CtorKind;
use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS; use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
@ -794,7 +793,7 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
// Convert the ctor, if any. This also registers the variant as // Convert the ctor, if any. This also registers the variant as
// an item. // an item.
if let Some(ctor_def_id) = variant.ctor_def_id { if let Some(ctor_def_id) = variant.ctor_def_id() {
convert_variant_ctor(tcx, ctor_def_id.expect_local()); convert_variant_ctor(tcx, ctor_def_id.expect_local());
} }
} }
@ -803,7 +802,6 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) {
fn convert_variant( fn convert_variant(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
variant_did: Option<LocalDefId>, variant_did: Option<LocalDefId>,
ctor_did: Option<LocalDefId>,
ident: Ident, ident: Ident,
discr: ty::VariantDiscr, discr: ty::VariantDiscr,
def: &hir::VariantData<'_>, def: &hir::VariantData<'_>,
@ -840,10 +838,9 @@ fn convert_variant(
ty::VariantDef::new( ty::VariantDef::new(
ident.name, ident.name,
variant_did.map(LocalDefId::to_def_id), variant_did.map(LocalDefId::to_def_id),
ctor_did.map(LocalDefId::to_def_id), def.ctor().map(|(kind, _, def_id)| (kind, def_id.to_def_id())),
discr, discr,
fields, fields,
CtorKind::from_hir(def),
adt_kind, adt_kind,
parent_did.to_def_id(), parent_did.to_def_id(),
recovered, recovered,
@ -882,7 +879,6 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> {
convert_variant( convert_variant(
tcx, tcx,
Some(v.def_id), Some(v.def_id),
v.data.ctor_def_id(),
v.ident, v.ident,
discr, discr,
&v.data, &v.data,
@ -894,35 +890,23 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> {
(AdtKind::Enum, variants) (AdtKind::Enum, variants)
} }
ItemKind::Struct(ref def, _) => { ItemKind::Struct(ref def, _) | ItemKind::Union(ref def, _) => {
let adt_kind = match item.kind {
ItemKind::Struct(..) => AdtKind::Struct,
_ => AdtKind::Union,
};
let variants = std::iter::once(convert_variant( let variants = std::iter::once(convert_variant(
tcx, tcx,
None, None,
def.ctor_def_id(),
item.ident, item.ident,
ty::VariantDiscr::Relative(0), ty::VariantDiscr::Relative(0),
def, def,
AdtKind::Struct, adt_kind,
def_id, def_id,
)) ))
.collect(); .collect();
(AdtKind::Struct, variants) (adt_kind, variants)
}
ItemKind::Union(ref def, _) => {
let variants = std::iter::once(convert_variant(
tcx,
None,
def.ctor_def_id(),
item.ident,
ty::VariantDiscr::Relative(0),
def,
AdtKind::Union,
def_id,
))
.collect();
(AdtKind::Union, variants)
} }
_ => bug!(), _ => bug!(),
}; };
@ -1171,7 +1155,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
compute_sig_of_foreign_fn_decl(tcx, def_id.to_def_id(), fn_decl, abi) compute_sig_of_foreign_fn_decl(tcx, def_id.to_def_id(), fn_decl, abi)
} }
Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor_hir_id().is_some() => { Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)); let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id));
let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id)); let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id));
ty::Binder::dummy(tcx.mk_fn_sig( ty::Binder::dummy(tcx.mk_fn_sig(

View file

@ -72,8 +72,8 @@ pub fn add_constraints_from_crate<'a, 'tcx>(
let adt = tcx.adt_def(def_id); let adt = tcx.adt_def(def_id);
for variant in adt.variants() { for variant in adt.variants() {
if let Some(ctor) = variant.ctor_def_id { if let Some(ctor_def_id) = variant.ctor_def_id() {
constraint_cx.build_constraints_for_item(ctor.expect_local()); constraint_cx.build_constraints_for_item(ctor_def_id.expect_local());
} }
} }
} }

View file

@ -91,8 +91,8 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
let adt = tcx.adt_def(def_id); let adt = tcx.adt_def(def_id);
for variant in adt.variants() { for variant in adt.variants() {
if let Some(ctor) = variant.ctor_def_id { if let Some(ctor_def_id) = variant.ctor_def_id() {
terms_cx.add_inferreds_for_item(ctor.expect_local()); terms_cx.add_inferreds_for_item(ctor_def_id.expect_local());
} }
} }
} }

View file

@ -6,7 +6,7 @@ use crate::type_error_struct;
use rustc_ast::util::parser::PREC_POSTFIX; use rustc_ast::util::parser::PREC_POSTFIX;
use rustc_errors::{struct_span_err, Applicability, Diagnostic, StashKey}; use rustc_errors::{struct_span_err, Applicability, Diagnostic, StashKey};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{self, Namespace, Res}; use rustc_hir::def::{self, CtorKind, Namespace, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_infer::{ use rustc_infer::{
infer, infer,
@ -595,7 +595,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) { ) {
let mut unit_variant = None; let mut unit_variant = None;
if let hir::ExprKind::Path(qpath) = &callee_expr.kind if let hir::ExprKind::Path(qpath) = &callee_expr.kind
&& let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _) && let Res::Def(def::DefKind::Ctor(kind, CtorKind::Const), _)
= self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id) = self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
// Only suggest removing parens if there are no arguments // Only suggest removing parens if there are no arguments
&& arg_exprs.is_empty() && arg_exprs.is_empty()

View file

@ -2,6 +2,7 @@ use crate::FnCtxt;
use rustc_ast::util::parser::PREC_POSTFIX; use rustc_ast::util::parser::PREC_POSTFIX;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::CtorKind;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::{is_range_literal, Node}; use rustc_hir::{is_range_literal, Node};
use rustc_infer::infer::InferOk; use rustc_infer::infer::InferOk;
@ -404,27 +405,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(path) = variant_path.strip_prefix("std::prelude::") if let Some(path) = variant_path.strip_prefix("std::prelude::")
&& let Some((_, path)) = path.split_once("::") && let Some((_, path)) = path.split_once("::")
{ {
return Some((path.to_string(), variant.ctor_kind, sole_field.name, note_about_variant_field_privacy)); return Some((path.to_string(), variant.ctor_kind(), sole_field.name, note_about_variant_field_privacy));
} }
Some((variant_path, variant.ctor_kind, sole_field.name, note_about_variant_field_privacy)) Some((variant_path, variant.ctor_kind(), sole_field.name, note_about_variant_field_privacy))
} else { } else {
None None
} }
}) })
.collect(); .collect();
let suggestions_for = |variant: &_, ctor, field_name| { let suggestions_for = |variant: &_, ctor_kind, field_name| {
let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) {
Some(ident) => format!("{ident}: "), Some(ident) => format!("{ident}: "),
None => String::new(), None => String::new(),
}; };
let (open, close) = match ctor { let (open, close) = match ctor_kind {
hir::def::CtorKind::Fn => ("(".to_owned(), ")"), Some(CtorKind::Fn) => ("(".to_owned(), ")"),
hir::def::CtorKind::Fictive => (format!(" {{ {field_name}: "), " }"), None => (format!(" {{ {field_name}: "), " }"),
// unit variants don't have fields // unit variants don't have fields
hir::def::CtorKind::Const => unreachable!(), Some(CtorKind::Const) => unreachable!(),
}; };
// Suggest constructor as deep into the block tree as possible. // Suggest constructor as deep into the block tree as possible.

View file

@ -533,8 +533,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.set_tainted_by_errors(e); self.set_tainted_by_errors(e);
tcx.ty_error_with_guaranteed(e) tcx.ty_error_with_guaranteed(e)
} }
Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => { Res::Def(DefKind::Variant, _) => {
let e = report_unexpected_variant_res(tcx, res, qpath, expr.span); let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, "E0533", "value");
tcx.ty_error_with_guaranteed(e) tcx.ty_error_with_guaranteed(e)
} }
_ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0, _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0,
@ -2025,8 +2025,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
); );
let variant_ident_span = self.tcx.def_ident_span(variant.def_id).unwrap(); let variant_ident_span = self.tcx.def_ident_span(variant.def_id).unwrap();
match variant.ctor_kind { match variant.ctor_kind() {
CtorKind::Fn => match ty.kind() { Some(CtorKind::Fn) => match ty.kind() {
ty::Adt(adt, ..) if adt.is_enum() => { ty::Adt(adt, ..) if adt.is_enum() => {
err.span_label( err.span_label(
variant_ident_span, variant_ident_span,

View file

@ -1164,11 +1164,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
match *ty.kind() { match *ty.kind() {
ty::Adt(adt_def, substs) if adt_def.has_ctor() => { ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
let variant = adt_def.non_enum_variant(); let variant = adt_def.non_enum_variant();
let ctor_def_id = variant.ctor_def_id.unwrap(); let (ctor_kind, ctor_def_id) = variant.ctor.unwrap();
( (Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id), Some(substs))
Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
Some(substs),
)
} }
_ => { _ => {
let mut err = tcx.sess.struct_span_err( let mut err = tcx.sess.struct_span_err(

View file

@ -53,9 +53,9 @@ use crate::check::check_fn;
use crate::coercion::DynamicCoerceMany; use crate::coercion::DynamicCoerceMany;
use crate::gather_locals::GatherLocalsVisitor; use crate::gather_locals::GatherLocalsVisitor;
use rustc_data_structures::unord::UnordSet; use rustc_data_structures::unord::UnordSet;
use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan}; use rustc_errors::{struct_span_err, DiagnosticId, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::{HirIdMap, Node}; use rustc_hir::{HirIdMap, Node};
use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::astconv::AstConv;
@ -433,15 +433,27 @@ fn report_unexpected_variant_res(
res: Res, res: Res,
qpath: &hir::QPath<'_>, qpath: &hir::QPath<'_>,
span: Span, span: Span,
err_code: &str,
expected: &str,
) -> ErrorGuaranteed { ) -> ErrorGuaranteed {
struct_span_err!( let res_descr = match res {
tcx.sess, Res::Def(DefKind::Variant, _) => "struct variant",
_ => res.descr(),
};
let path_str = rustc_hir_pretty::qpath_to_string(qpath);
let mut err = tcx.sess.struct_span_err_with_code(
span, span,
E0533, format!("expected {expected}, found {res_descr} `{path_str}`"),
"expected unit struct, unit variant or constant, found {} `{}`", DiagnosticId::Error(err_code.into()),
res.descr(), );
rustc_hir_pretty::qpath_to_string(qpath), match res {
) Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == "E0164" => {
let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html";
err.span_label(span, "`fn` calls are not allowed in patterns");
err.help(format!("for more information, visit {patterns_url}"))
}
_ => err.span_label(span, format!("not a {expected}")),
}
.emit() .emit()
} }

View file

@ -566,6 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
// Check if we have an enum variant. // Check if we have an enum variant.
let mut struct_variant = None;
if let ty::Adt(adt_def, _) = self_ty.kind() { if let ty::Adt(adt_def, _) = self_ty.kind() {
if adt_def.is_enum() { if adt_def.is_enum() {
let variant_def = adt_def let variant_def = adt_def
@ -573,16 +574,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.iter() .iter()
.find(|vd| tcx.hygienic_eq(method_name, vd.ident(tcx), adt_def.did())); .find(|vd| tcx.hygienic_eq(method_name, vd.ident(tcx), adt_def.did()));
if let Some(variant_def) = variant_def { if let Some(variant_def) = variant_def {
// Braced variants generate unusable names in value namespace (reserved for if let Some((ctor_kind, ctor_def_id)) = variant_def.ctor {
// possible future use), so variants resolved as associated items may refer to tcx.check_stability(
// them as well. It's ok to use the variant's id as a ctor id since an ctor_def_id,
// error will be reported on any use of such resolution anyway. Some(expr_id),
let ctor_def_id = variant_def.ctor_def_id.unwrap_or(variant_def.def_id); span,
tcx.check_stability(ctor_def_id, Some(expr_id), span, Some(method_name.span)); Some(method_name.span),
return Ok(( );
DefKind::Ctor(CtorOf::Variant, variant_def.ctor_kind), return Ok((DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id));
ctor_def_id, } else {
)); struct_variant = Some((DefKind::Variant, variant_def.def_id));
}
} }
} }
} }
@ -594,7 +596,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self_ty, self_ty,
expr_id, expr_id,
ProbeScope::TraitsInScope, ProbeScope::TraitsInScope,
)?; );
let pick = match (pick, struct_variant) {
// Fall back to a resolution that will produce an error later.
(Err(_), Some(res)) => return Ok(res),
(pick, _) => pick?,
};
pick.maybe_emit_unstable_name_collision_hint(self.tcx, span, expr_id); pick.maybe_emit_unstable_name_collision_hint(self.tcx, span, expr_id);

View file

@ -853,8 +853,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.set_tainted_by_errors(e); self.set_tainted_by_errors(e);
return tcx.ty_error_with_guaranteed(e); return tcx.ty_error_with_guaranteed(e);
} }
Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => { Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Variant, _) => {
let e = report_unexpected_variant_res(tcx, res, qpath, pat.span); let expected = "unit struct, unit variant or constant";
let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0533", expected);
return tcx.ty_error_with_guaranteed(e); return tcx.ty_error_with_guaranteed(e);
} }
Res::SelfCtor(..) Res::SelfCtor(..)
@ -1002,30 +1003,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
}; };
let report_unexpected_res = |res: Res| { let report_unexpected_res = |res: Res| {
let sm = tcx.sess.source_map(); let expected = "tuple struct or tuple variant";
let path_str = sm let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0164", expected);
.span_to_snippet(sm.span_until_char(pat.span, '('))
.map_or_else(|_| String::new(), |s| format!(" `{}`", s.trim_end()));
let msg = format!(
"expected tuple struct or tuple variant, found {}{}",
res.descr(),
path_str
);
let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{msg}");
match res {
Res::Def(DefKind::Fn | DefKind::AssocFn, _) => {
err.span_label(pat.span, "`fn` calls are not allowed in patterns");
err.help(
"for more information, visit \
https://doc.rust-lang.org/book/ch18-00-patterns.html",
);
}
_ => {
err.span_label(pat.span, "not a tuple variant or struct");
}
}
let e = err.emit();
on_error(e); on_error(e);
e e
}; };
@ -1481,8 +1460,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// if this is a tuple struct, then all field names will be numbers // if this is a tuple struct, then all field names will be numbers
// so if any fields in a struct pattern use shorthand syntax, they will // so if any fields in a struct pattern use shorthand syntax, they will
// be invalid identifiers (for example, Foo { 0, 1 }). // be invalid identifiers (for example, Foo { 0, 1 }).
if let (CtorKind::Fn, PatKind::Struct(qpath, field_patterns, ..)) = if let (Some(CtorKind::Fn), PatKind::Struct(qpath, field_patterns, ..)) =
(variant.ctor_kind, &pat.kind) (variant.ctor_kind(), &pat.kind)
{ {
let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand); let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand);
if has_shorthand_field_name { if has_shorthand_field_name {
@ -1659,7 +1638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fields: &'tcx [hir::PatField<'tcx>], fields: &'tcx [hir::PatField<'tcx>],
variant: &ty::VariantDef, variant: &ty::VariantDef,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
if let (CtorKind::Fn, PatKind::Struct(qpath, ..)) = (variant.ctor_kind, &pat.kind) { if let (Some(CtorKind::Fn), PatKind::Struct(qpath, ..)) = (variant.ctor_kind(), &pat.kind) {
let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| { let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| {
s.print_qpath(qpath, false) s.print_qpath(qpath, false)
}); });

View file

@ -65,7 +65,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg};
use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
@ -1967,7 +1967,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
.variants() .variants()
.iter() .iter()
.filter(|variant| { .filter(|variant| {
variant.fields.len() == 1 && variant.ctor_kind == hir::def::CtorKind::Fn variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
}) })
.filter_map(|variant| { .filter_map(|variant| {
let sole_field = &variant.fields[0]; let sole_field = &variant.fields[0];

View file

@ -159,8 +159,8 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
} }
fn visit_variant_data(&mut self, s: &'a ast::VariantData) { fn visit_variant_data(&mut self, s: &'a ast::VariantData) {
if let Some(ctor_hir_id) = s.ctor_id() { if let Some(ctor_node_id) = s.ctor_node_id() {
self.check_id(ctor_hir_id); self.check_id(ctor_node_id);
} }
ast_visit::walk_struct_def(self, s); ast_visit::walk_struct_def(self, s);
} }

View file

@ -11,7 +11,7 @@ use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell};
use rustc_data_structures::unhash::UnhashMap; use rustc_data_structures::unhash::UnhashMap;
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
use rustc_hir::diagnostic_items::DiagnosticItems; use rustc_hir::diagnostic_items::DiagnosticItems;
@ -31,7 +31,7 @@ use rustc_session::cstore::{
use rustc_session::Session; use rustc_session::Session;
use rustc_span::hygiene::{ExpnIndex, MacroKind}; use rustc_span::hygiene::{ExpnIndex, MacroKind};
use rustc_span::source_map::{respan, Spanned}; use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP}; use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
use proc_macro::bridge::client::ProcMacro; use proc_macro::bridge::client::ProcMacro;
@ -866,12 +866,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
let variant_did = let variant_did =
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None }; if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
let ctor_did = data.ctor.map(|index| self.local_def_id(index)); let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
ty::VariantDef::new( ty::VariantDef::new(
self.item_name(index), self.item_name(index),
variant_did, variant_did,
ctor_did, ctor,
data.discr, data.discr,
self.root self.root
.tables .tables
@ -885,7 +885,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
vis: self.get_visibility(index), vis: self.get_visibility(index),
}) })
.collect(), .collect(),
data.ctor_kind,
adt_kind, adt_kind,
parent_did, parent_did,
false, false,
@ -1041,29 +1040,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
}; };
callback(ModChild { ident, res, vis, span, macro_rules }); callback(ModChild { ident, res, vis, span, macro_rules });
// For non-reexport variants add their fictive constructors to children.
// Braced variants, unlike structs, generate unusable names in value namespace,
// they are reserved for possible future use. It's ok to use the variant's id as
// a ctor id since an error will be reported on any use of such resolution anyway.
// Reexport lists automatically contain such constructors when necessary.
if kind == DefKind::Variant && self.get_ctor_def_id_and_kind(child_index).is_none()
{
let ctor_res =
Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive), def_id);
let mut vis = vis;
if vis.is_public() {
// For non-exhaustive variants lower the constructor visibility to
// within the crate. We only need this for fictive constructors,
// for other constructors correct visibilities
// were already encoded in metadata.
let mut attrs = self.get_item_attrs(def_id.index, sess);
if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
vis = ty::Visibility::Restricted(self.local_def_id(CRATE_DEF_INDEX));
}
}
callback(ModChild { ident, res: ctor_res, vis, span, macro_rules: false });
}
} }
} }
@ -1136,11 +1112,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} }
} }
fn get_ctor_def_id_and_kind(self, node_id: DefIndex) -> Option<(DefId, CtorKind)> { fn get_ctor(self, node_id: DefIndex) -> Option<(CtorKind, DefId)> {
match self.def_kind(node_id) { match self.def_kind(node_id) {
DefKind::Struct | DefKind::Variant => { DefKind::Struct | DefKind::Variant => {
let vdata = self.root.tables.variant_data.get(self, node_id).unwrap().decode(self); let vdata = self.root.tables.variant_data.get(self, node_id).unwrap().decode(self);
vdata.ctor.map(|index| (self.local_def_id(index), vdata.ctor_kind)) vdata.ctor.map(|(kind, index)| (kind, self.local_def_id(index)))
} }
_ => None, _ => None,
} }

View file

@ -495,8 +495,8 @@ impl CStore {
self.get_crate_data(def.krate).get_struct_field_visibilities(def.index) self.get_crate_data(def.krate).get_struct_field_visibilities(def.index)
} }
pub fn ctor_def_id_and_kind_untracked(&self, def: DefId) -> Option<(DefId, CtorKind)> { pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> {
self.get_crate_data(def.krate).get_ctor_def_id_and_kind(def.index) self.get_crate_data(def.krate).get_ctor(def.index)
} }
pub fn visibility_untracked(&self, def: DefId) -> Visibility<DefId> { pub fn visibility_untracked(&self, def: DefId) -> Visibility<DefId> {

View file

@ -1221,9 +1221,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
debug!("EncodeContext::encode_enum_variant_info({:?})", def_id); debug!("EncodeContext::encode_enum_variant_info({:?})", def_id);
let data = VariantData { let data = VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
ctor: variant.ctor_def_id.map(|did| did.index), ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}; };
@ -1233,32 +1232,28 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
assert!(f.did.is_local()); assert!(f.did.is_local());
f.did.index f.did.index
})); }));
if variant.ctor_kind == CtorKind::Fn { if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
// FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`. // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
if let Some(ctor_def_id) = variant.ctor_def_id { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id));
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id));
}
} }
} }
fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) { fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
let tcx = self.tcx;
let variant = &def.variant(index); let variant = &def.variant(index);
let def_id = variant.ctor_def_id.unwrap(); let Some((ctor_kind, def_id)) = variant.ctor else { return };
debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id); debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
// FIXME(eddyb) encode only the `CtorKind` for constructors. // FIXME(eddyb) encode only the `CtorKind` for constructors.
let data = VariantData { let data = VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
ctor: Some(def_id.index), ctor: Some((ctor_kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}; };
record!(self.tables.variant_data[def_id] <- data); record!(self.tables.variant_data[def_id] <- data);
self.tables.constness.set(def_id.index, hir::Constness::Const); self.tables.constness.set(def_id.index, hir::Constness::Const);
if variant.ctor_kind == CtorKind::Fn { if ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id));
} }
} }
@ -1313,23 +1308,22 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} }
} }
fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>, def_id: DefId) { fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>) {
debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
let tcx = self.tcx;
let variant = adt_def.non_enum_variant(); let variant = adt_def.non_enum_variant();
let Some((ctor_kind, def_id)) = variant.ctor else { return };
debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
let data = VariantData { let data = VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
ctor: Some(def_id.index), ctor: Some((ctor_kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}; };
record!(self.tables.repr_options[def_id] <- adt_def.repr()); record!(self.tables.repr_options[def_id] <- adt_def.repr());
record!(self.tables.variant_data[def_id] <- data); record!(self.tables.variant_data[def_id] <- data);
self.tables.constness.set(def_id.index, hir::Constness::Const); self.tables.constness.set(def_id.index, hir::Constness::Const);
if variant.ctor_kind == CtorKind::Fn { if ctor_kind == CtorKind::Fn {
record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id));
} }
} }
@ -1550,21 +1544,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let adt_def = self.tcx.adt_def(def_id); let adt_def = self.tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr()); record!(self.tables.repr_options[def_id] <- adt_def.repr());
} }
hir::ItemKind::Struct(ref struct_def, _) => { hir::ItemKind::Struct(..) => {
let adt_def = self.tcx.adt_def(def_id); let adt_def = self.tcx.adt_def(def_id);
record!(self.tables.repr_options[def_id] <- adt_def.repr()); record!(self.tables.repr_options[def_id] <- adt_def.repr());
self.tables.constness.set(def_id.index, hir::Constness::Const); self.tables.constness.set(def_id.index, hir::Constness::Const);
// Encode def_ids for each field and method
// for methods, write all the stuff get_trait_method
// needs to know
let ctor = struct_def.ctor_def_id().map(|ctor_def_id| ctor_def_id.local_def_index);
let variant = adt_def.non_enum_variant(); let variant = adt_def.non_enum_variant();
record!(self.tables.variant_data[def_id] <- VariantData { record!(self.tables.variant_data[def_id] <- VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
ctor, ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}); });
} }
@ -1574,9 +1562,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let variant = adt_def.non_enum_variant(); let variant = adt_def.non_enum_variant();
record!(self.tables.variant_data[def_id] <- VariantData { record!(self.tables.variant_data[def_id] <- VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr, discr: variant.discr,
ctor: None, ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
is_non_exhaustive: variant.is_field_list_non_exhaustive(), is_non_exhaustive: variant.is_field_list_non_exhaustive(),
}); });
} }
@ -1629,7 +1616,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
for variant in tcx.adt_def(def_id).variants() { for variant in tcx.adt_def(def_id).variants() {
yield variant.def_id.index; yield variant.def_id.index;
// Encode constructors which take a separate slot in value namespace. // Encode constructors which take a separate slot in value namespace.
if let Some(ctor_def_id) = variant.ctor_def_id { if let Some(ctor_def_id) = variant.ctor_def_id() {
yield ctor_def_id.index; yield ctor_def_id.index;
} }
} }
@ -1672,20 +1659,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
match item.kind { match item.kind {
hir::ItemKind::Enum(..) => { hir::ItemKind::Enum(..) => {
let def = self.tcx.adt_def(item.owner_id.to_def_id()); let def = self.tcx.adt_def(item.owner_id.to_def_id());
for (i, variant) in def.variants().iter_enumerated() { for (i, _) in def.variants().iter_enumerated() {
self.encode_enum_variant_info(def, i); self.encode_enum_variant_info(def, i);
self.encode_enum_variant_ctor(def, i);
if let Some(_ctor_def_id) = variant.ctor_def_id {
self.encode_enum_variant_ctor(def, i);
}
} }
} }
hir::ItemKind::Struct(ref struct_def, _) => { hir::ItemKind::Struct(..) => {
let def = self.tcx.adt_def(item.owner_id.to_def_id()); let def = self.tcx.adt_def(item.owner_id.to_def_id());
// If the struct has a constructor, encode it. self.encode_struct_ctor(def);
if let Some(ctor_def_id) = struct_def.ctor_def_id() {
self.encode_struct_ctor(def, ctor_def_id.to_def_id());
}
} }
hir::ItemKind::Impl { .. } => { hir::ItemKind::Impl { .. } => {
for &trait_item_def_id in for &trait_item_def_id in

View file

@ -410,10 +410,9 @@ define_tables! {
#[derive(TyEncodable, TyDecodable)] #[derive(TyEncodable, TyDecodable)]
struct VariantData { struct VariantData {
ctor_kind: CtorKind,
discr: ty::VariantDiscr, discr: ty::VariantDiscr,
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id. /// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
ctor: Option<DefIndex>, ctor: Option<(CtorKind, DefIndex)>,
is_non_exhaustive: bool, is_non_exhaustive: bool,
} }

View file

@ -101,10 +101,8 @@ fixed_size_enum! {
( Static(ast::Mutability::Mut) ) ( Static(ast::Mutability::Mut) )
( Ctor(CtorOf::Struct, CtorKind::Fn) ) ( Ctor(CtorOf::Struct, CtorKind::Fn) )
( Ctor(CtorOf::Struct, CtorKind::Const) ) ( Ctor(CtorOf::Struct, CtorKind::Const) )
( Ctor(CtorOf::Struct, CtorKind::Fictive) )
( Ctor(CtorOf::Variant, CtorKind::Fn) ) ( Ctor(CtorOf::Variant, CtorKind::Fn) )
( Ctor(CtorOf::Variant, CtorKind::Const) ) ( Ctor(CtorOf::Variant, CtorKind::Const) )
( Ctor(CtorOf::Variant, CtorKind::Fictive) )
( Macro(MacroKind::Bang) ) ( Macro(MacroKind::Bang) )
( Macro(MacroKind::Attr) ) ( Macro(MacroKind::Attr) )
( Macro(MacroKind::Derive) ) ( Macro(MacroKind::Derive) )

View file

@ -245,15 +245,15 @@ impl<'hir> Map<'hir> {
}, },
Node::Variant(_) => DefKind::Variant, Node::Variant(_) => DefKind::Variant,
Node::Ctor(variant_data) => { Node::Ctor(variant_data) => {
// FIXME(eddyb) is this even possible, if we have a `Node::Ctor`?
assert_ne!(variant_data.ctor_hir_id(), None);
let ctor_of = match self.find(self.get_parent_node(hir_id)) { let ctor_of = match self.find(self.get_parent_node(hir_id)) {
Some(Node::Item(..)) => def::CtorOf::Struct, Some(Node::Item(..)) => def::CtorOf::Struct,
Some(Node::Variant(..)) => def::CtorOf::Variant, Some(Node::Variant(..)) => def::CtorOf::Variant,
_ => unreachable!(), _ => unreachable!(),
}; };
DefKind::Ctor(ctor_of, def::CtorKind::from_hir(variant_data)) match variant_data.ctor_kind() {
Some(kind) => DefKind::Ctor(ctor_of, kind),
None => bug!("constructor node without a constructor"),
}
} }
Node::AnonConst(_) => { Node::AnonConst(_) => {
let inline = match self.find(self.get_parent_node(hir_id)) { let inline = match self.find(self.get_parent_node(hir_id)) {

View file

@ -2115,10 +2115,10 @@ impl<'tcx> Debug for Rvalue<'tcx> {
.print_def_path(variant_def.def_id, substs)? .print_def_path(variant_def.def_id, substs)?
.into_buffer(); .into_buffer();
match variant_def.ctor_kind { match variant_def.ctor_kind() {
CtorKind::Const => fmt.write_str(&name), Some(CtorKind::Const) => fmt.write_str(&name),
CtorKind::Fn => fmt_tuple(fmt, &name), Some(CtorKind::Fn) => fmt_tuple(fmt, &name),
CtorKind::Fictive => { None => {
let mut struct_fmt = fmt.debug_struct(&name); let mut struct_fmt = fmt.debug_struct(&name);
for (field, place) in iter::zip(&variant_def.fields, places) { for (field, place) in iter::zip(&variant_def.fields, places) {
struct_fmt.field(field.name.as_str(), place); struct_fmt.field(field.name.as_str(), place);
@ -2955,14 +2955,14 @@ fn pretty_print_const_value<'tcx>(
let cx = cx.print_value_path(variant_def.def_id, substs)?; let cx = cx.print_value_path(variant_def.def_id, substs)?;
fmt.write_str(&cx.into_buffer())?; fmt.write_str(&cx.into_buffer())?;
match variant_def.ctor_kind { match variant_def.ctor_kind() {
CtorKind::Const => {} Some(CtorKind::Const) => {}
CtorKind::Fn => { Some(CtorKind::Fn) => {
fmt.write_str("(")?; fmt.write_str("(")?;
comma_sep(fmt, fields)?; comma_sep(fmt, fields)?;
fmt.write_str(")")?; fmt.write_str(")")?;
} }
CtorKind::Fictive => { None => {
fmt.write_str(" {{ ")?; fmt.write_str(" {{ ")?;
let mut first = true; let mut first = true;
for (field_def, field) in iter::zip(&variant_def.fields, fields) for (field_def, field) in iter::zip(&variant_def.fields, fields)

View file

@ -10,7 +10,6 @@
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::CtorKind;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::RangeEnd; use rustc_hir::RangeEnd;
use rustc_index::newtype_index; use rustc_index::newtype_index;
@ -751,7 +750,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
// Only for Adt we can have `S {...}`, // Only for Adt we can have `S {...}`,
// which we handle separately here. // which we handle separately here.
if variant.ctor_kind == CtorKind::Fictive { if variant.ctor.is_none() {
write!(f, " {{ ")?; write!(f, " {{ ")?;
let mut printed = 0; let mut printed = 0;

View file

@ -230,7 +230,7 @@ impl AdtDefData {
AdtKind::Struct => AdtFlags::IS_STRUCT, AdtKind::Struct => AdtFlags::IS_STRUCT,
}; };
if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor_def_id.is_some() { if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor.is_some() {
flags |= AdtFlags::HAS_CTOR; flags |= AdtFlags::HAS_CTOR;
} }
@ -386,11 +386,9 @@ impl<'tcx> AdtDef<'tcx> {
// Baz = 3, // Baz = 3,
// } // }
// ``` // ```
if self if self.variants().iter().any(|v| {
.variants() matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind() != Some(CtorKind::Const)
.iter() }) {
.any(|v| matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind != CtorKind::Const)
{
return false; return false;
} }
self.variants().iter().all(|v| v.fields.is_empty()) self.variants().iter().all(|v| v.fields.is_empty())
@ -405,7 +403,7 @@ impl<'tcx> AdtDef<'tcx> {
pub fn variant_with_ctor_id(self, cid: DefId) -> &'tcx VariantDef { pub fn variant_with_ctor_id(self, cid: DefId) -> &'tcx VariantDef {
self.variants() self.variants()
.iter() .iter()
.find(|v| v.ctor_def_id == Some(cid)) .find(|v| v.ctor_def_id() == Some(cid))
.expect("variant_with_ctor_id: unknown variant") .expect("variant_with_ctor_id: unknown variant")
} }
@ -422,7 +420,7 @@ impl<'tcx> AdtDef<'tcx> {
pub fn variant_index_with_ctor_id(self, cid: DefId) -> VariantIdx { pub fn variant_index_with_ctor_id(self, cid: DefId) -> VariantIdx {
self.variants() self.variants()
.iter_enumerated() .iter_enumerated()
.find(|(_, v)| v.ctor_def_id == Some(cid)) .find(|(_, v)| v.ctor_def_id() == Some(cid))
.expect("variant_index_with_ctor_id: unknown variant") .expect("variant_index_with_ctor_id: unknown variant")
.0 .0
} }

View file

@ -1808,15 +1808,13 @@ pub struct VariantDef {
pub def_id: DefId, pub def_id: DefId,
/// `DefId` that identifies the variant's constructor. /// `DefId` that identifies the variant's constructor.
/// If this variant is a struct variant, then this is `None`. /// If this variant is a struct variant, then this is `None`.
pub ctor_def_id: Option<DefId>, pub ctor: Option<(CtorKind, DefId)>,
/// Variant or struct name. /// Variant or struct name.
pub name: Symbol, pub name: Symbol,
/// Discriminant of this variant. /// Discriminant of this variant.
pub discr: VariantDiscr, pub discr: VariantDiscr,
/// Fields of this variant. /// Fields of this variant.
pub fields: Vec<FieldDef>, pub fields: Vec<FieldDef>,
/// Type of constructor of variant.
pub ctor_kind: CtorKind,
/// Flags of the variant (e.g. is field list non-exhaustive)? /// Flags of the variant (e.g. is field list non-exhaustive)?
flags: VariantFlags, flags: VariantFlags,
} }
@ -1841,19 +1839,18 @@ impl VariantDef {
pub fn new( pub fn new(
name: Symbol, name: Symbol,
variant_did: Option<DefId>, variant_did: Option<DefId>,
ctor_def_id: Option<DefId>, ctor: Option<(CtorKind, DefId)>,
discr: VariantDiscr, discr: VariantDiscr,
fields: Vec<FieldDef>, fields: Vec<FieldDef>,
ctor_kind: CtorKind,
adt_kind: AdtKind, adt_kind: AdtKind,
parent_did: DefId, parent_did: DefId,
recovered: bool, recovered: bool,
is_field_list_non_exhaustive: bool, is_field_list_non_exhaustive: bool,
) -> Self { ) -> Self {
debug!( debug!(
"VariantDef::new(name = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?}, "VariantDef::new(name = {:?}, variant_did = {:?}, ctor = {:?}, discr = {:?},
fields = {:?}, ctor_kind = {:?}, adt_kind = {:?}, parent_did = {:?})", fields = {:?}, adt_kind = {:?}, parent_did = {:?})",
name, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did, name, variant_did, ctor, discr, fields, adt_kind, parent_did,
); );
let mut flags = VariantFlags::NO_VARIANT_FLAGS; let mut flags = VariantFlags::NO_VARIANT_FLAGS;
@ -1865,15 +1862,7 @@ impl VariantDef {
flags |= VariantFlags::IS_RECOVERED; flags |= VariantFlags::IS_RECOVERED;
} }
VariantDef { VariantDef { def_id: variant_did.unwrap_or(parent_did), ctor, name, discr, fields, flags }
def_id: variant_did.unwrap_or(parent_did),
ctor_def_id,
name,
discr,
fields,
ctor_kind,
flags,
}
} }
/// Is this field list non-exhaustive? /// Is this field list non-exhaustive?
@ -1892,6 +1881,16 @@ impl VariantDef {
pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident { pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident {
Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap()) Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
} }
#[inline]
pub fn ctor_kind(&self) -> Option<CtorKind> {
self.ctor.map(|(kind, _)| kind)
}
#[inline]
pub fn ctor_def_id(&self) -> Option<DefId> {
self.ctor.map(|(_, def_id)| def_id)
}
} }
impl PartialEq for VariantDef { impl PartialEq for VariantDef {
@ -1904,26 +1903,8 @@ impl PartialEq for VariantDef {
// definition of `VariantDef` changes, a compile-error will be produced, // definition of `VariantDef` changes, a compile-error will be produced,
// reminding us to revisit this assumption. // reminding us to revisit this assumption.
let Self { let Self { def_id: lhs_def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = &self;
def_id: lhs_def_id, let Self { def_id: rhs_def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = other;
ctor_def_id: _,
name: _,
discr: _,
fields: _,
ctor_kind: _,
flags: _,
} = &self;
let Self {
def_id: rhs_def_id,
ctor_def_id: _,
name: _,
discr: _,
fields: _,
ctor_kind: _,
flags: _,
} = other;
lhs_def_id == rhs_def_id lhs_def_id == rhs_def_id
} }
} }
@ -1940,9 +1921,7 @@ impl Hash for VariantDef {
// of `VariantDef` changes, a compile-error will be produced, reminding // of `VariantDef` changes, a compile-error will be produced, reminding
// us to revisit this assumption. // us to revisit this assumption.
let Self { def_id, ctor_def_id: _, name: _, discr: _, fields: _, ctor_kind: _, flags: _ } = let Self { def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = &self;
&self;
def_id.hash(s) def_id.hash(s)
} }
} }

View file

@ -1487,12 +1487,12 @@ pub trait PrettyPrinter<'tcx>:
contents.variant.expect("destructed const of adt without variant idx"); contents.variant.expect("destructed const of adt without variant idx");
let variant_def = &def.variant(variant_idx); let variant_def = &def.variant(variant_idx);
p!(print_value_path(variant_def.def_id, substs)); p!(print_value_path(variant_def.def_id, substs));
match variant_def.ctor_kind { match variant_def.ctor_kind() {
CtorKind::Const => {} Some(CtorKind::Const) => {}
CtorKind::Fn => { Some(CtorKind::Fn) => {
p!("(", comma_sep(fields), ")"); p!("(", comma_sep(fields), ")");
} }
CtorKind::Fictive => { None => {
p!(" {{ "); p!(" {{ ");
let mut first = true; let mut first = true;
for (field_def, field) in iter::zip(&variant_def.fields, fields) { for (field_def, field) in iter::zip(&variant_def.fields, fields) {

View file

@ -564,7 +564,7 @@ fn check_for_bindings_named_same_as_variants(
&& let ty::Adt(edef, _) = pat_ty.kind() && let ty::Adt(edef, _) = pat_ty.kind()
&& edef.is_enum() && edef.is_enum()
&& edef.variants().iter().any(|variant| { && edef.variants().iter().any(|variant| {
variant.ident(cx.tcx) == ident && variant.ctor_kind == CtorKind::Const variant.ident(cx.tcx) == ident && variant.ctor_kind() == Some(CtorKind::Const)
}) })
{ {
let variant_count = edef.variants().len(); let variant_count = edef.variants().len();

View file

@ -747,7 +747,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
// If this is a tuple or unit struct, define a name // If this is a tuple or unit struct, define a name
// in the value namespace as well. // in the value namespace as well.
if let Some(ctor_node_id) = vdata.ctor_id() { if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(vdata) {
// If the structure is marked as non_exhaustive then lower the visibility // If the structure is marked as non_exhaustive then lower the visibility
// to within the crate. // to within the crate.
let mut ctor_vis = if vis.is_public() let mut ctor_vis = if vis.is_public()
@ -773,10 +773,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
ret_fields.push(field_vis.to_def_id()); ret_fields.push(field_vis.to_def_id());
} }
let ctor_def_id = self.r.local_def_id(ctor_node_id); let ctor_def_id = self.r.local_def_id(ctor_node_id);
let ctor_res = Res::Def( let ctor_res =
DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(vdata)), Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id.to_def_id());
ctor_def_id.to_def_id(),
);
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
self.r.visibilities.insert(ctor_def_id, ctor_vis); self.r.visibilities.insert(ctor_def_id, ctor_vis);
@ -999,8 +997,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
Res::Def(DefKind::Struct, def_id) => { Res::Def(DefKind::Struct, def_id) => {
let field_names = let field_names =
cstore.struct_field_names_untracked(def_id, self.r.session).collect(); cstore.struct_field_names_untracked(def_id, self.r.session).collect();
let ctor = cstore.ctor_def_id_and_kind_untracked(def_id); if let Some((ctor_kind, ctor_def_id)) = cstore.ctor_untracked(def_id) {
if let Some((ctor_def_id, ctor_kind)) = ctor {
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
let ctor_vis = cstore.visibility_untracked(ctor_def_id); let ctor_vis = cstore.visibility_untracked(ctor_def_id);
let field_visibilities = let field_visibilities =
@ -1517,20 +1514,20 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> {
}; };
// Define a constructor name in the value namespace. // Define a constructor name in the value namespace.
// Braced variants, unlike structs, generate unusable names in let fields_id = if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&variant.data) {
// value namespace, they are reserved for possible future use. let ctor_def_id = self.r.local_def_id(ctor_node_id);
// It's ok to use the variant's id as a ctor id since an let ctor_res =
// error will be reported on any use of such resolution anyway. Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id.to_def_id());
let ctor_node_id = variant.data.ctor_id().unwrap_or(variant.id); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
let ctor_def_id = self.r.local_def_id(ctor_node_id);
let ctor_kind = CtorKind::from_ast(&variant.data);
let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id.to_def_id());
self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
if ctor_def_id != def_id {
self.r.visibilities.insert(ctor_def_id, ctor_vis); self.r.visibilities.insert(ctor_def_id, ctor_vis);
} ctor_def_id
} else {
def_id
};
// Record field names for error reporting. // Record field names for error reporting.
self.insert_field_names_local(ctor_def_id.to_def_id(), &variant.data); // FIXME: Always use non-ctor id as the key.
self.insert_field_names_local(fields_id.to_def_id(), &variant.data);
visit::walk_variant(self, variant); visit::walk_variant(self, variant);
} }

View file

@ -118,8 +118,8 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
match i.kind { match i.kind {
ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => { ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
// If this is a unit or tuple-like struct, register the constructor. // If this is a unit or tuple-like struct, register the constructor.
if let Some(ctor_hir_id) = struct_def.ctor_id() { if let Some(ctor_node_id) = struct_def.ctor_node_id() {
this.create_def(ctor_hir_id, DefPathData::Ctor, i.span); this.create_def(ctor_node_id, DefPathData::Ctor, i.span);
} }
} }
_ => {} _ => {}
@ -196,8 +196,8 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> {
} }
let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span); let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span);
self.with_parent(def, |this| { self.with_parent(def, |this| {
if let Some(ctor_hir_id) = v.data.ctor_id() { if let Some(ctor_node_id) = v.data.ctor_node_id() {
this.create_def(ctor_hir_id, DefPathData::Ctor, v.span); this.create_def(ctor_node_id, DefPathData::Ctor, v.span);
} }
visit::walk_variant(this, v) visit::walk_variant(this, v)
}); });

View file

@ -1442,13 +1442,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
err.span_label(span, "constructor is not visible here due to private fields"); err.span_label(span, "constructor is not visible here due to private fields");
} }
( (Res::Def(DefKind::Union | DefKind::Variant, def_id), _) if ns == ValueNS => {
Res::Def(
DefKind::Union | DefKind::Variant | DefKind::Ctor(_, CtorKind::Fictive),
def_id,
),
_,
) if ns == ValueNS => {
bad_struct_syntax_suggestion(def_id); bad_struct_syntax_suggestion(def_id);
} }
(Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id), _) if ns == ValueNS => { (Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id), _) if ns == ValueNS => {
@ -1963,7 +1957,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
let has_no_fields = self.r.field_names.get(&def_id).map_or(false, |f| f.is_empty()); let has_no_fields = self.r.field_names.get(&def_id).map_or(false, |f| f.is_empty());
match kind { match kind {
CtorKind::Const => false, CtorKind::Const => false,
CtorKind::Fn | CtorKind::Fictive if has_no_fields => false, CtorKind::Fn if has_no_fields => false,
_ => true, _ => true,
} }
}; };
@ -1975,7 +1969,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
.map(|(variant, kind)| match kind { .map(|(variant, kind)| match kind {
CtorKind::Const => variant, CtorKind::Const => variant,
CtorKind::Fn => format!("({}())", variant), CtorKind::Fn => format!("({}())", variant),
CtorKind::Fictive => format!("({} {{}})", variant),
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let no_suggestable_variant = suggestable_variants.is_empty(); let no_suggestable_variant = suggestable_variants.is_empty();
@ -2001,7 +1994,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
.map(|(variant, _, kind)| (path_names_to_string(variant), kind)) .map(|(variant, _, kind)| (path_names_to_string(variant), kind))
.filter_map(|(variant, kind)| match kind { .filter_map(|(variant, kind)| match kind {
CtorKind::Fn => Some(format!("({}(/* fields */))", variant)), CtorKind::Fn => Some(format!("({}(/* fields */))", variant)),
CtorKind::Fictive => Some(format!("({} {{ /* fields */ }})", variant)),
_ => None, _ => None,
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();

View file

@ -689,15 +689,15 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
self.push("V"); self.push("V");
self = self.print_def_path(variant_def.def_id, substs)?; self = self.print_def_path(variant_def.def_id, substs)?;
match variant_def.ctor_kind { match variant_def.ctor_kind() {
CtorKind::Const => { Some(CtorKind::Const) => {
self.push("U"); self.push("U");
} }
CtorKind::Fn => { Some(CtorKind::Fn) => {
self.push("T"); self.push("T");
self = print_field_list(self)?; self = print_field_list(self)?;
} }
CtorKind::Fictive => { None => {
self.push("S"); self.push("S");
for (field_def, field) in iter::zip(&variant_def.fields, fields) { for (field_def, field) in iter::zip(&variant_def.fields, fields) {
// HACK(eddyb) this mimics `path_append`, // HACK(eddyb) this mimics `path_append`,

View file

@ -276,7 +276,7 @@ fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct {
let variant = cx.tcx.adt_def(did).non_enum_variant(); let variant = cx.tcx.adt_def(did).non_enum_variant();
clean::Struct { clean::Struct {
struct_type: variant.ctor_kind, ctor_kind: variant.ctor_kind(),
generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates),
fields: variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(), fields: variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(),
} }

View file

@ -1842,16 +1842,16 @@ pub(crate) fn clean_field_with_def_id(
} }
pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item { pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item {
let kind = match variant.ctor_kind { let kind = match variant.ctor_kind() {
CtorKind::Const => Variant::CLike(match variant.discr { Some(CtorKind::Const) => Variant::CLike(match variant.discr {
ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }), ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }),
ty::VariantDiscr::Relative(_) => None, ty::VariantDiscr::Relative(_) => None,
}), }),
CtorKind::Fn => Variant::Tuple( Some(CtorKind::Fn) => Variant::Tuple(
variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
), ),
CtorKind::Fictive => Variant::Struct(VariantStruct { None => Variant::Struct(VariantStruct {
struct_type: CtorKind::Fictive, ctor_kind: None,
fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
}), }),
}; };
@ -1865,7 +1865,7 @@ fn clean_variant_data<'tcx>(
) -> Variant { ) -> Variant {
match variant { match variant {
hir::VariantData::Struct(..) => Variant::Struct(VariantStruct { hir::VariantData::Struct(..) => Variant::Struct(VariantStruct {
struct_type: CtorKind::from_hir(variant), ctor_kind: None,
fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(), fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(),
}), }),
hir::VariantData::Tuple(..) => { hir::VariantData::Tuple(..) => {
@ -2060,7 +2060,7 @@ fn clean_maybe_renamed_item<'tcx>(
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}), }),
ItemKind::Struct(ref variant_data, generics) => StructItem(Struct { ItemKind::Struct(ref variant_data, generics) => StructItem(Struct {
struct_type: CtorKind::from_hir(variant_data), ctor_kind: variant_data.ctor_kind(),
generics: clean_generics(generics, cx), generics: clean_generics(generics, cx),
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}), }),

View file

@ -2081,7 +2081,7 @@ impl From<hir::PrimTy> for PrimitiveType {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct Struct { pub(crate) struct Struct {
pub(crate) struct_type: CtorKind, pub(crate) ctor_kind: Option<CtorKind>,
pub(crate) generics: Generics, pub(crate) generics: Generics,
pub(crate) fields: Vec<Item>, pub(crate) fields: Vec<Item>,
} }
@ -2109,7 +2109,7 @@ impl Union {
/// only as a variant in an enum. /// only as a variant in an enum.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct VariantStruct { pub(crate) struct VariantStruct {
pub(crate) struct_type: CtorKind, pub(crate) ctor_kind: Option<CtorKind>,
pub(crate) fields: Vec<Item>, pub(crate) fields: Vec<Item>,
} }

View file

@ -2280,12 +2280,12 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
let fields = get_struct_fields_name(&s.fields); let fields = get_struct_fields_name(&s.fields);
if !fields.is_empty() { if !fields.is_empty() {
match s.struct_type { match s.ctor_kind {
CtorKind::Fictive => { None => {
print_sidebar_block(&mut sidebar, "fields", "Fields", fields.iter()); print_sidebar_block(&mut sidebar, "fields", "Fields", fields.iter());
} }
CtorKind::Fn => print_sidebar_title(&mut sidebar, "fields", "Tuple Fields"), Some(CtorKind::Fn) => print_sidebar_title(&mut sidebar, "fields", "Tuple Fields"),
CtorKind::Const => {} Some(CtorKind::Const) => {}
} }
} }

View file

@ -1232,7 +1232,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
w, w,
v, v,
None, None,
s.struct_type, s.ctor_kind,
&s.fields, &s.fields,
" ", " ",
false, false,
@ -1458,7 +1458,7 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
wrap_into_item_decl(w, |w| { wrap_into_item_decl(w, |w| {
wrap_item(w, "struct", |w| { wrap_item(w, "struct", |w| {
render_attributes_in_code(w, it); render_attributes_in_code(w, it);
render_struct(w, it, Some(&s.generics), s.struct_type, &s.fields, "", true, cx); render_struct(w, it, Some(&s.generics), s.ctor_kind, &s.fields, "", true, cx);
}); });
}); });
@ -1472,14 +1472,14 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
_ => None, _ => None,
}) })
.peekable(); .peekable();
if let CtorKind::Fictive | CtorKind::Fn = s.struct_type { if let None | Some(CtorKind::Fn) = s.ctor_kind {
if fields.peek().is_some() { if fields.peek().is_some() {
write!( write!(
w, w,
"<h2 id=\"fields\" class=\"fields small-section-header\">\ "<h2 id=\"fields\" class=\"fields small-section-header\">\
{}{}<a href=\"#fields\" class=\"anchor\"></a>\ {}{}<a href=\"#fields\" class=\"anchor\"></a>\
</h2>", </h2>",
if let CtorKind::Fictive = s.struct_type { "Fields" } else { "Tuple Fields" }, if s.ctor_kind.is_none() { "Fields" } else { "Tuple Fields" },
document_non_exhaustive_header(it) document_non_exhaustive_header(it)
); );
document_non_exhaustive(w, it); document_non_exhaustive(w, it);
@ -1739,7 +1739,7 @@ fn render_struct(
w: &mut Buffer, w: &mut Buffer,
it: &clean::Item, it: &clean::Item,
g: Option<&clean::Generics>, g: Option<&clean::Generics>,
ty: CtorKind, ty: Option<CtorKind>,
fields: &[clean::Item], fields: &[clean::Item],
tab: &str, tab: &str,
structhead: bool, structhead: bool,
@ -1757,7 +1757,7 @@ fn render_struct(
write!(w, "{}", g.print(cx)) write!(w, "{}", g.print(cx))
} }
match ty { match ty {
CtorKind::Fictive => { None => {
let where_diplayed = g.map(|g| print_where_clause_and_check(w, g, cx)).unwrap_or(false); let where_diplayed = g.map(|g| print_where_clause_and_check(w, g, cx)).unwrap_or(false);
// If there wasn't a `where` clause, we add a whitespace. // If there wasn't a `where` clause, we add a whitespace.
@ -1799,7 +1799,7 @@ fn render_struct(
} }
w.write_str("}"); w.write_str("}");
} }
CtorKind::Fn => { Some(CtorKind::Fn) => {
w.write_str("("); w.write_str("(");
for (i, field) in fields.iter().enumerate() { for (i, field) in fields.iter().enumerate() {
if i > 0 { if i > 0 {
@ -1827,7 +1827,7 @@ fn render_struct(
w.write_str(";"); w.write_str(";");
} }
} }
CtorKind::Const => { Some(CtorKind::Const) => {
// Needed for PhantomData. // Needed for PhantomData.
if let Some(g) = g { if let Some(g) = g {
write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline)); write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline));

View file

@ -315,15 +315,15 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
impl FromWithTcx<clean::Struct> for Struct { impl FromWithTcx<clean::Struct> for Struct {
fn from_tcx(struct_: clean::Struct, tcx: TyCtxt<'_>) -> Self { fn from_tcx(struct_: clean::Struct, tcx: TyCtxt<'_>) -> Self {
let fields_stripped = struct_.has_stripped_entries(); let fields_stripped = struct_.has_stripped_entries();
let clean::Struct { struct_type, generics, fields } = struct_; let clean::Struct { ctor_kind, generics, fields } = struct_;
let kind = match struct_type { let kind = match ctor_kind {
CtorKind::Fn => StructKind::Tuple(ids_keeping_stripped(fields, tcx)), Some(CtorKind::Fn) => StructKind::Tuple(ids_keeping_stripped(fields, tcx)),
CtorKind::Const => { Some(CtorKind::Const) => {
assert!(fields.is_empty()); assert!(fields.is_empty());
StructKind::Unit StructKind::Unit
} }
CtorKind::Fictive => StructKind::Plain { fields: ids(fields, tcx), fields_stripped }, None => StructKind::Plain { fields: ids(fields, tcx), fields_stripped },
}; };
Struct { Struct {

View file

@ -17,7 +17,7 @@ fn main() {
//~^ ERROR expected function, tuple struct or tuple variant, found struct `Empty1` //~^ ERROR expected function, tuple struct or tuple variant, found struct `Empty1`
let e3 = E::Empty3; //~ ERROR expected value, found struct variant `E::Empty3` let e3 = E::Empty3; //~ ERROR expected value, found struct variant `E::Empty3`
let e3 = E::Empty3(); let e3 = E::Empty3();
//~^ ERROR expected function, tuple struct or tuple variant, found struct variant `E::Empty3` //~^ ERROR expected value, found struct variant `E::Empty3`
let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1` let xe1 = XEmpty1; //~ ERROR expected value, found struct `XEmpty1`
let xe1 = XEmpty1(); let xe1 = XEmpty1();

View file

@ -21,24 +21,6 @@ help: a unit struct with a similar name exists
LL | let e1 = XEmpty2; LL | let e1 = XEmpty2;
| ~~~~~~~ | ~~~~~~~
error[E0423]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:18:14
|
LL | Empty3 {}
| --------- `E::Empty3` defined here
...
LL | let e3 = E::Empty3;
| ^^^^^^^^^ help: use struct literal syntax instead: `E::Empty3 {}`
error[E0423]: expected function, tuple struct or tuple variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:19:14
|
LL | Empty3 {}
| --------- `E::Empty3` defined here
...
LL | let e3 = E::Empty3();
| ^^^^^^^^^^^ help: use struct literal syntax instead: `E::Empty3 {}`
error[E0423]: expected value, found struct `XEmpty1` error[E0423]: expected value, found struct `XEmpty1`
--> $DIR/empty-struct-braces-expr.rs:22:15 --> $DIR/empty-struct-braces-expr.rs:22:15
| |
@ -84,6 +66,18 @@ help: a unit struct with a similar name exists
LL | let e1 = XEmpty2(); LL | let e1 = XEmpty2();
| ~~~~~~~ | ~~~~~~~
error[E0533]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:18:14
|
LL | let e3 = E::Empty3;
| ^^^^^^^^^ not a value
error[E0533]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:19:14
|
LL | let e3 = E::Empty3();
| ^^^^^^^^^ not a value
error[E0423]: expected function, tuple struct or tuple variant, found struct `XEmpty1` error[E0423]: expected function, tuple struct or tuple variant, found struct `XEmpty1`
--> $DIR/empty-struct-braces-expr.rs:23:15 --> $DIR/empty-struct-braces-expr.rs:23:15
| |
@ -132,5 +126,5 @@ LL | XE::Empty1 {};
error: aborting due to 9 previous errors error: aborting due to 9 previous errors
Some errors have detailed explanations: E0423, E0599. Some errors have detailed explanations: E0423, E0533, E0599.
For more information about an error, try `rustc --explain E0423`. For more information about an error, try `rustc --explain E0423`.

View file

@ -1,34 +1,15 @@
error[E0532]: expected unit struct, unit variant or constant, found struct variant `E::Empty3` error[E0533]: expected unit struct, unit variant or constant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-1.rs:24:9 --> $DIR/empty-struct-braces-pat-1.rs:24:9
| |
LL | Empty3 {}
| --------- `E::Empty3` defined here
...
LL | E::Empty3 => () LL | E::Empty3 => ()
| ^^^^^^^^^ help: use struct pattern syntax instead: `E::Empty3 {}` | ^^^^^^^^^ not a unit struct, unit variant or constant
error[E0532]: expected unit struct, unit variant or constant, found struct variant `XE::XEmpty3` error[E0533]: expected unit struct, unit variant or constant, found struct variant `XE::XEmpty3`
--> $DIR/empty-struct-braces-pat-1.rs:31:9 --> $DIR/empty-struct-braces-pat-1.rs:31:9
| |
LL | XE::XEmpty3 => () LL | XE::XEmpty3 => ()
| ^^^^^^^^^^^ | ^^^^^^^^^^^ not a unit struct, unit variant or constant
|
::: $DIR/auxiliary/empty-struct.rs:6:5
|
LL | XEmpty3 {},
| ------- `XE::XEmpty3` defined here
LL | XEmpty4,
| ------- similarly named unit variant `XEmpty4` defined here
|
help: use struct pattern syntax instead
|
LL | XE::XEmpty3 { /* fields */ } => ()
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: a unit variant with a similar name exists
|
LL | XE::XEmpty4 => ()
| ~~~~~~~
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0532`. For more information about this error, try `rustc --explain E0533`.

View file

@ -1,67 +1,27 @@
error[E0532]: expected tuple struct or tuple variant, found struct variant `E::Empty3` error[E0164]: expected tuple struct or tuple variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-3.rs:17:9 --> $DIR/empty-struct-braces-pat-3.rs:17:9
| |
LL | Empty3 {}
| --------- `E::Empty3` defined here
...
LL | E::Empty3() => () LL | E::Empty3() => ()
| ^^^^^^^^^^^ help: use struct pattern syntax instead: `E::Empty3 {}` | ^^^^^^^^^^^ not a tuple struct or tuple variant
error[E0532]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3` error[E0164]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3`
--> $DIR/empty-struct-braces-pat-3.rs:21:9 --> $DIR/empty-struct-braces-pat-3.rs:21:9
| |
LL | XE::XEmpty3() => () LL | XE::XEmpty3() => ()
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^ not a tuple struct or tuple variant
|
::: $DIR/auxiliary/empty-struct.rs:6:5
|
LL | XEmpty3 {},
| ------- `XE::XEmpty3` defined here
LL | XEmpty4,
LL | XEmpty5(),
| ------- similarly named tuple variant `XEmpty5` defined here
|
help: use struct pattern syntax instead
|
LL | XE::XEmpty3 { /* fields */ } => ()
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: a tuple variant with a similar name exists
|
LL | XE::XEmpty5() => ()
| ~~~~~~~
error[E0532]: expected tuple struct or tuple variant, found struct variant `E::Empty3` error[E0164]: expected tuple struct or tuple variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-3.rs:25:9 --> $DIR/empty-struct-braces-pat-3.rs:25:9
| |
LL | Empty3 {}
| --------- `E::Empty3` defined here
...
LL | E::Empty3(..) => () LL | E::Empty3(..) => ()
| ^^^^^^^^^^^^^ help: use struct pattern syntax instead: `E::Empty3 {}` | ^^^^^^^^^^^^^ not a tuple struct or tuple variant
error[E0532]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3` error[E0164]: expected tuple struct or tuple variant, found struct variant `XE::XEmpty3`
--> $DIR/empty-struct-braces-pat-3.rs:29:9 --> $DIR/empty-struct-braces-pat-3.rs:29:9
| |
LL | XE::XEmpty3(..) => () LL | XE::XEmpty3(..) => ()
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
|
::: $DIR/auxiliary/empty-struct.rs:6:5
|
LL | XEmpty3 {},
| ------- `XE::XEmpty3` defined here
LL | XEmpty4,
LL | XEmpty5(),
| ------- similarly named tuple variant `XEmpty5` defined here
|
help: use struct pattern syntax instead
|
LL | XE::XEmpty3 { /* fields */ } => ()
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: a tuple variant with a similar name exists
|
LL | XE::XEmpty5(..) => ()
| ~~~~~~~
error: aborting due to 4 previous errors error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0532`. For more information about this error, try `rustc --explain E0164`.

View file

@ -2,7 +2,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated constant
--> $DIR/E0164.rs:9:9 --> $DIR/E0164.rs:9:9
| |
LL | Foo::B(i) => i, LL | Foo::B(i) => i,
| ^^^^^^^^^ not a tuple variant or struct | ^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to previous error error: aborting due to previous error

View file

@ -8,6 +8,6 @@ fn main() {
let f = FooB { x: 3, y: 4 }; let f = FooB { x: 3, y: 4 };
match f { match f {
FooB(a, b) => println!("{} {}", a, b), FooB(a, b) => println!("{} {}", a, b),
//~^ ERROR expected tuple struct or tuple variant, found struct variant `FooB` //~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
} }
} }

View file

@ -1,4 +1,4 @@
error[E0532]: expected tuple struct or tuple variant, found struct variant `FooB` error[E0532]: expected tuple struct or tuple variant, found variant `FooB`
--> $DIR/issue-19086.rs:10:9 --> $DIR/issue-19086.rs:10:9
| |
LL | FooB { x: i32, y: i32 } LL | FooB { x: i32, y: i32 }

View file

@ -8,7 +8,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated constant
--> $DIR/issue-28992-empty.rs:14:12 --> $DIR/issue-28992-empty.rs:14:12
| |
LL | if let S::C2(..) = 0 {} LL | if let S::C2(..) = 0 {}
| ^^^^^^^^^ not a tuple variant or struct | ^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -8,7 +8,7 @@ error[E0164]: expected tuple struct or tuple variant, found self constructor `Se
--> $DIR/issue-56835.rs:4:12 --> $DIR/issue-56835.rs:4:12
| |
LL | fn bar(Self(foo): Self) {} LL | fn bar(Self(foo): Self) {}
| ^^^^^^^^^ not a tuple variant or struct | ^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View file

@ -7,15 +7,13 @@ LL | Tuple(i32),
LL | MyEnum::Tuple => "", LL | MyEnum::Tuple => "",
| ^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `MyEnum::Tuple(_)` | ^^^^^^^^^^^^^ help: use the tuple variant pattern syntax instead: `MyEnum::Tuple(_)`
error[E0532]: expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct` error[E0533]: expected unit struct, unit variant or constant, found struct variant `MyEnum::Struct`
--> $DIR/issue-63983.rs:10:9 --> $DIR/issue-63983.rs:10:9
| |
LL | Struct{ s: i32 },
| ---------------- `MyEnum::Struct` defined here
...
LL | MyEnum::Struct => "", LL | MyEnum::Struct => "",
| ^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `MyEnum::Struct { s }` | ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0532`. Some errors have detailed explanations: E0532, E0533.
For more information about an error, try `rustc --explain E0532`.

View file

@ -2,37 +2,37 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f
--> $DIR/method-path-in-pattern.rs:15:9 --> $DIR/method-path-in-pattern.rs:15:9
| |
LL | Foo::bar => {} LL | Foo::bar => {}
| ^^^^^^^^ | ^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar` error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar`
--> $DIR/method-path-in-pattern.rs:19:9 --> $DIR/method-path-in-pattern.rs:19:9
| |
LL | <Foo>::bar => {} LL | <Foo>::bar => {}
| ^^^^^^^^^^ | ^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::trait_bar` error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::trait_bar`
--> $DIR/method-path-in-pattern.rs:23:9 --> $DIR/method-path-in-pattern.rs:23:9
| |
LL | <Foo>::trait_bar => {} LL | <Foo>::trait_bar => {}
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar` error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar`
--> $DIR/method-path-in-pattern.rs:26:12 --> $DIR/method-path-in-pattern.rs:26:12
| |
LL | if let Foo::bar = 0u32 {} LL | if let Foo::bar = 0u32 {}
| ^^^^^^^^ | ^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar` error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar`
--> $DIR/method-path-in-pattern.rs:28:12 --> $DIR/method-path-in-pattern.rs:28:12
| |
LL | if let <Foo>::bar = 0u32 {} LL | if let <Foo>::bar = 0u32 {}
| ^^^^^^^^^^ | ^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::trait_bar` error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::trait_bar`
--> $DIR/method-path-in-pattern.rs:30:12 --> $DIR/method-path-in-pattern.rs:30:12
| |
LL | if let Foo::trait_bar = 0u32 {} LL | if let Foo::trait_bar = 0u32 {}
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -97,13 +97,13 @@ mod m8 {
fn f78() { fn f78() {
check(m7::V{}); //~ ERROR c::Item check(m7::V{}); //~ ERROR c::Item
check(m7::V); //~ ERROR expected value, found struct variant `m7::V` check(m7::V); //~ ERROR expected value, found type alias `m7::V`
check(m8::V{}); //~ ERROR c::E check(m8::V{}); //~ ERROR c::E
check(m8::V); //~ ERROR c::Item check(m8::V); //~ ERROR c::Item
} }
fn xf78() { fn xf78() {
check(xm7::V{}); //~ ERROR c::Item check(xm7::V{}); //~ ERROR c::Item
check(xm7::V); //~ ERROR expected value, found struct variant `xm7::V` check(xm7::V); //~ ERROR expected value, found type alias `xm7::V`
check(xm8::V{}); //~ ERROR c::E check(xm8::V{}); //~ ERROR c::E
check(xm8::V); //~ ERROR c::Item check(xm8::V); //~ ERROR c::Item
} }

View file

@ -52,21 +52,16 @@ LL - check(xm1::S);
LL + check(S); LL + check(S);
| |
error[E0423]: expected value, found struct variant `m7::V` error[E0423]: expected value, found type alias `m7::V`
--> $DIR/namespace-mix.rs:100:11 --> $DIR/namespace-mix.rs:100:11
| |
LL | V {},
| ---- `m7::V` defined here
LL | TV(), LL | TV(),
| ---- similarly named tuple variant `TV` defined here | ---- similarly named tuple variant `TV` defined here
... ...
LL | check(m7::V); LL | check(m7::V);
| ^^^^^ | ^^^^^
| |
help: use struct literal syntax instead = note: can't use a type alias as a constructor
|
LL | check(m7::V {});
| ~~~~~~~~
help: a tuple variant with a similar name exists help: a tuple variant with a similar name exists
| |
LL | check(m7::TV); LL | check(m7::TV);
@ -83,23 +78,18 @@ LL - check(m7::V);
LL + check(V); LL + check(V);
| |
error[E0423]: expected value, found struct variant `xm7::V` error[E0423]: expected value, found type alias `xm7::V`
--> $DIR/namespace-mix.rs:106:11 --> $DIR/namespace-mix.rs:106:11
| |
LL | check(xm7::V); LL | check(xm7::V);
| ^^^^^^ | ^^^^^^
| |
::: $DIR/auxiliary/namespace-mix.rs:6:9 ::: $DIR/auxiliary/namespace-mix.rs:7:9
| |
LL | V {},
| - `xm7::V` defined here
LL | TV(), LL | TV(),
| -- similarly named tuple variant `TV` defined here | -- similarly named tuple variant `TV` defined here
| |
help: use struct literal syntax instead = note: can't use a type alias as a constructor
|
LL | check(xm7::V { /* fields */ });
| ~~~~~~~~~~~~~~~~~~~~~~~
help: a tuple variant with a similar name exists help: a tuple variant with a similar name exists
| |
LL | check(xm7::TV); LL | check(xm7::TV);

View file

@ -14,14 +14,11 @@ LL - let x = Enum::Foo(a: 3, b: 4);
LL + let x = Enum::Foo(3, 4); LL + let x = Enum::Foo(3, 4);
| |
error[E0532]: expected tuple struct or tuple variant, found struct variant `Enum::Foo` error[E0164]: expected tuple struct or tuple variant, found struct variant `Enum::Foo`
--> $DIR/recover-from-bad-variant.rs:10:9 --> $DIR/recover-from-bad-variant.rs:10:9
| |
LL | Foo { a: usize, b: usize },
| -------------------------- `Enum::Foo` defined here
...
LL | Enum::Foo(a, b) => {} LL | Enum::Foo(a, b) => {}
| ^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `Enum::Foo { a, b }` | ^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
error[E0769]: tuple variant `Enum::Bar` written as struct variant error[E0769]: tuple variant `Enum::Bar` written as struct variant
--> $DIR/recover-from-bad-variant.rs:12:9 --> $DIR/recover-from-bad-variant.rs:12:9
@ -36,5 +33,5 @@ LL | Enum::Bar(a, b) => {}
error: aborting due to 3 previous errors error: aborting due to 3 previous errors
Some errors have detailed explanations: E0532, E0769. Some errors have detailed explanations: E0164, E0769.
For more information about an error, try `rustc --explain E0532`. For more information about an error, try `rustc --explain E0164`.

View file

@ -42,16 +42,11 @@ help: surround the struct literal with parentheses
LL | if x == (E::K { field: "" }) {} LL | if x == (E::K { field: "" }) {}
| + + | + +
error[E0423]: expected value, found struct variant `E::V` error[E0533]: expected value, found struct variant `E::V`
--> $DIR/struct-literal-variant-in-if.rs:10:13 --> $DIR/struct-literal-variant-in-if.rs:10:13
| |
LL | if x == E::V { field } {} LL | if x == E::V { field } {}
| ^^^^ not a value | ^^^^ not a value
|
help: surround the struct literal with parentheses
|
LL | if x == (E::V { field }) {}
| + +
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/struct-literal-variant-in-if.rs:10:20 --> $DIR/struct-literal-variant-in-if.rs:10:20
@ -72,5 +67,5 @@ LL | let y: usize = ();
error: aborting due to 7 previous errors error: aborting due to 7 previous errors
Some errors have detailed explanations: E0308, E0423. Some errors have detailed explanations: E0308, E0533.
For more information about an error, try `rustc --explain E0308`. For more information about an error, try `rustc --explain E0308`.

View file

@ -33,7 +33,7 @@ fn main() {
TupleVariant => {} //~ ERROR match bindings cannot shadow tuple variants TupleVariant => {} //~ ERROR match bindings cannot shadow tuple variants
} }
match doesnt_matter { match doesnt_matter {
BracedVariant => {} //~ ERROR match bindings cannot shadow struct variants BracedVariant => {} // OK, `BracedVariant` is a fresh binding
} }
match CONST { match CONST {
CONST => {} // OK, `CONST` is a const pattern CONST => {} // OK, `CONST` is a const pattern
@ -50,7 +50,7 @@ fn main() {
let BracedStruct = doesnt_matter; // OK, `BracedStruct` is a fresh binding let BracedStruct = doesnt_matter; // OK, `BracedStruct` is a fresh binding
let UnitVariant = UnitVariant; // OK, `UnitVariant` is a unit variant pattern let UnitVariant = UnitVariant; // OK, `UnitVariant` is a unit variant pattern
let TupleVariant = doesnt_matter; //~ ERROR let bindings cannot shadow tuple variants let TupleVariant = doesnt_matter; //~ ERROR let bindings cannot shadow tuple variants
let BracedVariant = doesnt_matter; //~ ERROR let bindings cannot shadow struct variants let BracedVariant = doesnt_matter; // OK, `BracedVariant` is a fresh binding
let CONST = CONST; // OK, `CONST` is a const pattern let CONST = CONST; // OK, `CONST` is a const pattern
let STATIC = doesnt_matter; //~ ERROR let bindings cannot shadow statics let STATIC = doesnt_matter; //~ ERROR let bindings cannot shadow statics
let function = doesnt_matter; // OK, `function` is a fresh binding let function = doesnt_matter; // OK, `function` is a fresh binding

View file

@ -22,15 +22,6 @@ LL | TupleVariant => {}
| cannot be named the same as a tuple variant | cannot be named the same as a tuple variant
| help: try specify the pattern arguments: `TupleVariant(..)` | help: try specify the pattern arguments: `TupleVariant(..)`
error[E0530]: match bindings cannot shadow struct variants
--> $DIR/pattern-binding-disambiguation.rs:36:9
|
LL | use E::*;
| ---- the struct variant `BracedVariant` is imported here
...
LL | BracedVariant => {}
| ^^^^^^^^^^^^^ cannot be named the same as a struct variant
error[E0530]: match bindings cannot shadow statics error[E0530]: match bindings cannot shadow statics
--> $DIR/pattern-binding-disambiguation.rs:42:9 --> $DIR/pattern-binding-disambiguation.rs:42:9
| |
@ -58,15 +49,6 @@ LL | use E::*;
LL | let TupleVariant = doesnt_matter; LL | let TupleVariant = doesnt_matter;
| ^^^^^^^^^^^^ cannot be named the same as a tuple variant | ^^^^^^^^^^^^ cannot be named the same as a tuple variant
error[E0530]: let bindings cannot shadow struct variants
--> $DIR/pattern-binding-disambiguation.rs:53:9
|
LL | use E::*;
| ---- the struct variant `BracedVariant` is imported here
...
LL | let BracedVariant = doesnt_matter;
| ^^^^^^^^^^^^^ cannot be named the same as a struct variant
error[E0530]: let bindings cannot shadow statics error[E0530]: let bindings cannot shadow statics
--> $DIR/pattern-binding-disambiguation.rs:55:9 --> $DIR/pattern-binding-disambiguation.rs:55:9
| |
@ -76,6 +58,6 @@ LL | static STATIC: () = ();
LL | let STATIC = doesnt_matter; LL | let STATIC = doesnt_matter;
| ^^^^^^ cannot be named the same as a static | ^^^^^^ cannot be named the same as a static
error: aborting due to 8 previous errors error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0530`. For more information about this error, try `rustc --explain E0530`.

View file

@ -2,7 +2,7 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f
--> $DIR/qualified-path-params.rs:20:9 --> $DIR/qualified-path-params.rs:20:9
| |
LL | <S as Tr>::A::f::<u8> => {} LL | <S as Tr>::A::f::<u8> => {}
| ^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0029]: only `char` and numeric types are allowed in range patterns error[E0029]: only `char` and numeric types are allowed in range patterns
--> $DIR/qualified-path-params.rs:22:15 --> $DIR/qualified-path-params.rs:22:15

View file

@ -4,5 +4,5 @@ enum Foo {
fn main() { fn main() {
let f = Foo::Variant(42); let f = Foo::Variant(42);
//~^ ERROR expected function, tuple struct or tuple variant, found struct variant `Foo::Variant` //~^ ERROR expected value, found struct variant `Foo::Variant`
} }

View file

@ -1,12 +1,9 @@
error[E0423]: expected function, tuple struct or tuple variant, found struct variant `Foo::Variant` error[E0533]: expected value, found struct variant `Foo::Variant`
--> $DIR/issue-18252.rs:6:13 --> $DIR/issue-18252.rs:6:13
| |
LL | Variant { x: usize }
| -------------------- `Foo::Variant` defined here
...
LL | let f = Foo::Variant(42); LL | let f = Foo::Variant(42);
| ^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `Foo::Variant { x: val }` | ^^^^^^^^^^^^ not a value
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0423`. For more information about this error, try `rustc --explain E0533`.

View file

@ -1,23 +1,15 @@
error[E0423]: expected value, found struct variant `Homura::Madoka` error[E0533]: expected value, found struct variant `Homura::Madoka`
--> $DIR/issue-19452.rs:10:18 --> $DIR/issue-19452.rs:10:18
| |
LL | Madoka { age: u32 }
| ------------------- `Homura::Madoka` defined here
...
LL | let homura = Homura::Madoka; LL | let homura = Homura::Madoka;
| ^^^^^^^^^^^^^^ help: use struct literal syntax instead: `Homura::Madoka { age: val }` | ^^^^^^^^^^^^^^ not a value
error[E0423]: expected value, found struct variant `issue_19452_aux::Homura::Madoka` error[E0533]: expected value, found struct variant `issue_19452_aux::Homura::Madoka`
--> $DIR/issue-19452.rs:13:18 --> $DIR/issue-19452.rs:13:18
| |
LL | let homura = issue_19452_aux::Homura::Madoka; LL | let homura = issue_19452_aux::Homura::Madoka;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `issue_19452_aux::Homura::Madoka { /* fields */ }` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a value
|
::: $DIR/auxiliary/issue-19452-aux.rs:2:5
|
LL | Madoka { age: u32 }
| ------ `issue_19452_aux::Homura::Madoka` defined here
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0423`. For more information about this error, try `rustc --explain E0533`.

View file

@ -17,16 +17,12 @@ LL | | }
| |_^ | |_^
help: you might have meant to use one of the following enum variants help: you might have meant to use one of the following enum variants
| |
LL | (A::Struct {}).foo();
| ~~~~~~~~~~~~~~
LL | (A::Tuple()).foo(); LL | (A::Tuple()).foo();
| ~~~~~~~~~~~~ | ~~~~~~~~~~~~
LL | A::Unit.foo(); LL | A::Unit.foo();
| ~~~~~~~ | ~~~~~~~
help: alternatively, the following enum variants are also available help: alternatively, the following enum variant is available
| |
LL | (A::StructWithFields { /* fields */ }).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | (A::TupleWithFields(/* fields */)).foo(); LL | (A::TupleWithFields(/* fields */)).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -34,7 +30,7 @@ error[E0423]: expected value, found enum `B`
--> $DIR/issue-73427.rs:35:5 --> $DIR/issue-73427.rs:35:5
| |
LL | B.foo(); LL | B.foo();
| ^ | ^ help: the following enum variant is available: `(B::TupleWithFields(/* fields */))`
| |
note: the enum is defined here note: the enum is defined here
--> $DIR/issue-73427.rs:9:1 --> $DIR/issue-73427.rs:9:1
@ -44,12 +40,6 @@ LL | | StructWithFields { x: () },
LL | | TupleWithFields(()), LL | | TupleWithFields(()),
LL | | } LL | | }
| |_^ | |_^
help: the following enum variants are available
|
LL | (B::StructWithFields { /* fields */ }).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | (B::TupleWithFields(/* fields */)).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected value, found enum `C` error[E0423]: expected value, found enum `C`
--> $DIR/issue-73427.rs:37:5 --> $DIR/issue-73427.rs:37:5
@ -70,10 +60,8 @@ help: you might have meant to use the following enum variant
| |
LL | C::Unit.foo(); LL | C::Unit.foo();
| ~~~~~~~ | ~~~~~~~
help: alternatively, the following enum variants are also available help: alternatively, the following enum variant is available
| |
LL | (C::StructWithFields { /* fields */ }).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LL | (C::TupleWithFields(/* fields */)).foo(); LL | (C::TupleWithFields(/* fields */)).foo();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -130,7 +118,7 @@ error[E0532]: expected tuple struct or tuple variant, found enum `A`
LL | if let A(3) = x { } LL | if let A(3) = x { }
| ^ | ^
| |
= help: you might have meant to match against one of the enum's non-tuple variants = help: you might have meant to match against the enum's non-tuple variant
note: the enum is defined here note: the enum is defined here
--> $DIR/issue-73427.rs:1:1 --> $DIR/issue-73427.rs:1:1
| |
@ -155,7 +143,7 @@ error[E0423]: expected function, tuple struct or tuple variant, found enum `A`
LL | let x = A(3); LL | let x = A(3);
| ^ | ^
| |
= help: you might have meant to construct one of the enum's non-tuple variants = help: you might have meant to construct the enum's non-tuple variant
note: the enum is defined here note: the enum is defined here
--> $DIR/issue-73427.rs:1:1 --> $DIR/issue-73427.rs:1:1
| |

View file

@ -19,12 +19,10 @@ help: you might have meant to use the following enum variant
| |
LL | m::Z::Unit; LL | m::Z::Unit;
| ~~~~~~~~~~ | ~~~~~~~~~~
help: alternatively, the following enum variants are also available help: alternatively, the following enum variant is available
| |
LL | (m::Z::Fn(/* fields */)); LL | (m::Z::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~
LL | (m::Z::Struct { /* fields */ });
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected value, found enum `Z` error[E0423]: expected value, found enum `Z`
--> $DIR/privacy-enum-ctor.rs:25:9 --> $DIR/privacy-enum-ctor.rs:25:9
@ -47,23 +45,10 @@ help: you might have meant to use the following enum variant
| |
LL | m::Z::Unit; LL | m::Z::Unit;
| ~~~~~~~~~~ | ~~~~~~~~~~
help: alternatively, the following enum variants are also available help: alternatively, the following enum variant is available
| |
LL | (m::Z::Fn(/* fields */)); LL | (m::Z::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~
LL | (m::Z::Struct { /* fields */ });
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0423]: expected value, found struct variant `Z::Struct`
--> $DIR/privacy-enum-ctor.rs:29:20
|
LL | / Struct {
LL | | s: u8,
LL | | },
| |_____________- `Z::Struct` defined here
...
LL | let _: Z = Z::Struct;
| ^^^^^^^^^ help: use struct literal syntax instead: `Z::Struct { s: val }`
error[E0423]: expected value, found enum `m::E` error[E0423]: expected value, found enum `m::E`
--> $DIR/privacy-enum-ctor.rs:41:16 --> $DIR/privacy-enum-ctor.rs:41:16
@ -89,12 +74,10 @@ help: you might have meant to use the following enum variant
| |
LL | let _: E = E::Unit; LL | let _: E = E::Unit;
| ~~~~~~~ | ~~~~~~~
help: alternatively, the following enum variants are also available help: alternatively, the following enum variant is available
| |
LL | let _: E = (E::Fn(/* fields */)); LL | let _: E = (E::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~
LL | let _: E = (E::Struct { /* fields */ });
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: a function with a similar name exists help: a function with a similar name exists
| |
LL | let _: E = m::f; LL | let _: E = m::f;
@ -111,17 +94,6 @@ LL - let _: E = m::E;
LL + let _: E = E; LL + let _: E = E;
| |
error[E0423]: expected value, found struct variant `m::E::Struct`
--> $DIR/privacy-enum-ctor.rs:45:16
|
LL | / Struct {
LL | | s: u8,
LL | | },
| |_________- `m::E::Struct` defined here
...
LL | let _: E = m::E::Struct;
| ^^^^^^^^^^^^ help: use struct literal syntax instead: `m::E::Struct { s: val }`
error[E0423]: expected value, found enum `E` error[E0423]: expected value, found enum `E`
--> $DIR/privacy-enum-ctor.rs:49:16 --> $DIR/privacy-enum-ctor.rs:49:16
| |
@ -143,12 +115,10 @@ help: you might have meant to use the following enum variant
| |
LL | let _: E = E::Unit; LL | let _: E = E::Unit;
| ~~~~~~~ | ~~~~~~~
help: alternatively, the following enum variants are also available help: alternatively, the following enum variant is available
| |
LL | let _: E = (E::Fn(/* fields */)); LL | let _: E = (E::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~
LL | let _: E = (E::Struct { /* fields */ });
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: consider importing one of these items instead help: consider importing one of these items instead
| |
LL | use std::f32::consts::E; LL | use std::f32::consts::E;
@ -156,17 +126,6 @@ LL | use std::f32::consts::E;
LL | use std::f64::consts::E; LL | use std::f64::consts::E;
| |
error[E0423]: expected value, found struct variant `E::Struct`
--> $DIR/privacy-enum-ctor.rs:53:16
|
LL | / Struct {
LL | | s: u8,
LL | | },
| |_________- `E::Struct` defined here
...
LL | let _: E = E::Struct;
| ^^^^^^^^^ help: use struct literal syntax instead: `E::Struct { s: val }`
error[E0412]: cannot find type `Z` in this scope error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:57:12 --> $DIR/privacy-enum-ctor.rs:57:12
| |
@ -203,12 +162,10 @@ help: you might have meant to use the following enum variant
| |
LL | let _: Z = m::Z::Unit; LL | let _: Z = m::Z::Unit;
| ~~~~~~~~~~ | ~~~~~~~~~~
help: alternatively, the following enum variants are also available help: alternatively, the following enum variant is available
| |
LL | let _: Z = (m::Z::Fn(/* fields */)); LL | let _: Z = (m::Z::Fn(/* fields */));
| ~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~
LL | let _: Z = (m::Z::Struct { /* fields */ });
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error[E0412]: cannot find type `Z` in this scope error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:61:12 --> $DIR/privacy-enum-ctor.rs:61:12
@ -240,17 +197,6 @@ note: enum `m::Z` exists but is inaccessible
LL | pub(in m) enum Z { LL | pub(in m) enum Z {
| ^^^^^^^^^^^^^^^^ not accessible | ^^^^^^^^^^^^^^^^ not accessible
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
--> $DIR/privacy-enum-ctor.rs:64:16
|
LL | / Struct {
LL | | s: u8,
LL | | },
| |_____________- `m::n::Z::Struct` defined here
...
LL | let _: Z = m::n::Z::Struct;
| ^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `m::n::Z::Struct { s: val }`
error[E0412]: cannot find type `Z` in this scope error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:68:12 --> $DIR/privacy-enum-ctor.rs:68:12
| |
@ -332,6 +278,12 @@ help: use parentheses to construct this tuple variant
LL | let _: Z = Z::Fn(/* u8 */); LL | let _: Z = Z::Fn(/* u8 */);
| ++++++++++ | ++++++++++
error[E0533]: expected value, found struct variant `Z::Struct`
--> $DIR/privacy-enum-ctor.rs:29:20
|
LL | let _: Z = Z::Struct;
| ^^^^^^^^^ not a value
error[E0618]: expected function, found enum variant `Z::Unit` error[E0618]: expected function, found enum variant `Z::Unit`
--> $DIR/privacy-enum-ctor.rs:31:17 --> $DIR/privacy-enum-ctor.rs:31:17
| |
@ -367,6 +319,12 @@ help: use parentheses to construct this tuple variant
LL | let _: E = m::E::Fn(/* u8 */); LL | let _: E = m::E::Fn(/* u8 */);
| ++++++++++ | ++++++++++
error[E0533]: expected value, found struct variant `m::E::Struct`
--> $DIR/privacy-enum-ctor.rs:45:16
|
LL | let _: E = m::E::Struct;
| ^^^^^^^^^^^^ not a value
error[E0618]: expected function, found enum variant `m::E::Unit` error[E0618]: expected function, found enum variant `m::E::Unit`
--> $DIR/privacy-enum-ctor.rs:47:16 --> $DIR/privacy-enum-ctor.rs:47:16
| |
@ -402,6 +360,12 @@ help: use parentheses to construct this tuple variant
LL | let _: E = E::Fn(/* u8 */); LL | let _: E = E::Fn(/* u8 */);
| ++++++++++ | ++++++++++
error[E0533]: expected value, found struct variant `E::Struct`
--> $DIR/privacy-enum-ctor.rs:53:16
|
LL | let _: E = E::Struct;
| ^^^^^^^^^ not a value
error[E0618]: expected function, found enum variant `E::Unit` error[E0618]: expected function, found enum variant `E::Unit`
--> $DIR/privacy-enum-ctor.rs:55:16 --> $DIR/privacy-enum-ctor.rs:55:16
| |
@ -419,7 +383,13 @@ LL - let _: E = E::Unit();
LL + let _: E = E::Unit; LL + let _: E = E::Unit;
| |
error[E0533]: expected value, found struct variant `m::n::Z::Struct`
--> $DIR/privacy-enum-ctor.rs:64:16
|
LL | let _: Z = m::n::Z::Struct;
| ^^^^^^^^^^^^^^^ not a value
error: aborting due to 23 previous errors error: aborting due to 23 previous errors
Some errors have detailed explanations: E0308, E0412, E0423, E0603, E0618. Some errors have detailed explanations: E0308, E0412, E0423, E0533, E0603, E0618.
For more information about an error, try `rustc --explain E0308`. For more information about an error, try `rustc --explain E0308`.

View file

@ -1,23 +1,3 @@
error[E0423]: expected value, found struct variant `E::B`
--> $DIR/fn-or-tuple-struct-without-args.rs:36:16
|
LL | A(usize),
| -------- similarly named tuple variant `A` defined here
LL | B { a: usize },
| -------------- `E::B` defined here
...
LL | let _: E = E::B;
| ^^^^
|
help: use struct literal syntax instead
|
LL | let _: E = E::B { a: val };
| ~~~~~~~~~~~~~~~
help: a tuple variant with a similar name exists
|
LL | let _: E = E::A;
| ~
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:29:20 --> $DIR/fn-or-tuple-struct-without-args.rs:29:20
| |
@ -144,6 +124,12 @@ help: use parentheses to construct this tuple variant
LL | let _: E = E::A(/* usize */); LL | let _: E = E::A(/* usize */);
| +++++++++++++ | +++++++++++++
error[E0533]: expected value, found struct variant `E::B`
--> $DIR/fn-or-tuple-struct-without-args.rs:36:16
|
LL | let _: E = E::B;
| ^^^^ not a value
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/fn-or-tuple-struct-without-args.rs:37:20 --> $DIR/fn-or-tuple-struct-without-args.rs:37:20
| |
@ -293,5 +279,5 @@ LL | let _: usize = closure();
error: aborting due to 17 previous errors error: aborting due to 17 previous errors
Some errors have detailed explanations: E0308, E0423, E0615. Some errors have detailed explanations: E0308, E0533, E0615.
For more information about an error, try `rustc --explain E0308`. For more information about an error, try `rustc --explain E0308`.

View file

@ -7,15 +7,13 @@ LL | Cow,
LL | FarmAnimal::Cow(_) => "moo".to_string(), LL | FarmAnimal::Cow(_) => "moo".to_string(),
| ^^^^^^^^^^^^^^^^^^ help: use this syntax instead: `FarmAnimal::Cow` | ^^^^^^^^^^^^^^^^^^ help: use this syntax instead: `FarmAnimal::Cow`
error[E0532]: expected tuple struct or tuple variant, found struct variant `FarmAnimal::Chicken` error[E0164]: expected tuple struct or tuple variant, found struct variant `FarmAnimal::Chicken`
--> $DIR/issue-84700.rs:17:9 --> $DIR/issue-84700.rs:17:9
| |
LL | Chicken { num_eggs: usize },
| --------------------------- `FarmAnimal::Chicken` defined here
...
LL | FarmAnimal::Chicken(_) => "cluck, cluck!".to_string(), LL | FarmAnimal::Chicken(_) => "cluck, cluck!".to_string(),
| ^^^^^^^^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `FarmAnimal::Chicken { num_eggs }` | ^^^^^^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0532`. Some errors have detailed explanations: E0164, E0532.
For more information about an error, try `rustc --explain E0164`.

View file

@ -2,7 +2,7 @@ error[E0533]: expected unit struct, unit variant or constant, found tuple varian
--> $DIR/incorrect-variant-form-through-Self-issue-58006.rs:8:13 --> $DIR/incorrect-variant-form-through-Self-issue-58006.rs:8:13
| |
LL | Self::A => (), LL | Self::A => (),
| ^^^^^^^ | ^^^^^^^ not a unit struct, unit variant or constant
error: aborting due to previous error error: aborting due to previous error

View file

@ -6,7 +6,7 @@ type Alias = Enum;
fn main() { fn main() {
Alias::Braced; Alias::Braced;
//~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533] //~^ ERROR expected value, found struct variant `Alias::Braced` [E0533]
let Alias::Braced = panic!(); let Alias::Braced = panic!();
//~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533] //~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533]
let Alias::Braced(..) = panic!(); let Alias::Braced(..) = panic!();

View file

@ -1,20 +1,20 @@
error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced` error[E0533]: expected value, found struct variant `Alias::Braced`
--> $DIR/incorrect-variant-form-through-alias-caught.rs:8:5 --> $DIR/incorrect-variant-form-through-alias-caught.rs:8:5
| |
LL | Alias::Braced; LL | Alias::Braced;
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^ not a value
error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced` error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced`
--> $DIR/incorrect-variant-form-through-alias-caught.rs:10:9 --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:9
| |
LL | let Alias::Braced = panic!(); LL | let Alias::Braced = panic!();
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^ not a unit struct, unit variant or constant
error[E0164]: expected tuple struct or tuple variant, found struct variant `Alias::Braced` error[E0164]: expected tuple struct or tuple variant, found struct variant `Alias::Braced`
--> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9 --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9
| |
LL | let Alias::Braced(..) = panic!(); LL | let Alias::Braced(..) = panic!();
| ^^^^^^^^^^^^^^^^^ not a tuple variant or struct | ^^^^^^^^^^^^^^^^^ not a tuple struct or tuple variant
error[E0618]: expected function, found enum variant `Alias::Unit` error[E0618]: expected function, found enum variant `Alias::Unit`
--> $DIR/incorrect-variant-form-through-alias-caught.rs:15:5 --> $DIR/incorrect-variant-form-through-alias-caught.rs:15:5
@ -37,7 +37,7 @@ error[E0164]: expected tuple struct or tuple variant, found unit variant `Alias:
--> $DIR/incorrect-variant-form-through-alias-caught.rs:17:9 --> $DIR/incorrect-variant-form-through-alias-caught.rs:17:9
| |
LL | let Alias::Unit() = panic!(); LL | let Alias::Unit() = panic!();
| ^^^^^^^^^^^^^ not a tuple variant or struct | ^^^^^^^^^^^^^ not a tuple struct or tuple variant
error: aborting due to 5 previous errors error: aborting due to 5 previous errors

View file

@ -65,14 +65,14 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
_ => return, _ => return,
}; };
if arm.guard.is_none() { if arm.guard.is_none() {
missing_variants.retain(|e| e.ctor_def_id != Some(id)); missing_variants.retain(|e| e.ctor_def_id() != Some(id));
} }
path path
}, },
PatKind::TupleStruct(path, patterns, ..) => { PatKind::TupleStruct(path, patterns, ..) => {
if let Some(id) = cx.qpath_res(path, pat.hir_id).opt_def_id() { if let Some(id) = cx.qpath_res(path, pat.hir_id).opt_def_id() {
if arm.guard.is_none() && patterns.iter().all(|p| !is_refutable(cx, p)) { if arm.guard.is_none() && patterns.iter().all(|p| !is_refutable(cx, p)) {
missing_variants.retain(|e| e.ctor_def_id != Some(id)); missing_variants.retain(|e| e.ctor_def_id() != Some(id));
} }
} }
path path
@ -122,11 +122,11 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
s s
}, },
variant.name, variant.name,
match variant.ctor_kind { match variant.ctor_kind() {
CtorKind::Fn if variant.fields.len() == 1 => "(_)", Some(CtorKind::Fn) if variant.fields.len() == 1 => "(_)",
CtorKind::Fn => "(..)", Some(CtorKind::Fn) => "(..)",
CtorKind::Const => "", Some(CtorKind::Const) => "",
CtorKind::Fictive => "{ .. }", None => "{ .. }",
} }
) )
}; };

View file

@ -133,11 +133,11 @@ impl UnnecessaryDefPath {
let has_ctor = match cx.tcx.def_kind(def_id) { let has_ctor = match cx.tcx.def_kind(def_id) {
DefKind::Struct => { DefKind::Struct => {
let variant = cx.tcx.adt_def(def_id).non_enum_variant(); let variant = cx.tcx.adt_def(def_id).non_enum_variant();
variant.ctor_def_id.is_some() && variant.fields.iter().all(|f| f.vis.is_public()) variant.ctor.is_some() && variant.fields.iter().all(|f| f.vis.is_public())
}, },
DefKind::Variant => { DefKind::Variant => {
let variant = cx.tcx.adt_def(cx.tcx.parent(def_id)).variant_with_id(def_id); let variant = cx.tcx.adt_def(cx.tcx.parent(def_id)).variant_with_id(def_id);
variant.ctor_def_id.is_some() && variant.fields.iter().all(|f| f.vis.is_public()) variant.ctor.is_some() && variant.fields.iter().all(|f| f.vis.is_public())
}, },
_ => false, _ => false,
}; };