+// 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 std::iter;
use std::slice;
-use rustc_error_codes::*;
+use rustc::mir::interpret::LitToConstInput;
#[derive(Debug)]
pub struct PathSeg(pub DefId, pub usize);
// those that do.
self.one_bound_for_assoc_type(
|| traits::supertraits(tcx, trait_ref),
- &trait_ref.print_only_trait_path().to_string(),
+ || trait_ref.print_only_trait_path().to_string(),
binding.item_name,
path_span,
- match binding.kind {
+ || match binding.kind {
ConvertedBindingKind::Equality(ty) => Some(ty.to_string()),
_ => None,
},
predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref()),
)
},
- ¶m_name.as_str(),
+ || param_name.to_string(),
assoc_name,
span,
- None,
+ || None,
)
}
fn one_bound_for_assoc_type<I>(
&self,
all_candidates: impl Fn() -> I,
- ty_param_name: &str,
+ ty_param_name: impl Fn() -> String,
assoc_name: ast::Ident,
span: Span,
- is_equality: Option<String>,
+ is_equality: impl Fn() -> Option<String>,
) -> Result<ty::PolyTraitRef<'tcx>, ErrorReported>
where
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
None => {
self.complain_about_assoc_type_not_found(
all_candidates,
- ty_param_name,
+ &ty_param_name(),
assoc_name,
span,
);
if let Some(bound2) = matching_candidates.next() {
debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
+ let is_equality = is_equality();
let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates);
let mut err = if is_equality.is_some() {
// More specific Error Index entry.
E0222,
"ambiguous associated type `{}` in bounds of `{}`",
assoc_name,
- ty_param_name
+ ty_param_name()
)
} else {
struct_span_err!(
E0221,
"ambiguous associated type `{}` in bounds of `{}`",
assoc_name,
- ty_param_name
+ ty_param_name()
)
};
err.span_label(span, format!("ambiguous associated type `{}`", assoc_name));
"use fully qualified syntax to disambiguate",
format!(
"<{} as {}>::{}",
- ty_param_name,
+ ty_param_name(),
bound.print_only_trait_path(),
assoc_name,
),
} else {
err.note(&format!(
"associated type `{}` could derive from `{}`",
- ty_param_name,
+ ty_param_name(),
bound.print_only_trait_path(),
));
}
err.help(&format!(
"consider introducing a new type parameter `T` and adding `where` constraints:\
\n where\n T: {},\n{}",
- ty_param_name,
+ ty_param_name(),
where_bounds.join(",\n"),
));
}
self.one_bound_for_assoc_type(
|| traits::supertraits(tcx, ty::Binder::bind(trait_ref)),
- "Self",
+ || "Self".to_string(),
assoc_ident,
span,
- None,
+ || None,
)?
}
(&ty::Param(_), Res::SelfTy(Some(param_did), None))
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),
- None,
- ),
- 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(