Skip to content

Commit e54da71

Browse files
authored
HeaderValue::from_static can be const (#481)
* HeaderValue::from_static can be const * bump MSRV to 1.46.0 for const loop
1 parent 1179d6f commit e54da71

File tree

2 files changed

+30
-6
lines changed

2 files changed

+30
-6
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- stable
2020
- beta
2121
- nightly
22-
- 1.39.0
22+
- 1.46.0
2323

2424
include:
2525
- rust: nightly

src/header/value.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,27 @@ impl HeaderValue {
4949
/// This function panics if the argument contains invalid header value
5050
/// characters.
5151
///
52+
/// Until [Allow panicking in constants](https://github.com/rust-lang/rfcs/pull/2345)
53+
/// makes its way into stable, the panic message at compile-time is
54+
/// going to look cryptic, but should at least point at your header value:
55+
///
56+
/// ```text
57+
/// error: any use of this value will cause an error
58+
/// --> http/src/header/value.rs:67:17
59+
/// |
60+
/// 67 | ([] as [u8; 0])[0]; // Invalid header value
61+
/// | ^^^^^^^^^^^^^^^^^^
62+
/// | |
63+
/// | index out of bounds: the length is 0 but the index is 0
64+
/// | inside `HeaderValue::from_static` at http/src/header/value.rs:67:17
65+
/// | inside `INVALID_HEADER` at src/main.rs:73:33
66+
/// |
67+
/// ::: src/main.rs:73:1
68+
/// |
69+
/// 73 | const INVALID_HEADER: HeaderValue = HeaderValue::from_static("жsome value");
70+
/// | ----------------------------------------------------------------------------
71+
/// ```
72+
///
5273
/// # Examples
5374
///
5475
/// ```
@@ -57,12 +78,15 @@ impl HeaderValue {
5778
/// assert_eq!(val, "hello");
5879
/// ```
5980
#[inline]
60-
pub fn from_static(src: &'static str) -> HeaderValue {
81+
#[allow(unconditional_panic)] // required for the panic circumventon
82+
pub const fn from_static(src: &'static str) -> HeaderValue {
6183
let bytes = src.as_bytes();
62-
for &b in bytes {
63-
if !is_visible_ascii(b) {
64-
panic!("invalid header value");
84+
let mut i = 0;
85+
while i < bytes.len() {
86+
if !is_visible_ascii(bytes[i]) {
87+
([] as [u8; 0])[0]; // Invalid header value
6588
}
89+
i += 1;
6690
}
6791

6892
HeaderValue {
@@ -555,7 +579,7 @@ mod try_from_header_name_tests {
555579
}
556580
}
557581

558-
fn is_visible_ascii(b: u8) -> bool {
582+
const fn is_visible_ascii(b: u8) -> bool {
559583
b >= 32 && b < 127 || b == b'\t'
560584
}
561585

0 commit comments

Comments
 (0)