Skip to content

Commit a449535

Browse files
committed
Auto merge of #66640 - Centril:rollup-862009l, r=Centril
Rollup of 8 pull requests Successful merges: - #66183 (*Syntactically* permit visibilities on trait items & enum variants) - #66566 (Document pitfall with `impl PartialEq<B> for A`) - #66575 (Remove pretty printing of specific nodes in AST) - #66587 (Handle statics in MIR as const pointers) - #66619 (follow the convention in this file to use third-person singular verbs) - #66633 (Error code's long explanation cleanup) - #66637 (fix reoccuring typo: dereferencable -> dereferenceable) - #66639 (resolve: more declarative `fresh_binding`) Failed merges: r? @ghost
2 parents 5fa0af2 + 56512b9 commit a449535

File tree

86 files changed

+779
-778
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+779
-778
lines changed

src/libcore/cmp.rs

+18-14
Original file line numberDiff line numberDiff line change
@@ -135,17 +135,23 @@ use self::Ordering::*;
135135
/// By changing `impl PartialEq for Book` to `impl PartialEq<BookFormat> for Book`,
136136
/// we allow `BookFormat`s to be compared with `Book`s.
137137
///
138-
/// You can also combine these implementations to let the `==` operator work with
139-
/// two different types:
140-
///
141-
/// ```
138+
/// A comparison like the one above, which ignores some fields of the struct,
139+
/// can be dangerous. It can easily lead to an unintended violation of the
140+
/// requirements for a partial equivalence relation. For example, if we kept
141+
/// the above implementation of `PartialEq<Book>` for `BookFormat` and added an
142+
/// implementation of `PartialEq<Book>` for `Book` (either via a `#[derive]` or
143+
/// via the manual implementation from the first example) then the result would
144+
/// violate transitivity:
145+
///
146+
/// ```should_panic
142147
/// #[derive(PartialEq)]
143148
/// enum BookFormat {
144149
/// Paperback,
145150
/// Hardback,
146151
/// Ebook,
147152
/// }
148153
///
154+
/// #[derive(PartialEq)]
149155
/// struct Book {
150156
/// isbn: i32,
151157
/// format: BookFormat,
@@ -163,18 +169,16 @@ use self::Ordering::*;
163169
/// }
164170
/// }
165171
///
166-
/// impl PartialEq for Book {
167-
/// fn eq(&self, other: &Book) -> bool {
168-
/// self.isbn == other.isbn
169-
/// }
170-
/// }
172+
/// fn main() {
173+
/// let b1 = Book { isbn: 1, format: BookFormat::Paperback };
174+
/// let b2 = Book { isbn: 2, format: BookFormat::Paperback };
171175
///
172-
/// let b1 = Book { isbn: 3, format: BookFormat::Paperback };
173-
/// let b2 = Book { isbn: 3, format: BookFormat::Ebook };
176+
/// assert!(b1 == BookFormat::Paperback);
177+
/// assert!(BookFormat::Paperback == b2);
174178
///
175-
/// assert!(b1 == BookFormat::Paperback);
176-
/// assert!(BookFormat::Ebook != b1);
177-
/// assert!(b1 == b2);
179+
/// // The following should hold by transitivity but doesn't.
180+
/// assert!(b1 == b2); // <-- PANICS
181+
/// }
178182
/// ```
179183
///
180184
/// # Examples

src/libcore/iter/traits/iterator.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ pub trait Iterator {
12551255
Fuse::new(self)
12561256
}
12571257

1258-
/// Do something with each element of an iterator, passing the value on.
1258+
/// Does something with each element of an iterator, passing the value on.
12591259
///
12601260
/// When using iterators, you'll often chain several of them together.
12611261
/// While working on such code, you might want to check out what's
@@ -1548,7 +1548,7 @@ pub trait Iterator {
15481548
(left, right)
15491549
}
15501550

1551-
/// Reorder the elements of this iterator *in-place* according to the given predicate,
1551+
/// Reorders the elements of this iterator *in-place* according to the given predicate,
15521552
/// such that all those that return `true` precede all those that return `false`.
15531553
/// Returns the number of `true` elements found.
15541554
///

src/librustc/mir/mod.rs

+82-23
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use crate::hir::def::{CtorKind, Namespace};
88
use crate::hir::def_id::DefId;
99
use crate::hir;
10-
use crate::mir::interpret::{PanicInfo, Scalar};
10+
use crate::mir::interpret::{GlobalAlloc, PanicInfo, Scalar};
1111
use crate::mir::visit::MirVisitable;
1212
use crate::ty::adjustment::PointerCast;
1313
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@@ -292,7 +292,7 @@ impl<'tcx> Body<'tcx> {
292292
pub fn temps_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
293293
(self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
294294
let local = Local::new(index);
295-
if self.local_decls[local].is_user_variable.is_some() {
295+
if self.local_decls[local].is_user_variable() {
296296
None
297297
} else {
298298
Some(local)
@@ -305,7 +305,7 @@ impl<'tcx> Body<'tcx> {
305305
pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
306306
(self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
307307
let local = Local::new(index);
308-
if self.local_decls[local].is_user_variable.is_some() {
308+
if self.local_decls[local].is_user_variable() {
309309
Some(local)
310310
} else {
311311
None
@@ -319,7 +319,7 @@ impl<'tcx> Body<'tcx> {
319319
(self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
320320
let local = Local::new(index);
321321
let decl = &self.local_decls[local];
322-
if decl.is_user_variable.is_some() && decl.mutability == Mutability::Mut {
322+
if decl.is_user_variable() && decl.mutability == Mutability::Mut {
323323
Some(local)
324324
} else {
325325
None
@@ -333,7 +333,7 @@ impl<'tcx> Body<'tcx> {
333333
(1..self.local_decls.len()).filter_map(move |index| {
334334
let local = Local::new(index);
335335
let decl = &self.local_decls[local];
336-
if (decl.is_user_variable.is_some() || index < self.arg_count + 1)
336+
if (decl.is_user_variable() || index < self.arg_count + 1)
337337
&& decl.mutability == Mutability::Mut
338338
{
339339
Some(local)
@@ -689,14 +689,8 @@ pub struct LocalDecl<'tcx> {
689689
/// Temporaries and the return place are always mutable.
690690
pub mutability: Mutability,
691691

692-
/// `Some(binding_mode)` if this corresponds to a user-declared local variable.
693-
///
694-
/// This is solely used for local diagnostics when generating
695-
/// warnings/errors when compiling the current crate, and
696-
/// therefore it need not be visible across crates. pnkfelix
697-
/// currently hypothesized we *need* to wrap this in a
698-
/// `ClearCrossCrate` as long as it carries as `HirId`.
699-
pub is_user_variable: Option<ClearCrossCrate<BindingForm<'tcx>>>,
692+
// FIXME(matthewjasper) Don't store in this in `Body`
693+
pub local_info: LocalInfo<'tcx>,
700694

701695
/// `true` if this is an internal local.
702696
///
@@ -721,6 +715,7 @@ pub struct LocalDecl<'tcx> {
721715
/// then it is a temporary created for evaluation of some
722716
/// subexpression of some block's tail expression (with no
723717
/// intervening statement context).
718+
// FIXME(matthewjasper) Don't store in this in `Body`
724719
pub is_block_tail: Option<BlockTailInfo>,
725720

726721
/// The type of this local.
@@ -730,6 +725,7 @@ pub struct LocalDecl<'tcx> {
730725
/// e.g., via `let x: T`, then we carry that type here. The MIR
731726
/// borrow checker needs this information since it can affect
732727
/// region inference.
728+
// FIXME(matthewjasper) Don't store in this in `Body`
733729
pub user_ty: UserTypeProjections,
734730

735731
/// The name of the local, used in debuginfo and pretty-printing.
@@ -824,6 +820,21 @@ pub struct LocalDecl<'tcx> {
824820
pub visibility_scope: SourceScope,
825821
}
826822

823+
/// Extra information about a local that's used for diagnostics.
824+
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
825+
pub enum LocalInfo<'tcx> {
826+
/// A user-defined local variable or function parameter
827+
///
828+
/// The `BindingForm` is solely used for local diagnostics when generating
829+
/// warnings/errors when compiling the current crate, and therefore it need
830+
/// not be visible across crates.
831+
User(ClearCrossCrate<BindingForm<'tcx>>),
832+
/// A temporary created that references the static with the given `DefId`.
833+
StaticRef { def_id: DefId, is_thread_local: bool },
834+
/// Any other temporary, the return place, or an anonymous function parameter.
835+
Other,
836+
}
837+
827838
impl<'tcx> LocalDecl<'tcx> {
828839
/// Returns `true` only if local is a binding that can itself be
829840
/// made mutable via the addition of the `mut` keyword, namely
@@ -832,15 +843,17 @@ impl<'tcx> LocalDecl<'tcx> {
832843
/// - `let x = ...`,
833844
/// - or `match ... { C(x) => ... }`
834845
pub fn can_be_made_mutable(&self) -> bool {
835-
match self.is_user_variable {
836-
Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
846+
match self.local_info {
847+
LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
837848
binding_mode: ty::BindingMode::BindByValue(_),
838849
opt_ty_info: _,
839850
opt_match_place: _,
840851
pat_span: _,
841852
}))) => true,
842853

843-
Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(ImplicitSelfKind::Imm))) => true,
854+
LocalInfo::User(
855+
ClearCrossCrate::Set(BindingForm::ImplicitSelf(ImplicitSelfKind::Imm)),
856+
) => true,
844857

845858
_ => false,
846859
}
@@ -850,26 +863,54 @@ impl<'tcx> LocalDecl<'tcx> {
850863
/// `ref mut ident` binding. (Such bindings cannot be made into
851864
/// mutable bindings, but the inverse does not necessarily hold).
852865
pub fn is_nonref_binding(&self) -> bool {
853-
match self.is_user_variable {
854-
Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
866+
match self.local_info {
867+
LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
855868
binding_mode: ty::BindingMode::BindByValue(_),
856869
opt_ty_info: _,
857870
opt_match_place: _,
858871
pat_span: _,
859872
}))) => true,
860873

861-
Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(_))) => true,
874+
LocalInfo::User(ClearCrossCrate::Set(BindingForm::ImplicitSelf(_))) => true,
862875

863876
_ => false,
864877
}
865878
}
866879

880+
/// Returns `true` if this variable is a named variable or function
881+
/// parameter declared by the user.
882+
#[inline]
883+
pub fn is_user_variable(&self) -> bool {
884+
match self.local_info {
885+
LocalInfo::User(_) => true,
886+
_ => false,
887+
}
888+
}
889+
867890
/// Returns `true` if this is a reference to a variable bound in a `match`
868891
/// expression that is used to access said variable for the guard of the
869892
/// match arm.
870893
pub fn is_ref_for_guard(&self) -> bool {
871-
match self.is_user_variable {
872-
Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) => true,
894+
match self.local_info {
895+
LocalInfo::User(ClearCrossCrate::Set(BindingForm::RefForGuard)) => true,
896+
_ => false,
897+
}
898+
}
899+
900+
/// Returns `Some` if this is a reference to a static item that is used to
901+
/// access that static
902+
pub fn is_ref_to_static(&self) -> bool {
903+
match self.local_info {
904+
LocalInfo::StaticRef { .. } => true,
905+
_ => false,
906+
}
907+
}
908+
909+
/// Returns `Some` if this is a reference to a static item that is used to
910+
/// access that static
911+
pub fn is_ref_to_thread_local(&self) -> bool {
912+
match self.local_info {
913+
LocalInfo::StaticRef { is_thread_local, .. } => is_thread_local,
873914
_ => false,
874915
}
875916
}
@@ -918,7 +959,7 @@ impl<'tcx> LocalDecl<'tcx> {
918959
source_info: SourceInfo { span, scope: OUTERMOST_SOURCE_SCOPE },
919960
visibility_scope: OUTERMOST_SOURCE_SCOPE,
920961
internal,
921-
is_user_variable: None,
962+
local_info: LocalInfo::Other,
922963
is_block_tail: None,
923964
}
924965
}
@@ -937,7 +978,7 @@ impl<'tcx> LocalDecl<'tcx> {
937978
internal: false,
938979
is_block_tail: None,
939980
name: None, // FIXME maybe we do want some name here?
940-
is_user_variable: None,
981+
local_info: LocalInfo::Other,
941982
}
942983
}
943984
}
@@ -2341,6 +2382,24 @@ pub struct Constant<'tcx> {
23412382
pub literal: &'tcx ty::Const<'tcx>,
23422383
}
23432384

2385+
impl Constant<'tcx> {
2386+
pub fn check_static_ptr(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
2387+
match self.literal.val.try_to_scalar() {
2388+
Some(Scalar::Ptr(ptr)) => match tcx.alloc_map.lock().get(ptr.alloc_id) {
2389+
Some(GlobalAlloc::Static(def_id)) => Some(def_id),
2390+
Some(_) => None,
2391+
None => {
2392+
tcx.sess.delay_span_bug(
2393+
DUMMY_SP, "MIR cannot contain dangling const pointers",
2394+
);
2395+
None
2396+
},
2397+
},
2398+
_ => None,
2399+
}
2400+
}
2401+
}
2402+
23442403
/// A collection of projections into user types.
23452404
///
23462405
/// They are projections because a binding can occur a part of a

src/librustc/mir/tcx.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ impl<'tcx> PlaceTy<'tcx> {
8181
let ty = self.ty
8282
.builtin_deref(true)
8383
.unwrap_or_else(|| {
84-
bug!("deref projection of non-dereferencable ty {:?}", self)
84+
bug!("deref projection of non-dereferenceable ty {:?}", self)
8585
})
8686
.ty;
8787
PlaceTy::from_ty(ty)

src/librustc/mir/visit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ macro_rules! make_mir_visitor {
691691
source_info,
692692
visibility_scope,
693693
internal: _,
694-
is_user_variable: _,
694+
local_info: _,
695695
is_block_tail: _,
696696
} = local_decl;
697697

0 commit comments

Comments
 (0)