diff options
| author | bors <bors@rust-lang.org> | 2023-02-20 09:25:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-02-20 09:25:51 +0000 |
| commit | e7eaed21d50d7bfb8d614d6ee7fcea940b39185d (patch) | |
| tree | c0edc08f3287e10ebf5518a12bcced4fcb09aa92 /compiler | |
| parent | 7e253a7fb2e2e050021fed32da6fa2ec7bcea0fb (diff) | |
| parent | 758cc957638e4edcfd9985e9f32e46f1dbac1fc1 (diff) | |
| download | rust-e7eaed21d50d7bfb8d614d6ee7fcea940b39185d.tar.gz rust-e7eaed21d50d7bfb8d614d6ee7fcea940b39185d.zip | |
Auto merge of #107969 - b-naber:proj-relate-variance, r=lcnr
Use covariance on type relations of field projection types if possible It's fine to use covariance here unless we're in a mutating context. Fixes https://github.com/rust-lang/rust/issues/96514 Supersedes https://github.com/rust-lang/rust/pull/105958 r? `@lcnr`
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_borrowck/src/type_check/mod.rs | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 004b945eada..5e1334559f5 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -534,7 +534,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { return PlaceTy::from_ty(self.tcx().ty_error()); } } - place_ty = self.sanitize_projection(place_ty, elem, place, location); + place_ty = self.sanitize_projection(place_ty, elem, place, location, context); } if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { @@ -630,12 +630,14 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { } } + #[instrument(skip(self), level = "debug")] fn sanitize_projection( &mut self, base: PlaceTy<'tcx>, pi: PlaceElem<'tcx>, place: &Place<'tcx>, location: Location, + context: PlaceContext, ) -> PlaceTy<'tcx> { debug!("sanitize_projection: {:?} {:?} {:?}", base, pi, place); let tcx = self.tcx(); @@ -713,8 +715,11 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { match self.field_ty(place, base, field, location) { Ok(ty) => { let ty = self.cx.normalize(ty, location); - if let Err(terr) = self.cx.eq_types( + debug!(?fty, ?ty); + + if let Err(terr) = self.cx.relate_types( ty, + self.get_ambient_variance(context), fty, location.to_locations(), ConstraintCategory::Boring, @@ -743,9 +748,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { let ty = self.sanitize_type(place, ty); let ty = self.cx.normalize(ty, location); self.cx - .eq_types( - base.ty, + .relate_types( ty, + self.get_ambient_variance(context), + base.ty, location.to_locations(), ConstraintCategory::TypeAnnotation, ) @@ -760,6 +766,21 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { self.tcx().ty_error() } + fn get_ambient_variance(&self, context: PlaceContext) -> ty::Variance { + use rustc_middle::mir::visit::NonMutatingUseContext::*; + use rustc_middle::mir::visit::NonUseContext::*; + + match context { + PlaceContext::MutatingUse(_) => ty::Invariant, + PlaceContext::NonUse(StorageDead | StorageLive | VarDebugInfo) => ty::Invariant, + PlaceContext::NonMutatingUse( + Inspect | Copy | Move | SharedBorrow | ShallowBorrow | UniqueBorrow | AddressOf + | Projection, + ) => ty::Covariant, + PlaceContext::NonUse(AscribeUserTy) => ty::Covariant, + } + } + fn field_ty( &mut self, parent: &dyn fmt::Debug, |
