+
+ /// List the patterns corresponding to the missing constructors. In some cases, instead of
+ /// listing all constructors of a given type, we prefer to simply report a wildcard.
+ fn report_patterns<'p>(
+ &self,
+ cx: &MatchCheckCtxt<'p, 'tcx>,
+ pcx: PatCtxt<'tcx>,
+ ) -> SmallVec<[Pat<'tcx>; 1]> {
+ // There are 2 ways we can report a witness here.
+ // Commonly, we can report all the "free"
+ // constructors as witnesses, e.g., if we have:
+ //
+ // ```
+ // enum Direction { N, S, E, W }
+ // let Direction::N = ...;
+ // ```
+ //
+ // we can report 3 witnesses: `S`, `E`, and `W`.
+ //
+ // However, there is a case where we don't want
+ // to do this and instead report a single `_` witness:
+ // if the user didn't actually specify a constructor
+ // in this arm, e.g., in
+ //
+ // ```
+ // let x: (Direction, Direction, bool) = ...;
+ // let (_, _, false) = x;
+ // ```
+ //
+ // we don't want to show all 16 possible witnesses
+ // `(<direction-1>, <direction-2>, true)` - we are
+ // satisfied with `(_, _, true)`. In this case,
+ // `used_ctors` is empty.
+ // The exception is: if we are at the top-level, for example in an empty match, we
+ // sometimes prefer reporting the list of constructors instead of just `_`.
+ let report_when_all_missing = self.is_top_level && !IntRange::is_integral(pcx.ty);
+ if self.used_ctors.is_empty() && !report_when_all_missing {
+ // All constructors are unused. Report only a wildcard
+ // rather than each individual constructor.
+ smallvec![Pat::wildcard_from_ty(pcx.ty)]
+ } else {
+ // Construct for each missing constructor a "wild" version of this
+ // constructor, that matches everything that can be built with
+ // it. For example, if `ctor` is a `Constructor::Variant` for
+ // `Option::Some`, we get the pattern `Some(_)`.
+ self.iter()
+ .map(|missing_ctor| {
+ let fields = Fields::wildcards(cx, &missing_ctor, pcx.ty);
+ missing_ctor.apply(cx, pcx.ty, fields)
+ })
+ .collect()
+ }
+ }