Skip to content

Commit e6ad039

Browse files
committed
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
2 parents 65623db + 19996d4 commit e6ad039

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

src/librustc_privacy/lib.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ struct PrivacyVisitor<'a, 'tcx: 'a> {
389389
external_exports: ExternalExports,
390390
}
391391

392+
#[derive(Debug)]
392393
enum PrivacyResult {
393394
Allowable,
394395
ExternallyDenied,
@@ -645,9 +646,17 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
645646
/// Guarantee that a particular definition is public. Returns a CheckResult
646647
/// which contains any errors found. These can be reported using `report_error`.
647648
/// If the result is `None`, no errors were found.
648-
fn ensure_public(&self, span: Span, to_check: DefId,
649-
source_did: Option<DefId>, msg: &str) -> CheckResult {
650-
let id = match self.def_privacy(to_check) {
649+
fn ensure_public(&self,
650+
span: Span,
651+
to_check: DefId,
652+
source_did: Option<DefId>,
653+
msg: &str)
654+
-> CheckResult {
655+
debug!("ensure_public(span={:?}, to_check={:?}, source_did={:?}, msg={:?})",
656+
span, to_check, source_did, msg);
657+
let def_privacy = self.def_privacy(to_check);
658+
debug!("ensure_public: def_privacy={:?}", def_privacy);
659+
let id = match def_privacy {
651660
ExternallyDenied => {
652661
return Some((span, format!("{} is private", msg), None))
653662
}
@@ -662,8 +671,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
662671
// ancestry. (Both the item being checked and its parent must
663672
// be local.)
664673
let def_id = source_did.unwrap_or(to_check);
665-
let node_id = self.tcx.map.as_local_node_id(def_id).unwrap();
666-
let (err_span, err_msg) = if id == node_id {
674+
let node_id = self.tcx.map.as_local_node_id(def_id);
675+
let (err_span, err_msg) = if Some(id) == node_id {
667676
return Some((span, format!("{} is private", msg), None));
668677
} else {
669678
(span, format!("{} is inaccessible", msg))

src/test/compile-fail/issue-29161.rs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2015 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+
mod a {
12+
struct A;
13+
14+
impl Default for A {
15+
pub fn default() -> A {
16+
//~^ ERROR E0449
17+
A;
18+
}
19+
}
20+
}
21+
22+
23+
fn main() {
24+
a::A::default();
25+
//~^ ERROR method `default` is inaccessible
26+
}

0 commit comments

Comments
 (0)