Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,16 @@ use tracing::debug;

use crate::Namespace::{MacroNS, TypeNS, ValueNS};
use crate::def_collector::collect_definitions;
use crate::diagnostics::StructCtor;
use crate::imports::{ImportData, ImportKind, OnUnknownData};
use crate::macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef};
use crate::ref_mut::CmCell;
use crate::{
BindingKey, Decl, DeclData, DeclKind, ExternPreludeEntry, Finalize, IdentKey, MacroData,
Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, ResolutionError, Resolver,
Segment, Used, VisResolutionError, errors,
Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, Res, ResolutionError,
Resolver, Segment, Used, VisResolutionError, errors,
};

type Res = def::Res<NodeId>;

impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
/// Attempt to put the declaration with the given name and namespace into the module,
/// and report an error in case of a collision.
Expand Down Expand Up @@ -929,7 +928,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
vis
};

let mut ret_fields = Vec::with_capacity(vdata.fields().len());
let mut field_visibilities = Vec::with_capacity(vdata.fields().len());

for field in vdata.fields() {
// NOTE: The field may be an expansion placeholder, but expansion sets
Expand All @@ -941,7 +940,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
if ctor_vis.is_at_least(field_vis, self.r.tcx) {
ctor_vis = field_vis;
}
ret_fields.push(field_vis.to_def_id());
field_visibilities.push(field_vis.to_def_id());
}
let feed = self.r.feed(ctor_node_id);
let ctor_def_id = feed.key();
Expand All @@ -951,9 +950,9 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
// We need the field visibility spans also for the constructor for E0603.
self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata.fields());

self.r
.struct_constructors
.insert(local_def_id, (ctor_res, ctor_vis.to_def_id(), ret_fields));
let ctor =
StructCtor { res: ctor_res, vis: ctor_vis.to_def_id(), field_visibilities };
self.r.struct_ctors.insert(local_def_id, ctor);
}
self.r.struct_generics.insert(local_def_id, generics.clone());
}
Expand Down
40 changes: 35 additions & 5 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ use rustc_errors::{
use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::attrs::{CfgEntry, StrippedCfgItem};
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, MacroKinds, NonMacroAttrKind, PerNS};
use rustc_hir::def::{CtorKind, CtorOf, DefKind, MacroKinds, NonMacroAttrKind, PerNS};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
use rustc_hir::{PrimTy, Stability, StabilityLevel, find_attr};
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{TyCtxt, Visibility};
use rustc_session::Session;
use rustc_session::lint::builtin::{
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS, AMBIGUOUS_IMPORT_VISIBILITIES,
Expand Down Expand Up @@ -49,20 +49,31 @@ use crate::late::{DiagMetadata, PatternSource, Rib};
use crate::{
AmbiguityError, AmbiguityKind, AmbiguityWarning, BindingError, BindingKey, Decl, DeclKind,
Finalize, ForwardGenericParamBanReason, HasGenericParams, IdentKey, LateDecl, MacroRulesScope,
Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError,
Module, ModuleKind, ModuleOrUniformRoot, ParentScope, PathResult, PrivacyError, Res,
ResolutionError, Resolver, Scope, ScopeSet, Segment, UseError, Used, VisResolutionError,
errors as errs, path_names_to_string,
};

type Res = def::Res<ast::NodeId>;

/// A vector of spans and replacements, a message and applicability.
pub(crate) type Suggestion = (Vec<(Span, String)>, String, Applicability);

/// Potential candidate for an undeclared or out-of-scope label - contains the ident of a
/// similarly named label and whether or not it is reachable.
pub(crate) type LabelSuggestion = (Ident, bool);

#[derive(Clone)]
pub(crate) struct StructCtor {
pub res: Res,
pub vis: Visibility<DefId>,
pub field_visibilities: Vec<Visibility<DefId>>,
}

impl StructCtor {
pub(crate) fn has_private_fields<'ra>(&self, m: Module<'ra>, r: &Resolver<'ra, '_>) -> bool {
self.field_visibilities.iter().any(|&vis| !r.is_accessible_from(vis, m))
}
}

#[derive(Debug)]
pub(crate) enum SuggestionTarget {
/// The target has a similar name as the name used by the programmer (probably a typo)
Expand Down Expand Up @@ -3176,6 +3187,25 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
err.subdiagnostic(note);
}
}

pub(crate) fn struct_ctor(&self, def_id: DefId) -> Option<StructCtor> {
match def_id.as_local() {
Some(def_id) => self.struct_ctors.get(&def_id).cloned(),
None => {
self.cstore().ctor_untracked(self.tcx, def_id).map(|(ctor_kind, ctor_def_id)| {
let res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
let vis = self.tcx.visibility(ctor_def_id);
let field_visibilities = self
.tcx
.associated_item_def_ids(def_id)
.iter()
.map(|&field_id| self.tcx.visibility(field_id))
.collect();
StructCtor { res, vis, field_visibilities }
})
}
}
}
}

/// Given a `binding_span` of a binding within a use statement:
Expand Down
34 changes: 0 additions & 34 deletions compiler/rustc_resolve/src/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
orig_ident_span,
binding,
parent_scope,
module,
finalize,
shadowing,
);
Expand Down Expand Up @@ -1150,7 +1149,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
orig_ident_span,
binding,
parent_scope,
module,
finalize,
shadowing,
);
Expand Down Expand Up @@ -1260,7 +1258,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
orig_ident_span: Span,
binding: Option<Decl<'ra>>,
parent_scope: &ParentScope<'ra>,
module: Module<'ra>,
finalize: Finalize,
shadowing: Shadowing,
) -> Result<Decl<'ra>, ControlFlow<Determinacy, Determinacy>> {
Expand Down Expand Up @@ -1295,37 +1292,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.macro_expanded_macro_export_errors.insert((path_span, binding.span));
}

// If we encounter a re-export for a type with private fields, it will not be able to
// be constructed through this re-export. We track that case here to expand later
// privacy errors with appropriate information.
if let Res::Def(_, def_id) = binding.res() {
let struct_ctor = match def_id.as_local() {
Some(def_id) => self.struct_constructors.get(&def_id).cloned(),
None => {
let ctor = self.cstore().ctor_untracked(self.tcx(), def_id);
ctor.map(|(ctor_kind, ctor_def_id)| {
let ctor_res = Res::Def(
DefKind::Ctor(rustc_hir::def::CtorOf::Struct, ctor_kind),
ctor_def_id,
);
let ctor_vis = self.tcx.visibility(ctor_def_id);
let field_visibilities = self
.tcx
.associated_item_def_ids(def_id)
.iter()
.map(|&field_id| self.tcx.visibility(field_id))
.collect();
(ctor_res, ctor_vis, field_visibilities)
})
}
};
if let Some((_, _, fields)) = struct_ctor
&& fields.iter().any(|vis| !self.is_accessible_from(*vis, module))
{
self.inaccessible_ctor_reexport.insert(path_span, binding.span);
}
}

self.record_use(ident, binding, used);
return Ok(binding);
}
Expand Down
4 changes: 1 addition & 3 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,10 @@ use crate::errors::{
use crate::ref_mut::CmCell;
use crate::{
AmbiguityError, BindingKey, CmResolver, Decl, DeclData, DeclKind, Determinacy, Finalize,
IdentKey, ImportSuggestion, Module, ModuleOrUniformRoot, ParentScope, PathResult, PerNS,
IdentKey, ImportSuggestion, Module, ModuleOrUniformRoot, ParentScope, PathResult, PerNS, Res,
ResolutionError, Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string,
};

type Res = def::Res<NodeId>;

/// A potential import declaration in the process of being planted into a module.
/// Also used for lazily planting names from `--extern` flags to extern prelude.
#[derive(Clone, Copy, Default, PartialEq, Debug)]
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_errors::{
StashKey, Suggestions, elided_lifetime_in_path_suggestion, pluralize,
};
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
use rustc_hir::def::{CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate};
use rustc_middle::middle::resolve_bound_vars::Set1;
Expand All @@ -41,14 +41,12 @@ use tracing::{debug, instrument, trace};

use crate::{
BindingError, BindingKey, Decl, DelegationFnSig, Finalize, IdentKey, LateDecl, Module,
ModuleOrUniformRoot, ParentScope, PathResult, ResolutionError, Resolver, Segment, Stage,
ModuleOrUniformRoot, ParentScope, PathResult, Res, ResolutionError, Resolver, Segment, Stage,
TyCtxt, UseError, Used, errors, path_names_to_string, rustdoc,
};

mod diagnostics;

type Res = def::Res<NodeId>;

use diagnostics::{ElisionFnParameter, LifetimeElisionCandidate, MissingLifetime};

#[derive(Copy, Clone, Debug)]
Expand Down
Loading
Loading