Skip to content

Commit a2329e0

Browse files
Rollup merge of rust-lang#107941 - compiler-errors:str-has-u8-slice-for-auto, r=lcnr
Treat `str` as containing `[u8]` for auto trait purposes Wanted to gauge `@rust-lang/lang` and `@rust-lang/types` teams' thoughts on treating `str` as "containing" a `[u8]` slice for auto-trait purposes. `@dtolnay` brought this up in rust-lang#13231 (comment) as a blocker for future `str` type librarification, and I think it's both a valid concern and very easy to fix. I'm interested in actually doing that `str` type librarification (rust-lang#107939), but this probably should be considered in the mean time regardless of that PR. r? types for the impl, though this definitely needs an FCP.
2 parents 9960a3e + e9a8ff7 commit a2329e0

File tree

5 files changed

+36
-2
lines changed

5 files changed

+36
-2
lines changed

compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
2020
| ty::Float(_)
2121
| ty::FnDef(..)
2222
| ty::FnPtr(_)
23-
| ty::Str
2423
| ty::Error(_)
2524
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
2625
| ty::Never
2726
| ty::Char => Ok(vec![]),
2827

28+
// Treat this like `struct str([u8]);`
29+
ty::Str => Ok(vec![infcx.tcx.mk_slice(infcx.tcx.types.u8)]),
30+
2931
ty::Dynamic(..)
3032
| ty::Param(..)
3133
| ty::Foreign(..)

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3107,6 +3107,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
31073107
self.tcx.def_span(def_id),
31083108
"required because it's used within this closure",
31093109
),
3110+
ty::Str => err.note("`str` is considered to contain a `[u8]` slice for auto trait purposes"),
31103111
_ => err.note(&msg),
31113112
};
31123113
}

compiler/rustc_trait_selection/src/traits/select/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2300,12 +2300,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
23002300
| ty::Float(_)
23012301
| ty::FnDef(..)
23022302
| ty::FnPtr(_)
2303-
| ty::Str
23042303
| ty::Error(_)
23052304
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
23062305
| ty::Never
23072306
| ty::Char => ty::Binder::dummy(Vec::new()),
23082307

2308+
// Treat this like `struct str([u8]);`
2309+
ty::Str => ty::Binder::dummy(vec![self.tcx().mk_slice(self.tcx().types.u8)]),
2310+
23092311
ty::Placeholder(..)
23102312
| ty::Dynamic(..)
23112313
| ty::Param(..)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(negative_impls)]
2+
#![feature(auto_traits)]
3+
4+
auto trait AutoTrait {}
5+
6+
impl<T> !AutoTrait for [T] {}
7+
8+
fn needs_auto_trait<T: AutoTrait + ?Sized>() {}
9+
10+
fn main() {
11+
needs_auto_trait::<str>();
12+
//~^ ERROR the trait bound `[u8]: AutoTrait` is not satisfied in `str`
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0277]: the trait bound `[u8]: AutoTrait` is not satisfied in `str`
2+
--> $DIR/str-contains-slice-conceptually.rs:11:22
3+
|
4+
LL | needs_auto_trait::<str>();
5+
| ^^^ within `str`, the trait `AutoTrait` is not implemented for `[u8]`
6+
|
7+
= note: `str` is considered to contain a `[u8]` slice for auto trait purposes
8+
note: required by a bound in `needs_auto_trait`
9+
--> $DIR/str-contains-slice-conceptually.rs:8:24
10+
|
11+
LL | fn needs_auto_trait<T: AutoTrait + ?Sized>() {}
12+
| ^^^^^^^^^ required by this bound in `needs_auto_trait`
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)