1# Upgrading from previous releases
2
3- [Version 0.5 → 0.6](#version-05--06)
4- [Version 0.4 → 0.5](#version-04--05)
5- [Version 0.3 → 0.4](#version-03--04)
6- [Version 0.2 → 0.3](#version-02--03)
7- [Version 0.1 → 0.2](#version-01--02)
8
9## Version 0.5 → 0.6
10
11### Minimum supported version of Rust is now 1.31
12
13If you are writing a library, you will need to increase your minimum
14supported version of Rust to 1.31 or better. If you are writing an
15application, you should be able to upgrade your installed compiler by
16the same mechanism that you installed it.
17
18### Backtraces
19
20The `Backtrace` type is now always available, so it is encouraged to
21make liberal use of it in your errors. If you are writing an
22application that displays backtraces, make sure to enable the
23[`backtrace` feature flag](crate::guide::feature_flags) so that
24backtraces are populated when they are created.
25
26Implementations of `Backtrace::default` and `Backtrace::new` have been
27removed and replaced with `GenerateBacktrace::generate`.
28
29The `backtrace-crate` feature flag has been renamed to
30`backtraces-impl-backtrace-crate`. The backtrace returned by
31`ErrorCompat::backtrace` is now the `backtrace::Backtrace` type when
32this flag is enabled, so the implementation of `AsRef` has been
33removed..
34
35### Futures
36
37Support for the standard library features has been stabilized, so the
38feature flag has been renamed from `unstable-futures` to `futures`.
39
40## Version 0.4 → 0.5
41
42### `backtrace(delegate)` replaced with `backtrace`
43
44Previously, if you wanted to delegate backtrace creation to
45another error, you would specify `#[snafu(backtrace(delegate))]`
46on the source field that references the other error.
47
48Now, you specify the simpler `#[snafu(backtrace)]`.  Since source
49fields must be error types, and backtrace fields must be
50`Backtrace` types, this is unambiguous and simplifies the API.
51
52#### Before
53
54```rust,ignore
55#[derive(Debug, Snafu)]
56enum Error {
57    MyVariant {
58        #[snafu(backtrace(delegate))]
59        source: OtherError,
60    },
61}
62```
63
64#### After
65
66```rust,ignore
67#[derive(Debug, Snafu)]
68enum Error {
69    MyVariant {
70        #[snafu(backtrace)]
71        source: OtherError,
72    },
73}
74```
75
76### `source(from)` implies `source`
77
78Previously, if you had wanted to treat a field that wasn't named
79"source" as a source field, *and* you wanted to transform the
80field from another type, you had to specify both
81`#[snafu(source)]` and `#[snafu(source(from(...)))]`.
82
83Now, `#[snafu(source(from(...)))]` implies `#[snafu(source)]` --
84it automatically treats the field as a source field regardless of
85its name, so you can remove the `#[snafu(source)]` attribute.
86
87#### Before
88
89```rust,ignore
90#[derive(Debug, Snafu)]
91enum Error {
92    CauseIsAnError {
93        #[snafu(source)]
94        #[snafu(source(from(Error, Box::new)))]
95        cause: Box<Error>,
96    },
97}
98```
99
100#### After
101
102```rust,ignore
103#[derive(Debug, Snafu)]
104enum Error {
105    CauseIsAnError {
106        #[snafu(source(from(Error, Box::new)))]
107        cause: Box<Error>,
108    },
109}
110```
111
112### New errors for attribute misuse and duplication
113
114Previously, SNAFU would ignore `#[snafu(...)]` attributes that
115were used in invalid locations.  If attributes were duplicated,
116either the first or last would apply (depending on the attribute)
117and the rest would be ignored.
118
119One example is specifying `#[snafu(source(from(...)))]` on an
120enum variant instead of the source field in that variant:
121
122```rust,ignore
123#[derive(Debug, Snafu)]
124enum Error {
125    // This used to be ignored, and will now cause an error:
126    #[snafu(source(from(Error, Box::new)))]
127    MyVariant {
128        source: Box<Error>,
129    },
130}
131```
132
133Now, compiler errors will be emitted that point to any misused or
134duplicated attributes.
135
136## Version 0.3 → 0.4
137
138### `Context` vs. `IntoError`
139
140The `Context` type and related `From` implementations have been
141removed in favor of the [`IntoError`](crate::IntoError) trait. If
142you were making use of this for custom conversions, you will need
143to update your trait bounds:
144
145#### Before
146
147```rust,ignore
148fn example<C, E>(context: C) -> MyType<E>
149where
150    snafu::Context<SomeError, C>: Into<E>;
151```
152
153#### After
154
155```rust,ignore
156fn example<C, E>(context: C) -> MyType<E>
157where
158    C: snafu::IntoError<E, Source = SomeError>,
159    E: std::error::Error + snafu::ErrorCompat;
160```
161
162### `Borrow<std::error::Error>`
163
164SNAFU no longer generates `Borrow<std::error::Error>`
165implementations for SNAFU error types (sorry for the whiplash if
166you were affected by this when upgrading to 0.3).
167
168## Version 0.2 → 0.3
169
170Minimal changes should be required: if you previously implemented
171`Borrow<std::error::Error>` for a SNAFU error type, you should
172remove that implementation and allow SNAFU to implement it for
173you.
174
175## Version 0.1 → 0.2
176
177Support for the `snafu::display` attribute was removed as this
178type of attribute was [never intended to be
179supported][oops]. Since this required a SemVer-incompatible
180version, the attribute format has also been updated and
181normalized.
182
1831. Attributes have been renamed
184    - `snafu_display` and `snafu::display` became `snafu(display)`.
185    - `snafu_visibility` became `snafu(visibility)`
186    - `snafu_backtrace` became `snafu(backtrace)`
187
1881. Support for `snafu_display` with individually-quoted format
189   arguments was removed. Migrate to either the "clean" or "all
190   one string" styles, depending on what version of Rust you are
191   targeting.
192
193[oops]: https://github.com/rust-lang/rust/pull/58899
194
195### Before
196
197```rust,ignore
198#[derive(Debug, Snafu)]
199enum DisplayUpdate {
200    #[snafu::display("Format and {}", argument)]
201    CleanStyle { argument: i32 },
202
203    #[snafu_display("Format and {}", "argument")]
204    QuotedArgumentStyle { argument: i32 },
205
206    #[snafu_display = r#"("Format and {}", argument)"#]
207    AllOneStringStyle { argument: i32 },
208}
209```
210
211```rust,ignore
212#[derive(Debug, Snafu)]
213enum VisibilityUpdate {
214    #[snafu_visibility(pub(crate))]
215    CleanStyle,
216
217    #[snafu_visibility = "pub(crate)"]
218    AllOneStringStyle,
219}
220```
221
222### After
223
224```rust,ignore
225# use snafu::Snafu;
226#[derive(Debug, Snafu)]
227enum DisplayUpdate {
228    #[snafu(display("Format and {}", argument))]
229    CleanStyle { argument: i32 },
230
231    #[snafu(display = r#"("Format and {}", argument)"#)]
232    QuotedArgumentStyle { argument: i32 },
233
234    #[snafu(display = r#"("Format and {}", argument)"#)]
235    AllOneStringStyle { argument: i32 },
236}
237```
238
239```rust,ignore
240# use snafu::Snafu;
241#[derive(Debug, Snafu)]
242enum VisibilityUpdate {
243    #[snafu(visibility(pub(crate)))]
244    CleanStyle,
245
246    #[snafu(visibility = "pub(crate)")]
247    AllOneStringStyle,
248}
249```
250