From 1f46f771a6b579c1330976c1638ccc4a03e8863f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 17 Feb 2022 15:23:28 +0000 Subject: [PATCH] Remove some special code handling TAIT being passed through if and match This is not necessary for RPIT anymore, since we reverted that to using inference vars. --- .../rustc_typeck/src/check/expectation.rs | 28 ++----------------- .../ui/lazy-type-alias-impl-trait/branches.rs | 14 ++++++++++ .../branches.stderr | 16 +++++++++++ .../lazy-type-alias-impl-trait/branches2.rs | 28 +++++++++++++++++++ .../type-alias-impl-trait/issue-63279.stderr | 4 ++- .../type-alias-impl-trait/issue-74280.stderr | 5 +++- 6 files changed, 68 insertions(+), 27 deletions(-) create mode 100644 src/test/ui/lazy-type-alias-impl-trait/branches.rs create mode 100644 src/test/ui/lazy-type-alias-impl-trait/branches.stderr create mode 100644 src/test/ui/lazy-type-alias-impl-trait/branches2.rs diff --git a/compiler/rustc_typeck/src/check/expectation.rs b/compiler/rustc_typeck/src/check/expectation.rs index 9e1a70b7dfb..e9e81034477 100644 --- a/compiler/rustc_typeck/src/check/expectation.rs +++ b/compiler/rustc_typeck/src/check/expectation.rs @@ -1,6 +1,5 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::{self, Ty}; -use rustc_span::DUMMY_SP; use rustc_span::{self, Span}; use super::Expectation::*; @@ -44,7 +43,7 @@ impl<'a, 'tcx> Expectation<'tcx> { // when checking the 'then' block which are incompatible with the // 'else' branch. pub(super) fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> { - match self.strip_opaque(fcx) { + match *self { ExpectHasType(ety) => { let ety = fcx.shallow_resolve(ety); if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation } @@ -105,35 +104,14 @@ pub(super) fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option> { /// for the program to type-check). `only_has_type` will return /// such a constraint, if it exists. pub(super) fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option> { - match self.strip_opaque(fcx) { - ExpectHasType(ty) => Some(ty), + match self { + ExpectHasType(ty) => Some(fcx.resolve_vars_if_possible(ty)), NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) | IsLast(_) => { None } } } - /// We must not treat opaque types as expected types in their defining scope, as that - /// will break `fn foo() -> impl Trait { if cond { a } else { b } }` if `a` and `b` are - /// only "equal" if they coerce to a common target, like two different function items - /// coercing to a function pointer if they have the same signature. - fn strip_opaque(self, fcx: &FnCtxt<'a, 'tcx>) -> Self { - match self { - ExpectHasType(ty) => { - let ty = fcx.resolve_vars_if_possible(ty); - match *ty.kind() { - ty::Opaque(def_id, _) - if fcx.infcx.opaque_type_origin(def_id, DUMMY_SP).is_some() => - { - NoExpectation - } - _ => self, - } - } - _ => self, - } - } - /// Like `only_has_type`, but instead of returning `None` if no /// hard constraint exists, creates a fresh type variable. pub(super) fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> { diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches.rs b/src/test/ui/lazy-type-alias-impl-trait/branches.rs new file mode 100644 index 00000000000..aa172f3f19b --- /dev/null +++ b/src/test/ui/lazy-type-alias-impl-trait/branches.rs @@ -0,0 +1,14 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl std::fmt::Debug; + +fn foo(b: bool) -> Foo { + if b { + vec![42_i32] + } else { + std::iter::empty().collect() + //~^ ERROR `Foo` cannot be built from an iterator over elements of type `_` + } +} + +fn main() {} diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches.stderr b/src/test/ui/lazy-type-alias-impl-trait/branches.stderr new file mode 100644 index 00000000000..c3902f34706 --- /dev/null +++ b/src/test/ui/lazy-type-alias-impl-trait/branches.stderr @@ -0,0 +1,16 @@ +error[E0277]: a value of type `Foo` cannot be built from an iterator over elements of type `_` + --> $DIR/branches.rs:9:28 + | +LL | std::iter::empty().collect() + | ^^^^^^^ value of type `Foo` cannot be built from `std::iter::Iterator` + | + = help: the trait `FromIterator<_>` is not implemented for `Foo` +note: required by a bound in `collect` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | +LL | fn collect>(self) -> B + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/lazy-type-alias-impl-trait/branches2.rs b/src/test/ui/lazy-type-alias-impl-trait/branches2.rs new file mode 100644 index 00000000000..af605e4d806 --- /dev/null +++ b/src/test/ui/lazy-type-alias-impl-trait/branches2.rs @@ -0,0 +1,28 @@ +#![feature(type_alias_impl_trait)] + +// run-pass + +type Foo = impl std::iter::FromIterator + PartialEq> + std::fmt::Debug; + +fn foo(b: bool) -> Foo { + if b { + vec![42_i32] + } else { + std::iter::empty().collect() + } +} + +fn bar(b: bool) -> impl PartialEq> + std::fmt::Debug { + if b { + vec![42_i32] + } else { + std::iter::empty().collect() + } +} + +fn main() { + assert_eq!(foo(true), vec![42]); + assert_eq!(foo(false), vec![]); + assert_eq!(bar(true), vec![42]); + assert_eq!(bar(false), vec![]); +} diff --git a/src/test/ui/type-alias-impl-trait/issue-63279.stderr b/src/test/ui/type-alias-impl-trait/issue-63279.stderr index 4b7dbbd6a56..bcc9c57f91c 100644 --- a/src/test/ui/type-alias-impl-trait/issue-63279.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-63279.stderr @@ -21,7 +21,9 @@ error[E0308]: mismatched types | LL | type Closure = impl FnOnce(); | ------------- the expected opaque type -... +LL | +LL | fn c() -> Closure { + | ------- expected `Closure` because of return type LL | || -> Closure { || () } | ^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found closure | diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.stderr b/src/test/ui/type-alias-impl-trait/issue-74280.stderr index 38591e37f53..7a22b360a31 100644 --- a/src/test/ui/type-alias-impl-trait/issue-74280.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-74280.stderr @@ -3,7 +3,10 @@ error[E0308]: mismatched types | LL | type Test = impl Copy; | --------- the expected opaque type -... +LL | +LL | fn test() -> Test { + | ---- expected `Test` because of return type +LL | let y = || -> Test { () }; LL | 7 | ^ expected `()`, found integer |