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.
This commit is contained in:
parent
02536fe18b
commit
1f46f771a6
@ -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<Ty<'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> {
|
||||
|
14
src/test/ui/lazy-type-alias-impl-trait/branches.rs
Normal file
14
src/test/ui/lazy-type-alias-impl-trait/branches.rs
Normal file
@ -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() {}
|
16
src/test/ui/lazy-type-alias-impl-trait/branches.stderr
Normal file
16
src/test/ui/lazy-type-alias-impl-trait/branches.stderr
Normal file
@ -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`.
|
28
src/test/ui/lazy-type-alias-impl-trait/branches2.rs
Normal file
28
src/test/ui/lazy-type-alias-impl-trait/branches2.rs
Normal file
@ -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![]);
|
||||
}
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
|
||||
|
Loading…
Reference in New Issue
Block a user