]> git.lizzy.rs Git - rust.git/commitdiff
changed some stuff in probe.rs and it broke libstd
authorMichael Hewson <michael@michaelhewson.ca>
Fri, 10 Nov 2017 12:52:30 +0000 (07:52 -0500)
committerMichael Hewson <michael@michaelhewson.ca>
Sun, 17 Dec 2017 09:13:09 +0000 (10:13 +0100)
src/librustc_typeck/check/method/probe.rs

index 81e5b2fe00a6ae895e73dfe1f0d5526b94c662a4..19fb32f96dffbeda5f49cdc2588b711a7645fc62 100644 (file)
@@ -77,6 +77,12 @@ fn deref(&self) -> &Self::Target {
 struct CandidateStep<'tcx> {
     self_ty: Ty<'tcx>,
     autoderefs: usize,
+    // true if the type results from a dereference of a raw pointer.
+    // when assembling candidates, we include these steps, but not when
+    // picking methods. This so that if we have `foo: *const Foo` and `Foo` has methods
+    // `fn by_raw_ptr(self: *const Self)` and `fn by_ref(&self)`, then
+    // `foo.by_raw_ptr()` will work and `foo.by_ref()` won't.
+    from_unsafe_deref: bool,
     unsize: bool,
 }
 
@@ -257,6 +263,7 @@ fn probe_op<OP,R>(&'a self,
             vec![CandidateStep {
                      self_ty,
                      autoderefs: 0,
+                     from_unsafe_deref: false,
                      unsize: false,
                  }]
         };
@@ -289,14 +296,21 @@ fn create_steps(&self,
                     -> Option<Vec<CandidateStep<'tcx>>> {
         // FIXME: we don't need to create the entire steps in one pass
 
-        let mut autoderef = self.autoderef(span, self_ty);
+        let mut autoderef = self.autoderef(span, self_ty).include_raw_pointers();
+        let mut reached_raw_pointer = false;
         let mut steps: Vec<_> = autoderef.by_ref()
             .map(|(ty, d)| {
-                CandidateStep {
+                let step = CandidateStep {
                     self_ty: ty,
                     autoderefs: d,
+                    from_unsafe_deref: reached_raw_pointer,
                     unsize: false,
+                };
+                if let ty::TyRawPtr(_) = ty.sty {
+                    // all the subsequent steps will be from_unsafe_deref
+                    reached_raw_pointer = true;
                 }
+                step
             })
             .collect();
 
@@ -322,6 +336,9 @@ fn create_steps(&self,
                 steps.push(CandidateStep {
                     self_ty: self.tcx.mk_slice(elem_ty),
                     autoderefs: dereferences,
+                    // this could be from an unsafe deref if we had
+                    // a *mut/const [T; N]
+                    from_unsafe_deref: reached_raw_pointer,
                     unsize: true,
                 });
             }
@@ -830,7 +847,9 @@ fn pick_core(&mut self) -> Option<PickResult<'tcx>> {
             .iter()
             .filter(|step| {
                 debug!("pick_core: step={:?}", step);
-                !step.self_ty.references_error()
+                // skip types that are from a type error or that would require dereferencing
+                // a raw pointer
+                !step.self_ty.references_error() && !step.from_unsafe_deref
             }).flat_map(|step| {
                 self.pick_by_value_method(step).or_else(|| {
                 self.pick_autorefd_method(step, hir::MutImmutable).or_else(|| {