+// ignore-tidy-filelength FIXME(#67418) Split up this file.
//! Conversion from AST representation of types to the `ty.rs` representation.
//! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an
//! instance of `AstConv`.
use crate::namespace::Namespace;
use crate::require_c_abi_if_c_variadic;
use crate::util::common::ErrorReported;
-use errors::{struct_span_err, Applicability, DiagnosticId};
use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
+use rustc::session::parse::feature_err;
use rustc::traits;
use rustc::traits::astconv_object_safety_violations;
use rustc::traits::error_reporting::report_object_safety_error;
use rustc::ty::{self, Const, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
use rustc::ty::{GenericParamDef, GenericParamDefKind};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
use rustc_target::spec::abi;
use smallvec::SmallVec;
use syntax::ast;
-use syntax::errors::pluralize;
-use syntax::feature_gate::feature_err;
use syntax::util::lev_distance::find_best_match_for_name;
use std::collections::BTreeSet;
use std::iter;
use std::slice;
+use rustc::mir::interpret::LitToConstInput;
use rustc_error_codes::*;
#[derive(Debug)]
let msg = format!("expected type, found variant `{}`", assoc_ident);
tcx.sess.span_err(span, &msg);
} else if qself_ty.is_enum() {
- let mut err = tcx.sess.struct_span_err(
+ let mut err = struct_span_err!(
+ tcx.sess,
assoc_ident.span,
- &format!("no variant `{}` in enum `{}`", assoc_ident, qself_ty),
+ E0599,
+ "no variant named `{}` found for enum `{}`",
+ assoc_ident,
+ qself_ty,
);
let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
let tcx = self.tcx();
let def_id = tcx.hir().local_def_id(ast_const.hir_id);
- let mut const_ = ty::Const {
- val: ty::ConstKind::Unevaluated(def_id, InternalSubsts::identity_for_item(tcx, def_id)),
- ty,
+ let expr = &tcx.hir().body(ast_const.body).value;
+
+ let lit_input = match expr.kind {
+ hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
+ hir::ExprKind::Unary(hir::UnOp::UnNeg, ref expr) => match expr.kind {
+ hir::ExprKind::Lit(ref lit) => {
+ Some(LitToConstInput { lit: &lit.node, ty, neg: true })
+ }
+ _ => None,
+ },
+ _ => None,
};
- let expr = &tcx.hir().body(ast_const.body).value;
- if let Some(def_id) = self.const_param_def_id(expr) {
+ if let Some(lit_input) = lit_input {
+ // If an error occurred, ignore that it's a literal and leave reporting the error up to
+ // mir.
+ if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) {
+ return c;
+ }
+ }
+
+ let kind = if let Some(def_id) = self.const_param_def_id(expr) {
// Find the name and index of the const parameter by indexing the generics of the
// parent item and construct a `ParamConst`.
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(hir_id)];
let name = tcx.hir().name(hir_id);
- const_.val = ty::ConstKind::Param(ty::ParamConst::new(index, name));
- }
-
- tcx.mk_const(const_)
+ ty::ConstKind::Param(ty::ParamConst::new(index, name))
+ } else {
+ ty::ConstKind::Unevaluated(def_id, InternalSubsts::identity_for_item(tcx, def_id), None)
+ };
+ tcx.mk_const(ty::Const { val: kind, ty })
}
pub fn impl_trait_ty_to_ty(
// allowed. `allow_ty_infer` gates this behavior.
crate::collect::placeholder_type_error(
tcx,
- ident_span.unwrap_or(DUMMY_SP),
+ ident_span.map(|sp| sp.shrink_to_hi()).unwrap_or(DUMMY_SP),
generic_params,
visitor.0,
ident_span.is_some(),