Description
All traits with unconstrained associated types have been removed as we prepare the 1.0.0 release. We are aware that this will be problematic in the short term but agreed it is the best way forward for embedded-hal
(see the reasoning below).
This includes these traits, which are available on the 0.2.x
versions:
- adc::OneShot
- adc::Channel
- capture::Capture
- digital::IoPin
- pwm::Pwm
- pwm::PwmPin
- qei::Qei
- serial::Read
-> embedded-io
- serial::Write
-> embedded-io
- timer::Cancel
- timer::CountDown
- timer::Periodic
- watchdog::Disable
- watchdog::Enable
- watchdog::Watchdog
Why
Traits defined in embedded-hal
pursue creating an interface for interoperability between generic code (be it generic user code, generic application code, generic device drivers, etc.).
When a trait has an unconstrained associated type, it is not possible to write generic code around it. Each side (implementer and user) need to specify which type the associated type will be. If the types match, the both parts can work together, however, this is not truly generic code.
For example, if somebody creates a device driver that receives a CountDown
struct, it needs to specify what its Time
type should be. If they choose a type coming from fugit
, somebody else cannot use this driver if the HAL implementation for the MCU they are using only provides CountDown
with Time
types defined in embedded-time
. It is also not possible for the user to implement CountDown
for Time
types defined by fugit
in a straight-forward way due to the orphan rule.
In summary, it is not possible for anybody to start a countdown for a certain duration in a generic way, without it being tied to a particular time implementation and thus forcing everybody to use that one.
In the case of the digital::IoPin
trait, some problems about it usage have been surfaced (#340) that have moved us to remove it for the 1.0.0 release as well.
We want to avoid the need for a semver-incompatible embedded-hal
release (i.e. 2.0) for as long as possible. As such, the best compromise is to remove the traits before the release and add at least some of them back later.
The way forward
As stated above, we have removed these traits ahead of the 1.0.0 release but plan to add at least some of them back in a future semver-compatible release like 1.1.x, once we find suitable bounds for the associated types.
Some problems on these traits have been highlighted as well (see open issues), so removing them also gives us the chance to rethink them.
How to get them back
The most pressing issue is finding suitable bounds for time/duration types which make these traits usable in pretty much any situation.
See: #211, #122, #59, #24.
Please have a look at the issues for each of the removed traits/modules for further details.
What to do in the mean time
HALs that implement these traits, have at least the following options:
- Continue offering implementations using the traits from the embedded-hal 0.2.x versions which should reduce the ecosystem fragmentation and keep any dependent code working.
- Copy the removed traits into the HALs and keep everything as-is.
- Offer only inherent methods on the structs.
- Remove the implementations.
Generic code can do their version of these options as well for now.