use rustc::ty::subst::{Subst, InternalSubsts};
use rustc::ty::util::Discr;
use rustc::ty::util::IntTypeExt;
-use rustc::ty::subst::UnpackedKind;
+use rustc::ty::subst::GenericArgKind;
use rustc::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, Const};
use rustc::ty::{ReprOptions, ToPredicate};
use rustc::util::captures::Captures;
use rustc::hir::GenericParamKind;
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
-use errors::{Applicability, DiagnosticId};
+use errors::{Applicability, DiagnosticId, StashKey};
struct OnlySelfBounds(bool);
}
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
- if let hir::ExprKind::Closure(..) = expr.node {
+ if let hir::ExprKind::Closure(..) = expr.kind {
let def_id = self.tcx.hir().local_def_id(expr.hir_id);
self.tcx.generics_of(def_id);
self.tcx.type_of(def_id);
Node::ImplItem(item) => &item.generics,
Node::Item(item) => {
- match item.node {
+ match item.kind {
ItemKind::Fn(.., ref generics, _)
| ItemKind::Impl(_, _, _, ref generics, ..)
| ItemKind::TyAlias(_, ref generics)
/// `ast_ty_to_ty`, because we want to avoid triggering an all-out
/// conversion of the type to avoid inducing unnecessary cycles.
fn is_param(tcx: TyCtxt<'_>, ast_ty: &hir::Ty, param_id: hir::HirId) -> bool {
- if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ast_ty.node {
+ if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ast_ty.kind {
match path.res {
Res::SelfTy(Some(def_id), None) | Res::Def(DefKind::TyParam, def_id) => {
def_id == tcx.hir().local_def_id(param_id)
let it = tcx.hir().expect_item(item_id);
debug!("convert: item {} with id {}", it.ident, it.hir_id);
let def_id = tcx.hir().local_def_id(item_id);
- match it.node {
+ match it.kind {
// These don't define types.
hir::ItemKind::ExternCrate(_)
| hir::ItemKind::Use(..)
tcx.generics_of(def_id);
tcx.type_of(def_id);
tcx.predicates_of(def_id);
- if let hir::ItemKind::Fn(..) = it.node {
+ if let hir::ItemKind::Fn(..) = it.kind {
tcx.fn_sig(def_id);
}
}
let def_id = tcx.hir().local_def_id(trait_item.hir_id);
tcx.generics_of(def_id);
- match trait_item.node {
+ match trait_item.kind {
hir::TraitItemKind::Const(..)
| hir::TraitItemKind::Type(_, Some(_))
| hir::TraitItemKind::Method(..) => {
tcx.type_of(def_id);
- if let hir::TraitItemKind::Method(..) = trait_item.node {
+ if let hir::TraitItemKind::Method(..) = trait_item.kind {
tcx.fn_sig(def_id);
}
}
tcx.generics_of(def_id);
tcx.type_of(def_id);
tcx.predicates_of(def_id);
- if let hir::ImplItemKind::Method(..) = tcx.hir().expect_impl_item(impl_item_id).node {
+ if let hir::ImplItemKind::Method(..) = tcx.hir().expect_impl_item(impl_item_id).kind {
tcx.fn_sig(def_id);
}
}
tcx.predicates_of(def_id);
}
-fn convert_enum_variant_types<'tcx>(
- tcx: TyCtxt<'tcx>,
+fn convert_enum_variant_types(
+ tcx: TyCtxt<'_>,
def_id: DefId,
variants: &[hir::Variant]
) {
let def = tcx.adt_def(def_id);
let repr_type = def.repr.discr_type();
let initial = repr_type.initial_discriminant(tcx);
- let mut prev_discr = None::<Discr<'tcx>>;
+ let mut prev_discr = None::<Discr<'_>>;
// fill the discriminant values and field types
for variant in variants {
};
let repr = ReprOptions::new(tcx, def_id);
- let (kind, variants) = match item.node {
+ let (kind, variants) = match item.kind {
ItemKind::Enum(ref def, _) => {
let mut distance_from_explicit = 0;
let variants = def.variants
_ => bug!("trait_node_id {} is not an item", trait_hir_id),
};
- let (generics, bounds) = match item.node {
+ let (generics, bounds) = match item.kind {
hir::ItemKind::Trait(.., ref generics, ref supertraits, _) => (generics, supertraits),
hir::ItemKind::TraitAlias(ref generics, ref supertraits) => (generics, supertraits),
_ => span_bug!(item.span, "super_predicates invoked on non-trait"),
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
let item = tcx.hir().expect_item(hir_id);
- let (is_auto, unsafety) = match item.node {
+ let (is_auto, unsafety) = match item.kind {
hir::ItemKind::Trait(is_auto, unsafety, ..) => (is_auto == hir::IsAuto::Yes, unsafety),
hir::ItemKind::TraitAlias(..) => (false, hir::Unsafety::Normal),
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
if self.has_late_bound_regions.is_some() {
return;
}
- match ty.node {
+ match ty.kind {
hir::TyKind::BareFn(..) => {
self.outer_index.shift_in(1);
intravisit::walk_ty(self, ty);
}
match node {
- Node::TraitItem(item) => match item.node {
+ Node::TraitItem(item) => match item.kind {
hir::TraitItemKind::Method(ref sig, _) => {
has_late_bound_regions(tcx, &item.generics, &sig.decl)
}
_ => None,
},
- Node::ImplItem(item) => match item.node {
+ Node::ImplItem(item) => match item.kind {
hir::ImplItemKind::Method(ref sig, _) => {
has_late_bound_regions(tcx, &item.generics, &sig.decl)
}
}
_ => None,
},
- Node::Item(item) => match item.node {
+ Node::Item(item) => match item.kind {
hir::ItemKind::Fn(ref fn_decl, .., ref generics, _) => {
has_late_bound_regions(tcx, generics, fn_decl)
}
}
}
Node::Expr(&hir::Expr {
- node: hir::ExprKind::Closure(..),
+ kind: hir::ExprKind::Closure(..),
..
}) => Some(tcx.closure_base_def_id(def_id)),
- Node::Item(item) => match item.node {
+ Node::Item(item) => match item.kind {
ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => impl_trait_fn,
_ => None,
},
Node::ImplItem(item) => &item.generics,
Node::Item(item) => {
- match item.node {
+ match item.kind {
ItemKind::Fn(.., ref generics, _) | ItemKind::Impl(_, _, _, ref generics, ..) => {
generics
}
// cares about anything but the length is instantiation,
// and we don't do that for closures.
if let Node::Expr(&hir::Expr {
- node: hir::ExprKind::Closure(.., gen),
+ kind: hir::ExprKind::Closure(.., gen),
..
}) = node
{
def_id: DefId,
body_id: hir::BodyId,
span: Span,
+ item_ident: Ident,
) -> Ty<'_> {
let ty = tcx.typeck_tables_of(def_id).node_type(body_id.hir_id);
- let mut diag = bad_placeholder_type(tcx, span);
- if ty != tcx.types.err {
- diag.span_suggestion(
- span,
- "replace `_` with the correct type",
- ty.to_string(),
- Applicability::MaybeIncorrect,
- );
+
+ // If this came from a free `const` or `static mut?` item,
+ // then the user may have written e.g. `const A = 42;`.
+ // In this case, the parser has stashed a diagnostic for
+ // us to improve in typeck so we do that now.
+ match tcx.sess.diagnostic().steal_diagnostic(span, StashKey::ItemNoType) {
+ Some(mut err) => {
+ // The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
+ // We are typeck and have the real type, so remove that and suggest the actual type.
+ err.suggestions.clear();
+ err.span_suggestion(
+ span,
+ "provide a type for the item",
+ format!("{}: {}", item_ident, ty),
+ Applicability::MachineApplicable,
+ )
+ .emit();
+ }
+ None => {
+ let mut diag = bad_placeholder_type(tcx, span);
+ if ty != tcx.types.err {
+ diag.span_suggestion(
+ span,
+ "replace `_` with the correct type",
+ ty.to_string(),
+ Applicability::MaybeIncorrect,
+ );
+ }
+ diag.emit();
+ }
}
- diag.emit();
+
ty
}
let icx = ItemCtxt::new(tcx, def_id);
Some(match tcx.hir().get(hir_id) {
- Node::TraitItem(item) => match item.node {
+ Node::TraitItem(item) => match item.kind {
TraitItemKind::Method(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs)
}
TraitItemKind::Const(ref ty, body_id) => {
body_id.and_then(|body_id| {
- if let hir::TyKind::Infer = ty.node {
- Some(infer_placeholder_type(tcx, def_id, body_id, ty.span))
+ if let hir::TyKind::Infer = ty.kind {
+ Some(infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident))
} else {
None
}
}
},
- Node::ImplItem(item) => match item.node {
+ Node::ImplItem(item) => match item.kind {
ImplItemKind::Method(..) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id);
tcx.mk_fn_def(def_id, substs)
}
ImplItemKind::Const(ref ty, body_id) => {
- if let hir::TyKind::Infer = ty.node {
- infer_placeholder_type(tcx, def_id, body_id, ty.span)
+ if let hir::TyKind::Infer = ty.kind {
+ infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
} else {
icx.to_ty(ty)
}
},
Node::Item(item) => {
- match item.node {
+ match item.kind {
ItemKind::Static(ref ty, .., body_id)
| ItemKind::Const(ref ty, body_id) => {
- if let hir::TyKind::Infer = ty.node {
- infer_placeholder_type(tcx, def_id, body_id, ty.span)
+ if let hir::TyKind::Infer = ty.kind {
+ infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident)
} else {
icx.to_ty(ty)
}
span_bug!(
item.span,
"compute_type_of_item: unexpected item type: {:?}",
- item.node
+ item.kind
);
}
}
Node::Field(field) => icx.to_ty(&field.ty),
Node::Expr(&hir::Expr {
- node: hir::ExprKind::Closure(.., gen),
+ kind: hir::ExprKind::Closure(.., gen),
..
}) => {
if gen.is_some() {
let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
match parent_node {
Node::Ty(&hir::Ty {
- node: hir::TyKind::Array(_, ref constant),
+ kind: hir::TyKind::Array(_, ref constant),
..
})
| Node::Ty(&hir::Ty {
- node: hir::TyKind::Typeof(ref constant),
+ kind: hir::TyKind::Typeof(ref constant),
..
})
| Node::Expr(&hir::Expr {
- node: ExprKind::Repeat(_, ref constant),
+ kind: ExprKind::Repeat(_, ref constant),
..
}) if constant.hir_id == hir_id =>
{
.to_ty(tcx)
}
- Node::Ty(&hir::Ty { node: hir::TyKind::Path(_), .. }) |
- Node::Expr(&hir::Expr { node: ExprKind::Struct(..), .. }) |
- Node::Expr(&hir::Expr { node: ExprKind::Path(_), .. }) |
+ Node::Ty(&hir::Ty { kind: hir::TyKind::Path(_), .. }) |
+ Node::Expr(&hir::Expr { kind: ExprKind::Struct(..), .. }) |
+ Node::Expr(&hir::Expr { kind: ExprKind::Path(_), .. }) |
Node::TraitRef(..) => {
let path = match parent_node {
Node::Ty(&hir::Ty {
- node: hir::TyKind::Path(QPath::Resolved(_, ref path)),
+ kind: hir::TyKind::Path(QPath::Resolved(_, ref path)),
..
})
| Node::Expr(&hir::Expr {
- node: ExprKind::Path(QPath::Resolved(_, ref path)),
+ kind: ExprKind::Path(QPath::Resolved(_, ref path)),
..
}) => {
Some(&**path)
}
- Node::Expr(&hir::Expr { node: ExprKind::Struct(ref path, ..), .. }) => {
+ Node::Expr(&hir::Expr { kind: ExprKind::Struct(ref path, ..), .. }) => {
if let QPath::Resolved(_, ref path) = **path {
Some(&**path)
} else {
// Skipping binder is ok, since we only use this to find generic parameters and
// their positions.
for (idx, subst) in substs.iter().enumerate() {
- if let UnpackedKind::Type(ty) = subst.unpack() {
- if let ty::Param(p) = ty.sty {
+ if let GenericArgKind::Type(ty) = subst.unpack() {
+ if let ty::Param(p) = ty.kind {
if index_map.insert(p, idx).is_some() {
// There was already an entry for `p`, meaning a generic parameter
// was used twice.
let indices = concrete_type
.subst(self.tcx, substs)
.walk()
- .filter_map(|t| match &t.sty {
+ .filter_map(|t| match &t.kind {
ty::Param(p) => Some(*index_map.get(p).unwrap()),
_ => None,
}).collect();
- let is_param = |ty: Ty<'_>| match ty.sty {
+ let is_param = |ty: Ty<'_>| match ty.kind {
ty::Param(_) => true,
_ => false,
};
} else if let Some((prev_span, prev_ty, ref prev_indices)) = self.found {
let mut ty = concrete_type.walk().fuse();
let mut p_ty = prev_ty.walk().fuse();
- let iter_eq = (&mut ty).zip(&mut p_ty).all(|(t, p)| match (&t.sty, &p.sty) {
+ let iter_eq = (&mut ty).zip(&mut p_ty).all(|(t, p)| match (&t.kind, &p.kind) {
// Type parameters are equal to any other type parameter for the purpose of
// concrete type equality, as it is possible to obtain the same type just
// by passing matching parameters to a function.
pub fn get_infer_ret_ty(output: &'_ hir::FunctionRetTy) -> Option<&hir::Ty> {
if let hir::FunctionRetTy::Return(ref ty) = output {
- if let hir::TyKind::Infer = ty.node {
+ if let hir::TyKind::Infer = ty.kind {
return Some(&**ty)
}
}
match tcx.hir().get(hir_id) {
TraitItem(hir::TraitItem {
- node: TraitItemKind::Method(MethodSig { header, decl }, TraitMethod::Provided(_)),
+ kind: TraitItemKind::Method(MethodSig { header, decl }, TraitMethod::Provided(_)),
..
})
| ImplItem(hir::ImplItem {
- node: ImplItemKind::Method(MethodSig { header, decl }, _),
+ kind: ImplItemKind::Method(MethodSig { header, decl }, _),
..
})
| Item(hir::Item {
- node: ItemKind::Fn(decl, header, _, _),
+ kind: ItemKind::Fn(decl, header, _, _),
..
}) => match get_infer_ret_ty(&decl.output) {
Some(ty) => {
},
TraitItem(hir::TraitItem {
- node: TraitItemKind::Method(MethodSig { header, decl }, _),
+ kind: TraitItemKind::Method(MethodSig { header, decl }, _),
..
}) => {
AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl)
}
Expr(&hir::Expr {
- node: hir::ExprKind::Closure(..),
+ kind: hir::ExprKind::Closure(..),
..
}) => {
// Closure signatures are not like other function
let icx = ItemCtxt::new(tcx, def_id);
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
- match tcx.hir().expect_item(hir_id).node {
+ match tcx.hir().expect_item(hir_id).kind {
hir::ItemKind::Impl(.., ref opt_trait_ref, _, _) => {
opt_trait_ref.as_ref().map(|ast_trait_ref| {
let selfty = tcx.type_of(def_id);
}
}
-fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> hir::ImplPolarity {
+fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
- match tcx.hir().expect_item(hir_id).node {
- hir::ItemKind::Impl(_, polarity, ..) => polarity,
+ let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
+ let item = tcx.hir().expect_item(hir_id);
+ match &item.kind {
+ hir::ItemKind::Impl(_, hir::ImplPolarity::Negative, ..) => {
+ if is_rustc_reservation {
+ tcx.sess.span_err(item.span, "reservation impls can't be negative");
+ }
+ ty::ImplPolarity::Negative
+ }
+ hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, None, _, _) => {
+ if is_rustc_reservation {
+ tcx.sess.span_err(item.span, "reservation impls can't be inherent");
+ }
+ ty::ImplPolarity::Positive
+ }
+ hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, Some(_tr), _, _) => {
+ if is_rustc_reservation {
+ ty::ImplPolarity::Reservation
+ } else {
+ ty::ImplPolarity::Positive
+ }
+ }
ref item => bug!("impl_polarity: {:?} not an impl", item),
}
}
let ast_generics = match node {
Node::TraitItem(item) => &item.generics,
- Node::ImplItem(item) => match item.node {
+ Node::ImplItem(item) => match item.kind {
ImplItemKind::OpaqueTy(ref bounds) => {
let substs = InternalSubsts::identity_for_item(tcx, def_id);
let opaque_ty = tcx.mk_opaque(def_id, substs);
},
Node::Item(item) => {
- match item.node {
+ match item.kind {
ItemKind::Impl(_, _, defaultness, ref generics, ..) => {
if defaultness.is_default() {
is_default_impl_trait = tcx.impl_trait_ref(def_id);
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
// is still checked for WF.
if bound_pred.bounds.is_empty() {
- if let ty::Param(_) = ty.sty {
+ if let ty::Param(_) = ty.kind {
// This is a `where T:`, which can be in the HIR from the
// transformation that moves `?Sized` to `T`'s declaration.
// We can skip the predicate because type parameters are
if let Some((self_trait_ref, trait_items)) = is_trait {
predicates.extend(trait_items.iter().flat_map(|trait_item_ref| {
let trait_item = tcx.hir().trait_item(trait_item_ref.id);
- let bounds = match trait_item.node {
+ let bounds = match trait_item.kind {
hir::TraitItemKind::Type(ref bounds, _) => bounds,
_ => return Vec::new().into_iter()
};
// in trait checking. See `setup_constraining_predicates`
// for details.
if let Node::Item(&Item {
- node: ItemKind::Impl(..),
+ kind: ItemKind::Impl(..),
..
}) = node
{
fn static_mutability(tcx: TyCtxt<'_>, def_id: DefId) -> Option<hir::Mutability> {
match tcx.hir().get_if_local(def_id) {
Some(Node::Item(&hir::Item {
- node: hir::ItemKind::Static(_, mutbl, _), ..
+ kind: hir::ItemKind::Static(_, mutbl, _), ..
})) |
Some(Node::ForeignItem( &hir::ForeignItem {
node: hir::ForeignItemKind::Static(_, mutbl), ..