diff options
| author | DrMeepster <19316085+DrMeepster@users.noreply.github.com> | 2023-04-16 14:13:29 -0700 |
|---|---|---|
| committer | DrMeepster <19316085+DrMeepster@users.noreply.github.com> | 2023-04-21 02:14:03 -0700 |
| commit | b92c2f792c33fbb180358997c5368f336f8912d2 (patch) | |
| tree | 810354c07ce694399c29c46949fc722e48aa712e | |
| parent | b95852b93c8a7b70f9238b0bbd787de68c9241bd (diff) | |
| download | rust-b92c2f792c33fbb180358997c5368f336f8912d2.tar.gz rust-b92c2f792c33fbb180358997c5368f336f8912d2.zip | |
fix incorrect param env in dead code lint
| -rw-r--r-- | compiler/rustc_passes/src/dead.rs | 9 | ||||
| -rw-r--r-- | library/core/tests/mem.rs | 2 | ||||
| -rw-r--r-- | tests/ui/lint/dead-code/offset-of-correct-param-env.rs | 40 | ||||
| -rw-r--r-- | tests/ui/lint/dead-code/offset-of.rs (renamed from tests/ui/liveness/liveness-offset-of.rs) | 0 | ||||
| -rw-r--r-- | tests/ui/lint/dead-code/offset-of.stderr (renamed from tests/ui/liveness/liveness-offset-of.stderr) | 0 |
5 files changed, 46 insertions, 5 deletions
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 82b55df106c..170b0b91e57 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -242,7 +242,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { let &(container, ref indices) = data.get(expr.hir_id).expect("no offset_of_data for offset_of"); - let mut last_did = expr.hir_id.owner.to_def_id(); + let body_did = self.typeck_results().hir_owner.to_def_id(); + let param_env = self.tcx.param_env(body_did); + let mut current_ty = container; for &index in indices { @@ -253,15 +255,14 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { self.insert_def_id(field.did); let field_ty = field.ty(self.tcx, subst); - last_did = field.did; current_ty = - self.tcx.normalize_erasing_regions(self.tcx.param_env(field.did), field_ty); + self.tcx.normalize_erasing_regions(param_env, field_ty); } // we don't need to mark tuple fields as live, // but we may need to mark subfields ty::Tuple(tys) => { current_ty = self.tcx.normalize_erasing_regions( - self.tcx.param_env(last_did), + param_env, tys[index.as_usize()], ); } diff --git a/library/core/tests/mem.rs b/library/core/tests/mem.rs index 2351406ddd2..b2a7df6b2e9 100644 --- a/library/core/tests/mem.rs +++ b/library/core/tests/mem.rs @@ -458,4 +458,4 @@ fn offset_of_addr() { assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, y), ptr::addr_of!(base.y).addr()); assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.0), ptr::addr_of!(base.z.0).addr()); assert_eq!(ptr::addr_of!(base).addr() + offset_of!(Foo, z.1), ptr::addr_of!(base.z.1).addr()); -} +} \ No newline at end of file diff --git a/tests/ui/lint/dead-code/offset-of-correct-param-env.rs b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs new file mode 100644 index 00000000000..b7444049a88 --- /dev/null +++ b/tests/ui/lint/dead-code/offset-of-correct-param-env.rs @@ -0,0 +1,40 @@ +// check-pass + +#![feature(offset_of)] +#![deny(dead_code)] + +// This struct contains a projection that can only be normalized after getting the field type. +struct A<T: Project> { + a: <T as Project>::EquateParamTo, +} + +// This is the inner struct that we want to get. +struct MyFieldIsNotDead { + not_dead: u8, +} + +// These are some helpers. +// Inside the param env of `test`, we want to make it so that it considers T=MyFieldIsNotDead. +struct GenericIsEqual<T>(T); +trait Project { + type EquateParamTo; +} +impl<T> Project for GenericIsEqual<T> { + type EquateParamTo = T; +} + +fn test<T>() -> usize +where + GenericIsEqual<T>: Project<EquateParamTo = MyFieldIsNotDead>, +{ + // The first field of the A that we construct here is `<GenericIsEqual<T>> as Project>::EquateParamTo`. + // Typeck normalizes this and figures that the not_dead field is totally fine and accessible. + // But importantly, the normalization ends up with T, which, as we've declared in our param env is MyFieldDead. + // When we're in the param env of the `a` field, the where bound above is not in scope, so we don't know what T is - it's generic. + // We cannot access a field on T. Boom! + std::mem::offset_of!(A<GenericIsEqual<T>>, a.not_dead) +} + +fn main() { + test::<MyFieldIsNotDead>(); +} \ No newline at end of file diff --git a/tests/ui/liveness/liveness-offset-of.rs b/tests/ui/lint/dead-code/offset-of.rs index da91de3862f..da91de3862f 100644 --- a/tests/ui/liveness/liveness-offset-of.rs +++ b/tests/ui/lint/dead-code/offset-of.rs diff --git a/tests/ui/liveness/liveness-offset-of.stderr b/tests/ui/lint/dead-code/offset-of.stderr index afc4c590eeb..afc4c590eeb 100644 --- a/tests/ui/liveness/liveness-offset-of.stderr +++ b/tests/ui/lint/dead-code/offset-of.stderr |
