|
1 | 1 | //! Diagnostics related methods for `TyS`.
|
2 | 2 |
|
| 3 | +use crate::ty::subst::{GenericArg, GenericArgKind}; |
3 | 4 | use crate::ty::TyKind::*;
|
4 |
| -use crate::ty::{InferTy, TyCtxt, TyS}; |
| 5 | +use crate::ty::{ |
| 6 | + ConstKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, InferTy, |
| 7 | + ProjectionTy, TyCtxt, TyS, TypeAndMut, |
| 8 | +}; |
| 9 | + |
5 | 10 | use rustc_errors::{Applicability, DiagnosticBuilder};
|
6 | 11 | use rustc_hir as hir;
|
7 | 12 | use rustc_hir::def_id::DefId;
|
@@ -63,16 +68,55 @@ impl<'tcx> TyS<'tcx> {
|
63 | 68 |
|
64 | 69 | /// Whether the type can be safely suggested during error recovery.
|
65 | 70 | pub fn is_suggestable(&self) -> bool {
|
66 |
| - !matches!( |
67 |
| - self.kind(), |
| 71 | + fn generic_arg_is_suggestible(arg: GenericArg<'_>) -> bool { |
| 72 | + match arg.unpack() { |
| 73 | + GenericArgKind::Type(ty) => ty.is_suggestable(), |
| 74 | + GenericArgKind::Const(c) => const_is_suggestable(c.val), |
| 75 | + _ => true, |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + fn const_is_suggestable(kind: ConstKind<'_>) -> bool { |
| 80 | + match kind { |
| 81 | + ConstKind::Infer(..) |
| 82 | + | ConstKind::Bound(..) |
| 83 | + | ConstKind::Placeholder(..) |
| 84 | + | ConstKind::Error(..) => false, |
| 85 | + _ => true, |
| 86 | + } |
| 87 | + } |
| 88 | + |
| 89 | + // FIXME(compiler-errors): Some types are still not good to suggest, |
| 90 | + // specifically references with lifetimes within the function. Not |
| 91 | + //sure we have enough information to resolve whether a region is |
| 92 | + // temporary, so I'll leave this as a fixme. |
| 93 | + |
| 94 | + match self.kind() { |
68 | 95 | Opaque(..)
|
69 |
| - | FnDef(..) |
70 |
| - | FnPtr(..) |
71 |
| - | Dynamic(..) |
72 |
| - | Closure(..) |
73 |
| - | Infer(..) |
74 |
| - | Projection(..) |
75 |
| - ) |
| 96 | + | FnDef(..) |
| 97 | + | Closure(..) |
| 98 | + | Infer(..) |
| 99 | + | Generator(..) |
| 100 | + | GeneratorWitness(..) |
| 101 | + | Bound(_, _) |
| 102 | + | Placeholder(_) |
| 103 | + | Error(_) => false, |
| 104 | + Dynamic(dty, _) => dty.iter().all(|pred| match pred.skip_binder() { |
| 105 | + ExistentialPredicate::Trait(ExistentialTraitRef { substs, .. }) => { |
| 106 | + substs.iter().all(generic_arg_is_suggestible) |
| 107 | + } |
| 108 | + ExistentialPredicate::Projection(ExistentialProjection { substs, ty, .. }) => { |
| 109 | + ty.is_suggestable() && substs.iter().all(generic_arg_is_suggestible) |
| 110 | + } |
| 111 | + _ => true, |
| 112 | + }), |
| 113 | + Projection(ProjectionTy { substs: args, .. }) | Adt(_, args) | Tuple(args) => { |
| 114 | + args.iter().all(generic_arg_is_suggestible) |
| 115 | + } |
| 116 | + Slice(ty) | RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => ty.is_suggestable(), |
| 117 | + Array(ty, c) => ty.is_suggestable() && const_is_suggestable(c.val), |
| 118 | + _ => true, |
| 119 | + } |
76 | 120 | }
|
77 | 121 | }
|
78 | 122 |
|
|
0 commit comments