Struct serialization using rustc-serialize in Rust stable [duplicate] - serialization

A few repos (e.g. https://github.com/sebcrozet/nalgebra) have errors along the lines of
warning: deriving(Decodable) is deprecated in favor of deriving(RustcDecodable).
Replacing Decodable with RustcDecodable causes
error: attempt to bound type parameter with a nonexistent trait `rustc_serialize::Decoder`
How do I get these updated?

I believe that your error comes from this commit:
This commit completes the deprecation story for the in-tree
serialization library. The compiler will now emit a warning whenever
it encounters deriving(Encodable) or deriving(Decodable), and the
library itself is now marked #[unstable] for when feature staging is
enabled.
All users of serialization can migrate to the rustc-serialize crate
on crates.io which provides the exact same interface as the
libserialize library in-tree. The new deriving modes are named
RustcEncodable and RustcDecodable and require extern crate
"rustc-serialize" as rustc_serialize at the crate root in order to
expand correctly.
To migrate all crates, add the following to your Cargo.toml:
[dependencies]
rustc-serialize = "0.1.1"
And then add the following to your crate root:
extern crate "rustc-serialize" as rustc_serialize;
Finally, rename Encodable and Decodable deriving modes to
RustcEncodable and RustcDecodable.

At least with 1.0.0-alpha the version 0.1.5 is always downloaded even if you specify the version in Cargo.toml. That version does not compile against the alpha:
Compiling rustc-serialize v0.1.5
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/serialize.rs:175:42: 175:47 error: obsolete syntax: for Sized?
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/serialize.rs:175 pub trait Encodable, E> for Sized? {
^~~~~
note: no longer required. Traits (and their `Self` type) do not have the `Sized` bound by default
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/serialize.rs:381:35: 381:36 error: obsolete syntax: `Sized? T` syntax for removing the `Sized` bound
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/serialize.rs:381 impl, Sized? T: Encodable> Encodable for &'a T {
^
note: write `T: ?Sized` instead
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/serialize.rs:387:31: 387:32 error: obsolete syntax: `Sized? T` syntax for removing the `Sized` bound
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/serialize.rs:387 impl, Sized? T: Encodable> Encodable for Box {
^
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/base64.rs:73:24: 73:29 error: obsolete syntax: for Sized?
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/base64.rs:73 pub trait ToBase64 for Sized? {
^~~~~
note: no longer required. Traits (and their `Self` type) do not have the `Sized` bound by default
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/base64.rs:173:26: 173:31 error: obsolete syntax: for Sized?
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/base64.rs:173 pub trait FromBase64 for Sized? {
^~~~~
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/hex.rs:21:21: 21:26 error: obsolete syntax: for Sized?
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/hex.rs:21 pub trait ToHex for Sized? {
^~~~~
note: no longer required. Traits (and their `Self` type) do not have the `Sized` bound by default
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/hex.rs:57:23: 57:28 error: obsolete syntax: for Sized?
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/hex.rs:57 pub trait FromHex for Sized? {
^~~~~
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/json.rs:396:30: 396:33 error: expected identifier, found keyword `mut`
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/json.rs:396 escape_bytes(writer, buf[mut ..len])
^~~
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/json.rs:401:20: 401:21 error: expected one of `(`, `+`, `::`, `;`, or `]`, found `,`
/home/jsakkine/.cargo/registry/src/github.com-1ecc6299db9ec823/rustc-serialize-0.1.5/src/json.rs:401 static BUF: [u8, ..LEN] = [b' ', ..LEN];
^
Could not compile `rustc-serialize`.
To learn more, run the command again with --verbose.

I got this working by using 0.2 version of rustc-serialize:
[dependencies]
rustc-serialize = "0.2"

Related

Why can I not access `::class.companionObject`?

I am trying to access the companion object of an unknown class with a known interface, given an instance of the class.
Code below:
class AccessTest() {
companion object {
val prop = 5
}
fun getComp() {
print(this)
print(this::class)
print(this::class.companionObject) // Unresolved reference.
print(this::class.companionObjectInstance) // Unresolved reference.
}
}
inline fun <reified T> getCompanion() {
print(T::class.companionObject) // Unresolved reference.
print(T::class.companionObjectInstance) // Unresolved reference.
}
fun main() {
AccessTest().getComp()
getCompanion<AccessTest>()
}
Output:
$ kotlinc -d main.jar main.kt && kotlin -classpath main.jar MainKt
main.kt:8:27: error: unresolved reference: companionObject
print(this::class.companionObject) // Unresolved reference.
^
main.kt:9:27: error: unresolved reference: companionObjectInstance
print(this::class.companionObjectInstance) // Unresolved reference.
^
main.kt:14:20: error: unresolved reference: companionObject
print(T::class.companionObject) // Unresolved reference.
^
main.kt:15:20: error: unresolved reference: companionObjectInstance
print(T::class.companionObjectInstance) // Unresolved reference.
^
I do not think this is a duplicate of either of the below questions, as I am specifically asking what has changed or what I am misunderstanding such that the solution in the two below questions is not working for me:
how to access companion object from object instance in kotlin?
Kotlin invoke companion function with reflection
After a short discussion in comments, it turned out it was just a missing import.
companionObject is not a member of KClass, but extension on it, so it is possible we have access to KClass object, but we don't see its companionObject property. Also, as it's the part of kotlin-reflect library, it is not located in kotlin.reflect package, but in kotlin.reflect.full, so importing kotlin.reflect.* isn't enough to get it.

error[E0277]: the trait bound `my_struct::MyStruct: my_trait::MyTrait` is not satisfied

I am writing projects in Rust to help me learn it, but am having trouble implementing a trait and then using a function required by that trait when a type implementing it is passed to a function.
To try and narrow down the problem, I've created an MVCE. Here is the error message and code:
error message
error[E0277]: the trait bound `my_struct::MyStruct: my_trait::MyTrait` is not satisfied
--> src\main.rs:12:5
|
12 | invoke_print_i32(&MyStruct { });
| ^^^^^^^^^^^^^^^^ the trait `my_trait::MyTrait` is not implemented for `my_struct::MyStruct`
|
note: required by `invoke_print_i32`
--> src\main.rs:7:1
|
7 | fn invoke_print_i32<T: MyTrait>(instance: &T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_trait.rs
pub trait MyTrait {
fn print_i32(&self, n: i32);
}
my_struct.rs
#[path = "my_trait.rs"]
mod my_trait;
use my_trait::MyTrait;
pub struct MyStruct { }
impl MyTrait for MyStruct {
fn print_i32(&self, n: i32) {
println!("n: {}", n);
}
}
main.rs
mod my_trait;
use my_trait::MyTrait;
mod my_struct;
use my_struct::MyStruct;
fn invoke_print_i32<T: MyTrait>(instance: &T) {
instance.print_i32(42);
}
fn main() {
invoke_print_i32(&MyStruct { });
}
My attempts at researching the problem mostly found people trying to implement fairly standard Rust traits, for example:
How can I implement Rust's Copy trait?
The trait bound is not satisfied in Rust
The trait bound is not satisfied
I also read somewhere that I needed to reimplement the trait for variables such as &MyStruct, but my attempts to do so didn't resolve the issue.
extra info
rustc -V outputs rustc 1.36.0 (a53f9df32 2019-07-03)
cargo -V outputs cargo 1.36.0 (c4fcfb725 2019-05-15)
Platform/OS is Windows 10 Pro (x86_64)
question
What am I doing wrong; how can I correctly implement the trait?
You have declared the module my_trait twice, so there are actually two different traits called MyTrait: crate::my_trait and crate::my_struct::my_trait.
You don't need to declare the module in the my_struct module. Instead, use the module that is declared in the crate root, with:
use crate::my_trait::MyTrait;
Or
use super::my_trait::MyTrait;

Why does the Rust compiler not convert from a library error to my error using the From trait?

Given this crate referencing an error from another crate, I would normally write a From implementation to convert types.
use xladd::variant::{Variant, XLAddError};
use failure::Fail;
use std::convert::TryInto;
use std::convert::From;
use std::error::Error;
#[derive(Debug, Fail)]
enum AARCError {
#[fail(display = "F64 Conversion failure")]
ExcelF64ConversionError,
#[fail(display = "Bool Conversion failure")]
ExcelBoolConversionError,
#[fail(display = "Conversion failure")]
ExcelStrConversionError,
}
impl From<XLAddError> for AARCError {
fn from(err: XLAddError) -> Self {
AARCError::ExcelF64ConversionError // Test for now
}
}
pub fn normalize(array: Variant, min: Variant, max: Variant, scale: Variant) -> Result<Variant, AARCError> {
let min: f64 = min.try_into().map_err(|e| AARCError::from(e))?;
Ok(Variant::from_str("foo"))
}
But in this case I get an error:
error[E0277]: the trait bound `basic_stats::AARCError: std::convert::From<!>` is not satisfied
--> src\basic_stats.rs:24:48
|
24 | let min: f64 = min.try_into().map_err(|e| AARCError::from(e))?;
| ^^^^^^^^^^^^^^^ the trait `std::convert::From<!>` is not implemented for `basic_stats::AARCError`
|
= help: the following implementations were found:
<basic_stats::AARCError as std::convert::From<xladd::variant::XLAddError>>
= note: required by `std::convert::From::from`
I don't understand what the From<!> trait is and trying to implement something like that gives an error for unnamed types.
What should I be doing to enable Rust to convert the external crate's errors to my ones?
I don't understand what the From<!> trait is and trying to implement something like that gives an error for unnamed types.
! is the "never" or uninhabited type; the type that has no possible values.
If a Result has ! for its error type, that means the operation cannot fail. It is impossible to convert from it to some other error type, because an error value cannot exist in the first place.
The never type is currently an experimental feature, requiring a nightly build of Rust. As such, it likely has a few rough edges, and it isn't as ergonomic as it could be. For example, I would expect the final feature to provide a blanket From<T> implementation for all types that implement TryFrom<T> with associated type Error = !. It should be made easy to not have to handle the error that can't happen.
To fix your immediate problem, you can map that error to unreachable!(). The only issue with that approach is forwards-compatibility - if the third party crate later introduces a reachable error then your code would have an unhandled error, and no compile-time error to protect you. That's probably a part of why ! is not yet stabilised.

Typedef Return-Type in Objective-C does not work in Swift

I want to use a Objective-C class in my Swift project and have imported the files and Xcode created the bridge header file and everything is cool... except:
The Objective-C class defines a callback type for a function
typedef void (^SSScanManagerCallback)(BOOL success, NSError *error, NSArray *scannedURLs);
And uses the type in the function declaration
- (void)scanSync:(SSScanManagerCallback)callback; // Synchronous scan.
The class in question is the following: https://github.com/counsyl/scanstream/blob/master/ScanStream/SSScanManager.h#L16
If I then want to use the class in Swift:
let scanManager = SSScanManager();
scanManager.scanSync({(_ success: Bool, _ error: Error, _ scannedURLs: [Any]) -> Void in
if !success {
// ...
}
});
I get the following error:
Cannot convert value of type '(Bool, Error, [Any]) -> Void' to expected argument type 'SSScanManagerCallback!'
Update: Even if I try to set the argument type like so:
scanManager.scanSync({(_ justATry: SSScanManagerCallback!) -> Void in
});
I get the error:
Cannot convert value of type '(SSScanManagerCallback!) -> Void' to expected argument type 'SSScanManagerCallback!'
But how would I set the type to just 'SSScanManagerCallback!' as requested in the error message?
Interestingly, it appears that Swift (tested with 3.0.2) now imports Objective-C block argument types without any nullability annotations as strong optionals (previously they were imported as implicitly unwrapped optionals). I can't seem to find the documentation for this change though.
So in your case, the correct signature is:
scanManager.scanSync {(success: Bool, error: Error?, scannedURLs: [Any]?) -> Void in
// ...
}
But never write it like this, always let Swift infer the argument types where it can, it solves these kinds of type-mismatch problems for you.
scanManager.scanSync { success, error, scannedURLs in
// ...
}
Now you can ⌥ click on the closure arguments and Xcode will tell you the type that Swift infers them to be.

Rust trait object's &self cannot be used in a trait default function

Trying to override a trait cast problem, described here. Stuck at implementing the trait function which returns the enum instance with own implementation inside:
//the "trait matcher" enum
enum Side<'a> {
Good(&'a GoodDude),
Bad(&'a BadDude),
}
//very general trait
trait Dude {
fn who_am_i(&self) -> Side;
fn do_useful_stuff(&self);
}
//specific trait #1
trait GoodDude: Dude {
fn who_am_i_inner(&self) -> Side {
Side::Good(&self)
}
fn save_the_world(&self);
}
//specific trait #2
trait BadDude: Dude {
fn who_am_i_inner(&self) -> Side {
Side::Bad(&self)
}
fn do_evil(&self);
}
But for some reason the compilation of this part fails with E0277:
trait GoodDude: Dude {
fn who_am_i_inner(&self) -> Side {
Side::Good(&self) //&self should be &GoodDude, but compiler says it is not...
}
fn save_the_world(&self);
}
And results in:
<anon>:16:20: 16:25 error: the trait `GoodDude` is not implemented for the type `&Self` [E0277]
<anon>:16 Side::Good(&self)
^~~~~
<anon>:16:20: 16:25 help: see the detailed explanation for E0277
<anon>:16:20: 16:25 note: required for the cast to the object type `GoodDude`
Can this be worked out?
Full sample: https://play.rust-lang.org/?gist=8ae2384e401da76c16214c4a642ce8b4&version=stable&backtrace=0
Firstly, the type of self in fn who_am_i_inner is already a reference, so you don't need to &.
fn who_am_i_inner(&self) -> Side {
Side::Good(self)
}
But then rustc complains...
<anon>:13:20: 13:24 error: the trait `core::marker::Sized` is not implemented for the type `Self` [E0277]
<anon>:13 Side::Good(self)
^~~~
<anon>:13:20: 13:24 help: see the detailed explanation for E0277
<anon>:13:20: 13:24 note: `Self` does not have a constant size known at compile-time
<anon>:13:20: 13:24 note: required for the cast to the object type `GoodDude`
Admittedly the error message is very unclear and E0277 is about something totally different. Let's try the nightly compiler instead, which gives better error messages:
error: the trait bound `Self: std::marker::Sized` is not satisfied [--explain E0277]
--> <anon>:13:20
13 |> Side::Good(self)
|> ^^^^
help: consider adding a `where Self: std::marker::Sized` bound
note: required for the cast to the object type `GoodDude`
OK let's try to add the where Self: Sized:
fn who_am_i_inner(&self) -> Side where Self: Sized {
Side::Good(self)
}
and now it works.
World saved. Press any key to continue
May the 4th be with you
Pew Pew Pew
Luke I am yr father
The where Self: Sized is Rust's way to signify that the method cannot be used from trait objects. We say the method ignored from "object-safety", or "cannot be virtual" if you like C++.
The effect is that if all you have got is luke: &GoodDude, then you cannot call luke.who_am_i_inner() since *luke has an unknown size.
The reason we need to make the method not object-safe is due to the cast &Self → &GoodDude. In Rust a trait object reference like &GoodDude is a fat pointer, internally it is represented as a 2-tuple (pointer, method_table). However, in a trait the self is a thin-pointer.
We cannot convert a thin-pointer to a fat-pointer, since there is a missing information, the method_table. This can be filled in if we knew the concrete type. That's why we add the where Self: Sized.
If you want to make who_am_i_inner object-safe, then you cannot provide a default implementation.