about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-02-17 15:23:28 +0000
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2022-03-28 17:00:29 +0000
commit1f46f771a6b579c1330976c1638ccc4a03e8863f (patch)
treea54fc28fe4ae7cb77086229aa99f69216de5aae3
parent02536fe18b78c0bbda2543617d75a4873e1016dd (diff)
downloadrust-1f46f771a6b579c1330976c1638ccc4a03e8863f.tar.gz
rust-1f46f771a6b579c1330976c1638ccc4a03e8863f.zip
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.
-rw-r--r--compiler/rustc_typeck/src/check/expectation.rs28
-rw-r--r--src/test/ui/lazy-type-alias-impl-trait/branches.rs14
-rw-r--r--src/test/ui/lazy-type-alias-impl-trait/branches.stderr16
-rw-r--r--src/test/ui/lazy-type-alias-impl-trait/branches2.rs28
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-63279.stderr4
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74280.stderr5
6 files changed, 68 insertions, 27 deletions
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 @@ impl<'a, 'tcx> Expectation<'tcx> {
     /// 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<Ty<'tcx>> {
-        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<Item=_>`
+   |
+   = 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<B: FromIterator<Self::Item>>(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<i32> + PartialEq<Vec<i32>> + std::fmt::Debug;
+
+fn foo(b: bool) -> Foo {
+    if b {
+        vec![42_i32]
+    } else {
+        std::iter::empty().collect()
+    }
+}
+
+fn bar(b: bool) -> impl PartialEq<Vec<i32>> + 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
    |