diff options
| author | bors <bors@rust-lang.org> | 2023-11-08 20:42:32 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-11-08 20:42:32 +0000 |
| commit | fdaaaf9f923281ab98b865259aa40fbf93d72c7a (patch) | |
| tree | 3a4c4d48c50672184c66f5f4605aade7275e864e /compiler/rustc_mir_build/src/thir | |
| parent | 90fdc1fc270fef7d1a999207f1da29b41da70dac (diff) | |
| parent | 30588657b753b9ae500b3514d58da18a4a155b08 (diff) | |
| download | rust-fdaaaf9f923281ab98b865259aa40fbf93d72c7a.tar.gz rust-fdaaaf9f923281ab98b865259aa40fbf93d72c7a.zip | |
Auto merge of #116930 - RalfJung:raw-ptr-match, r=davidtwco
patterns: reject raw pointers that are not just integers Matching against `0 as *const i32` is fine, matching against `&42 as *const i32` is not. This extends the existing check against function pointers and wide pointers: we now uniformly reject all these pointer types during valtree construction, and then later lint because of that. See [here](https://github.com/rust-lang/rust/pull/116930#issuecomment-1784654073) for some more explanation and context. Also fixes https://github.com/rust-lang/rust/issues/116929. Cc `@oli-obk` `@lcnr`
Diffstat (limited to 'compiler/rustc_mir_build/src/thir')
| -rw-r--r-- | compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index fc03f7891a8..48a590f5d37 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -123,6 +123,8 @@ impl<'tcx> ConstToPat<'tcx> { }); debug!(?check_body_for_struct_match_violation, ?mir_structural_match_violation); + let have_valtree = + matches!(cv, mir::Const::Ty(c) if matches!(c.kind(), ty::ConstKind::Value(_))); let inlined_const_as_pat = match cv { mir::Const::Ty(c) => match c.kind() { ty::ConstKind::Param(_) @@ -209,16 +211,6 @@ impl<'tcx> ConstToPat<'tcx> { } else if !self.saw_const_match_lint.get() { if let Some(mir_structural_match_violation) = mir_structural_match_violation { match non_sm_ty.kind() { - ty::RawPtr(pointee) - if pointee.ty.is_sized(self.tcx(), self.param_env) => {} - ty::FnPtr(..) | ty::RawPtr(..) => { - self.tcx().emit_spanned_lint( - lint::builtin::POINTER_STRUCTURAL_MATCH, - self.id, - self.span, - PointerPattern, - ); - } ty::Adt(..) if mir_structural_match_violation => { self.tcx().emit_spanned_lint( lint::builtin::INDIRECT_STRUCTURAL_MATCH, @@ -236,19 +228,15 @@ impl<'tcx> ConstToPat<'tcx> { } } } - } else if !self.saw_const_match_lint.get() { - match cv.ty().kind() { - ty::RawPtr(pointee) if pointee.ty.is_sized(self.tcx(), self.param_env) => {} - ty::FnPtr(..) | ty::RawPtr(..) => { - self.tcx().emit_spanned_lint( - lint::builtin::POINTER_STRUCTURAL_MATCH, - self.id, - self.span, - PointerPattern, - ); - } - _ => {} - } + } else if !have_valtree && !self.saw_const_match_lint.get() { + // The only way valtree construction can fail without the structural match + // checker finding a violation is if there is a pointer somewhere. + self.tcx().emit_spanned_lint( + lint::builtin::POINTER_STRUCTURAL_MATCH, + self.id, + self.span, + PointerPattern, + ); } // Always check for `PartialEq`, even if we emitted other lints. (But not if there were @@ -389,11 +377,19 @@ impl<'tcx> ConstToPat<'tcx> { subpatterns: self .field_pats(cv.unwrap_branch().iter().copied().zip(fields.iter()))?, }, - ty::Adt(def, args) => PatKind::Leaf { - subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip( - def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx(), args)), - ))?, - }, + ty::Adt(def, args) => { + assert!(!def.is_union()); // Valtree construction would never succeed for unions. + PatKind::Leaf { + subpatterns: self.field_pats( + cv.unwrap_branch().iter().copied().zip( + def.non_enum_variant() + .fields + .iter() + .map(|field| field.ty(self.tcx(), args)), + ), + )?, + } + } ty::Slice(elem_ty) => PatKind::Slice { prefix: cv .unwrap_branch() @@ -480,10 +476,15 @@ impl<'tcx> ConstToPat<'tcx> { } } }, - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) => { + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::RawPtr(..) => { + // The raw pointers we see here have been "vetted" by valtree construction to be + // just integers, so we simply allow them. PatKind::Constant { value: mir::Const::Ty(ty::Const::new_value(tcx, cv, ty)) } } - ty::FnPtr(..) | ty::RawPtr(..) => unreachable!(), + ty::FnPtr(..) => { + // Valtree construction would never succeed for these, so this is unreachable. + unreachable!() + } _ => { let err = InvalidPattern { span, non_sm_ty: ty }; let e = tcx.sess.emit_err(err); |
