Cast to unsized type: `std::io::Stdout` as `std::io::Write` error - casting

I am trying to cast Stdout to Write:
use std::io::{self, Write};
pub struct A<Output: Write> {
output: Output,
}
impl<Output: Write> A<Output> {
pub fn new() -> A<Output> {
A {
output: io::stdout() as Write,
}
}
}
The compiler is complaining:
error[E0620]: cast to unsized type: `std::io::Stdout` as `std::io::Write`
--> src/main.rs:10:21
|
10 | output: io::stdout() as Write,
| ^^^^^^^^^^^^^^^^^^^^^
|
help: consider using a box or reference as appropriate
--> src/main.rs:10:21
|
10 | output: io::stdout() as Write,
| ^^^^^^^^^^^^
I want to cast this and tried to do what the compiler suggested but then it is saying that the as keyword could only be used for primitives and that I should implement the From trait.
How could I cast the Stdout as a Write trait?

cast Stdout to Write
This does not make sense because Write isn't a type that you cast to. Write is a trait. There are trait objects that are types though, such as Box<Write> or &Write. Re-read the trait objects chapter of The Rust Programming Language to refresh your memory on this topic. Rust 1.27 is going to improve the syntax here to make it more obvious as Box<dyn Write> / &dyn Write.
You could use Box::new(io::stdout()) as Box<Write>, but you'll quickly run into "Expected type parameter" error in the constructor of a generic struct.
impl A<Box<Write>> {
pub fn new() -> Self {
A {
output: Box::new(io::stdout()) as Box<Write>,
}
}
}
See also:
What makes something a "trait object"?
Why is `let ref a: Trait = Struct` forbidden
"Expected type parameter" error in the constructor of a generic struct

Related

Roslyn uses MemberAccessExpressionSyntax instead of QualifiedNameSyntax

In the following code, I'd expect that both references to System.Action type to be represented as a QualifiedNameSyntax but the second one is represented as a MemberAccessExpressionSyntax.
Is that correct? If so, why can't it be a QualifiedNameSyntax?
class Foo
{
public void M(object o)
{
var t = typeof(System.Action); // 1
switch(o)
{
case System.Action: // 2
break;
}
}
}
Generally you're only going to get a QualifiedNameSyntax in a Roslyn syntax tree where the only legal thing there is a qualified name; in those cases we're running a restricted parser that will only understand qualified names. Anything else we're running our generic expression parser which will spit out whatever expression is there, and we'll figure out what it actually is during binding. Because consider another case like:
SomeEnum e;
switch (e)
{
case SomeEnum.Blue: Console.WriteLine("Blue!"); return;
}
In that case the SomeEnum.Blue is absolutely an access to a member. But we don't actually know what "SomeEnum" is until binding, so we just always go with MemberAccessExpression.
I can't tell you why for sure, but here's one relevant thing to think about:
In legal code, I think you're right that a switch can never accept a MemberAccessExpression, and so a QualifiedNameSyntax would be sufficient to represent this.
However let's look at some illegal code, and see what happens:
class Foo
{
public static void M(object o)
{
var t = typeof(Foo.M(5)); // 1
switch(o)
{
case Foo.M(5): // 2
break;
}
}
}
This gives 4 errors for the first usage of Foo.M(5):
error CS1026: ) expected
error CS1002: ; expected
error CS1513: } expected
error CS0426: The type name 'M' does not exist in the type 'Foo'
And only 1 for the second:
error CS0426: The type name 'M' does not exist in the type 'Foo'
By allowing a more flexible grammar in the second case, error messages are much better, as they can be done at the semantic level rather than a syntax level.
Since switch expressions accept any pattern as a case, it's more likely that you'll write something invalid, so good error messages are more important in that case.

Why you can't use pointer to member as a callable / invokeable in range-v3 for_each?

Suppose I have a bar and a foo structures:
struct bar {
void bar_function() { }
};
struct foo {
bar* bar_ptr;
void foo_function() { }
};
Now, I'd like to call bar_function() on each of foo's bar_ptrs from an std::vector of foos:
std::vector<foo> fooVec;
ranges::for_each(
fooVec,
&bar::bar_function,
&foo::bar_ptr
);
This uses range-v3's projections - for each foo, we take out bar_ptr from it and then we call bar_function on each of them.
I would assume that the above will work - we can, after all, std::invoke a &bar::bar_function with a pointer to a bar (which we do have - the bar_ptr). For the record I know that range-v3 uses std::invoke magic to always do the right thing, so it surprises me that this fails with the following error:
error: no match for call to '(const ranges::for_each_fn) (std::vector<foo>&, void (bar::*)(), bar* foo::*)'
[...]
error: no class template named 'apply' in 'struct ranges::detail::enable_if<false>'
73 | using enable_if_t = typename enable_if<B>::template apply<T>;
| ^~~~~~~~~~~
[...]
I'm not quite sure which part of the error is relevant here - I know that this fails the SFINAE tests, but I do not know why. Is there a reason why the above should fail or is it a bug?
Note that, if we replace &bar::bar_function with [](auto bar_ptr) { bar_ptr->bar_function(); }, the code happily compiles, which is weird, because, due to std::invoke's nature (to "always do the right thing"), I fail to see the difference between those two:
std::invoke(&bar::bar_function, bar_ptr); // 1
std::invoke([](auto bar_ptr_arg) { // 2
bar_ptr_arg->bar_function();
}, bar_ptr);

"error: underscore lifetimes are unstable" when implementing From<std::sync::PoisonError>

I'm working on a function that looks like this:
fn do_stuff(&mut self, a: MyStruct) -> Result<(), MyError> {
let x = try!(serde_json::to_vec(a));
let cache = Arc::clone(self.data); // Get shared reference
{
let cache = try!(cache.lock()); // Get lock
cache.push(x);
}
/* Do stuff with other resources */
Ok(())
}
Where the definition of MyError is:
#[derive(Debug)]
pub enum MyError {
Serialization(serde_json::Error),
Synch(PoisonError<MutexGuard<'_, Vec<u8>>>),
}
Before I even get to implementing From<std::sync::PoisonError> for MyError, the compiler already tells me the definition of the Synch variant of my enum is wrong:
error: underscore lifetimes are unstable (see issue #44524)
The declaration using underscore lifetimes actually came from an earlier hint from the compiler when I was trying to figure out the error I should convert from when the lock operation fails. I read the aforementioned issue and that doesn't help me.
What's the full type I should be converting from in order to catch the error from the Mutex::lock operation?
Like so:
#[derive(Debug)]
pub enum MyError<'a> {
Serialization(serde_json::Error),
Synch(PoisonError<MutexGuard<'a, Vec<u8>>>),
}
The closest explanation I can find in the book is the section on Lifetime Annotations in Struct Definitions (enums behave the same way).
The compiler suggesting unstable syntax as a solution is quite unfair.

Moving Arc Mutex Ncurses window down thread still doesn't implement send

I'm building an ncurses interface for a little thing I'm working on. For the input, I want to read it non blocking. I figured I could wrap the WINDOW in an Arc Mutex but this doesn't seem to work, as it still complains about send. Is this because the implementation of ncurses is unsafe? How can I solve this? Ideally, I'd have this work with a callback instead of the tx, so I can cut the dependency from the view up the stack, but I couldn't get that closure to Send either.
I'm using this library: https://github.com/jeaye/ncurses-rs
Simplified code:
pub struct View {
max_x: i32,
max_y: i32,
messages_window: WINDOW,
input_window: Arc<Mutex<WINDOW>>
}
pub fn init(&mut self, input_tx: mpsc::Sender<DispatchMessage>) {
let input_window = self.input_window.clone();
thread::spawn(move || {
loop {
let input_window = input_window.lock().unwrap();
draw_prompt(input_window);
let input = prompt_input(input_window);
input_tx.send(input_to_message(input)).unwrap();
}
});
}
fn prompt_input(input: WINDOW) -> String {
let mut string = String::new();
wgetstr(input, &mut string);
string
}
fn draw_prompt(input: WINDOW) {
wclear(input);
let top = 0 as chtype;
let bottom = ' ' as chtype;
let empty = ' ' as chtype;
wborder(input, empty,empty,top,bottom,empty,empty,empty,empty);
mvwprintw(input, 1, 1, ">> ");
wrefresh(input);
}
And the errors I get:
src/view.rs:40:33: 40:45 error: mismatched types:
expected `*mut ncurses::ll::WINDOW_impl`,
found `std::sync::mutex::MutexGuard<'_, *mut ncurses::ll::WINDOW_impl>`
(expected *-ptr,
found struct `std::sync::mutex::MutexGuard`) [E0308]
src/view.rs:40 draw_prompt(input_window);
^~~~~~~~~~~~
note: in expansion of closure expansion
src/view.rs:37:27: 44:14 note: expansion site
src/view.rs:40:33: 40:45 help: run `rustc --explain E0308` to see a detailed explanation
src/view.rs:41:46: 41:58 error: mismatched types:
expected `*mut ncurses::ll::WINDOW_impl`,
found `std::sync::mutex::MutexGuard<'_, *mut ncurses::ll::WINDOW_impl>`
(expected *-ptr,
found struct `std::sync::mutex::MutexGuard`) [E0308]
src/view.rs:41 let input = prompt_input(input_window);
^~~~~~~~~~~~
note: in expansion of closure expansion
src/view.rs:37:27: 44:14 note: expansion site
src/view.rs:41:46: 41:58 help: run `rustc --explain E0308` to see a detailed explanation
src/view.rs:37:13: 37:26 error: the trait `core::marker::Send` is not implemented for the type `*mut ncurses::ll::WINDOW_impl` [E0277]
src/view.rs:37 thread::spawn(move || {
^~~~~~~~~~~~~
src/view.rs:37:13: 37:26 note: `*mut ncurses::ll::WINDOW_impl` cannot be sent between threads safely
src/view.rs:37 thread::spawn(move || {
^~~~~~~~~~~~~
error: aborting due to 3 previous errors
Manually dereferencing the window removes the type errors, but I figured I'd leave it in as it might be an indication of what's wrong.
Arc<T> implements Send where T implements both Send and Sync. Mutex<T> implements Send and Sync where T implements Send. So Arc<Mutex<T>> only implements Send if T implements Send. Remember that Send means “Types able to be transferred across thread boundaries.” Arc<Mutex<T>> allows access to its contents from multiple threads, purely taking care of ownership and mutability issues, so if the underlying type cannot be transferred across thread boundaries it won’t help. You may well need to do all your ncurses operations from one thread.
Raw pointers explicitly do not implement Send because there can be no guarantees about it. You can construct types on top of it which explicitly implement Send, thus providing a guarantee that the contained raw pointer is in fact safe for transferring across thread boundaries.

Type cast vs type assertion on concrete struct?

I am new to golang, so appologize if this question is too naive. Looked around, but could not find answer to my basic question.
Lets say I have a concrete struct and methods as shown below.
type MyData struct{
field1 string
field2 int
}
func(a MyData) OperatorOnString() string{
return a.field1.(string)
}
func(a MyData) OperatorOnInt() int{
return a.field2.(int)
}
My question is, can I type cast and return rather than performing assertion? From what I have learned so far is that, assertion is used on data of type interface. But in this case I have concrete type. Should I still use assertion or I can do something like return int(a.field2). I know this example is trivial, but the point that I am confused is when to use between the two conversion types. Or is there some golang idiomaticity involved here?
Thanks
First of all, type assertion can be used only on interfaces:
For an expression x of interface type and a type T, the primary expression
x.(T)
asserts that x is not nil and that the value stored in x is of type T. The notation x.(T) is called a type assertion.
But you're applying it to non interface typed fields (int and string). That makes compiler unhappy.
Secondly, if you want to return type T from a method/function, it's always enough to return an expression of type T, which your fields already happen to be. The correct code is then easy:
package main
import "fmt"
type MyData struct {
field1 string
field2 int
}
func (a MyData) OperatorOnString() string {
return a.field1
}
func (a MyData) OperatorOnInt() int {
return a.field2
}
func main() {
a := MyData{"foo", 42}
fmt.Println(a.OperatorOnString(), a.OperatorOnInt())
}
Playground
Output:
foo 42