diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index fa745a8e08b95..54bd25d647130 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2675,7 +2675,7 @@ impl VariantData { } /// Return the `NodeId` of this variant's constructor, if it has one. - pub fn ctor_id(&self) -> Option { + pub fn ctor_node_id(&self) -> Option { match *self { VariantData::Struct(..) => None, VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id), diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 7f26af67c71b2..4c3216d98783b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -350,7 +350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else { 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; } Some(variant.fields[field.index()].name.to_string()) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 163ccd9460c54..d87117dffdc60 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -998,7 +998,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( .iter() .enumerate() .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 tuple_field_name(i) } else { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index cb558a50d9148..564ab351bd41f 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -269,7 +269,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( |cx, struct_type_di_node| { (0..variant_layout.fields.count()) .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 Cow::from(variant_def.fields[field_index].name.as_str()) } else { diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 4ef4aad902c68..149cf4ece37d1 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -28,8 +28,6 @@ pub enum CtorKind { Fn, /// Constructor constant automatically created by a unit struct/variant. 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]`. @@ -132,13 +130,9 @@ impl DefKind { DefKind::Variant => "variant", DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant", DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant", - DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive) => "struct variant", DefKind::Struct => "struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct", - DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => { - panic!("impossible struct constructor") - } DefKind::OpaqueTy => "opaque type", DefKind::ImplTraitPlaceholder => "opaque type in trait", DefKind::TyAlias => "type alias", @@ -562,19 +556,11 @@ impl PerNS> { } impl CtorKind { - pub fn from_ast(vdata: &ast::VariantData) -> CtorKind { - match *vdata { - ast::VariantData::Tuple(..) => CtorKind::Fn, - ast::VariantData::Unit(..) => CtorKind::Const, - ast::VariantData::Struct(..) => CtorKind::Fictive, - } - } - - pub fn from_hir(vdata: &hir::VariantData<'_>) -> CtorKind { + pub fn from_ast(vdata: &ast::VariantData) -> Option<(CtorKind, NodeId)> { match *vdata { - hir::VariantData::Tuple(..) => CtorKind::Fn, - hir::VariantData::Unit(..) => CtorKind::Const, - hir::VariantData::Struct(..) => CtorKind::Fictive, + ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)), + ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)), + ast::VariantData::Struct(..) => None, } } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index e0a3864506548..bd5b93293a9b6 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2913,20 +2913,29 @@ impl<'hir> VariantData<'hir> { } } - /// Return the `LocalDefId` of this variant's constructor, if it has one. - pub fn ctor_def_id(&self) -> Option { + pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> { match *self { - VariantData::Struct(_, _) => None, - VariantData::Tuple(_, _, def_id) | VariantData::Unit(_, def_id) => Some(def_id), + VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, 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 { + self.ctor().map(|(kind, ..)| kind) + } + /// Return the `HirId` of this variant's constructor, if it has one. + #[inline] pub fn ctor_hir_id(&self) -> Option { - match *self { - VariantData::Struct(_, _) => None, - VariantData::Tuple(_, hir_id, _) | VariantData::Unit(hir_id, _) => Some(hir_id), - } + self.ctor().map(|(_, hir_id, _)| hir_id) + } + + /// Return the `LocalDefId` of this variant's constructor, if it has one. + #[inline] + pub fn ctor_def_id(&self) -> Option { + self.ctor().map(|(.., def_id)| def_id) } } diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 33b9c61993a3c..069b405423c46 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1165,7 +1165,7 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { } 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_non_units = def.variants().iter().any(|var| !is_unit(var)); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index a738ee4a14887..9b8cc884e181c 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -24,7 +24,6 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey}; use rustc_hir as hir; -use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, Visitor}; 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 // 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()); } } @@ -803,7 +802,6 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { fn convert_variant( tcx: TyCtxt<'_>, variant_did: Option, - ctor_did: Option, ident: Ident, discr: ty::VariantDiscr, def: &hir::VariantData<'_>, @@ -840,10 +838,9 @@ fn convert_variant( ty::VariantDef::new( ident.name, 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, fields, - CtorKind::from_hir(def), adt_kind, parent_did.to_def_id(), recovered, @@ -882,7 +879,6 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> { convert_variant( tcx, Some(v.def_id), - v.data.ctor_def_id(), v.ident, discr, &v.data, @@ -894,35 +890,23 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> { (AdtKind::Enum, variants) } - ItemKind::Struct(ref def, _) => { - let variants = std::iter::once(convert_variant( - tcx, - None, - def.ctor_def_id(), - item.ident, - ty::VariantDiscr::Relative(0), - def, - AdtKind::Struct, - def_id, - )) - .collect(); - - (AdtKind::Struct, variants) - } - ItemKind::Union(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( tcx, None, - def.ctor_def_id(), item.ident, ty::VariantDiscr::Relative(0), def, - AdtKind::Union, + adt_kind, def_id, )) .collect(); - (AdtKind::Union, variants) + (adt_kind, variants) } _ => 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) } - 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 inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id)); ty::Binder::dummy(tcx.mk_fn_sig( diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index eaf0310d57aec..6ce0c18bf45f1 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -72,8 +72,8 @@ pub fn add_constraints_from_crate<'a, 'tcx>( let adt = tcx.adt_def(def_id); for variant in adt.variants() { - if let Some(ctor) = variant.ctor_def_id { - constraint_cx.build_constraints_for_item(ctor.expect_local()); + if let Some(ctor_def_id) = variant.ctor_def_id() { + constraint_cx.build_constraints_for_item(ctor_def_id.expect_local()); } } } diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs index 1f763011e0614..58e8f4747611a 100644 --- a/compiler/rustc_hir_analysis/src/variance/terms.rs +++ b/compiler/rustc_hir_analysis/src/variance/terms.rs @@ -91,8 +91,8 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>( let adt = tcx.adt_def(def_id); for variant in adt.variants() { - if let Some(ctor) = variant.ctor_def_id { - terms_cx.add_inferreds_for_item(ctor.expect_local()); + if let Some(ctor_def_id) = variant.ctor_def_id() { + terms_cx.add_inferreds_for_item(ctor_def_id.expect_local()); } } } diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 302d512c71d13..42aa3bcee49a4 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -6,7 +6,7 @@ use crate::type_error_struct; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::{struct_span_err, Applicability, Diagnostic, StashKey}; 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_infer::{ infer, @@ -595,7 +595,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let mut unit_variant = None; 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) // Only suggest removing parens if there are no arguments && arg_exprs.is_empty() diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 5a34ab401749f..934d12404427e 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -2,6 +2,7 @@ use crate::FnCtxt; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; +use rustc_hir::def::CtorKind; use rustc_hir::lang_items::LangItem; use rustc_hir::{is_range_literal, Node}; 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::") && 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 { None } }) .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) { Some(ident) => format!("{ident}: "), None => String::new(), }; - let (open, close) = match ctor { - hir::def::CtorKind::Fn => ("(".to_owned(), ")"), - hir::def::CtorKind::Fictive => (format!(" {{ {field_name}: "), " }"), + let (open, close) = match ctor_kind { + Some(CtorKind::Fn) => ("(".to_owned(), ")"), + None => (format!(" {{ {field_name}: "), " }"), // 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. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index de30bfe6923a7..886a3ad755df9 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -533,8 +533,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.set_tainted_by_errors(e); tcx.ty_error_with_guaranteed(e) } - Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => { - let e = report_unexpected_variant_res(tcx, res, qpath, expr.span); + Res::Def(DefKind::Variant, _) => { + let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, "E0533", "value"); tcx.ty_error_with_guaranteed(e) } _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0, @@ -2024,8 +2024,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); let variant_ident_span = self.tcx.def_ident_span(variant.def_id).unwrap(); - match variant.ctor_kind { - CtorKind::Fn => match ty.kind() { + match variant.ctor_kind() { + Some(CtorKind::Fn) => match ty.kind() { ty::Adt(adt, ..) if adt.is_enum() => { err.span_label( variant_ident_span, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index b85a23257286b..38499907663e1 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1164,11 +1164,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *ty.kind() { ty::Adt(adt_def, substs) if adt_def.has_ctor() => { let variant = adt_def.non_enum_variant(); - let ctor_def_id = variant.ctor_def_id.unwrap(); - ( - Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id), - Some(substs), - ) + let (ctor_kind, ctor_def_id) = variant.ctor.unwrap(); + (Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id), Some(substs)) } _ => { let mut err = tcx.sess.struct_span_err( diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 334d6d0aa6c20..5104b44802323 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -53,9 +53,9 @@ use crate::check::check_fn; use crate::coercion::DynamicCoerceMany; use crate::gather_locals::GatherLocalsVisitor; 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::def::Res; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::Visitor; use rustc_hir::{HirIdMap, Node}; use rustc_hir_analysis::astconv::AstConv; @@ -433,15 +433,27 @@ fn report_unexpected_variant_res( res: Res, qpath: &hir::QPath<'_>, span: Span, + err_code: &str, + expected: &str, ) -> ErrorGuaranteed { - struct_span_err!( - tcx.sess, + let res_descr = match res { + 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, - E0533, - "expected unit struct, unit variant or constant, found {} `{}`", - res.descr(), - rustc_hir_pretty::qpath_to_string(qpath), - ) + format!("expected {expected}, found {res_descr} `{path_str}`"), + DiagnosticId::Error(err_code.into()), + ); + 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() } diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 37336edd1fda5..9b1f0cff074a6 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -566,6 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; // Check if we have an enum variant. + let mut struct_variant = None; if let ty::Adt(adt_def, _) = self_ty.kind() { if adt_def.is_enum() { let variant_def = adt_def @@ -573,16 +574,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .find(|vd| tcx.hygienic_eq(method_name, vd.ident(tcx), adt_def.did())); if let Some(variant_def) = variant_def { - // Braced variants generate unusable names in value namespace (reserved for - // possible future use), so variants resolved as associated items may refer to - // them as well. 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. - let ctor_def_id = variant_def.ctor_def_id.unwrap_or(variant_def.def_id); - tcx.check_stability(ctor_def_id, Some(expr_id), span, Some(method_name.span)); - return Ok(( - DefKind::Ctor(CtorOf::Variant, variant_def.ctor_kind), - ctor_def_id, - )); + if let Some((ctor_kind, ctor_def_id)) = variant_def.ctor { + tcx.check_stability( + ctor_def_id, + Some(expr_id), + span, + Some(method_name.span), + ); + return Ok((DefKind::Ctor(CtorOf::Variant, ctor_kind), 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, expr_id, 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); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 1d021f19104ea..2fe1b1d8999bc 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -853,8 +853,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.set_tainted_by_errors(e); return tcx.ty_error_with_guaranteed(e); } - Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => { - let e = report_unexpected_variant_res(tcx, res, qpath, pat.span); + Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Variant, _) => { + 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); } Res::SelfCtor(..) @@ -1002,30 +1003,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; let report_unexpected_res = |res: Res| { - let sm = tcx.sess.source_map(); - let path_str = sm - .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(); + let expected = "tuple struct or tuple variant"; + let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0164", expected); on_error(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 // so if any fields in a struct pattern use shorthand syntax, they will // be invalid identifiers (for example, Foo { 0, 1 }). - if let (CtorKind::Fn, PatKind::Struct(qpath, field_patterns, ..)) = - (variant.ctor_kind, &pat.kind) + if let (Some(CtorKind::Fn), PatKind::Struct(qpath, field_patterns, ..)) = + (variant.ctor_kind(), &pat.kind) { let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand); if has_shorthand_field_name { @@ -1659,7 +1638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fields: &'tcx [hir::PatField<'tcx>], variant: &ty::VariantDef, ) -> Option> { - 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| { s.print_qpath(qpath, false) }); diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index b8aff69b3719d..613a05e415ff9 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -65,7 +65,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan}; 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::intravisit::Visitor; use rustc_hir::lang_items::LangItem; @@ -1967,7 +1967,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .variants() .iter() .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| { let sole_field = &variant.fields[0]; diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index fc760ee3b8fa0..a7a4d0ca52772 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -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) { - if let Some(ctor_hir_id) = s.ctor_id() { - self.check_id(ctor_hir_id); + if let Some(ctor_node_id) = s.ctor_node_id() { + self.check_id(ctor_node_id); } ast_visit::walk_struct_def(self, s); } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 8e80d794a1368..ac4b512619025 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -11,7 +11,7 @@ use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell}; use rustc_data_structures::unhash::UnhashMap; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; 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::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc_hir::diagnostic_items::DiagnosticItems; @@ -31,7 +31,7 @@ use rustc_session::cstore::{ use rustc_session::Session; use rustc_span::hygiene::{ExpnIndex, MacroKind}; 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 proc_macro::bridge::client::ProcMacro; @@ -866,12 +866,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let variant_did = 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( self.item_name(index), variant_did, - ctor_did, + ctor, data.discr, self.root .tables @@ -885,7 +885,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { vis: self.get_visibility(index), }) .collect(), - data.ctor_kind, adt_kind, parent_did, false, @@ -1041,29 +1040,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }; 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) { DefKind::Struct | DefKind::Variant => { 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, } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index f475b0b39811c..d96252ba569c6 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -495,8 +495,8 @@ impl CStore { 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)> { - self.get_crate_data(def.krate).get_ctor_def_id_and_kind(def.index) + pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> { + self.get_crate_data(def.krate).get_ctor(def.index) } pub fn visibility_untracked(&self, def: DefId) -> Visibility { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 76a7fb41e6c90..af4be12fe3a5d 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1221,9 +1221,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_enum_variant_info({:?})", def_id); let data = VariantData { - ctor_kind: variant.ctor_kind, 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(), }; @@ -1233,32 +1232,28 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { assert!(f.did.is_local()); 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`. - 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) { - let tcx = self.tcx; 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); // FIXME(eddyb) encode only the `CtorKind` for constructors. let data = VariantData { - ctor_kind: variant.ctor_kind, discr: variant.discr, - ctor: Some(def_id.index), + ctor: Some((ctor_kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; record!(self.tables.variant_data[def_id] <- data); self.tables.constness.set(def_id.index, hir::Constness::Const); - if variant.ctor_kind == CtorKind::Fn { - record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); + if ctor_kind == CtorKind::Fn { + 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) { - debug!("EncodeContext::encode_struct_ctor({:?})", def_id); - let tcx = self.tcx; + fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>) { 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 { - ctor_kind: variant.ctor_kind, discr: variant.discr, - ctor: Some(def_id.index), + ctor: Some((ctor_kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; record!(self.tables.repr_options[def_id] <- adt_def.repr()); record!(self.tables.variant_data[def_id] <- data); self.tables.constness.set(def_id.index, hir::Constness::Const); - if variant.ctor_kind == CtorKind::Fn { - record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); + if ctor_kind == CtorKind::Fn { + 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); 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); record!(self.tables.repr_options[def_id] <- adt_def.repr()); 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(); record!(self.tables.variant_data[def_id] <- VariantData { - ctor_kind: variant.ctor_kind, discr: variant.discr, - ctor, + ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), 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(); record!(self.tables.variant_data[def_id] <- VariantData { - ctor_kind: variant.ctor_kind, 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(), }); } @@ -1629,7 +1616,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for variant in tcx.adt_def(def_id).variants() { yield variant.def_id.index; // 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; } } @@ -1672,20 +1659,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { match item.kind { hir::ItemKind::Enum(..) => { 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); - - if let Some(_ctor_def_id) = variant.ctor_def_id { - self.encode_enum_variant_ctor(def, i); - } + 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()); - // If the struct has a constructor, encode it. - if let Some(ctor_def_id) = struct_def.ctor_def_id() { - self.encode_struct_ctor(def, ctor_def_id.to_def_id()); - } + self.encode_struct_ctor(def); } hir::ItemKind::Impl { .. } => { for &trait_item_def_id in diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index ba6a3aeb20935..3e0b5fa6dd9ff 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -410,10 +410,9 @@ define_tables! { #[derive(TyEncodable, TyDecodable)] struct VariantData { - ctor_kind: CtorKind, discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. - ctor: Option, + ctor: Option<(CtorKind, DefIndex)>, is_non_exhaustive: bool, } diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index e7c1abd126e04..29fe6110797e3 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -101,10 +101,8 @@ fixed_size_enum! { ( Static(ast::Mutability::Mut) ) ( Ctor(CtorOf::Struct, CtorKind::Fn) ) ( Ctor(CtorOf::Struct, CtorKind::Const) ) - ( Ctor(CtorOf::Struct, CtorKind::Fictive) ) ( Ctor(CtorOf::Variant, CtorKind::Fn) ) ( Ctor(CtorOf::Variant, CtorKind::Const) ) - ( Ctor(CtorOf::Variant, CtorKind::Fictive) ) ( Macro(MacroKind::Bang) ) ( Macro(MacroKind::Attr) ) ( Macro(MacroKind::Derive) ) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index e14ea7be9cfd9..d4456adf201a6 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -245,15 +245,15 @@ impl<'hir> Map<'hir> { }, Node::Variant(_) => DefKind::Variant, 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)) { Some(Node::Item(..)) => def::CtorOf::Struct, Some(Node::Variant(..)) => def::CtorOf::Variant, _ => 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(_) => { let inline = match self.find(self.get_parent_node(hir_id)) { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 8b70eabb105c8..364c1b375ae5d 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2115,10 +2115,10 @@ impl<'tcx> Debug for Rvalue<'tcx> { .print_def_path(variant_def.def_id, substs)? .into_buffer(); - match variant_def.ctor_kind { - CtorKind::Const => fmt.write_str(&name), - CtorKind::Fn => fmt_tuple(fmt, &name), - CtorKind::Fictive => { + match variant_def.ctor_kind() { + Some(CtorKind::Const) => fmt.write_str(&name), + Some(CtorKind::Fn) => fmt_tuple(fmt, &name), + None => { let mut struct_fmt = fmt.debug_struct(&name); for (field, place) in iter::zip(&variant_def.fields, places) { 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)?; fmt.write_str(&cx.into_buffer())?; - match variant_def.ctor_kind { - CtorKind::Const => {} - CtorKind::Fn => { + match variant_def.ctor_kind() { + Some(CtorKind::Const) => {} + Some(CtorKind::Fn) => { fmt.write_str("(")?; comma_sep(fmt, fields)?; fmt.write_str(")")?; } - CtorKind::Fictive => { + None => { fmt.write_str(" {{ ")?; let mut first = true; for (field_def, field) in iter::zip(&variant_def.fields, fields) diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index ea7a507d7a43c..8bef9dfe099b9 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -10,7 +10,6 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir as hir; -use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; use rustc_hir::RangeEnd; use rustc_index::newtype_index; @@ -751,7 +750,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { // Only for Adt we can have `S {...}`, // which we handle separately here. - if variant.ctor_kind == CtorKind::Fictive { + if variant.ctor.is_none() { write!(f, " {{ ")?; let mut printed = 0; diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 137b59cf6c2e6..6b6aa40a1604f 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -230,7 +230,7 @@ impl AdtDefData { 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; } @@ -386,11 +386,9 @@ impl<'tcx> AdtDef<'tcx> { // Baz = 3, // } // ``` - if self - .variants() - .iter() - .any(|v| matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind != CtorKind::Const) - { + if self.variants().iter().any(|v| { + matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind() != Some(CtorKind::Const) + }) { return false; } 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 { self.variants() .iter() - .find(|v| v.ctor_def_id == Some(cid)) + .find(|v| v.ctor_def_id() == Some(cid)) .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 { self.variants() .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") .0 } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 8bac76d559f24..3f26d337d4575 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1812,15 +1812,13 @@ pub struct VariantDef { pub def_id: DefId, /// `DefId` that identifies the variant's constructor. /// If this variant is a struct variant, then this is `None`. - pub ctor_def_id: Option, + pub ctor: Option<(CtorKind, DefId)>, /// Variant or struct name. pub name: Symbol, /// Discriminant of this variant. pub discr: VariantDiscr, /// Fields of this variant. pub fields: Vec, - /// Type of constructor of variant. - pub ctor_kind: CtorKind, /// Flags of the variant (e.g. is field list non-exhaustive)? flags: VariantFlags, } @@ -1845,19 +1843,18 @@ impl VariantDef { pub fn new( name: Symbol, variant_did: Option, - ctor_def_id: Option, + ctor: Option<(CtorKind, DefId)>, discr: VariantDiscr, fields: Vec, - ctor_kind: CtorKind, adt_kind: AdtKind, parent_did: DefId, recovered: bool, is_field_list_non_exhaustive: bool, ) -> Self { debug!( - "VariantDef::new(name = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?}, - fields = {:?}, ctor_kind = {:?}, adt_kind = {:?}, parent_did = {:?})", - name, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did, + "VariantDef::new(name = {:?}, variant_did = {:?}, ctor = {:?}, discr = {:?}, + fields = {:?}, adt_kind = {:?}, parent_did = {:?})", + name, variant_did, ctor, discr, fields, adt_kind, parent_did, ); let mut flags = VariantFlags::NO_VARIANT_FLAGS; @@ -1869,15 +1866,7 @@ impl VariantDef { flags |= VariantFlags::IS_RECOVERED; } - VariantDef { - def_id: variant_did.unwrap_or(parent_did), - ctor_def_id, - name, - discr, - fields, - ctor_kind, - flags, - } + VariantDef { def_id: variant_did.unwrap_or(parent_did), ctor, name, discr, fields, flags } } /// Is this field list non-exhaustive? @@ -1896,6 +1885,16 @@ impl VariantDef { pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident { Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap()) } + + #[inline] + pub fn ctor_kind(&self) -> Option { + self.ctor.map(|(kind, _)| kind) + } + + #[inline] + pub fn ctor_def_id(&self) -> Option { + self.ctor.map(|(_, def_id)| def_id) + } } impl PartialEq for VariantDef { @@ -1908,26 +1907,8 @@ impl PartialEq for VariantDef { // definition of `VariantDef` changes, a compile-error will be produced, // reminding us to revisit this assumption. - let Self { - def_id: lhs_def_id, - 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; - + let Self { def_id: lhs_def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = &self; + let Self { def_id: rhs_def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = other; lhs_def_id == rhs_def_id } } @@ -1944,9 +1925,7 @@ impl Hash for VariantDef { // of `VariantDef` changes, a compile-error will be produced, reminding // us to revisit this assumption. - let Self { def_id, ctor_def_id: _, name: _, discr: _, fields: _, ctor_kind: _, flags: _ } = - &self; - + let Self { def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = &self; def_id.hash(s) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index a0c076cbbb245..d828d08805ec3 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1487,12 +1487,12 @@ pub trait PrettyPrinter<'tcx>: contents.variant.expect("destructed const of adt without variant idx"); let variant_def = &def.variant(variant_idx); p!(print_value_path(variant_def.def_id, substs)); - match variant_def.ctor_kind { - CtorKind::Const => {} - CtorKind::Fn => { + match variant_def.ctor_kind() { + Some(CtorKind::Const) => {} + Some(CtorKind::Fn) => { p!("(", comma_sep(fields), ")"); } - CtorKind::Fictive => { + None => { p!(" {{ "); let mut first = true; for (field_def, field) in iter::zip(&variant_def.fields, fields) { diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 0df228a0d599a..ba04cb6eef82d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -564,7 +564,7 @@ fn check_for_bindings_named_same_as_variants( && let ty::Adt(edef, _) = pat_ty.kind() && edef.is_enum() && 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(); diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index e7e419c9b4238..7ac4fcfa64c68 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -747,7 +747,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // If this is a tuple or unit struct, define a name // 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 // to within the crate. 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()); } let ctor_def_id = self.r.local_def_id(ctor_node_id); - let ctor_res = Res::Def( - DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(vdata)), - ctor_def_id.to_def_id(), - ); + let ctor_res = + Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id.to_def_id()); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); 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) => { let field_names = 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_def_id, ctor_kind)) = ctor { + if let Some((ctor_kind, ctor_def_id)) = cstore.ctor_untracked(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 field_visibilities = @@ -1517,20 +1514,20 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { }; // Define a constructor name in the value namespace. - // Braced variants, unlike structs, generate unusable names in - // value namespace, they are reserved for possible future use. - // 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. - let ctor_node_id = variant.data.ctor_id().unwrap_or(variant.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 { + let fields_id = if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&variant.data) { + let ctor_def_id = self.r.local_def_id(ctor_node_id); + 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)); self.r.visibilities.insert(ctor_def_id, ctor_vis); - } + ctor_def_id + } else { + def_id + }; + // 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); } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index b1cee06849dd9..4bd62d3d824d0 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -118,8 +118,8 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { match i.kind { ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => { // If this is a unit or tuple-like struct, register the constructor. - if let Some(ctor_hir_id) = struct_def.ctor_id() { - this.create_def(ctor_hir_id, DefPathData::Ctor, i.span); + if let Some(ctor_node_id) = struct_def.ctor_node_id() { + 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); self.with_parent(def, |this| { - if let Some(ctor_hir_id) = v.data.ctor_id() { - this.create_def(ctor_hir_id, DefPathData::Ctor, v.span); + if let Some(ctor_node_id) = v.data.ctor_node_id() { + this.create_def(ctor_node_id, DefPathData::Ctor, v.span); } visit::walk_variant(this, v) }); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index e0c927dd1e760..b340bee28c3c3 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1442,13 +1442,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_label(span, "constructor is not visible here due to private fields"); } - ( - Res::Def( - DefKind::Union | DefKind::Variant | DefKind::Ctor(_, CtorKind::Fictive), - def_id, - ), - _, - ) if ns == ValueNS => { + (Res::Def(DefKind::Union | DefKind::Variant, def_id), _) if ns == ValueNS => { bad_struct_syntax_suggestion(def_id); } (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()); match kind { CtorKind::Const => false, - CtorKind::Fn | CtorKind::Fictive if has_no_fields => false, + CtorKind::Fn if has_no_fields => false, _ => true, } }; @@ -1975,7 +1969,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .map(|(variant, kind)| match kind { CtorKind::Const => variant, CtorKind::Fn => format!("({}())", variant), - CtorKind::Fictive => format!("({} {{}})", variant), }) .collect::>(); 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)) .filter_map(|(variant, kind)| match kind { CtorKind::Fn => Some(format!("({}(/* fields */))", variant)), - CtorKind::Fictive => Some(format!("({} {{ /* fields */ }})", variant)), _ => None, }) .collect::>(); diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 6ad0a7d29110c..d1a2aee207dcd 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -689,15 +689,15 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { self.push("V"); self = self.print_def_path(variant_def.def_id, substs)?; - match variant_def.ctor_kind { - CtorKind::Const => { + match variant_def.ctor_kind() { + Some(CtorKind::Const) => { self.push("U"); } - CtorKind::Fn => { + Some(CtorKind::Fn) => { self.push("T"); self = print_field_list(self)?; } - CtorKind::Fictive => { + None => { self.push("S"); for (field_def, field) in iter::zip(&variant_def.fields, fields) { // HACK(eddyb) this mimics `path_append`, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3fc4aae923a60..e7c3e5a45e838 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -276,7 +276,7 @@ fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct { let variant = cx.tcx.adt_def(did).non_enum_variant(); clean::Struct { - struct_type: variant.ctor_kind, + ctor_kind: variant.ctor_kind(), generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), fields: variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(), } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c20595614b0b9..7085bc8d1be55 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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 { - let kind = match variant.ctor_kind { - CtorKind::Const => Variant::CLike(match variant.discr { + let kind = match variant.ctor_kind() { + Some(CtorKind::Const) => Variant::CLike(match variant.discr { ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }), ty::VariantDiscr::Relative(_) => None, }), - CtorKind::Fn => Variant::Tuple( + Some(CtorKind::Fn) => Variant::Tuple( variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), ), - CtorKind::Fictive => Variant::Struct(VariantStruct { - struct_type: CtorKind::Fictive, + None => Variant::Struct(VariantStruct { + ctor_kind: None, fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), }), }; @@ -1865,7 +1865,7 @@ fn clean_variant_data<'tcx>( ) -> Variant { match variant { 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(), }), 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(), }), 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), fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(), }), diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 3d13f7463cbb0..340d6d7df180f 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -2081,7 +2081,7 @@ impl From for PrimitiveType { #[derive(Clone, Debug)] pub(crate) struct Struct { - pub(crate) struct_type: CtorKind, + pub(crate) ctor_kind: Option, pub(crate) generics: Generics, pub(crate) fields: Vec, } @@ -2109,7 +2109,7 @@ impl Union { /// only as a variant in an enum. #[derive(Clone, Debug)] pub(crate) struct VariantStruct { - pub(crate) struct_type: CtorKind, + pub(crate) ctor_kind: Option, pub(crate) fields: Vec, } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 647eb69d9a6f6..d12874e1bfd1e 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -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); if !fields.is_empty() { - match s.struct_type { - CtorKind::Fictive => { + match s.ctor_kind { + None => { print_sidebar_block(&mut sidebar, "fields", "Fields", fields.iter()); } - CtorKind::Fn => print_sidebar_title(&mut sidebar, "fields", "Tuple Fields"), - CtorKind::Const => {} + Some(CtorKind::Fn) => print_sidebar_title(&mut sidebar, "fields", "Tuple Fields"), + Some(CtorKind::Const) => {} } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index c95f117a20588..a0e5309a70cb0 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1232,7 +1232,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: w, v, None, - s.struct_type, + s.ctor_kind, &s.fields, " ", 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_item(w, "struct", |w| { 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, }) .peekable(); - if let CtorKind::Fictive | CtorKind::Fn = s.struct_type { + if let None | Some(CtorKind::Fn) = s.ctor_kind { if fields.peek().is_some() { write!( w, "

\ {}{}\

", - 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(w, it); @@ -1739,7 +1739,7 @@ fn render_struct( w: &mut Buffer, it: &clean::Item, g: Option<&clean::Generics>, - ty: CtorKind, + ty: Option, fields: &[clean::Item], tab: &str, structhead: bool, @@ -1757,7 +1757,7 @@ fn render_struct( write!(w, "{}", g.print(cx)) } match ty { - CtorKind::Fictive => { + None => { 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. @@ -1799,7 +1799,7 @@ fn render_struct( } w.write_str("}"); } - CtorKind::Fn => { + Some(CtorKind::Fn) => { w.write_str("("); for (i, field) in fields.iter().enumerate() { if i > 0 { @@ -1827,7 +1827,7 @@ fn render_struct( w.write_str(";"); } } - CtorKind::Const => { + Some(CtorKind::Const) => { // Needed for PhantomData. if let Some(g) = g { write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline)); diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 6995778a93d61..d7184053c87a4 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -315,15 +315,15 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum { impl FromWithTcx for Struct { fn from_tcx(struct_: clean::Struct, tcx: TyCtxt<'_>) -> Self { 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 { - CtorKind::Fn => StructKind::Tuple(ids_keeping_stripped(fields, tcx)), - CtorKind::Const => { + let kind = match ctor_kind { + Some(CtorKind::Fn) => StructKind::Tuple(ids_keeping_stripped(fields, tcx)), + Some(CtorKind::Const) => { assert!(fields.is_empty()); StructKind::Unit } - CtorKind::Fictive => StructKind::Plain { fields: ids(fields, tcx), fields_stripped }, + None => StructKind::Plain { fields: ids(fields, tcx), fields_stripped }, }; Struct { diff --git a/src/test/ui/empty/empty-struct-braces-expr.rs b/src/test/ui/empty/empty-struct-braces-expr.rs index f4144277f16be..2aab3e7772cc0 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.rs +++ b/src/test/ui/empty/empty-struct-braces-expr.rs @@ -17,7 +17,7 @@ fn main() { //~^ 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 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(); diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr index 5b0ca613fc4af..e1a7a02a56869 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.stderr +++ b/src/test/ui/empty/empty-struct-braces-expr.stderr @@ -21,24 +21,6 @@ help: a unit struct with a similar name exists 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` --> $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(); | ~~~~~~~ +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` --> $DIR/empty-struct-braces-expr.rs:23:15 | @@ -132,5 +126,5 @@ LL | XE::Empty1 {}; 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`. diff --git a/src/test/ui/empty/empty-struct-braces-pat-1.stderr b/src/test/ui/empty/empty-struct-braces-pat-1.stderr index 0215a9e593532..14e09fc27a06d 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-1.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-1.stderr @@ -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 | -LL | Empty3 {} - | --------- `E::Empty3` defined here -... 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 | LL | XE::XEmpty3 => () - | ^^^^^^^^^^^ - | - ::: $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 => () - | ~~~~~~~ + | ^^^^^^^^^^^ not a unit struct, unit variant or constant 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`. diff --git a/src/test/ui/empty/empty-struct-braces-pat-3.stderr b/src/test/ui/empty/empty-struct-braces-pat-3.stderr index 615e7fb4aae29..00c8b12e6f984 100644 --- a/src/test/ui/empty/empty-struct-braces-pat-3.stderr +++ b/src/test/ui/empty/empty-struct-braces-pat-3.stderr @@ -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 | -LL | Empty3 {} - | --------- `E::Empty3` defined here -... 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 | LL | XE::XEmpty3() => () - | ^^^^^^^^^^^^^ - | - ::: $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() => () - | ~~~~~~~ + | ^^^^^^^^^^^^^ not a tuple struct or tuple variant -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 | -LL | Empty3 {} - | --------- `E::Empty3` defined here -... 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 | LL | XE::XEmpty3(..) => () - | ^^^^^^^^^^^^^^^ - | - ::: $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(..) => () - | ~~~~~~~ + | ^^^^^^^^^^^^^^^ not a tuple struct or tuple variant 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`. diff --git a/src/test/ui/error-codes/E0164.stderr b/src/test/ui/error-codes/E0164.stderr index 0db89dfec8408..5a80d6ec31aa9 100644 --- a/src/test/ui/error-codes/E0164.stderr +++ b/src/test/ui/error-codes/E0164.stderr @@ -2,7 +2,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated constant --> $DIR/E0164.rs:9:9 | LL | Foo::B(i) => i, - | ^^^^^^^^^ not a tuple variant or struct + | ^^^^^^^^^ not a tuple struct or tuple variant error: aborting due to previous error diff --git a/src/test/ui/issues/issue-19086.rs b/src/test/ui/issues/issue-19086.rs index cc83874cb16c2..42148c5f5a18d 100644 --- a/src/test/ui/issues/issue-19086.rs +++ b/src/test/ui/issues/issue-19086.rs @@ -8,6 +8,6 @@ fn main() { let f = FooB { x: 3, y: 4 }; match f { 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` } } diff --git a/src/test/ui/issues/issue-19086.stderr b/src/test/ui/issues/issue-19086.stderr index a54f1008e4ba9..a3c06a7251115 100644 --- a/src/test/ui/issues/issue-19086.stderr +++ b/src/test/ui/issues/issue-19086.stderr @@ -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 | LL | FooB { x: i32, y: i32 } diff --git a/src/test/ui/issues/issue-28992-empty.stderr b/src/test/ui/issues/issue-28992-empty.stderr index 71f337278f29a..f69773b8c2b91 100644 --- a/src/test/ui/issues/issue-28992-empty.stderr +++ b/src/test/ui/issues/issue-28992-empty.stderr @@ -8,7 +8,7 @@ error[E0164]: expected tuple struct or tuple variant, found associated constant --> $DIR/issue-28992-empty.rs:14:12 | 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 diff --git a/src/test/ui/issues/issue-56835.stderr b/src/test/ui/issues/issue-56835.stderr index c200ba8d52a32..e949ae7b32402 100644 --- a/src/test/ui/issues/issue-56835.stderr +++ b/src/test/ui/issues/issue-56835.stderr @@ -8,7 +8,7 @@ error[E0164]: expected tuple struct or tuple variant, found self constructor `Se --> $DIR/issue-56835.rs:4:12 | 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 diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr index eb0428341020f..f90c81116264a 100644 --- a/src/test/ui/issues/issue-63983.stderr +++ b/src/test/ui/issues/issue-63983.stderr @@ -7,15 +7,13 @@ LL | Tuple(i32), LL | 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 | -LL | Struct{ s: i32 }, - | ---------------- `MyEnum::Struct` defined here -... 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 -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`. diff --git a/src/test/ui/methods/method-path-in-pattern.stderr b/src/test/ui/methods/method-path-in-pattern.stderr index 1d1bdb6b052a8..63c7abe0e4a63 100644 --- a/src/test/ui/methods/method-path-in-pattern.stderr +++ b/src/test/ui/methods/method-path-in-pattern.stderr @@ -2,37 +2,37 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f --> $DIR/method-path-in-pattern.rs:15:9 | 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` --> $DIR/method-path-in-pattern.rs:19:9 | LL | ::bar => {} - | ^^^^^^^^^^ + | ^^^^^^^^^^ not a unit struct, unit variant or constant error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::trait_bar` --> $DIR/method-path-in-pattern.rs:23:9 | LL | ::trait_bar => {} - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar` --> $DIR/method-path-in-pattern.rs:26:12 | 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` --> $DIR/method-path-in-pattern.rs:28:12 | LL | if let ::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` --> $DIR/method-path-in-pattern.rs:30:12 | LL | if let Foo::trait_bar = 0u32 {} - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant error: aborting due to 6 previous errors diff --git a/src/test/ui/namespace/namespace-mix.rs b/src/test/ui/namespace/namespace-mix.rs index b0f7e3c622537..c5b30f148bd5b 100644 --- a/src/test/ui/namespace/namespace-mix.rs +++ b/src/test/ui/namespace/namespace-mix.rs @@ -97,13 +97,13 @@ mod m8 { fn f78() { 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::Item } fn xf78() { 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::Item } diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr index c07914df7273a..cb72d4a1c4292 100644 --- a/src/test/ui/namespace/namespace-mix.stderr +++ b/src/test/ui/namespace/namespace-mix.stderr @@ -52,21 +52,16 @@ LL - check(xm1::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 | -LL | V {}, - | ---- `m7::V` defined here LL | TV(), | ---- similarly named tuple variant `TV` defined here ... LL | check(m7::V); | ^^^^^ | -help: use struct literal syntax instead - | -LL | check(m7::V {}); - | ~~~~~~~~ + = note: can't use a type alias as a constructor help: a tuple variant with a similar name exists | LL | check(m7::TV); @@ -83,23 +78,18 @@ LL - check(m7::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 | 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(), | -- similarly named tuple variant `TV` defined here | -help: use struct literal syntax instead - | -LL | check(xm7::V { /* fields */ }); - | ~~~~~~~~~~~~~~~~~~~~~~~ + = note: can't use a type alias as a constructor help: a tuple variant with a similar name exists | LL | check(xm7::TV); diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr index 483312c16cc9c..04968bbdf999d 100644 --- a/src/test/ui/parser/recover-from-bad-variant.stderr +++ b/src/test/ui/parser/recover-from-bad-variant.stderr @@ -14,14 +14,11 @@ LL - let x = Enum::Foo(a: 3, b: 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 | -LL | Foo { a: usize, b: usize }, - | -------------------------- `Enum::Foo` defined here -... 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 --> $DIR/recover-from-bad-variant.rs:12:9 @@ -36,5 +33,5 @@ LL | Enum::Bar(a, b) => {} error: aborting due to 3 previous errors -Some errors have detailed explanations: E0532, E0769. -For more information about an error, try `rustc --explain E0532`. +Some errors have detailed explanations: E0164, E0769. +For more information about an error, try `rustc --explain E0164`. diff --git a/src/test/ui/parser/struct-literal-variant-in-if.stderr b/src/test/ui/parser/struct-literal-variant-in-if.stderr index 4cffbe433b87d..9f0c0074d674c 100644 --- a/src/test/ui/parser/struct-literal-variant-in-if.stderr +++ b/src/test/ui/parser/struct-literal-variant-in-if.stderr @@ -42,16 +42,11 @@ help: surround the struct literal with parentheses 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 | LL | if x == E::V { field } {} | ^^^^ not a value - | -help: surround the struct literal with parentheses - | -LL | if x == (E::V { field }) {} - | + + error[E0308]: mismatched types --> $DIR/struct-literal-variant-in-if.rs:10:20 @@ -72,5 +67,5 @@ LL | let y: usize = (); 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`. diff --git a/src/test/ui/pattern/pattern-binding-disambiguation.rs b/src/test/ui/pattern/pattern-binding-disambiguation.rs index 2e80ea345dcf7..ce1d8c6c047b1 100644 --- a/src/test/ui/pattern/pattern-binding-disambiguation.rs +++ b/src/test/ui/pattern/pattern-binding-disambiguation.rs @@ -33,7 +33,7 @@ fn main() { TupleVariant => {} //~ ERROR match bindings cannot shadow tuple variants } match doesnt_matter { - BracedVariant => {} //~ ERROR match bindings cannot shadow struct variants + BracedVariant => {} // OK, `BracedVariant` is a fresh binding } match CONST { CONST => {} // OK, `CONST` is a const pattern @@ -50,7 +50,7 @@ fn main() { let BracedStruct = doesnt_matter; // OK, `BracedStruct` is a fresh binding let UnitVariant = UnitVariant; // OK, `UnitVariant` is a unit variant pattern 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 STATIC = doesnt_matter; //~ ERROR let bindings cannot shadow statics let function = doesnt_matter; // OK, `function` is a fresh binding diff --git a/src/test/ui/pattern/pattern-binding-disambiguation.stderr b/src/test/ui/pattern/pattern-binding-disambiguation.stderr index 1529e538b5521..d54467b3c0c08 100644 --- a/src/test/ui/pattern/pattern-binding-disambiguation.stderr +++ b/src/test/ui/pattern/pattern-binding-disambiguation.stderr @@ -22,15 +22,6 @@ LL | TupleVariant => {} | cannot be named the same as a tuple variant | 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 --> $DIR/pattern-binding-disambiguation.rs:42:9 | @@ -58,15 +49,6 @@ LL | use E::*; LL | let TupleVariant = doesnt_matter; | ^^^^^^^^^^^^ 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 --> $DIR/pattern-binding-disambiguation.rs:55:9 | @@ -76,6 +58,6 @@ LL | static STATIC: () = (); LL | let STATIC = doesnt_matter; | ^^^^^^ 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`. diff --git a/src/test/ui/qualified/qualified-path-params.stderr b/src/test/ui/qualified/qualified-path-params.stderr index 82cc6e19f9d1e..a49ed6c8f607a 100644 --- a/src/test/ui/qualified/qualified-path-params.stderr +++ b/src/test/ui/qualified/qualified-path-params.stderr @@ -2,7 +2,7 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f --> $DIR/qualified-path-params.rs:20:9 | LL | ::A::f:: => {} - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant error[E0029]: only `char` and numeric types are allowed in range patterns --> $DIR/qualified-path-params.rs:22:15 diff --git a/src/test/ui/resolve/issue-18252.rs b/src/test/ui/resolve/issue-18252.rs index af0a3cbcb2d81..f6ebe292076e8 100644 --- a/src/test/ui/resolve/issue-18252.rs +++ b/src/test/ui/resolve/issue-18252.rs @@ -4,5 +4,5 @@ enum Foo { fn main() { 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` } diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr index 13e7a59732db1..d9006c0a6c269 100644 --- a/src/test/ui/resolve/issue-18252.stderr +++ b/src/test/ui/resolve/issue-18252.stderr @@ -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 | -LL | Variant { x: usize } - | -------------------- `Foo::Variant` defined here -... 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 -For more information about this error, try `rustc --explain E0423`. +For more information about this error, try `rustc --explain E0533`. diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr index 8df84067e6741..eff89241fd218 100644 --- a/src/test/ui/resolve/issue-19452.stderr +++ b/src/test/ui/resolve/issue-19452.stderr @@ -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 | -LL | Madoka { age: u32 } - | ------------------- `Homura::Madoka` defined here -... 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 | LL | let homura = issue_19452_aux::Homura::Madoka; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `issue_19452_aux::Homura::Madoka { /* fields */ }` - | - ::: $DIR/auxiliary/issue-19452-aux.rs:2:5 - | -LL | Madoka { age: u32 } - | ------ `issue_19452_aux::Homura::Madoka` defined here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a value 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`. diff --git a/src/test/ui/resolve/issue-73427.stderr b/src/test/ui/resolve/issue-73427.stderr index d31c5e47775c9..4af5f29d8093d 100644 --- a/src/test/ui/resolve/issue-73427.stderr +++ b/src/test/ui/resolve/issue-73427.stderr @@ -17,16 +17,12 @@ LL | | } | |_^ help: you might have meant to use one of the following enum variants | -LL | (A::Struct {}).foo(); - | ~~~~~~~~~~~~~~ LL | (A::Tuple()).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(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -34,7 +30,7 @@ error[E0423]: expected value, found enum `B` --> $DIR/issue-73427.rs:35:5 | LL | B.foo(); - | ^ + | ^ help: the following enum variant is available: `(B::TupleWithFields(/* fields */))` | note: the enum is defined here --> $DIR/issue-73427.rs:9:1 @@ -44,12 +40,6 @@ LL | | StructWithFields { x: () }, LL | | TupleWithFields(()), 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` --> $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(); | ~~~~~~~ -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(); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -130,7 +118,7 @@ error[E0532]: expected tuple struct or tuple variant, found enum `A` 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 --> $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); | ^ | - = 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 --> $DIR/issue-73427.rs:1:1 | diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index 82a4211f08ac3..d734fa76b4a35 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -19,12 +19,10 @@ help: you might have meant to use the following enum variant | 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::Struct { /* fields */ }); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0423]: expected value, found enum `Z` --> $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; | ~~~~~~~~~~ -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::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` --> $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; | ~~~~~~~ -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::Struct { /* fields */ }); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ help: a function with a similar name exists | LL | let _: E = m::f; @@ -111,17 +94,6 @@ LL - let _: E = m::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` --> $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; | ~~~~~~~ -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::Struct { /* fields */ }); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ help: consider importing one of these items instead | LL | use std::f32::consts::E; @@ -156,17 +126,6 @@ LL | use std::f32::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 --> $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; | ~~~~~~~~~~ -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::Struct { /* fields */ }); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0412]: cannot find type `Z` in this scope --> $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 { | ^^^^^^^^^^^^^^^^ 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 --> $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 */); | ++++++++++ +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` --> $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 */); | ++++++++++ +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` --> $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 */); | ++++++++++ +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` --> $DIR/privacy-enum-ctor.rs:55:16 | @@ -419,7 +383,13 @@ 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 -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`. diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr index 597dc61c3f7e2..d0ddb34d9fe2c 100644 --- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr +++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr @@ -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 --> $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 */); | +++++++++++++ +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 --> $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 -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`. diff --git a/src/test/ui/suggestions/issue-84700.stderr b/src/test/ui/suggestions/issue-84700.stderr index b36d8aba36d30..ac9f5ab0b0cbb 100644 --- a/src/test/ui/suggestions/issue-84700.stderr +++ b/src/test/ui/suggestions/issue-84700.stderr @@ -7,15 +7,13 @@ LL | Cow, LL | FarmAnimal::Cow(_) => "moo".to_string(), | ^^^^^^^^^^^^^^^^^^ 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 | -LL | Chicken { num_eggs: usize }, - | --------------------------- `FarmAnimal::Chicken` defined here -... 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 -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`. diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr index 15d15f2f40d98..6870b9d7d09f4 100644 --- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr @@ -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 | LL | Self::A => (), - | ^^^^^^^ + | ^^^^^^^ not a unit struct, unit variant or constant error: aborting due to previous error diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs index e4abb96b4bff3..5ed7988e4da34 100644 --- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.rs @@ -6,7 +6,7 @@ type Alias = Enum; fn main() { 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!(); //~^ ERROR expected unit struct, unit variant or constant, found struct variant `Alias::Braced` [E0533] let Alias::Braced(..) = panic!(); diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr index 8f3180a8639d8..c9ac99ede6f31 100644 --- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr +++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr @@ -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 | LL | Alias::Braced; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ not a value error[E0533]: expected unit struct, unit variant or constant, found struct variant `Alias::Braced` --> $DIR/incorrect-variant-form-through-alias-caught.rs:10:9 | 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` --> $DIR/incorrect-variant-form-through-alias-caught.rs:12:9 | 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` --> $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 | 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 diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs index 6f8d766aef7c7..7f8d124838cb8 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs @@ -65,14 +65,14 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { _ => return, }; 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 }, PatKind::TupleStruct(path, patterns, ..) => { 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)) { - missing_variants.retain(|e| e.ctor_def_id != Some(id)); + missing_variants.retain(|e| e.ctor_def_id() != Some(id)); } } path @@ -122,11 +122,11 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { s }, variant.name, - match variant.ctor_kind { - CtorKind::Fn if variant.fields.len() == 1 => "(_)", - CtorKind::Fn => "(..)", - CtorKind::Const => "", - CtorKind::Fictive => "{ .. }", + match variant.ctor_kind() { + Some(CtorKind::Fn) if variant.fields.len() == 1 => "(_)", + Some(CtorKind::Fn) => "(..)", + Some(CtorKind::Const) => "", + None => "{ .. }", } ) }; diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs index cfba7fa8791de..f2276395fed0b 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs @@ -133,11 +133,11 @@ impl UnnecessaryDefPath { let has_ctor = match cx.tcx.def_kind(def_id) { DefKind::Struct => { 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 => { 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, };