Skip to content

Commit 2eb83ee

Browse files
committedJul 20, 2018
data_structures: Add a reference wrapper for pointer-indexed maps/sets
Use `ptr::eq` for comparing pointers
1 parent 414a86e commit 2eb83ee

File tree

7 files changed

+76
-30
lines changed

7 files changed

+76
-30
lines changed
 

‎src/liballoc/collections/btree/node.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl<K, V> LeafNode<K, V> {
103103
}
104104

105105
fn is_shared_root(&self) -> bool {
106-
self as *const _ == &EMPTY_ROOT_NODE as *const _ as *const LeafNode<K, V>
106+
ptr::eq(self, &EMPTY_ROOT_NODE as *const _ as *const _)
107107
}
108108
}
109109

‎src/librustc/lint/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use hir::intravisit;
3939
use hir;
4040
use lint::builtin::BuiltinLintDiagnostics;
4141
use session::{Session, DiagnosticMessageId};
42-
use std::hash;
42+
use std::{hash, ptr};
4343
use syntax::ast;
4444
use syntax::codemap::MultiSpan;
4545
use syntax::edition::Edition;
@@ -354,7 +354,7 @@ pub struct LintId {
354354

355355
impl PartialEq for LintId {
356356
fn eq(&self, other: &LintId) -> bool {
357-
(self.lint as *const Lint) == (other.lint as *const Lint)
357+
ptr::eq(self.lint, other.lint)
358358
}
359359
}
360360

‎src/librustc/ty/mod.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use std::ops::Deref;
4747
use rustc_data_structures::sync::{self, Lrc, ParallelIterator, par_iter};
4848
use std::slice;
4949
use std::vec::IntoIter;
50-
use std::mem;
50+
use std::{mem, ptr};
5151
use syntax::ast::{self, DUMMY_NODE_ID, Name, Ident, NodeId};
5252
use syntax::attr;
5353
use syntax::ext::hygiene::Mark;
@@ -527,8 +527,7 @@ impl<'tcx> PartialOrd for TyS<'tcx> {
527527
impl<'tcx> PartialEq for TyS<'tcx> {
528528
#[inline]
529529
fn eq(&self, other: &TyS<'tcx>) -> bool {
530-
// (self as *const _) == (other as *const _)
531-
(self as *const TyS<'tcx>) == (other as *const TyS<'tcx>)
530+
ptr::eq(self, other)
532531
}
533532
}
534533
impl<'tcx> Eq for TyS<'tcx> {}
@@ -678,7 +677,7 @@ impl<T> PartialOrd for Slice<T> where T: PartialOrd {
678677
impl<T: PartialEq> PartialEq for Slice<T> {
679678
#[inline]
680679
fn eq(&self, other: &Slice<T>) -> bool {
681-
(self as *const _) == (other as *const _)
680+
ptr::eq(self, other)
682681
}
683682
}
684683
impl<T: Eq> Eq for Slice<T> {}
@@ -1730,7 +1729,7 @@ impl Ord for AdtDef {
17301729
impl PartialEq for AdtDef {
17311730
// AdtDef are always interned and this is part of TyS equality
17321731
#[inline]
1733-
fn eq(&self, other: &Self) -> bool { self as *const _ == other as *const _ }
1732+
fn eq(&self, other: &Self) -> bool { ptr::eq(self, other) }
17341733
}
17351734

17361735
impl Eq for AdtDef {}

‎src/librustc/ty/query/job.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#![allow(warnings)]
1212

1313
use std::mem;
14+
use rustc_data_structures::ptr_key::PtrKey;
1415
use rustc_data_structures::sync::{Lock, LockGuard, Lrc, Weak};
1516
use rustc_data_structures::OnDrop;
1617
use syntax_pos::Span;
@@ -20,7 +21,7 @@ use ty::query::plumbing::CycleError;
2021
use ty::context::TyCtxt;
2122
use errors::Diagnostic;
2223
use std::process;
23-
use std::fmt;
24+
use std::{fmt, ptr};
2425
use std::collections::HashSet;
2526
#[cfg(parallel_queries)]
2627
use {
@@ -124,7 +125,7 @@ impl<'tcx> QueryJob<'tcx> {
124125
while let Some(job) = current_job {
125126
cycle.insert(0, job.info.clone());
126127

127-
if &*job as *const _ == self as *const _ {
128+
if ptr::eq(&*job, self) {
128129
// This is the end of the cycle
129130
// The span entry we included was for the usage
130131
// of the cycle itself, and not part of the cycle
@@ -282,7 +283,7 @@ where
282283
fn cycle_check<'tcx>(query: Lrc<QueryJob<'tcx>>,
283284
span: Span,
284285
stack: &mut Vec<(Span, Lrc<QueryJob<'tcx>>)>,
285-
visited: &mut HashSet<*const QueryJob<'tcx>>
286+
visited: &mut HashSet<PtrKey<'tcx, QueryJob<'tcx>>>
286287
) -> Option<Option<Waiter<'tcx>>> {
287288
if visited.contains(&query.as_ptr()) {
288289
return if let Some(p) = stack.iter().position(|q| q.1.as_ptr() == query.as_ptr()) {
@@ -321,7 +322,7 @@ fn cycle_check<'tcx>(query: Lrc<QueryJob<'tcx>>,
321322
#[cfg(parallel_queries)]
322323
fn connected_to_root<'tcx>(
323324
query: Lrc<QueryJob<'tcx>>,
324-
visited: &mut HashSet<*const QueryJob<'tcx>>
325+
visited: &mut HashSet<PtrKey<'tcx, QueryJob<'tcx>>>
325326
) -> bool {
326327
// We already visited this or we're deliberately ignoring it
327328
if visited.contains(&query.as_ptr()) {

‎src/librustc_data_structures/lib.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -56,29 +56,30 @@ extern crate rustc_cratesio_shim;
5656

5757
pub use rustc_serialize::hex::ToHex;
5858

59-
pub mod array_vec;
6059
pub mod accumulate_vec;
61-
pub mod small_vec;
60+
pub mod array_vec;
6261
pub mod base_n;
6362
pub mod bitslice;
6463
pub mod bitvec;
64+
pub mod flock;
65+
pub mod fx;
66+
pub mod graph;
6567
pub mod indexed_set;
6668
pub mod indexed_vec;
6769
pub mod obligation_forest;
70+
pub mod owning_ref;
71+
pub mod ptr_key;
6872
pub mod sip128;
73+
pub mod small_vec;
6974
pub mod snapshot_map;
7075
pub use ena::snapshot_vec;
76+
pub mod sorted_map;
7177
pub mod stable_hasher;
72-
pub mod transitive_relation;
73-
pub use ena::unify;
74-
pub mod fx;
75-
pub mod tuple_slice;
76-
pub mod graph;
77-
pub mod flock;
7878
pub mod sync;
79-
pub mod owning_ref;
8079
pub mod tiny_list;
81-
pub mod sorted_map;
80+
pub mod transitive_relation;
81+
pub mod tuple_slice;
82+
pub use ena::unify;
8283
pub mod work_queue;
8384

8485
pub struct OnDrop<F: Fn()>(pub F);
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::{hash, ptr};
12+
use std::ops::Deref;
13+
14+
/// A wrapper around reference that compares and hashes like a pointer.
15+
/// Can be used as a key in sets/maps indexed by pointers to avoid `unsafe`.
16+
#[derive(Debug)]
17+
pub struct PtrKey<'a, T: 'a>(pub &'a T);
18+
19+
impl<'a, T> Clone for PtrKey<'a, T> {
20+
fn clone(&self) -> Self { *self }
21+
}
22+
23+
impl<'a, T> Copy for PtrKey<'a, T> {}
24+
25+
impl<'a, T> PartialEq for PtrKey<'a, T> {
26+
fn eq(&self, rhs: &Self) -> bool {
27+
ptr::eq(self.0, rhs.0)
28+
}
29+
}
30+
31+
impl<'a, T> Eq for PtrKey<'a, T> {}
32+
33+
impl<'a, T> hash::Hash for PtrKey<'a, T> {
34+
fn hash<H: hash::Hasher>(&self, hasher: &mut H) {
35+
(self.0 as *const T).hash(hasher)
36+
}
37+
}
38+
39+
impl<'a, T> Deref for PtrKey<'a, T> {
40+
type Target = T;
41+
42+
fn deref(&self) -> &Self::Target {
43+
self.0
44+
}
45+
}

‎src/librustc_resolve/resolve_imports.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use Resolver;
1717
use {names_to_string, module_to_string};
1818
use {resolve_error, ResolutionError};
1919

20+
use rustc_data_structures::ptr_key::PtrKey;
2021
use rustc::ty;
2122
use rustc::lint::builtin::BuiltinLintDiagnostics;
2223
use rustc::lint::builtin::{DUPLICATE_MACRO_EXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE};
@@ -33,7 +34,7 @@ use syntax::util::lev_distance::find_best_match_for_name;
3334
use syntax_pos::Span;
3435

3536
use std::cell::{Cell, RefCell};
36-
use std::mem;
37+
use std::{mem, ptr};
3738

3839
/// Contains data for specific types of import directives.
3940
#[derive(Clone, Debug)]
@@ -105,8 +106,8 @@ impl<'a> ImportDirective<'a> {
105106
/// Records information about the resolution of a name in a namespace of a module.
106107
pub struct NameResolution<'a> {
107108
/// Single imports that may define the name in the namespace.
108-
/// Import directives are arena-allocated, so it's ok to use pointers as keys, they are stable.
109-
single_imports: FxHashSet<*const ImportDirective<'a>>,
109+
/// Import directives are arena-allocated, so it's ok to use pointers as keys.
110+
single_imports: FxHashSet<PtrKey<'a, ImportDirective<'a>>>,
110111
/// The least shadowable known binding for this name, or None if there are no known bindings.
111112
pub binding: Option<&'a NameBinding<'a>>,
112113
shadowed_glob: Option<&'a NameBinding<'a>>,
@@ -192,7 +193,6 @@ impl<'a> Resolver<'a> {
192193
// Check if one of single imports can still define the name,
193194
// if it can then our result is not determined and can be invalidated.
194195
for single_import in &resolution.single_imports {
195-
let single_import = unsafe { &**single_import };
196196
if !self.is_accessible(single_import.vis.get()) {
197197
continue;
198198
}
@@ -291,7 +291,7 @@ impl<'a> Resolver<'a> {
291291
SingleImport { target, type_ns_only, .. } => {
292292
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
293293
let mut resolution = this.resolution(current_module, target, ns).borrow_mut();
294-
resolution.single_imports.insert(directive);
294+
resolution.single_imports.insert(PtrKey(directive));
295295
});
296296
}
297297
// We don't add prelude imports to the globs since they only affect lexical scopes,
@@ -398,7 +398,7 @@ impl<'a> Resolver<'a> {
398398
_ if old_binding.is_some() => return t,
399399
None => return t,
400400
Some(binding) => match old_binding {
401-
Some(old_binding) if old_binding as *const _ == binding as *const _ => return t,
401+
Some(old_binding) if ptr::eq(old_binding, binding) => return t,
402402
_ => (binding, t),
403403
}
404404
}
@@ -583,7 +583,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
583583
Err(Undetermined) => indeterminate = true,
584584
Err(Determined) => {
585585
this.update_resolution(parent, target, ns, |_, resolution| {
586-
resolution.single_imports.remove(&(directive as *const _));
586+
resolution.single_imports.remove(&PtrKey(directive));
587587
});
588588
}
589589
Ok(binding) if !binding.is_importable() => {
@@ -916,7 +916,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
916916

917917
let mut reexports = Vec::new();
918918
let mut exported_macro_names = FxHashMap();
919-
if module as *const _ == self.graph_root as *const _ {
919+
if ptr::eq(module, self.graph_root) {
920920
let macro_exports = mem::replace(&mut self.macro_exports, Vec::new());
921921
for export in macro_exports.into_iter().rev() {
922922
if let Some(later_span) = exported_macro_names.insert(export.ident.modern(),

0 commit comments

Comments
 (0)
Please sign in to comment.