Unreserve braced enum variants in value namespace
This commit is contained in:
parent
1cbc45942d
commit
7a5376d23c
71 changed files with 364 additions and 642 deletions
|
@ -2664,7 +2664,7 @@ impl VariantData {
|
|||
}
|
||||
|
||||
/// Return the `NodeId` of this variant's constructor, if it has one.
|
||||
pub fn ctor_id(&self) -> Option<NodeId> {
|
||||
pub fn ctor_node_id(&self) -> Option<NodeId> {
|
||||
match *self {
|
||||
VariantData::Struct(..) => None,
|
||||
VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id),
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<T> PerNS<Option<T>> {
|
|||
}
|
||||
|
||||
impl CtorKind {
|
||||
pub fn from_ast(vdata: &ast::VariantData) -> CtorKind {
|
||||
pub fn from_ast(vdata: &ast::VariantData) -> Option<(CtorKind, NodeId)> {
|
||||
match *vdata {
|
||||
ast::VariantData::Tuple(..) => CtorKind::Fn,
|
||||
ast::VariantData::Unit(..) => CtorKind::Const,
|
||||
ast::VariantData::Struct(..) => CtorKind::Fictive,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_hir(vdata: &hir::VariantData<'_>) -> CtorKind {
|
||||
match *vdata {
|
||||
hir::VariantData::Tuple(..) => CtorKind::Fn,
|
||||
hir::VariantData::Unit(..) => CtorKind::Const,
|
||||
hir::VariantData::Struct(..) => CtorKind::Fictive,
|
||||
ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)),
|
||||
ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)),
|
||||
ast::VariantData::Struct(..) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<LocalDefId> {
|
||||
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<CtorKind> {
|
||||
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<HirId> {
|
||||
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<LocalDefId> {
|
||||
self.ctor().map(|(.., def_id)| def_id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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<LocalDefId>,
|
||||
ctor_did: Option<LocalDefId>,
|
||||
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, _) => {
|
||||
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::Struct,
|
||||
adt_kind,
|
||||
def_id,
|
||||
))
|
||||
.collect();
|
||||
|
||||
(AdtKind::Struct, variants)
|
||||
}
|
||||
ItemKind::Union(ref def, _) => {
|
||||
let variants = std::iter::once(convert_variant(
|
||||
tcx,
|
||||
None,
|
||||
def.ctor_def_id(),
|
||||
item.ident,
|
||||
ty::VariantDiscr::Relative(0),
|
||||
def,
|
||||
AdtKind::Union,
|
||||
def_id,
|
||||
))
|
||||
.collect();
|
||||
|
||||
(AdtKind::Union, variants)
|
||||
(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(
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
@ -2025,8 +2025,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,
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
|
||||
if let (CtorKind::Fn, PatKind::Struct(qpath, ..)) = (variant.ctor_kind, &pat.kind) {
|
||||
if let (Some(CtorKind::Fn), PatKind::Struct(qpath, ..)) = (variant.ctor_kind(), &pat.kind) {
|
||||
let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| {
|
||||
s.print_qpath(qpath, false)
|
||||
});
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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<DefId> {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<DefIndex>,
|
||||
ctor: Option<(CtorKind, DefIndex)>,
|
||||
is_non_exhaustive: bool,
|
||||
}
|
||||
|
||||
|
|
|
@ -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) )
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -1808,15 +1808,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<DefId>,
|
||||
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<FieldDef>,
|
||||
/// Type of constructor of variant.
|
||||
pub ctor_kind: CtorKind,
|
||||
/// Flags of the variant (e.g. is field list non-exhaustive)?
|
||||
flags: VariantFlags,
|
||||
}
|
||||
|
@ -1841,19 +1839,18 @@ impl VariantDef {
|
|||
pub fn new(
|
||||
name: Symbol,
|
||||
variant_did: Option<DefId>,
|
||||
ctor_def_id: Option<DefId>,
|
||||
ctor: Option<(CtorKind, DefId)>,
|
||||
discr: VariantDiscr,
|
||||
fields: Vec<FieldDef>,
|
||||
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;
|
||||
|
@ -1865,15 +1862,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?
|
||||
|
@ -1892,6 +1881,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<CtorKind> {
|
||||
self.ctor.map(|(kind, _)| kind)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn ctor_def_id(&self) -> Option<DefId> {
|
||||
self.ctor.map(|(_, def_id)| def_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for VariantDef {
|
||||
|
@ -1904,26 +1903,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
|
||||
}
|
||||
}
|
||||
|
@ -1940,9 +1921,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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
});
|
||||
|
|
|
@ -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::<Vec<_>>();
|
||||
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::<Vec<_>>();
|
||||
|
|
|
@ -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`,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue