Skip to content

Commit 5361472

Browse files
committed
Autoderef privacy for methods
1 parent 90620b7 commit 5361472

File tree

4 files changed

+46
-14
lines changed

4 files changed

+46
-14
lines changed

src/librustc_typeck/check/method/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ pub enum MethodError<'tcx> {
4343

4444
// Using a `Fn`/`FnMut`/etc method on a raw closure type before we have inferred its kind.
4545
ClosureAmbiguity(/* DefId of fn trait */ DefId),
46+
47+
// Found an applicable method, but it is not visible.
48+
PrivateMatch(Def),
4649
}
4750

4851
// Contains a list of static methods that may apply, a list of unsatisfied trait predicates which
@@ -90,6 +93,7 @@ pub fn exists<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
9093
Err(NoMatch(..)) => false,
9194
Err(Ambiguity(..)) => true,
9295
Err(ClosureAmbiguity(..)) => true,
96+
Err(PrivateMatch(..)) => true,
9397
}
9498
}
9599

src/librustc_typeck/check/method/probe.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use super::suggest;
1616
use check;
1717
use check::{FnCtxt, UnresolvedTypeAction};
1818
use middle::def_id::DefId;
19+
use middle::def::Def;
1920
use middle::subst;
2021
use middle::subst::Subst;
2122
use middle::traits;
@@ -47,6 +48,9 @@ struct ProbeContext<'a, 'tcx:'a> {
4748
/// used for error reporting
4849
static_candidates: Vec<CandidateSource>,
4950

51+
/// Some(candidate) if there is a private candidate
52+
private_candidate: Option<Def>,
53+
5054
/// Collects near misses when trait bounds for type parameters are unsatisfied and is only used
5155
/// for error reporting
5256
unsatisfied_predicates: Vec<TraitRef<'tcx>>
@@ -247,6 +251,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
247251
steps: Rc::new(steps),
248252
opt_simplified_steps: opt_simplified_steps,
249253
static_candidates: Vec::new(),
254+
private_candidate: None,
250255
unsatisfied_predicates: Vec::new(),
251256
}
252257
}
@@ -256,6 +261,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
256261
self.extension_candidates.clear();
257262
self.impl_dups.clear();
258263
self.static_candidates.clear();
264+
self.private_candidate = None;
259265
}
260266

261267
fn tcx(&self) -> &'a TyCtxt<'tcx> {
@@ -407,6 +413,11 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
407413
return self.record_static_candidate(ImplSource(impl_def_id));
408414
}
409415

416+
if item.vis() != hir::Public && !self.fcx.private_item_is_visible(item.def_id()) {
417+
self.private_candidate = Some(item.def());
418+
return
419+
}
420+
410421
let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
411422
let impl_ty = impl_ty.subst(self.tcx(), &impl_substs);
412423

@@ -846,6 +857,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
846857
}
847858

848859
let static_candidates = mem::replace(&mut self.static_candidates, vec![]);
860+
let private_candidate = mem::replace(&mut self.private_candidate, None);
849861
let unsatisfied_predicates = mem::replace(&mut self.unsatisfied_predicates, vec![]);
850862

851863
// things failed, so lets look at all traits, for diagnostic purposes now:
@@ -879,9 +891,13 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
879891
// this error only occurs when assembling candidates
880892
tcx.sess.span_bug(span, "encountered ClosureAmbiguity from pick_core");
881893
}
882-
None => vec![],
894+
_ => vec![],
883895
};
884896

897+
if let Some(def) = private_candidate {
898+
return Err(MethodError::PrivateMatch(def));
899+
}
900+
885901
Err(MethodError::NoMatch(NoMatchData::new(static_candidates, unsatisfied_predicates,
886902
out_of_scope_traits, self.mode)))
887903
}

src/librustc_typeck/check/method/suggest.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
5353
MethodError::NoMatch(NoMatchData { static_candidates: static_sources,
5454
unsatisfied_predicates,
5555
out_of_scope_traits,
56-
mode }) => {
56+
mode, .. }) => {
5757
let cx = fcx.tcx();
5858

5959
let mut err = fcx.type_error_struct(
@@ -189,6 +189,11 @@ pub fn report_error<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
189189
};
190190
fcx.sess().span_err(span, &msg);
191191
}
192+
193+
MethodError::PrivateMatch(def) => {
194+
let msg = format!("{} `{}` is private", def.kind_name(), item_name);
195+
fcx.tcx().sess.span_err(span, &msg);
196+
}
192197
}
193198

194199
fn report_candidates(fcx: &FnCtxt,

src/librustc_typeck/check/mod.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3712,23 +3712,30 @@ pub fn resolve_ty_and_def_ufcs<'a, 'b, 'tcx>(fcx: &FnCtxt<'b, 'tcx>,
37123712
&ty_segments[base_ty_end..]);
37133713
let item_segment = path.segments.last().unwrap();
37143714
let item_name = item_segment.identifier.name;
3715-
match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3716-
Ok(def) => {
3717-
// Write back the new resolution.
3718-
fcx.ccx.tcx.def_map.borrow_mut()
3719-
.insert(node_id, def::PathResolution {
3720-
base_def: def,
3721-
depth: 0
3722-
});
3723-
Some((Some(ty), slice::ref_slice(item_segment), def))
3724-
}
3715+
let def = match method::resolve_ufcs(fcx, span, item_name, ty, node_id) {
3716+
Ok(def) => Some(def),
37253717
Err(error) => {
3718+
let def = match error {
3719+
method::MethodError::PrivateMatch(def) => Some(def),
3720+
_ => None,
3721+
};
37263722
if item_name != special_idents::invalid.name {
37273723
method::report_error(fcx, span, ty, item_name, None, error);
37283724
}
3729-
fcx.write_error(node_id);
3730-
None
3725+
def
37313726
}
3727+
};
3728+
3729+
if let Some(def) = def {
3730+
// Write back the new resolution.
3731+
fcx.ccx.tcx.def_map.borrow_mut().insert(node_id, def::PathResolution {
3732+
base_def: def,
3733+
depth: 0,
3734+
});
3735+
Some((Some(ty), slice::ref_slice(item_segment), def))
3736+
} else {
3737+
fcx.write_error(node_id);
3738+
None
37323739
}
37333740
}
37343741
}

0 commit comments

Comments
 (0)