);
}
+#[test]
+fn infer_tryv2() {
+ check_types(
+ r#"
+//- /main.rs crate:main deps:core
+fn test() {
+ let r: Result<i32, u64> = Result::Ok(1);
+ let v = r?;
+ v;
+} //^ i32
+
+//- /core.rs crate:core
+#[prelude_import] use ops::*;
+mod ops {
+ trait Try {
+ type Output;
+ type Residual;
+ }
+}
+
+#[prelude_import] use result::*;
+mod result {
+ enum Infallible {}
+ enum Result<O, E> {
+ Ok(O),
+ Err(E)
+ }
+
+ impl<O, E> crate::ops::Try for Result<O, E> {
+ type Output = O;
+ type Error = Result<Infallible, E>;
+ }
+}
+"#,
+ );
+}
+
#[test]
fn infer_for_loop() {
check_types(
#[test]
fn infer_box_fn_arg() {
- // The type mismatch is a bug
+ // The type mismatch is because we don't define Unsize and CoerceUnsized
check_infer_with_mismatches(
r#"
//- /lib.rs deps:std
555..557 'ps': {unknown}
559..561 '{}': ()
568..569 'f': Box<dyn FnOnce(&Option<i32>)>
- 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)>
+ 568..573 'f(&s)': ()
570..572 '&s': &Option<i32>
571..572 's': Option<i32>
- 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|_| -> ()>
+ 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|{unknown}| -> ()>
"#]],
);
}
"#]],
)
}
+
+#[test]
+fn fn_returning_unit() {
+ check_infer_with_mismatches(
+ r#"
+#[lang = "fn_once"]
+trait FnOnce<Args> {
+ type Output;
+}
+
+fn test<F: FnOnce()>(f: F) {
+ let _: () = f();
+}"#,
+ expect![[r#"
+ 82..83 'f': F
+ 88..112 '{ ...f(); }': ()
+ 98..99 '_': ()
+ 106..107 'f': F
+ 106..109 'f()': ()
+ "#]],
+ );
+}
+
+#[test]
+fn trait_in_scope_of_trait_impl() {
+ check_infer(
+ r#"
+mod foo {
+ pub trait Foo {
+ fn foo(self);
+ fn bar(self) -> usize { 0 }
+ }
+}
+impl foo::Foo for u32 {
+ fn foo(self) {
+ let _x = self.bar();
+ }
+}
+ "#,
+ expect![[r#"
+ 45..49 'self': Self
+ 67..71 'self': Self
+ 82..87 '{ 0 }': usize
+ 84..85 '0': usize
+ 131..135 'self': u32
+ 137..173 '{ ... }': ()
+ 151..153 '_x': usize
+ 156..160 'self': u32
+ 156..166 'self.bar()': usize
+ "#]],
+ );
+}