-> &'tcx ty::GenericPredicates<'tcx>;
/// Returns the lifetime to use when a lifetime is omitted (and not elided).
- fn re_infer(&self, span: Span, _def: Option<&ty::GenericParamDef>)
+ fn re_infer(
+ &self,
+ param: Option<&ty::GenericParamDef>,
+ span: Span,
+ )
-> Option<ty::Region<'tcx>>;
/// Returns the type to use when a type is omitted.
- fn ty_infer(&self, span: Span) -> Ty<'tcx>;
+ fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
- /// Same as `ty_infer`, but with a known type parameter definition.
- fn ty_infer_for_def(&self,
- _def: &ty::GenericParamDef,
- span: Span) -> Ty<'tcx> {
- self.ty_infer(span)
- }
- /// What const should we use when a const is omitted?
+ /// Returns the const to use when a const is omitted.
fn ct_infer(
&self,
ty: Ty<'tcx>,
}
None => {
- self.re_infer(lifetime.span, def)
+ self.re_infer(def, lifetime.span)
.unwrap_or_else(|| {
// This indicates an illegal lifetime
// elision. `resolve_lifetime` should have
}
} else if infer_args {
// No type parameters were provided, we can infer all.
- if !default_needs_object_self(param) {
- self.ty_infer_for_def(param, span).into()
+ let param = if !default_needs_object_self(param) {
+ Some(param)
} else {
- self.ty_infer(span).into()
- }
+ None
+ };
+ self.ty_infer(param, span).into()
} else {
// We've already errored above about the mismatch.
tcx.types.err.into()
if tcx.named_region(lifetime.hir_id).is_some() {
self.ast_region_to_region(lifetime, None)
} else {
- self.re_infer(span, None).unwrap_or_else(|| {
+ self.re_infer(None, span).unwrap_or_else(|| {
span_err!(tcx.sess, span, E0228,
"the lifetime bound for this object type cannot be deduced \
from context; please supply an explicit bound");
// values in a ExprKind::Closure, or as
// the type of local variables. Both of these cases are
// handled specially and will not descend into this routine.
- self.ty_infer(ast_ty.span)
+ self.ty_infer(None, ast_ty.span)
}
hir::TyKind::CVarArgs(lt) => {
let va_list_did = match tcx.lang_items().va_list() {
result_ty
}
+ /// Returns the `DefId` of the constant parameter that the provided expression is a path to.
+ pub fn const_param_def_id(&self, expr: &hir::Expr) -> Option<DefId> {
+ match &expr.node {
+ ExprKind::Path(hir::QPath::Resolved(_, path)) => match path.res {
+ Res::Def(DefKind::ConstParam, did) => Some(did),
+ _ => None,
+ },
+ _ => None,
+ }
+ }
+
pub fn ast_const_to_const(
&self,
ast_const: &hir::AnonConst,
}
}
- if let ExprKind::Path(ref qpath) = expr.node {
- if let hir::QPath::Resolved(_, ref path) = qpath {
- if let Res::Def(DefKind::ConstParam, def_id) = path.res {
- let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
- let item_id = tcx.hir().get_parent_node(node_id);
- let item_def_id = tcx.hir().local_def_id(item_id);
- let generics = tcx.generics_of(item_def_id);
- let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
- let name = tcx.hir().name(node_id).as_interned_str();
- const_.val = ConstValue::Param(ty::ParamConst::new(index, name));
- }
- }
- };
+ 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 node_id = tcx.hir().as_local_node_id(def_id).unwrap();
+ let item_id = tcx.hir().get_parent_node(node_id);
+ let item_def_id = tcx.hir().local_def_id(item_id);
+ let generics = tcx.generics_of(item_def_id);
+ let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
+ let name = tcx.hir().name(node_id).as_interned_str();
+ const_.val = ConstValue::Param(ty::ParamConst::new(index, name));
+ }
tcx.mk_const(const_)
}