From bf1afe136d65fbd461e273f1c9d855d985b8cd80 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 Feb 2023 23:01:22 +0000 Subject: [PATCH 1/2] Treat `str` as containing `[u8]` for auto trait purposes --- .../src/solve/trait_goals/structural_traits.rs | 4 +++- .../src/traits/select/mod.rs | 4 +++- .../str-contains-slice-conceptually.rs | 13 +++++++++++++ .../str-contains-slice-conceptually.stderr | 16 ++++++++++++++++ 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 tests/ui/auto-traits/str-contains-slice-conceptually.rs create mode 100644 tests/ui/auto-traits/str-contains-slice-conceptually.stderr diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs index 1ee35a86e6264..7570ceaacf604 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs @@ -18,12 +18,14 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( | ty::Float(_) | ty::FnDef(..) | ty::FnPtr(_) - | ty::Str | ty::Error(_) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Never | ty::Char => Ok(vec![]), + // Treat this like `struct str([u8]);` + ty::Str => Ok(vec![infcx.tcx.mk_slice(infcx.tcx.types.u8)]), + ty::Dynamic(..) | ty::Param(..) | ty::Foreign(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 45c4811321a01..d25cd0203b9e8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2250,12 +2250,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Float(_) | ty::FnDef(..) | ty::FnPtr(_) - | ty::Str | ty::Error(_) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Never | ty::Char => ty::Binder::dummy(Vec::new()), + // Treat this like `struct str([u8]);` + ty::Str => ty::Binder::dummy(vec![self.tcx().mk_slice(self.tcx().types.u8)]), + ty::Placeholder(..) | ty::Dynamic(..) | ty::Param(..) diff --git a/tests/ui/auto-traits/str-contains-slice-conceptually.rs b/tests/ui/auto-traits/str-contains-slice-conceptually.rs new file mode 100644 index 0000000000000..6a16fdcf2842f --- /dev/null +++ b/tests/ui/auto-traits/str-contains-slice-conceptually.rs @@ -0,0 +1,13 @@ +#![feature(negative_impls)] +#![feature(auto_traits)] + +auto trait AutoTrait {} + +impl !AutoTrait for [T] {} + +fn needs_auto_trait() {} + +fn main() { + needs_auto_trait::(); + //~^ ERROR the trait bound `[u8]: AutoTrait` is not satisfied in `str` +} diff --git a/tests/ui/auto-traits/str-contains-slice-conceptually.stderr b/tests/ui/auto-traits/str-contains-slice-conceptually.stderr new file mode 100644 index 0000000000000..755fc69972e7c --- /dev/null +++ b/tests/ui/auto-traits/str-contains-slice-conceptually.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `[u8]: AutoTrait` is not satisfied in `str` + --> $DIR/str-contains-slice-conceptually.rs:11:22 + | +LL | needs_auto_trait::(); + | ^^^ within `str`, the trait `AutoTrait` is not implemented for `[u8]` + | + = note: required because it appears within the type `str` +note: required by a bound in `needs_auto_trait` + --> $DIR/str-contains-slice-conceptually.rs:8:24 + | +LL | fn needs_auto_trait() {} + | ^^^^^^^^^ required by this bound in `needs_auto_trait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From e9a8ff72b7be4780a6c309c9c21c5a952756bc35 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 14 Feb 2023 21:19:39 +0000 Subject: [PATCH 2/2] Special note for str in auto traits --- .../src/traits/error_reporting/suggestions.rs | 1 + tests/ui/auto-traits/str-contains-slice-conceptually.stderr | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 048a547199419..d458ed51e8a6c 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3102,6 +3102,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.tcx.def_span(def_id), "required because it's used within this closure", ), + ty::Str => err.note("`str` is considered to contain a `[u8]` slice for auto trait purposes"), _ => err.note(&msg), }; } diff --git a/tests/ui/auto-traits/str-contains-slice-conceptually.stderr b/tests/ui/auto-traits/str-contains-slice-conceptually.stderr index 755fc69972e7c..1cf16cebddd15 100644 --- a/tests/ui/auto-traits/str-contains-slice-conceptually.stderr +++ b/tests/ui/auto-traits/str-contains-slice-conceptually.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `[u8]: AutoTrait` is not satisfied in `str` LL | needs_auto_trait::(); | ^^^ within `str`, the trait `AutoTrait` is not implemented for `[u8]` | - = note: required because it appears within the type `str` + = note: `str` is considered to contain a `[u8]` slice for auto trait purposes note: required by a bound in `needs_auto_trait` --> $DIR/str-contains-slice-conceptually.rs:8:24 |