diff options
| author | Michael Goulet <michael@errs.io> | 2023-02-11 23:01:22 +0000 |
|---|---|---|
| committer | Michael Goulet <michael@errs.io> | 2023-02-25 20:01:33 +0000 |
| commit | 3560e65c444ea0d3069ca83ba1b706ae9e5a85c9 (patch) | |
| tree | 4aebf066a62f9ff29f8f9977f93d5043d92b2059 | |
| parent | 31448badfd74ea72d2c8622cc60d3dca889ef7d4 (diff) | |
| download | rust-3560e65c444ea0d3069ca83ba1b706ae9e5a85c9.tar.gz rust-3560e65c444ea0d3069ca83ba1b706ae9e5a85c9.zip | |
Treat `str` as containing `[u8]` for auto trait purposes
4 files changed, 35 insertions, 2 deletions
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 3a887f54587..6d15c952c99 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 @@ -20,12 +20,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![tcx.mk_slice(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 a2c16e6d0b4..01c1ad3a4ce 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2300,12 +2300,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 00000000000..6a16fdcf284 --- /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<T> !AutoTrait for [T] {} + +fn needs_auto_trait<T: AutoTrait + ?Sized>() {} + +fn main() { + needs_auto_trait::<str>(); + //~^ 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 00000000000..755fc69972e --- /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::<str>(); + | ^^^ 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<T: AutoTrait + ?Sized>() {} + | ^^^^^^^^^ required by this bound in `needs_auto_trait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. |
