Auto merge of #29415 - nikomatsakis:issue-29161, r=nikomatsakis

Fix corner case in privacy that was causing ICEs when the `source_did` was not crate-local.

Full confession: I only kinda sorta understand this code, but afaict it's legit for `source_did` to be from another crate.

r? @alexcrichton
This commit is contained in:
bors 2015-10-28 21:37:42 +00:00
commit e6ad039d2c
2 changed files with 40 additions and 5 deletions

View File

@ -389,6 +389,7 @@ struct PrivacyVisitor<'a, 'tcx: 'a> {
external_exports: ExternalExports,
}
#[derive(Debug)]
enum PrivacyResult {
Allowable,
ExternallyDenied,
@ -645,9 +646,17 @@ fn report_error(&self, result: CheckResult) -> bool {
/// Guarantee that a particular definition is public. Returns a CheckResult
/// which contains any errors found. These can be reported using `report_error`.
/// If the result is `None`, no errors were found.
fn ensure_public(&self, span: Span, to_check: DefId,
source_did: Option<DefId>, msg: &str) -> CheckResult {
let id = match self.def_privacy(to_check) {
fn ensure_public(&self,
span: Span,
to_check: DefId,
source_did: Option<DefId>,
msg: &str)
-> CheckResult {
debug!("ensure_public(span={:?}, to_check={:?}, source_did={:?}, msg={:?})",
span, to_check, source_did, msg);
let def_privacy = self.def_privacy(to_check);
debug!("ensure_public: def_privacy={:?}", def_privacy);
let id = match def_privacy {
ExternallyDenied => {
return Some((span, format!("{} is private", msg), None))
}
@ -662,8 +671,8 @@ fn ensure_public(&self, span: Span, to_check: DefId,
// ancestry. (Both the item being checked and its parent must
// be local.)
let def_id = source_did.unwrap_or(to_check);
let node_id = self.tcx.map.as_local_node_id(def_id).unwrap();
let (err_span, err_msg) = if id == node_id {
let node_id = self.tcx.map.as_local_node_id(def_id);
let (err_span, err_msg) = if Some(id) == node_id {
return Some((span, format!("{} is private", msg), None));
} else {
(span, format!("{} is inaccessible", msg))

View File

@ -0,0 +1,26 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod a {
struct A;
impl Default for A {
pub fn default() -> A {
//~^ ERROR E0449
A;
}
}
}
fn main() {
a::A::default();
//~^ ERROR method `default` is inaccessible
}