use rustc::hir::GenericParamKind;
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
-use errors::{Applicability, DiagnosticId, StashKey};
+use errors::{Applicability, StashKey};
+
+use rustc_error_codes::*;
struct OnlySelfBounds(bool);
// Utility types and common code for the above passes.
fn bad_placeholder_type(tcx: TyCtxt<'tcx>, span: Span) -> errors::DiagnosticBuilder<'tcx> {
- let mut diag = tcx.sess.struct_span_err_with_code(
+ let mut diag = struct_span_err!(
+ tcx.sess,
span,
+ E0121,
"the type placeholder `_` is not allowed within types on item signatures",
- DiagnosticId::Error("E0121".into()),
);
diag.span_label(span, "not allowed in type signatures");
diag
ty::Param(_) => true,
_ => false,
};
- if !substs.types().all(is_param) {
- self.tcx.sess.span_err(
- span,
- "defining opaque type use does not fully define opaque type",
- );
+ let bad_substs: Vec<_> = substs.types().enumerate()
+ .filter(|(_, ty)| !is_param(ty)).collect();
+ if !bad_substs.is_empty() {
+ let identity_substs = InternalSubsts::identity_for_item(self.tcx, self.def_id);
+ for (i, bad_subst) in bad_substs {
+ self.tcx.sess.span_err(
+ span,
+ &format!("defining opaque type use does not fully define opaque type: \
+ generic parameter `{}` is specified as concrete type `{}`",
+ identity_substs.type_at(i), bad_subst)
+ );
+ }
} 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();
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);
-
- // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`.
- let bounds = AstConv::compute_bounds(
- &icx,
- opaque_ty,
- bounds,
- SizedByDefault::Yes,
- tcx.def_span(def_id),
- );
+ ty::print::with_no_queries(|| {
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
+ let opaque_ty = tcx.mk_opaque(def_id, substs);
+ debug!("explicit_predicates_of({:?}): created opaque type {:?}",
+ def_id, opaque_ty);
+
+
+ // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`.
+ let bounds = AstConv::compute_bounds(
+ &icx,
+ opaque_ty,
+ bounds,
+ SizedByDefault::Yes,
+ tcx.def_span(def_id),
+ );
- predicates.extend(bounds.predicates(tcx, opaque_ty));
- &item.generics
+ predicates.extend(bounds.predicates(tcx, opaque_ty));
+ &item.generics
+ })
}
_ => &item.generics,
},
ref generics,
origin: _,
}) => {
- let substs = InternalSubsts::identity_for_item(tcx, def_id);
- let opaque_ty = tcx.mk_opaque(def_id, substs);
-
- // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`.
- let bounds = AstConv::compute_bounds(
- &icx,
- opaque_ty,
- bounds,
- SizedByDefault::Yes,
- tcx.def_span(def_id),
- );
+ let bounds_predicates = ty::print::with_no_queries(|| {
+ let substs = InternalSubsts::identity_for_item(tcx, def_id);
+ let opaque_ty = tcx.mk_opaque(def_id, substs);
+
+ // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`.
+ let bounds = AstConv::compute_bounds(
+ &icx,
+ opaque_ty,
+ bounds,
+ SizedByDefault::Yes,
+ tcx.def_span(def_id),
+ );
- let bounds_predicates = bounds.predicates(tcx, opaque_ty);
+ bounds.predicates(tcx, opaque_ty)
+ });
if impl_trait_fn.is_some() {
// opaque types
return ty::GenericPredicates {