diff options
| author | bors <bors@rust-lang.org> | 2019-06-15 03:47:55 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-06-15 03:47:55 +0000 |
| commit | 9f8cd9da7b6380b5658163141c767a321f5f0f62 (patch) | |
| tree | 45a2ed6d8654f6b100a0a08d821b1932d3c40a70 | |
| parent | 9606f6fa64926a84d82e3c62dbdc57f5c10f756d (diff) | |
| parent | 065151f8b2c31d9e4ddd34aaf8d3263a997f5cfe (diff) | |
| download | rust-9f8cd9da7b6380b5658163141c767a321f5f0f62.tar.gz rust-9f8cd9da7b6380b5658163141c767a321f5f0f62.zip | |
Auto merge of #61825 - Centril:tauv-infer-fix, r=petrochenkov
type_alias_enum_variants: fix #61801; allow a path pattern to infer Fix #61801. Given a type-relative path pattern referring to an enum variant through a type alias, allow inferring the generic argument applied in the expectation set by the scrutinee of a `match` expression. Similar issues may exist for `let` statements but I don't know how to test for that since `PhantomData<T>` is necessary...) The gist of the problem here was that `resolve_ty_and_res_ufcs` was called twice which is apparently no good... It is possible that this PR is papering over some deeper problem, but that is beyond my knowledge of the compiler. r? @petrochenkov cc @eddyb @alexreg cc https://github.com/rust-lang/rust/pull/61682 cc https://github.com/rust-lang/rust/issues/49683
| -rw-r--r-- | src/librustc_typeck/check/_match.rs | 13 | ||||
| -rw-r--r-- | src/test/ui/type-alias-enum-variants/issue-61801-path-pattern-can-infer.rs | 30 |
2 files changed, 38 insertions, 5 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 9ffbbd384c6..f74dbe30d3c 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<Ty<'tcx>>, &'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 00000000000..21be61acb0c --- /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<T> { + N, + S(T), +} + +type OptAlias<T> = Opt<T>; + +fn f1(x: OptAlias<u8>) { + 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() {} |
