Use trait from submodule with same name as struct - module

Trying to compile the following Rust code
mod traits {
pub trait Dog {
fn bark(&self) {
println!("Bow");
}
}
}
struct Dog;
impl traits::Dog for Dog {}
fn main() {
let dog = Dog;
dog.bark();
}
gives the error message
error[E0599]: no method named `bark` found for type `Dog` in the current scope
--> src/main.rs:15:9
|
9 | struct Dog;
| ----------- method `bark` not found for this
...
15 | dog.bark();
| ^^^^
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope, perhaps add a `use` for it:
|
1 | use crate::traits::Dog;
|
If I add use crate::traits::Dog;, the error becomes:
error[E0255]: the name `Dog` is defined multiple times
--> src/main.rs:11:1
|
1 | use crate::traits::Dog;
| ------------------ previous import of the trait `Dog` here
...
11 | struct Dog;
| ^^^^^^^^^^^ `Dog` redefined here
|
= note: `Dog` must be defined only once in the type namespace of this module
If I rename trait Dog to trait DogTrait, everything works. How can I use a trait from a submodule that has the same name as a struct in my main module?

You could rename the trait when importing it to get the same result without renaming the trait globally:
use traits::Dog as DogTrait;
The compiler now even suggests this:
help: you can use `as` to change the binding name of the import
|
1 | use crate::traits::Dog as OtherDog;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
documentation

If you don't wish to import both (or can't for whatever reason), you can use Fully Qualified Syntax (FQS) to use the trait's method directly:
fn main() {
let dog = Dog;
traits::Dog::bark(&dog);
}

Related

Why do lines 14 and 21 not compile (for my Kotlin function)?

I have a function named collectCustomizerFunctions which should create a MutableList<KCallable<*>> of all the functions of a specified class and its sub-classes which are annotated with CustomizerFunction.
Recursively, customizerFuns (the MutableList<KCallable<*>>) should have all of the "cutomizer functions" added to it.
When I try to build my Gradle project, it fails with two exceptions:
e: collectCustomizerFuns.kt:14:33 Type inference failed. The value of the type parameter T should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly.
e: collectCustomizerFuns.kt:21:30 Type mismatch: inferred type is Any but CapturedType(*) was expected
Here is my code:
3 | import kotlin.reflect.KClass
4 | import kotlin.reflect.KCallable
5 | import kotlin.reflect.full.allSuperclasses
6 |
7 | #Utility
8 | public tailrec fun <T: Any> collectCustomizerFuns(
9 | specClass: KClass<T>,
10 | customizerFuns: MutableList<KCallable<*>>
11 | ): Unit {
12 | // add annotated functions of this class
13 | for (member in specClass.members) {
14 | if (CustomizerFunction::class in member.annotations) { <--- ERROR
15 | customizerFuns.add(member)
16 | } else {}
17 | }
18 |
19 | // add annotated functions of all super-classes
20 | for (superclass in specClass.allSuperclasses) {
21 | collectCustomizerFuns<Any>(superclass, customizerFuns) <--- ERROR
22 | }
23 | }
I have been trying to fix these bugs for a while now, and would appreciate any help!
Also, please provide any constructive criticism you want regarding this function, it would help a lot!
For the first error, member.annotations returns List<Annotation>. You have to fetch actual classes of these annotations.
For the second error, remove the type where you call collectCustomizerFuns. Let kotlin infers the type by itself :).
So try this:
public tailrec fun <T: Any> collectCustomizerFuns(
specClass: KClass<T>,
customizerFuns: MutableList<KCallable<*>>
) {
// add annotated functions of this class
for (member in specClass.members) {
if (CustomizerFunction::class in member.annotations.map { it.annotationClass }) {
customizerFuns.add(member)
} else {
}
}
// add annotated functions of all super-classes
for (superclass in specClass.allSuperclasses ) {
collectCustomizerFuns(superclass, customizerFuns)
}
}
By the way, you can remove Unit from the method signature.

Vlang module calls confusion

Basics
| main.v
| beta.v
|
|__ parent
| mod1.v
|
|__ child
| mod2.v
Codes:
main.v
import parent
import parent.child as pc
fn main(){
parent.name_parent()
pc.name_child()
}
mod1.v
module parent
pub fn name_parent(){
println('Parent!!!')
}
mod2.v
module child
pub fn name_child(){
println('child!!!')
}
beta.v
pub fn beta_test(){
println('Beta!!!')
}
Need some insight on the module structure:
Error when I run main.v to access child directory.
*error: unknown function: parent.child.name_child*
How to access beta.v function from main.v ?

How do I define a from method to convert the error in a foreign result type? [duplicate]

This question already has answers here:
Is it possible to implement methods on type aliases?
(1 answer)
Rust proper error handling (auto convert from one error type to another with question mark)
(5 answers)
How to do error handling in Rust and what are the common pitfalls?
(2 answers)
Closed 2 years ago.
I have a pair of Result type aliases, AResult and BResult. AResult is from another crate, and embeds its own error type AError. I have my result (BResult) and I want to convert errors from AError to BError so I can embed them in the BResults that I return.
TIO demo
struct AError(u32);
struct BError(i64);
type AResult = Result<(), AError>;
type BResult = Result<(), BError>;
impl From<AError> for BError {
fn from(item: AError) -> Self {
(item as i64)
}
}
impl From<AResult> for BResult {
fn from(item: AResult) -> Self {
item.map_err(BError::from)
}
}
fn main() {
let result_as_a: AResult = Err(5u32);
let result_as_b = result_as_a;
if let Err(value) = result_as_b {
print!("{}", value);
}
}
I have defined a conversion for the errors from AError to BError (impl From<AError> for BError { ... }) and I'm trying to define a conversion for the Result which uses it, thinking I could do:
impl From<AResult> for BResult {
fn from(item: AResult) -> Self {
item.map_err(BError::from)
}
}
But Rust complains that I can't define things from another crate:
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
--> src/main.rs:12:1
|
12 | impl From<AResult> for BResult {
| ^^^^^-------------^^^^^-------
| | | |
| | | `std::result::Result` is not defined in the current crate
| | `std::result::Result` is not defined in the current crate
| impl doesn't use only types from inside the current crate
|
= note: define and implement a trait or new type instead
I'm trying to define an implementation on BResult, not AResult?!
Am I doing something very stupid? Is there a better way to do this?

Why Isn't This Module Visible?

I'm coding a hash in Rust for practice. The code looks like this:
pub fn get_fnv1a32(to_hash:&str) -> u32{
const OFFSET_BASIS:u32 = 2_166_136_261;
const PRIME:u32 = 16_777_619;
if !to_hash.is_empty(){
let mut hash = OFFSET_BASIS;
for b in to_hash.bytes(){
hash = hash ^ (b as u32);
hash = hash.wrapping_mul(PRIME);
}
hash
}
else
{
0
}
}
And this is the code I'm trying to use to test this:
mod fnv;
#[cfg(test)]
mod tests {
#[test]
fn get_correct_hash(){
assert_eq!(0x7a78f512, fnv::get_fnv1a32("Hello world!"));
}
#[test]
fn hash_handles_empty_string_correctly(){
assert_eq!(0, fnv::get_fnv1a32(""));
}
}
The test code is in lib.rs and the get_fnv1a32 function is in fnv.rs. They're both in the same directory. But when I try to run cargo test I keep getting these messages:
Compiling hashes v0.1.0 (U:\skunkworks\rust\hashes)
warning: function is never used: `get_fnv1a32`
--> src\fnv.rs:1:8
|
1 | pub fn get_fnv1a32(to_hash:&str) -> u32{
| ^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
error[E0433]: failed to resolve: use of undeclared type or module `fnv`
--> src\lib.rs:7:32
|
7 | assert_eq!(0x7a78f512, fnv::get_fnv1a32("Hello world!"));
| ^^^ use of undeclared type or module `fnv`
error[E0433]: failed to resolve: use of undeclared type or module `fnv`
--> src\lib.rs:12:23
|
12 | assert_eq!(0, fnv::get_fnv1a32(""));
| ^^^ use of undeclared type or module `fnv`
error: aborting due to 2 previous errors
I can't figure out what I'm doing wrong. I tried changing the mod fnv; line at the top to pub mod fnv; and that gets rid of the dead code warning but it doesn't fix the two errors. What do I need to do to get the get_fnv1a32 function to be visible in the lib.rs file?
Not that I would think it would matter but the version of rustc is rustc 1.41.0 (5e1a79984 2020-01-27)
The test module is separate from the outer module. Add
use super::*;
or an equivalent statement like use crate::fnv inside the tests module to make the fnv module visible.

Returning a boxed iterator over a value in a structure [duplicate]

This question already has answers here:
Why is adding a lifetime to a trait with the plus operator (Iterator<Item = &Foo> + 'a) needed?
(1 answer)
What is the correct way to return an Iterator (or any other trait)?
(2 answers)
Closed 5 years ago.
I want a function on a struct which returns an iterator to one of the struct's members. I tried something like the following, which doesn't work.
struct Foo {
bar: Vec<String>,
}
impl Foo {
fn baz(&self) -> Box<Iterator<Item = &String>> {
Box::new(self.bar.iter())
}
}
fn main() {
let x = Foo { bar: vec!["quux".to_string()] };
x.baz();
}
When compiling, I get the error below:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:7:27
|
7 | Box::new(self.bar.iter())
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
--> src/main.rs:6:5
|
6 | / fn baz(&self) -> Box<Iterator<Item = &String>> {
7 | | Box::new(self.bar.iter())
8 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:7:18
|
7 | Box::new(self.bar.iter())
| ^^^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that expression is assignable (expected std::boxed::Box<std::iter::Iterator<Item=&std::string::String> + 'static>, found std::boxed::Box<std::iter::Iterator<Item=&std::string::String>>)
--> src/main.rs:7:9
|
7 | Box::new(self.bar.iter())
| ^^^^^^^^^^^^^^^^^^^^^^^^^
I also tried adding lifetime information as suggested elsewhere
struct Foo {
bar: Vec<String>,
}
impl Foo {
fn baz<'a>(&self) -> Box<Iterator<Item = &String> + 'a> {
Box::new(self.bar.iter())
}
}
fn main() {
let x = Foo { bar: vec!["quux".to_string()] };
x.baz();
}
Now my error is the following:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:7:27
|
7 | Box::new(self.bar.iter())
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 6:5...
--> src/main.rs:6:5
|
6 | / fn baz<'a>(&self) -> Box<Iterator<Item = &String> + 'a> {
7 | | Box::new(self.bar.iter())
8 | | }
| |_____^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:7:18
|
7 | Box::new(self.bar.iter())
| ^^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the method body at 6:5...
--> src/main.rs:6:5
|
6 | / fn baz<'a>(&self) -> Box<Iterator<Item = &String> + 'a> {
7 | | Box::new(self.bar.iter())
8 | | }
| |_____^
note: ...so that expression is assignable (expected std::boxed::Box<std::iter::Iterator<Item=&std::string::String> + 'a>, found std::boxed::Box<std::iter::Iterator<Item=&std::string::String>>)
--> src/main.rs:7:9
|
7 | Box::new(self.bar.iter())
| ^^^^^^^^^^^^^^^^^^^^^^^^^