So as I'm learning rust so I wanted to write a wrapper for uart in stm32l0xx-hal as understand it, the error I keep getting is the USART template in impl is different to struct declaration
the code:
pub struct Uart<USART, TX, RX> {
_tx: serial::Tx<USART>,
_rx: serial::Rx<USART>,
_tx_pin: TX,
_rx_pin: RX
}
impl<USART: serial::Serial2Ext<TX,RX>, TX, RX> Uart<USART, TX,RX> {
pub fn new
(usart: USART, mut rcc: rcc::Rcc, tx_pin: TX, rx_pin: RX) -> Self {
let serial = usart
.usart(tx_pin, rx_pin, serial::Config::default(), &mut rcc)
.unwrap();
let (tx, rx) = serial.split();
Uart{
_tx : tx, // <- error
_rx : rx, // <- error
_tx_pin : tx_pin,
_rx_pin : rx_pin
}
}
}
the error:
error[E0308]: mismatched types
--> src/uart.rs:28:19
|
17 | impl<USART: serial::Serial2Ext<TX,RX>, TX, RX> Uart<USART, TX,RX> {
| ----- expected this type parameter
...
28 | _tx : tx,
| ^^ expected `Tx<USART>`, found `Tx<USART2>`
|
= note: expected struct `stm32l0xx_hal::serial::Tx<USART>`
found struct `stm32l0xx_hal::serial::Tx<stm32l0xx_hal::serial::USART2>`
stm32l0xx_hal::serial::USART2
- is the type of usart that I pass to the new function
The problem is that you are lying to the compiler: The new
-function as written in it's impl
-block says that it will return any Uart<USART, TX, RX>
that the caller chose (as long as USART: serial::Serial2Ext<TX,RX>
). But then, instead of assigning to _tx
a value of the caller-chose generic type UART
, it tries to assign the specific type UART2
. That would work if UART
was UART2
, but the impl
-block doesn't say that.
It would be possible to keep the generics around if Serial2Ext
had defined an associated type, so one would have been be able to constraint the impl
("this type here is not yet defined, but it is whatever Serial2Ext
says will be returned from uart()
for the given (TX, RS)
). Since it does not, one can't do that. So it's not possible - without adding even more code - to have UART
be a generic type and use a specific type at the same time.
The simplest way would be to remove the generic parameter UART
and replace it with the specific type UART2
, since this is what Serial2Ext::uart
will return in the Ok
-case.