diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 9ffbbd384c6d5..f74dbe30d3c56 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -50,6 +50,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("check_pat_walk(pat={:?},expected={:?},def_bm={:?})", pat, expected, def_bm); + let mut path_resolution = None; let is_non_ref_pat = match pat.node { PatKind::Struct(..) | PatKind::TupleStruct(..) | @@ -65,8 +66,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } PatKind::Path(ref qpath) => { - let (def, _, _) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span); - match def { + let resolution = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span); + path_resolution = Some(resolution); + match resolution.0 { Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => false, _ => true, } @@ -294,7 +296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } PatKind::Path(ref qpath) => { - self.check_pat_path(pat, qpath, expected) + self.check_pat_path(pat, path_resolution.unwrap(), qpath, expected) } PatKind::Struct(ref qpath, ref fields, etc) => { self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, discrim_span) @@ -1054,13 +1056,14 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); fn check_pat_path( &self, pat: &hir::Pat, + path_resolution: (Res, Option>, &'b [hir::PathSegment]), qpath: &hir::QPath, expected: Ty<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; - // Resolve the path and check the definition for errors. - let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span); + // We have already resolved the path. + let (res, opt_ty, segments) = path_resolution; match res { Res::Err => { self.set_tainted_by_errors(); diff --git a/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs new file mode 100644 index 0000000000000..21be61acb0c61 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs @@ -0,0 +1,30 @@ +// In this regression test we check that a path pattern referring to a unit variant +// through a type alias is successful in inferring the generic argument. + +// compile-pass + +#![feature(type_alias_enum_variants)] + +enum Opt { + N, + S(T), +} + +type OptAlias = Opt; + +fn f1(x: OptAlias) { + match x { + OptAlias::N // We previously failed to infer `T` to `u8`. + => (), + _ => (), + } + + match x { + < + OptAlias<_> // And we failed to infer this type also. + >::N => (), + _ => (), + } +} + +fn main() {}