A few things:
First, I think that as long as we are using explicit !
patterns, there is no problem. As @RalfJung pointed out, the second example -- matching a (T, !)
with a !
pattern -- would not compile. This is why -- to me -- the idea of using lints makes a difference -- it points people in that direction.
If we do not have a lint, though, then people might just write match x { }
-- and then I would still think there is some potential danger. That is, I think that this refactoring could have introduced a bug that was not there before.
In particular, in your example where we started with this:
let x: Uninit<!> = ...;
... // do some stuff
match x.value { }
and then refactored x
to have the type Uninit<(u32, !)>
, I would assume that we have also made changes to the ...
("do some stuff") part of the program. And those changes may mean that the match x.value { }
match is now reachable when it was not before -- and (partially) initialized.