use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::fold::TypeFolder;
+use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{
self, fast_reject, AdtKind, SubtypePredicate, ToPolyTraitRef, ToPredicate, Ty, TyCtxt,
TypeFoldable, WithConstness,
(
Some(format!(
"`?` couldn't convert the error to `{}`",
- trait_ref.self_ty(),
+ trait_ref.skip_binder().self_ty(),
)),
Some(
"the question mark operation (`?`) implicitly performs a \
if let Some(ret_span) = self.return_type_span(obligation) {
err.span_label(
ret_span,
- &format!("expected `{}` because of this", trait_ref.self_ty()),
+ &format!(
+ "expected `{}` because of this",
+ trait_ref.skip_binder().self_ty()
+ ),
);
}
}
"{}the trait `{}` is not implemented for `{}`",
pre_message,
trait_ref.print_only_trait_path(),
- trait_ref.self_ty(),
+ trait_ref.skip_binder().self_ty(),
)
};
return;
}
- let found_trait_ty = found_trait_ref.self_ty();
+ let found_trait_ty = match found_trait_ref.self_ty().no_bound_vars() {
+ Some(ty) => ty,
+ None => return,
+ };
let found_did = match found_trait_ty.kind {
ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did),
) {
let get_trait_impl = |trait_def_id| {
let mut trait_impl = None;
- self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| {
- if trait_impl.is_none() {
- trait_impl = Some(impl_def_id);
- }
- });
+ self.tcx.for_each_relevant_impl(
+ trait_def_id,
+ trait_ref.skip_binder().self_ty(),
+ |impl_def_id| {
+ if trait_impl.is_none() {
+ trait_impl = Some(impl_def_id);
+ }
+ },
+ );
trait_impl
};
let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
let mut err = match predicate.kind() {
ty::PredicateKind::Trait(ref data, _) => {
let trait_ref = data.to_poly_trait_ref();
- let self_ty = trait_ref.self_ty();
+ let self_ty = trait_ref.skip_binder().self_ty();
debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref);
if predicate.references_error() {
err
}
- ty::PredicateKind::WellFormed(ty) => {
+ ty::PredicateKind::WellFormed(arg) => {
// Same hacky approach as above to avoid deluging user
// with error messages.
- if ty.references_error() || self.tcx.sess.has_errors() {
+ if arg.references_error() || self.tcx.sess.has_errors() {
return;
}
- self.need_type_info_err(body_id, span, ty, ErrorCode::E0282)
+
+ match arg.unpack() {
+ GenericArgKind::Lifetime(lt) => {
+ span_bug!(span, "unexpected well formed predicate: {:?}", lt)
+ }
+ GenericArgKind::Type(ty) => {
+ self.need_type_info_err(body_id, span, ty, ErrorCode::E0282)
+ }
+ GenericArgKind::Const(ct) => {
+ self.need_type_info_err_const(body_id, span, ct, ErrorCode::E0282)
+ }
+ }
}
ty::PredicateKind::Subtype(ref data) => {
}
ty::PredicateKind::Projection(ref data) => {
let trait_ref = data.to_poly_trait_ref(self.tcx);
- let self_ty = trait_ref.self_ty();
+ let self_ty = trait_ref.skip_binder().self_ty();
let ty = data.skip_binder().ty;
if predicate.references_error() {
return;
pub fn recursive_type_with_infinite_size_error(
tcx: TyCtxt<'tcx>,
type_def_id: DefId,
-) -> DiagnosticBuilder<'tcx> {
+ spans: Vec<Span>,
+) {
assert!(type_def_id.is_local());
let span = tcx.hir().span_if_local(type_def_id).unwrap();
let span = tcx.sess.source_map().guess_head_span(span);
- let mut err = struct_span_err!(
- tcx.sess,
- span,
- E0072,
- "recursive type `{}` has infinite size",
- tcx.def_path_str(type_def_id)
- );
+ let path = tcx.def_path_str(type_def_id);
+ let mut err =
+ struct_span_err!(tcx.sess, span, E0072, "recursive type `{}` has infinite size", path);
err.span_label(span, "recursive type has infinite size");
- err.help(&format!(
- "insert indirection (e.g., a `Box`, `Rc`, or `&`) \
- at some point to make `{}` representable",
- tcx.def_path_str(type_def_id)
- ));
- err
+ for &span in &spans {
+ err.span_label(span, "recursive without indirection");
+ }
+ let short_msg = format!("insert some indirection to make `{}` representable", path);
+ let msg = format!(
+ "insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `{}` representable",
+ path,
+ );
+ match &spans[..] {
+ [span] => {
+ err.multipart_suggestions(
+ &short_msg,
+ vec![
+ vec![
+ (span.shrink_to_lo(), "Box<".to_string()),
+ (span.shrink_to_hi(), ">".to_string()),
+ ],
+ vec![
+ (span.shrink_to_lo(), "Rc<".to_string()),
+ (span.shrink_to_hi(), ">".to_string()),
+ ],
+ vec![(span.shrink_to_lo(), "&".to_string())],
+ ],
+ Applicability::HasPlaceholders,
+ );
+ }
+ _ if spans.len() <= 4 => {
+ err.multipart_suggestion(
+ &msg,
+ spans
+ .iter()
+ .flat_map(|&span| {
+ vec![
+ (span.shrink_to_lo(), "Box<".to_string()),
+ (span.shrink_to_hi(), ">".to_string()),
+ ]
+ .into_iter()
+ })
+ .collect(),
+ Applicability::HasPlaceholders,
+ );
+ }
+ _ => {
+ err.help(&msg);
+ }
+ }
+ err.emit();
}
/// Summarizes information