use crate::collect::PlaceholderHirTyCollector;
use crate::middle::resolve_lifetime as rl;
use crate::require_c_abi_if_c_variadic;
+use rustc_ast::ast::ParamKindOrd;
use rustc_ast::util::lev_distance::find_best_match_for_name;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::ErrorReported;
arg.descr(),
kind,
);
+
+ let kind_ord = match kind {
+ "lifetime" => ParamKindOrd::Lifetime,
+ "type" => ParamKindOrd::Type,
+ "constant" => ParamKindOrd::Const,
+ // It's more concise to match on the string representation, though it means
+ // the match is non-exhaustive.
+ _ => bug!("invalid generic parameter kind {}", kind),
+ };
+ let arg_ord = match arg {
+ GenericArg::Lifetime(_) => ParamKindOrd::Lifetime,
+ GenericArg::Type(_) => ParamKindOrd::Type,
+ GenericArg::Const(_) => ParamKindOrd::Const,
+ };
+
// This note will be true as long as generic parameters are strictly ordered by their kind.
- err.note(&format!("{} arguments must be provided before {} arguments", kind, arg.descr()));
+ let (first, last) =
+ if kind_ord < arg_ord { (kind, arg.descr()) } else { (arg.descr(), kind) };
+ err.note(&format!("{} arguments must be provided before {} arguments", first, last));
err.emit();
}
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
self.res_to_ty(opt_self_ty, path, false)
}
- hir::TyKind::Def(item_id, ref lifetimes) => {
- let did = tcx.hir().local_def_id(item_id.id);
- self.impl_trait_ty_to_ty(did.to_def_id(), lifetimes)
+ hir::TyKind::OpaqueDef(item_id, ref lifetimes) => {
+ let opaque_ty = tcx.hir().expect_item(item_id.id);
+ let def_id = tcx.hir().local_def_id(item_id.id).to_def_id();
+
+ match opaque_ty.kind {
+ hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn, .. }) => {
+ self.impl_trait_ty_to_ty(def_id, lifetimes, impl_trait_fn.is_some())
+ }
+ ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
+ }
}
hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment);
&self,
def_id: DefId,
lifetimes: &[hir::GenericArg<'_>],
+ replace_parent_lifetimes: bool,
) -> Ty<'tcx> {
debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
let tcx = self.tcx();
_ => bug!(),
}
} else {
- // Replace all parent lifetimes with `'static`.
match param.kind {
- GenericParamDefKind::Lifetime => tcx.lifetimes.re_static.into(),
+ // For RPIT (return position impl trait), only lifetimes
+ // mentioned in the impl Trait predicate are captured by
+ // the opaque type, so the lifetime parameters from the
+ // parent item need to be replaced with `'static`.
+ //
+ // For `impl Trait` in the types of statics, constants,
+ // locals and type aliases. These capture all parent
+ // lifetimes, so they can use their identity subst.
+ GenericParamDefKind::Lifetime if replace_parent_lifetimes => {
+ tcx.lifetimes.re_static.into()
+ }
_ => tcx.mk_param_from_def(param),
}
}