Skip to content

Rollup of 8 pull requests #109450

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 20 commits into from
Closed
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
82297a5
expand: Pass `ast::Crate` by reference to AST transforming passes
petrochenkov Feb 18, 2023
0261d25
Add some tests for the current `#![cfg(FALSE)]` crate behavior
petrochenkov Mar 14, 2023
bf00e7d
rustc_interface: Add a new query `pre_configure`
petrochenkov Mar 14, 2023
6639538
Remove VecMap
compiler-errors Mar 17, 2023
572c56c
Update links for custom discriminants.
ehuss Jan 19, 2023
d3352de
Add #[inline] to as_deref
saethlin Mar 18, 2023
9da1da9
Allow optional RET type annotation
cbeuw Mar 20, 2023
9dc275b
Add documentation for `type RET = ...`
cbeuw Mar 20, 2023
460ecd2
Eagerly intern and check CrateNum/StableCrateId collisions
oli-obk Mar 16, 2023
d3a5541
rustdoc: Cleanup parent module tracking for doc links
petrochenkov Mar 18, 2023
0f45d85
rustdoc: Factor out some doc link resolution code into a separate fun…
petrochenkov Mar 21, 2023
dfbf610
Set LLVM `LLVM_UNREACHABLE_OPTIMIZE` to `OFF`
ids1024 Mar 20, 2023
2a3bdb0
Rollup merge of #108221 - petrochenkov:cratecfg, r=michaelwoerister
Dylan-DPC Mar 21, 2023
b2e0fe0
Rollup merge of #109213 - oli-obk:cstore, r=cjgillot
Dylan-DPC Mar 21, 2023
244e78f
Rollup merge of #109280 - compiler-errors:no-vec-map, r=Mark-Simulacrum
Dylan-DPC Mar 21, 2023
1f62643
Rollup merge of #109312 - petrochenkov:docice5, r=GuillaumeGomez
Dylan-DPC Mar 21, 2023
374d005
Rollup merge of #109317 - ehuss:discriminant-link-fix, r=Nilstrieb
Dylan-DPC Mar 21, 2023
233f242
Rollup merge of #109357 - saethlin:inline-as-deref, r=thomcc
Dylan-DPC Mar 21, 2023
c62a13e
Rollup merge of #109373 - ids1024:llvm-unreachable-optimize, r=ozkanonur
Dylan-DPC Mar 21, 2023
cd37e04
Rollup merge of #109392 - cbeuw:composite-ret, r=JakobDegen
Dylan-DPC Mar 21, 2023
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -5294,6 +5294,7 @@ name = "rustc_span"
version = "0.0.0"
dependencies = [
"cfg-if",
"indexmap",
"md-5",
"rustc_arena",
"rustc_data_structures",
3 changes: 1 addition & 2 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ extern crate tracing;

use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_data_structures::vec_map::VecMap;
use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, SubdiagnosticMessage};
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
@@ -141,7 +140,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor
debug!("Skipping borrowck because of injected body");
// Let's make up a borrowck result! Fun times!
let result = BorrowCheckResult {
concrete_opaque_types: VecMap::new(),
concrete_opaque_types: FxIndexMap::default(),
closure_requirements: None,
used_mut_upvars: SmallVec::new(),
tainted_by_errors: None,
6 changes: 3 additions & 3 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
#![deny(rustc::diagnostic_outside_of_impl)]
//! The entry point of the NLL borrow checker.
use rustc_data_structures::vec_map::VecMap;
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def_id::LocalDefId;
use rustc_index::vec::IndexVec;
use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere};
@@ -44,7 +44,7 @@ pub type PoloniusOutput = Output<RustcFacts>;
/// closure requirements to propagate, and any generated errors.
pub(crate) struct NllOutput<'tcx> {
pub regioncx: RegionInferenceContext<'tcx>,
pub opaque_type_values: VecMap<LocalDefId, OpaqueHiddenType<'tcx>>,
pub opaque_type_values: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
pub polonius_input: Option<Box<AllFacts>>,
pub polonius_output: Option<Rc<PoloniusOutput>>,
pub opt_closure_req: Option<ClosureRegionRequirements<'tcx>>,
@@ -377,7 +377,7 @@ pub(super) fn dump_annotation<'tcx>(
body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
opaque_type_values: &VecMap<LocalDefId, OpaqueHiddenType<'tcx>>,
opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
errors: &mut crate::error::BorrowckErrors<'tcx>,
) {
let tcx = infcx.tcx;
7 changes: 3 additions & 4 deletions compiler/rustc_borrowck/src/region_infer/opaque_types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::vec_map::VecMap;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::OpaqueTyOrigin;
@@ -61,9 +60,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(crate) fn infer_opaque_types(
&self,
infcx: &InferCtxt<'tcx>,
opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
) -> VecMap<LocalDefId, OpaqueHiddenType<'tcx>> {
let mut result: VecMap<LocalDefId, OpaqueHiddenType<'tcx>> = VecMap::new();
opaque_ty_decls: FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
) -> FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> {
let mut result: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>> = FxIndexMap::default();

let member_constraints: FxIndexMap<_, _> = self
.member_constraints
3 changes: 1 addition & 2 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,6 @@ use either::Either;
use hir::OpaqueTyOrigin;
use rustc_data_structures::frozen::Frozen;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::vec_map::VecMap;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
@@ -894,7 +893,7 @@ pub(crate) struct MirTypeckResults<'tcx> {
pub(crate) constraints: MirTypeckRegionConstraints<'tcx>,
pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
pub(crate) opaque_type_values:
VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
FxIndexMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>,
}

/// A collection of region constraints that must be satisfied for the
4 changes: 1 addition & 3 deletions compiler/rustc_builtin_macros/src/cmdline_attrs.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ use rustc_ast::{self as ast, AttrItem, AttrStyle};
use rustc_session::parse::ParseSess;
use rustc_span::FileName;

pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
pub fn inject(krate: &mut ast::Crate, parse_sess: &ParseSess, attrs: &[String]) {
for raw_attr in attrs {
let mut parser = rustc_parse::new_parser_from_source_str(
parse_sess,
@@ -36,6 +36,4 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
start_span.to(end_span),
));
}

krate
}
12 changes: 5 additions & 7 deletions compiler/rustc_builtin_macros/src/proc_macro_harness.rs
Original file line number Diff line number Diff line change
@@ -44,14 +44,14 @@ struct CollectProcMacros<'a> {
}

pub fn inject(
krate: &mut ast::Crate,
sess: &Session,
resolver: &mut dyn ResolverExpand,
mut krate: ast::Crate,
is_proc_macro_crate: bool,
has_proc_macro_decls: bool,
is_test_crate: bool,
handler: &rustc_errors::Handler,
) -> ast::Crate {
) {
let ecfg = ExpansionConfig::default("proc_macro".to_string());
let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);

@@ -66,22 +66,20 @@ pub fn inject(
};

if has_proc_macro_decls || is_proc_macro_crate {
visit::walk_crate(&mut collect, &krate);
visit::walk_crate(&mut collect, krate);
}
let macros = collect.macros;

if !is_proc_macro_crate {
return krate;
return;
}

if is_test_crate {
return krate;
return;
}

let decls = mk_decls(&mut cx, &macros);
krate.items.push(decls);

krate
}

impl<'a> CollectProcMacros<'a> {
17 changes: 9 additions & 8 deletions compiler/rustc_builtin_macros/src/standard_library_imports.rs
Original file line number Diff line number Diff line change
@@ -9,17 +9,19 @@ use rustc_span::DUMMY_SP;
use thin_vec::thin_vec;

pub fn inject(
mut krate: ast::Crate,
krate: &mut ast::Crate,
pre_configured_attrs: &[ast::Attribute],
resolver: &mut dyn ResolverExpand,
sess: &Session,
) -> ast::Crate {
) -> usize {
let orig_num_items = krate.items.len();
let edition = sess.parse_sess.edition;

// the first name in this list is the crate name of the crate with the prelude
let names: &[Symbol] = if sess.contains_name(&krate.attrs, sym::no_core) {
return krate;
} else if sess.contains_name(&krate.attrs, sym::no_std) {
if sess.contains_name(&krate.attrs, sym::compiler_builtins) {
let names: &[Symbol] = if sess.contains_name(pre_configured_attrs, sym::no_core) {
return 0;
} else if sess.contains_name(pre_configured_attrs, sym::no_std) {
if sess.contains_name(pre_configured_attrs, sym::compiler_builtins) {
&[sym::core]
} else {
&[sym::core, sym::compiler_builtins]
@@ -88,6 +90,5 @@ pub fn inject(
);

krate.items.insert(0, use_item);

krate
krate.items.len() - orig_num_items
}
2 changes: 1 addition & 1 deletion compiler/rustc_builtin_macros/src/test_harness.rs
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ struct TestCtxt<'a> {

/// Traverse the crate, collecting all the test functions, eliding any
/// existing main functions, and synthesizing a main test harness
pub fn inject(sess: &Session, resolver: &mut dyn ResolverExpand, krate: &mut ast::Crate) {
pub fn inject(krate: &mut ast::Crate, sess: &Session, resolver: &mut dyn ResolverExpand) {
let span_diagnostic = sess.diagnostic();
let panic_strategy = sess.panic_strategy();
let platform_panic_strategy = sess.target.panic_strategy;
1 change: 0 additions & 1 deletion compiler/rustc_data_structures/src/lib.rs
Original file line number Diff line number Diff line change
@@ -79,7 +79,6 @@ pub mod sync;
pub mod tiny_list;
pub mod transitive_relation;
pub mod vec_linked_list;
pub mod vec_map;
pub mod work_queue;
pub use atomic_ref::AtomicRef;
pub mod frozen;
192 changes: 0 additions & 192 deletions compiler/rustc_data_structures/src/vec_map.rs

This file was deleted.

48 changes: 0 additions & 48 deletions compiler/rustc_data_structures/src/vec_map/tests.rs

This file was deleted.

2 changes: 1 addition & 1 deletion compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
@@ -353,7 +353,7 @@ fn run_compiler(

{
let plugins = queries.register_plugins()?;
let (_, lint_store) = &*plugins.borrow();
let (.., lint_store) = &*plugins.borrow();

// Lint plugins are registered; now we can process command line flags.
if sess.opts.describe_lints {
9 changes: 4 additions & 5 deletions compiler/rustc_error_codes/src/error_codes/E0080.md
Original file line number Diff line number Diff line change
@@ -15,9 +15,8 @@ or causing an integer overflow are two ways to induce this error.

Ensure that the expressions given can be evaluated as the desired integer type.

See the [Custom Discriminants][custom-discriminants] section of the Reference
for more information about setting custom integer types on fieldless enums
using the [`repr` attribute][repr-attribute].
See the [Discriminants] section of the Reference for more information about
setting custom integer types on enums using the [`repr` attribute][repr-attribute].

[custom-discriminants]: https://doc.rust-lang.org/reference/items/enumerations.html#custom-discriminant-values-for-field-less-enumerations
[repr-attribute]: https://doc.rust-lang.org/reference/type-layout.html#reprc-enums
[discriminants]: https://doc.rust-lang.org/reference/items/enumerations.html#discriminants
[repr-attribute]: https://doc.rust-lang.org/reference/type-layout.html#representations
2 changes: 2 additions & 0 deletions compiler/rustc_expand/src/base.rs
Original file line number Diff line number Diff line change
@@ -1004,6 +1004,7 @@ pub struct ExpansionData {
pub struct ExtCtxt<'a> {
pub sess: &'a Session,
pub ecfg: expand::ExpansionConfig<'a>,
pub num_standard_library_imports: usize,
pub reduced_recursion_limit: Option<Limit>,
pub root_path: PathBuf,
pub resolver: &'a mut dyn ResolverExpand,
@@ -1032,6 +1033,7 @@ impl<'a> ExtCtxt<'a> {
ExtCtxt {
sess,
ecfg,
num_standard_library_imports: 0,
reduced_recursion_limit: None,
resolver,
lint_store,
69 changes: 22 additions & 47 deletions compiler/rustc_expand/src/config.rs
Original file line number Diff line number Diff line change
@@ -24,7 +24,6 @@ use rustc_session::Session;
use rustc_span::edition::{Edition, ALL_EDITIONS};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::{Span, DUMMY_SP};
use thin_vec::ThinVec;

/// A folder that strips out items that do not belong in the current configuration.
pub struct StripUnconfigured<'a> {
@@ -37,7 +36,7 @@ pub struct StripUnconfigured<'a> {
pub lint_node_id: NodeId,
}

fn get_features(sess: &Session, krate_attrs: &[ast::Attribute]) -> Features {
pub fn features(sess: &Session, krate_attrs: &[Attribute]) -> Features {
fn feature_removed(sess: &Session, span: Span, reason: Option<&str>) {
sess.emit_err(FeatureRemoved {
span,
@@ -191,39 +190,16 @@ fn get_features(sess: &Session, krate_attrs: &[ast::Attribute]) -> Features {
features
}

/// `cfg_attr`-process the crate's attributes and compute the crate's features.
pub fn features(
sess: &Session,
mut krate: ast::Crate,
lint_node_id: NodeId,
) -> (ast::Crate, Features) {
let mut strip_unconfigured =
StripUnconfigured { sess, features: None, config_tokens: false, lint_node_id };

let unconfigured_attrs = krate.attrs.clone();
let diag = &sess.parse_sess.span_diagnostic;
let err_count = diag.err_count();
let features = match strip_unconfigured.configure_krate_attrs(krate.attrs) {
None => {
// The entire crate is unconfigured.
krate.attrs = ast::AttrVec::new();
krate.items = ThinVec::new();
Features::default()
}
Some(attrs) => {
krate.attrs = attrs;
let features = get_features(sess, &krate.attrs);
if err_count == diag.err_count() {
// Avoid reconfiguring malformed `cfg_attr`s.
strip_unconfigured.features = Some(&features);
// Run configuration again, this time with features available
// so that we can perform feature-gating.
strip_unconfigured.configure_krate_attrs(unconfigured_attrs);
}
features
}
pub fn pre_configure_attrs(sess: &Session, attrs: &[Attribute]) -> ast::AttrVec {
let strip_unconfigured = StripUnconfigured {
sess,
features: None,
config_tokens: false,
lint_node_id: ast::CRATE_NODE_ID,
};
(krate, features)
let attrs: ast::AttrVec =
attrs.iter().flat_map(|attr| strip_unconfigured.process_cfg_attr(attr)).collect();
if strip_unconfigured.in_cfg(&attrs) { attrs } else { ast::AttrVec::new() }
}

#[macro_export]
@@ -254,11 +230,6 @@ impl<'a> StripUnconfigured<'a> {
}
}

fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> {
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
self.in_cfg(&attrs).then_some(attrs)
}

/// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`.
/// This is only used during the invocation of `derive` proc-macros,
/// which require that we cfg-expand their entire input.
@@ -281,7 +252,7 @@ impl<'a> StripUnconfigured<'a> {
.iter()
.flat_map(|tree| match tree.clone() {
AttrTokenTree::Attributes(mut data) => {
data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));

if self.in_cfg(&data.attrs) {
data.tokens = LazyAttrTokenStream::new(
@@ -319,12 +290,16 @@ impl<'a> StripUnconfigured<'a> {
/// the syntax of any `cfg_attr` is incorrect.
fn process_cfg_attrs<T: HasAttrs>(&self, node: &mut T) {
node.visit_attrs(|attrs| {
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));
});
}

fn process_cfg_attr(&self, attr: Attribute) -> Vec<Attribute> {
if attr.has_name(sym::cfg_attr) { self.expand_cfg_attr(attr, true) } else { vec![attr] }
fn process_cfg_attr(&self, attr: &Attribute) -> Vec<Attribute> {
if attr.has_name(sym::cfg_attr) {
self.expand_cfg_attr(attr, true)
} else {
vec![attr.clone()]
}
}

/// Parse and expand a single `cfg_attr` attribute into a list of attributes
@@ -334,9 +309,9 @@ impl<'a> StripUnconfigured<'a> {
/// Gives a compiler warning when the `cfg_attr` contains no attributes and
/// is in the original source file. Gives a compiler error if the syntax of
/// the attribute is incorrect.
pub(crate) fn expand_cfg_attr(&self, attr: Attribute, recursive: bool) -> Vec<Attribute> {
pub(crate) fn expand_cfg_attr(&self, attr: &Attribute, recursive: bool) -> Vec<Attribute> {
let Some((cfg_predicate, expanded_attrs)) =
rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) else {
rustc_parse::parse_cfg_attr(attr, &self.sess.parse_sess) else {
return vec![];
};

@@ -365,10 +340,10 @@ impl<'a> StripUnconfigured<'a> {
// `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
expanded_attrs
.into_iter()
.flat_map(|item| self.process_cfg_attr(self.expand_cfg_attr_item(&attr, item)))
.flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(attr, item)))
.collect()
} else {
expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(&attr, item)).collect()
expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(attr, item)).collect()
}
}

16 changes: 12 additions & 4 deletions compiler/rustc_expand/src/expand.rs
Original file line number Diff line number Diff line change
@@ -1038,6 +1038,9 @@ trait InvocationCollectorNode: HasAttrs + HasNodeId + Sized {
) -> Result<Self::OutputTy, Self> {
Ok(noop_flat_map(node, collector))
}
fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, span: Span) {
collector.cx.emit_err(RemoveNodeNotSupported { span, descr: Self::descr() });
}
}

impl InvocationCollectorNode for P<ast::Item> {
@@ -1378,6 +1381,11 @@ impl InvocationCollectorNode for ast::Crate {
fn noop_visit<V: MutVisitor>(&mut self, visitor: &mut V) {
noop_visit_crate(self, visitor)
}
fn expand_cfg_false(&mut self, collector: &mut InvocationCollector<'_, '_>, _span: Span) {
self.attrs.clear();
// Standard prelude imports are left in the crate for backward compatibility.
self.items.truncate(collector.cx.num_standard_library_imports);
}
}

impl InvocationCollectorNode for P<ast::Ty> {
@@ -1688,7 +1696,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
res
}

fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: ast::Attribute, pos: usize) {
fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: &ast::Attribute, pos: usize) {
node.visit_attrs(|attrs| {
// Repeated `insert` calls is inefficient, but the number of
// insertions is almost always 0 or 1 in practice.
@@ -1712,7 +1720,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
Default::default()
}
sym::cfg_attr => {
self.expand_cfg_attr(&mut node, attr, pos);
self.expand_cfg_attr(&mut node, &attr, pos);
continue;
}
_ => {
@@ -1756,11 +1764,11 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
continue;
}

self.cx.emit_err(RemoveNodeNotSupported { span, descr: Node::descr() });
node.expand_cfg_false(self, span);
continue;
}
sym::cfg_attr => {
self.expand_cfg_attr(node, attr, pos);
self.expand_cfg_attr(node, &attr, pos);
continue;
}
_ => visit_clobber(node, |node| {
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/collect/type_of.rs
Original file line number Diff line number Diff line change
@@ -777,7 +777,7 @@ fn find_opaque_ty_constraints_for_rpit(
// Use borrowck to get the type with unerased regions.
let concrete_opaque_types = &self.tcx.mir_borrowck(def_id).concrete_opaque_types;
debug!(?concrete_opaque_types);
for &(def_id, concrete_type) in concrete_opaque_types {
for (&def_id, &concrete_type) in concrete_opaque_types {
if def_id != self.def_id {
// Ignore constraints for other opaque types.
continue;
4 changes: 1 addition & 3 deletions compiler/rustc_infer/src/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
@@ -159,9 +159,7 @@ impl<'tcx> InferCtxt<'tcx> {
.opaque_type_storage
.opaque_types
.iter()
.map(|&(k, ref v)| {
(self.tcx.mk_opaque(k.def_id.to_def_id(), k.substs), v.hidden_type.ty)
})
.map(|(k, v)| (self.tcx.mk_opaque(k.def_id.to_def_id(), k.substs), v.hidden_type.ty))
.collect()
}

4 changes: 2 additions & 2 deletions compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@ use crate::infer::{DefiningAnchor, InferCtxt, InferOk};
use crate::traits;
use hir::def_id::{DefId, LocalDefId};
use hir::OpaqueTyOrigin;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::vec_map::VecMap;
use rustc_hir as hir;
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
@@ -21,7 +21,7 @@ use std::ops::ControlFlow;

mod table;

pub type OpaqueTypeMap<'tcx> = VecMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
pub type OpaqueTypeMap<'tcx> = FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueTypeDecl<'tcx>>;
pub use table::{OpaqueTypeStorage, OpaqueTypeTable};

/// Information about the opaque types whose values we
56 changes: 29 additions & 27 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@ use crate::interface::{Compiler, Result};
use crate::proc_macro_decls;
use crate::util;

use ast::CRATE_NODE_ID;
use rustc_ast::{self as ast, visit};
use rustc_borrowck as mir_borrowck;
use rustc_codegen_ssa::traits::CodegenBackend;
@@ -76,22 +75,14 @@ pub fn register_plugins<'a>(
sess: &'a Session,
metadata_loader: &'a dyn MetadataLoader,
register_lints: impl Fn(&Session, &mut LintStore),
mut krate: ast::Crate,
pre_configured_attrs: &[ast::Attribute],
crate_name: Symbol,
) -> Result<(ast::Crate, LintStore)> {
krate = sess.time("attributes_injection", || {
rustc_builtin_macros::cmdline_attrs::inject(
krate,
&sess.parse_sess,
&sess.opts.unstable_opts.crate_attr,
)
});

let (krate, features) = rustc_expand::config::features(sess, krate, CRATE_NODE_ID);
) -> Result<LintStore> {
// these need to be set "early" so that expansion sees `quote` if enabled.
let features = rustc_expand::config::features(sess, pre_configured_attrs);
sess.init_features(features);

let crate_types = util::collect_crate_types(sess, &krate.attrs);
let crate_types = util::collect_crate_types(sess, pre_configured_attrs);
sess.init_crate_types(crate_types);

let stable_crate_id = StableCrateId::new(
@@ -117,16 +108,17 @@ pub fn register_plugins<'a>(
let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
register_lints(sess, &mut lint_store);

let registrars =
sess.time("plugin_loading", || plugin::load::load_plugins(sess, metadata_loader, &krate));
let registrars = sess.time("plugin_loading", || {
plugin::load::load_plugins(sess, metadata_loader, pre_configured_attrs)
});
sess.time("plugin_registration", || {
let mut registry = plugin::Registry { lint_store: &mut lint_store };
for registrar in registrars {
registrar(&mut registry);
}
});

Ok((krate, lint_store))
Ok(lint_store)
}

fn pre_expansion_lint<'a>(
@@ -173,19 +165,28 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> {
/// harness if one is to be provided, injection of a dependency on the
/// standard library and prelude, and name resolution.
#[instrument(level = "trace", skip(krate, resolver))]
fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>) -> ast::Crate {
fn configure_and_expand(
mut krate: ast::Crate,
pre_configured_attrs: &[ast::Attribute],
resolver: &mut Resolver<'_, '_>,
) -> ast::Crate {
let tcx = resolver.tcx();
let sess = tcx.sess;
let lint_store = unerased_lint_store(tcx);
let crate_name = tcx.crate_name(LOCAL_CRATE);
pre_expansion_lint(sess, lint_store, tcx.registered_tools(()), &krate, crate_name);
rustc_builtin_macros::register_builtin_macros(resolver);

krate = sess.time("crate_injection", || {
rustc_builtin_macros::standard_library_imports::inject(krate, resolver, sess)
let num_standard_library_imports = sess.time("crate_injection", || {
rustc_builtin_macros::standard_library_imports::inject(
&mut krate,
pre_configured_attrs,
resolver,
sess,
)
});

util::check_attr_crate_type(sess, &krate.attrs, &mut resolver.lint_buffer());
util::check_attr_crate_type(sess, pre_configured_attrs, &mut resolver.lint_buffer());

// Expand all macros
krate = sess.time("macro_expand_crate", || {
@@ -222,7 +223,7 @@ fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>)

// Create the config for macro expansion
let features = sess.features_untracked();
let recursion_limit = get_recursion_limit(&krate.attrs, sess);
let recursion_limit = get_recursion_limit(pre_configured_attrs, sess);
let cfg = rustc_expand::expand::ExpansionConfig {
features: Some(features),
recursion_limit,
@@ -235,6 +236,7 @@ fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>)

let lint_store = LintStoreExpandImpl(lint_store);
let mut ecx = ExtCtxt::new(sess, cfg, resolver, Some(&lint_store));
ecx.num_standard_library_imports = num_standard_library_imports;
// Expand macros now!
let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate));

@@ -263,7 +265,7 @@ fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>)
});

sess.time("maybe_building_test_harness", || {
rustc_builtin_macros::test_harness::inject(sess, resolver, &mut krate)
rustc_builtin_macros::test_harness::inject(&mut krate, sess, resolver)
});

let has_proc_macro_decls = sess.time("AST_validation", || {
@@ -287,12 +289,12 @@ fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>)
sess.emit_warning(errors::ProcMacroCratePanicAbort);
}

krate = sess.time("maybe_create_a_macro_crate", || {
sess.time("maybe_create_a_macro_crate", || {
let is_test_crate = sess.opts.test;
rustc_builtin_macros::proc_macro_harness::inject(
&mut krate,
sess,
resolver,
krate,
is_proc_macro_crate,
has_proc_macro_decls,
is_test_crate,
@@ -557,9 +559,9 @@ fn resolver_for_lowering<'tcx>(
) -> &'tcx Steal<(ty::ResolverAstLowering, Lrc<ast::Crate>)> {
let arenas = Resolver::arenas();
let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`.
let krate = tcx.crate_for_resolver(()).steal();
let mut resolver = Resolver::new(tcx, &krate, &arenas);
let krate = configure_and_expand(krate, &mut resolver);
let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal();
let mut resolver = Resolver::new(tcx, &pre_configured_attrs, krate.spans.inner_span, &arenas);
let krate = configure_and_expand(krate, &pre_configured_attrs, &mut resolver);

// Make sure we don't mutate the cstore from here on.
tcx.untracked().cstore.leak();
43 changes: 32 additions & 11 deletions compiler/rustc_interface/src/queries.rs
Original file line number Diff line number Diff line change
@@ -88,8 +88,9 @@ pub struct Queries<'tcx> {

dep_graph_future: Query<Option<DepGraphFuture>>,
parse: Query<ast::Crate>,
pre_configure: Query<(ast::Crate, ast::AttrVec)>,
crate_name: Query<Symbol>,
register_plugins: Query<(ast::Crate, Lrc<LintStore>)>,
register_plugins: Query<(ast::Crate, ast::AttrVec, Lrc<LintStore>)>,
dep_graph: Query<DepGraph>,
// This just points to what's in `gcx_cell`.
gcx: Query<&'tcx GlobalCtxt<'tcx>>,
@@ -106,6 +107,7 @@ impl<'tcx> Queries<'tcx> {
hir_arena: WorkerLocal::new(|_| rustc_hir::Arena::default()),
dep_graph_future: Default::default(),
parse: Default::default(),
pre_configure: Default::default(),
crate_name: Default::default(),
register_plugins: Default::default(),
dep_graph: Default::default(),
@@ -133,17 +135,36 @@ impl<'tcx> Queries<'tcx> {
.compute(|| passes::parse(self.session()).map_err(|mut parse_error| parse_error.emit()))
}

pub fn register_plugins(&self) -> Result<QueryResult<'_, (ast::Crate, Lrc<LintStore>)>> {
pub fn pre_configure(&self) -> Result<QueryResult<'_, (ast::Crate, ast::AttrVec)>> {
self.pre_configure.compute(|| {
let mut krate = self.parse()?.steal();

let sess = self.session();
rustc_builtin_macros::cmdline_attrs::inject(
&mut krate,
&sess.parse_sess,
&sess.opts.unstable_opts.crate_attr,
);

let pre_configured_attrs =
rustc_expand::config::pre_configure_attrs(sess, &krate.attrs);
Ok((krate, pre_configured_attrs))
})
}

pub fn register_plugins(
&self,
) -> Result<QueryResult<'_, (ast::Crate, ast::AttrVec, Lrc<LintStore>)>> {
self.register_plugins.compute(|| {
let crate_name = *self.crate_name()?.borrow();
let krate = self.parse()?.steal();
let (krate, pre_configured_attrs) = self.pre_configure()?.steal();

let empty: &(dyn Fn(&Session, &mut LintStore) + Sync + Send) = &|_, _| {};
let (krate, lint_store) = passes::register_plugins(
let lint_store = passes::register_plugins(
self.session(),
&*self.codegen_backend().metadata_loader(),
self.compiler.register_lints.as_deref().unwrap_or_else(|| empty),
krate,
&pre_configured_attrs,
crate_name,
)?;

@@ -154,17 +175,17 @@ impl<'tcx> Queries<'tcx> {
// called, which happens within passes::register_plugins().
self.dep_graph_future().ok();

Ok((krate, Lrc::new(lint_store)))
Ok((krate, pre_configured_attrs, Lrc::new(lint_store)))
})
}

fn crate_name(&self) -> Result<QueryResult<'_, Symbol>> {
self.crate_name.compute(|| {
Ok({
let parse_result = self.parse()?;
let krate = parse_result.borrow();
let pre_configure_result = self.pre_configure()?;
let (_, pre_configured_attrs) = &*pre_configure_result.borrow();
// parse `#[crate_name]` even if `--crate-name` was passed, to make sure it matches.
find_crate_name(self.session(), &krate.attrs)
find_crate_name(self.session(), pre_configured_attrs)
})
})
}
@@ -188,7 +209,7 @@ impl<'tcx> Queries<'tcx> {
pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
self.gcx.compute(|| {
let crate_name = *self.crate_name()?.borrow();
let (krate, lint_store) = self.register_plugins()?.steal();
let (krate, pre_configured_attrs, lint_store) = self.register_plugins()?.steal();

let sess = self.session();

@@ -215,7 +236,7 @@ impl<'tcx> Queries<'tcx> {
feed.crate_name(crate_name);

let feed = tcx.feed_unit_query();
feed.crate_for_resolver(tcx.arena.alloc(Steal::new(krate)));
feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
feed.metadata_loader(
tcx.arena.alloc(Steal::new(self.codegen_backend().metadata_loader())),
);
75 changes: 21 additions & 54 deletions compiler/rustc_metadata/src/creader.rs
Original file line number Diff line number Diff line change
@@ -6,11 +6,11 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob

use rustc_ast::expand::allocator::AllocatorKind;
use rustc_ast::{self as ast, *};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{MappedReadGuard, MappedWriteGuard, ReadGuard, WriteGuard};
use rustc_expand::base::SyntaxExtension;
use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, LOCAL_CRATE};
use rustc_hir::def_id::{CrateNum, LocalDefId, StableCrateId, StableCrateIdMap, LOCAL_CRATE};
use rustc_hir::definitions::Definitions;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::TyCtxt;
@@ -46,9 +46,8 @@ pub struct CStore {
/// This crate has a `#[alloc_error_handler]` item.
has_alloc_error_handler: bool,

/// This map is used to verify we get no hash conflicts between
/// `StableCrateId` values.
pub(crate) stable_crate_ids: FxHashMap<StableCrateId, CrateNum>,
/// The interned [StableCrateId]s.
pub(crate) stable_crate_ids: StableCrateIdMap,

/// Unused externs of the crate
unused_externs: Vec<Symbol>,
@@ -144,9 +143,21 @@ impl CStore {
})
}

fn alloc_new_crate_num(&mut self) -> CrateNum {
self.metas.push(None);
CrateNum::new(self.metas.len() - 1)
fn intern_stable_crate_id(&mut self, root: &CrateRoot) -> Result<CrateNum, CrateError> {
assert_eq!(self.metas.len(), self.stable_crate_ids.len());
let num = CrateNum::new(self.stable_crate_ids.len());
if let Some(&existing) = self.stable_crate_ids.get(&root.stable_crate_id()) {
let crate_name0 = root.name();
if let Some(crate_name1) = self.metas[existing].as_ref().map(|data| data.name()) {
Err(CrateError::StableCrateIdCollision(crate_name0, crate_name1))
} else {
Err(CrateError::SymbolConflictsCurrent(crate_name0))
}
} else {
self.metas.push(None);
self.stable_crate_ids.insert(root.stable_crate_id(), num);
Ok(num)
}
}

pub fn has_crate_data(&self, cnum: CrateNum) -> bool {
@@ -247,7 +258,7 @@ impl CStore {
}

pub fn new(sess: &Session) -> CStore {
let mut stable_crate_ids = FxHashMap::default();
let mut stable_crate_ids = StableCrateIdMap::default();
stable_crate_ids.insert(sess.local_stable_crate_id(), LOCAL_CRATE);
CStore {
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
@@ -342,42 +353,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
None
}

fn verify_no_symbol_conflicts(&self, root: &CrateRoot) -> Result<(), CrateError> {
// Check for (potential) conflicts with the local crate
if self.sess.local_stable_crate_id() == root.stable_crate_id() {
return Err(CrateError::SymbolConflictsCurrent(root.name()));
}

// Check for conflicts with any crate loaded so far
for (_, other) in self.cstore.iter_crate_data() {
// Same stable crate id but different SVH
if other.stable_crate_id() == root.stable_crate_id() && other.hash() != root.hash() {
bug!(
"Previously returned E0523 here. \
See https://github.com/rust-lang/rust/pull/100599 for additional discussion.\
root.name() = {}.",
root.name()
);
}
}

Ok(())
}

fn verify_no_stable_crate_id_hash_conflicts(
&mut self,
root: &CrateRoot,
cnum: CrateNum,
) -> Result<(), CrateError> {
if let Some(existing) = self.cstore.stable_crate_ids.insert(root.stable_crate_id(), cnum) {
let crate_name0 = root.name();
let crate_name1 = self.cstore.get_crate_data(existing).name();
return Err(CrateError::StableCrateIdCollision(crate_name0, crate_name1));
}

Ok(())
}

fn register_crate(
&mut self,
host_lib: Option<Library>,
@@ -396,7 +371,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
self.sess.opts.externs.get(name.as_str()).map_or(false, |e| e.is_private_dep);

// Claim this crate number and cache it
let cnum = self.cstore.alloc_new_crate_num();
let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;

info!(
"register crate `{}` (cnum = {}. private_dep = {})",
@@ -432,14 +407,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
None
};

// Perform some verification *after* resolve_crate_deps() above is
// known to have been successful. It seems that - in error cases - the
// cstore can be in a temporarily invalid state between cnum allocation
// and dependency resolution and the verification code would produce
// ICEs in that case (see #83045).
self.verify_no_symbol_conflicts(&crate_root)?;
self.verify_no_stable_crate_id_hash_conflicts(&crate_root, cnum)?;

let crate_metadata = CrateMetadata::new(
self.sess,
&self.cstore,
4 changes: 0 additions & 4 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
@@ -1709,10 +1709,6 @@ impl CrateMetadata {
self.root.name
}

pub(crate) fn stable_crate_id(&self) -> StableCrateId {
self.root.stable_crate_id
}

pub(crate) fn hash(&self) -> Svh {
self.root.hash
}
5 changes: 4 additions & 1 deletion compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
@@ -607,7 +607,10 @@ impl CrateStore for CStore {
}

fn stable_crate_id_to_crate_num(&self, stable_crate_id: StableCrateId) -> CrateNum {
self.stable_crate_ids[&stable_crate_id]
*self
.stable_crate_ids
.get(&stable_crate_id)
.unwrap_or_else(|| bug!("uninterned StableCrateId: {stable_crate_id:?}"))
}

/// Returns the `DefKey` for a given `DefId`. This indicates the
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
@@ -36,7 +36,7 @@ macro_rules! arena_types {
)>,
[] output_filenames: std::sync::Arc<rustc_session::config::OutputFilenames>,
[] metadata_loader: rustc_data_structures::steal::Steal<Box<rustc_session::cstore::MetadataLoaderDyn>>,
[] crate_for_resolver: rustc_data_structures::steal::Steal<rustc_ast::ast::Crate>,
[] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>,
[] resolutions: rustc_middle::ty::ResolverGlobalCtxt,
[decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult,
[decode] code_region: rustc_middle::mir::coverage::CodeRegion,
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/mir/query.rs
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@
use crate::mir::{Body, ConstantKind, Promoted};
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::unord::UnordSet;
use rustc_data_structures::vec_map::VecMap;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -227,7 +227,7 @@ pub struct BorrowCheckResult<'tcx> {
/// All the opaque types that are restricted to concrete types
/// by this function. Unlike the value in `TypeckResults`, this has
/// unerased regions.
pub concrete_opaque_types: VecMap<LocalDefId, OpaqueHiddenType<'tcx>>,
pub concrete_opaque_types: FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
pub used_mut_upvars: SmallVec<[Field; 8]>,
pub tainted_by_errors: Option<ErrorGuaranteed>,
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
@@ -2117,7 +2117,7 @@ rustc_queries! {
desc { "raw operations for metadata file access" }
}

query crate_for_resolver((): ()) -> &'tcx Steal<rustc_ast::ast::Crate> {
query crate_for_resolver((): ()) -> &'tcx Steal<(rustc_ast::Crate, rustc_ast::AttrVec)> {
feedable
no_hash
desc { "the ast before macro expansion and name resolution" }
5 changes: 2 additions & 3 deletions compiler/rustc_middle/src/ty/typeck_results.rs
Original file line number Diff line number Diff line change
@@ -8,10 +8,9 @@ use crate::{
},
};
use rustc_data_structures::{
fx::FxHashMap,
fx::{FxHashMap, FxIndexMap},
sync::Lrc,
unord::{UnordItems, UnordSet},
vec_map::VecMap,
};
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
@@ -155,7 +154,7 @@ pub struct TypeckResults<'tcx> {
/// by this function. We also store the
/// type here, so that mir-borrowck can use it as a hint for figuring out hidden types,
/// even if they are only set in dead code (which doesn't show up in MIR).
pub concrete_opaque_types: VecMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
pub concrete_opaque_types: FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,

/// Tracks the minimum captures required for a closure;
/// see `MinCaptureInformationMap` for more details.
6 changes: 3 additions & 3 deletions compiler/rustc_plugin_impl/src/load.rs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
use crate::errors::{LoadPluginError, MalformedPluginAttribute};
use crate::Registry;
use libloading::Library;
use rustc_ast::Crate;
use rustc_ast::Attribute;
use rustc_metadata::locator;
use rustc_session::cstore::MetadataLoader;
use rustc_session::Session;
@@ -20,11 +20,11 @@ type PluginRegistrarFn = fn(&mut Registry<'_>);
pub fn load_plugins(
sess: &Session,
metadata_loader: &dyn MetadataLoader,
krate: &Crate,
attrs: &[Attribute],
) -> Vec<PluginRegistrarFn> {
let mut plugins = Vec::new();

for attr in &krate.attrs {
for attr in attrs {
if !attr.has_name(sym::plugin) {
continue;
}
11 changes: 6 additions & 5 deletions compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1180,7 +1180,8 @@ impl<'tcx> Resolver<'_, 'tcx> {
impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub fn new(
tcx: TyCtxt<'tcx>,
krate: &Crate,
attrs: &[ast::Attribute],
crate_span: Span,
arenas: &'a ResolverArenas<'a>,
) -> Resolver<'a, 'tcx> {
let root_def_id = CRATE_DEF_ID.to_def_id();
@@ -1189,8 +1190,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None,
ModuleKind::Def(DefKind::Mod, root_def_id, kw::Empty),
ExpnId::root(),
krate.spans.inner_span,
tcx.sess.contains_name(&krate.attrs, sym::no_implicit_prelude),
crate_span,
tcx.sess.contains_name(attrs, sym::no_implicit_prelude),
&mut module_map,
);
let empty_module = arenas.new_module(
@@ -1222,9 +1223,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
.map(|(name, _)| (Ident::from_str(name), Default::default()))
.collect();

if !tcx.sess.contains_name(&krate.attrs, sym::no_core) {
if !tcx.sess.contains_name(attrs, sym::no_core) {
extern_prelude.insert(Ident::with_dummy_span(sym::core), Default::default());
if !tcx.sess.contains_name(&krate.attrs, sym::no_std) {
if !tcx.sess.contains_name(attrs, sym::no_std) {
extern_prelude.insert(Ident::with_dummy_span(sym::std), Default::default());
}
}
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/macros.rs
Original file line number Diff line number Diff line change
@@ -112,8 +112,8 @@ fn fast_print_path(path: &ast::Path) -> Symbol {

pub(crate) fn registered_tools(tcx: TyCtxt<'_>, (): ()) -> RegisteredTools {
let mut registered_tools = RegisteredTools::default();
let krate = tcx.crate_for_resolver(()).borrow();
for attr in tcx.sess.filter_by_name(&krate.attrs, sym::register_tool) {
let (_, pre_configured_attrs) = &*tcx.crate_for_resolver(()).borrow();
for attr in tcx.sess.filter_by_name(pre_configured_attrs, sym::register_tool) {
for nested_meta in attr.meta_item_list().unwrap_or_default() {
match nested_meta.ident() {
Some(ident) => {
18 changes: 10 additions & 8 deletions compiler/rustc_resolve/src/rustdoc.rs
Original file line number Diff line number Diff line change
@@ -26,11 +26,13 @@ pub enum DocFragmentKind {
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct DocFragment {
pub span: Span,
/// The module this doc-comment came from.
///
/// This allows distinguishing between the original documentation and a pub re-export.
/// If it is `None`, the item was not re-exported.
pub parent_module: Option<DefId>,
/// The item this doc-comment came from.
/// Used to determine the scope in which doc links in this fragment are resolved.
/// Typically filled for reexport docs when they are merged into the docs of the
/// original reexported item.
/// If the id is not filled, which happens for the original reexported item, then
/// it has to be taken from somewhere else during doc link resolution.
pub item_id: Option<DefId>,
pub doc: Symbol,
pub kind: DocFragmentKind,
pub indent: usize,
@@ -186,15 +188,15 @@ pub fn attrs_to_doc_fragments<'a>(
) -> (Vec<DocFragment>, ast::AttrVec) {
let mut doc_fragments = Vec::new();
let mut other_attrs = ast::AttrVec::new();
for (attr, parent_module) in attrs {
for (attr, item_id) in attrs {
if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() {
let doc = beautify_doc_string(doc_str, comment_kind);
let kind = if attr.is_doc_comment() {
DocFragmentKind::SugaredDoc
} else {
DocFragmentKind::RawDoc
};
let fragment = DocFragment { span: attr.span, doc, kind, parent_module, indent: 0 };
let fragment = DocFragment { span: attr.span, doc, kind, item_id, indent: 0 };
doc_fragments.push(fragment);
} else if !doc_only {
other_attrs.push(attr.clone());
@@ -216,7 +218,7 @@ pub fn prepare_to_doc_link_resolution(
) -> FxHashMap<Option<DefId>, String> {
let mut res = FxHashMap::default();
for fragment in doc_fragments {
let out_str = res.entry(fragment.parent_module).or_default();
let out_str = res.entry(fragment.item_id).or_default();
add_doc_fragment(out_str, fragment);
}
res
1 change: 1 addition & 0 deletions compiler/rustc_span/Cargo.toml
Original file line number Diff line number Diff line change
@@ -18,3 +18,4 @@ tracing = "0.1"
sha1 = "0.10.0"
sha2 = "0.10.1"
md5 = { package = "md-5", version = "0.10.0" }
indexmap = { version = "1.9.1" }
6 changes: 5 additions & 1 deletion compiler/rustc_span/src/def_id.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
use crate::{HashStableContext, Symbol};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_data_structures::unhash::Unhasher;
use rustc_data_structures::AtomicRef;
use rustc_index::vec::Idx;
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::borrow::Borrow;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::hash::{BuildHasherDefault, Hash, Hasher};

pub type StableCrateIdMap =
indexmap::IndexMap<StableCrateId, CrateNum, BuildHasherDefault<Unhasher>>;

rustc_index::newtype_index! {
#[custom_encodable]
17 changes: 16 additions & 1 deletion library/core/src/intrinsics/mir.rs
Original file line number Diff line number Diff line change
@@ -49,6 +49,8 @@
//!
//! The input to the [`mir!`] macro is:
//!
//! - An optional return type annotation in the form of `type RET = ...;`. This may be required
//! if the compiler cannot infer the type of RET.
//! - A possibly empty list of local declarations. Locals can also be declared inline on
//! assignments via `let`. Type inference generally works. Shadowing does not.
//! - A list of basic blocks. The first of these is the start block and is where execution begins.
@@ -124,6 +126,18 @@
//! }
//! )
//! }
//!
//! #[custom_mir(dialect = "runtime", phase = "optimized")]
//! fn annotated_return_type() -> (i32, bool) {
//! mir!(
//! type RET = (i32, bool);
//! {
//! RET.0 = 1;
//! RET.1 = true;
//! Return()
//! }
//! )
//! }
//! ```
//!
//! We can also set off compilation failures that happen in sufficiently late stages of the
@@ -342,6 +356,7 @@ define!(
#[rustc_macro_transparency = "transparent"]
pub macro mir {
(
$(type RET = $ret_ty:ty ;)?
$(let $local_decl:ident $(: $local_decl_ty:ty)? ;)*

{
@@ -362,7 +377,7 @@ pub macro mir {
{
// Now all locals
#[allow(non_snake_case)]
let RET;
let RET $(: $ret_ty)?;
$(
let $local_decl $(: $local_decl_ty)? ;
)*
2 changes: 2 additions & 0 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
@@ -1310,6 +1310,7 @@ impl<T> Option<T> {
/// let x: Option<String> = None;
/// assert_eq!(x.as_deref(), None);
/// ```
#[inline]
#[stable(feature = "option_deref", since = "1.40.0")]
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
pub const fn as_deref(&self) -> Option<&T::Target>
@@ -1336,6 +1337,7 @@ impl<T> Option<T> {
/// x
/// }), Some("HEY".to_owned().as_mut_str()));
/// ```
#[inline]
#[stable(feature = "option_deref", since = "1.40.0")]
#[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target>
2 changes: 2 additions & 0 deletions library/core/src/result.rs
Original file line number Diff line number Diff line change
@@ -908,6 +908,7 @@ impl<T, E> Result<T, E> {
/// let y: Result<&str, &u32> = Err(&42);
/// assert_eq!(x.as_deref(), y);
/// ```
#[inline]
#[stable(feature = "inner_deref", since = "1.47.0")]
pub fn as_deref(&self) -> Result<&T::Target, &E>
where
@@ -934,6 +935,7 @@ impl<T, E> Result<T, E> {
/// let y: Result<&mut str, &mut u32> = Err(&mut i);
/// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
/// ```
#[inline]
#[stable(feature = "inner_deref", since = "1.47.0")]
pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E>
where
2 changes: 1 addition & 1 deletion src/bootstrap/download-ci-llvm-stamp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Change this file to make users of the `download-ci-llvm` configuration download
a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.

Last change is for: https://github.com/rust-lang/rust/pull/104748
Last change is for: https://github.com/rust-lang/rust/pull/109373
1 change: 1 addition & 0 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
@@ -309,6 +309,7 @@ impl Step for Llvm {
cfg.out_dir(&out_dir)
.profile(profile)
.define("LLVM_ENABLE_ASSERTIONS", assertions)
.define("LLVM_UNREACHABLE_OPTIMIZE", "OFF")
.define("LLVM_ENABLE_PLUGINS", plugins)
.define("LLVM_TARGETS_TO_BUILD", llvm_targets)
.define("LLVM_EXPERIMENTAL_TARGETS_TO_BUILD", llvm_exp_targets)
75 changes: 23 additions & 52 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
@@ -36,15 +36,11 @@ use crate::formats::item_type::ItemType;
///
/// The returned value is `None` if the definition could not be inlined,
/// and `Some` of a vector of items if it was successfully expanded.
///
/// `parent_module` refers to the parent of the *re-export*, not the original item.
pub(crate) fn try_inline(
cx: &mut DocContext<'_>,
parent_module: DefId,
import_def_id: Option<DefId>,
res: Res,
name: Symbol,
attrs: Option<&[ast::Attribute]>,
attrs: Option<(&[ast::Attribute], Option<DefId>)>,
visited: &mut DefIdSet,
) -> Option<Vec<clean::Item>> {
let did = res.opt_def_id()?;
@@ -55,38 +51,17 @@ pub(crate) fn try_inline(

debug!("attrs={:?}", attrs);

let attrs_without_docs = attrs.map(|attrs| {
attrs.into_iter().filter(|a| a.doc_str().is_none()).cloned().collect::<Vec<_>>()
let attrs_without_docs = attrs.map(|(attrs, def_id)| {
(attrs.into_iter().filter(|a| a.doc_str().is_none()).cloned().collect::<Vec<_>>(), def_id)
});
// We need this ugly code because:
//
// ```
// attrs_without_docs.map(|a| a.as_slice())
// ```
//
// will fail because it returns a temporary slice and:
//
// ```
// attrs_without_docs.map(|s| {
// vec = s.as_slice();
// vec
// })
// ```
//
// will fail because we're moving an uninitialized variable into a closure.
let vec;
let attrs_without_docs = match attrs_without_docs {
Some(s) => {
vec = s;
Some(vec.as_slice())
}
None => None,
};
let attrs_without_docs =
attrs_without_docs.as_ref().map(|(attrs, def_id)| (&attrs[..], *def_id));

let import_def_id = attrs.and_then(|(_, def_id)| def_id);
let kind = match res {
Res::Def(DefKind::Trait, did) => {
record_extern_fqn(cx, did, ItemType::Trait);
build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
build_impls(cx, did, attrs_without_docs, &mut ret);
clean::TraitItem(Box::new(build_external_trait(cx, did)))
}
Res::Def(DefKind::Fn, did) => {
@@ -95,27 +70,27 @@ pub(crate) fn try_inline(
}
Res::Def(DefKind::Struct, did) => {
record_extern_fqn(cx, did, ItemType::Struct);
build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
build_impls(cx, did, attrs_without_docs, &mut ret);
clean::StructItem(build_struct(cx, did))
}
Res::Def(DefKind::Union, did) => {
record_extern_fqn(cx, did, ItemType::Union);
build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
build_impls(cx, did, attrs_without_docs, &mut ret);
clean::UnionItem(build_union(cx, did))
}
Res::Def(DefKind::TyAlias, did) => {
record_extern_fqn(cx, did, ItemType::Typedef);
build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
build_impls(cx, did, attrs_without_docs, &mut ret);
clean::TypedefItem(build_type_alias(cx, did))
}
Res::Def(DefKind::Enum, did) => {
record_extern_fqn(cx, did, ItemType::Enum);
build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
build_impls(cx, did, attrs_without_docs, &mut ret);
clean::EnumItem(build_enum(cx, did))
}
Res::Def(DefKind::ForeignTy, did) => {
record_extern_fqn(cx, did, ItemType::ForeignType);
build_impls(cx, Some(parent_module), did, attrs_without_docs, &mut ret);
build_impls(cx, did, attrs_without_docs, &mut ret);
clean::ForeignTypeItem
}
// Never inline enum variants but leave them shown as re-exports.
@@ -149,7 +124,7 @@ pub(crate) fn try_inline(
_ => return None,
};

let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs);
let (attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs);
cx.inlined.insert(did.into());
let mut item =
clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, Box::new(attrs), cfg);
@@ -316,17 +291,16 @@ fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box<clean::Typedef>
/// Builds all inherent implementations of an ADT (struct/union/enum) or Trait item/path/reexport.
pub(crate) fn build_impls(
cx: &mut DocContext<'_>,
parent_module: Option<DefId>,
did: DefId,
attrs: Option<&[ast::Attribute]>,
attrs: Option<(&[ast::Attribute], Option<DefId>)>,
ret: &mut Vec<clean::Item>,
) {
let _prof_timer = cx.tcx.sess.prof.generic_activity("build_inherent_impls");
let tcx = cx.tcx;

// for each implementation of an item represented by `did`, build the clean::Item for that impl
for &did in tcx.inherent_impls(did).iter() {
build_impl(cx, parent_module, did, attrs, ret);
build_impl(cx, did, attrs, ret);
}

// This pretty much exists expressly for `dyn Error` traits that exist in the `alloc` crate.
@@ -340,28 +314,26 @@ pub(crate) fn build_impls(
let type_ =
if tcx.is_trait(did) { TraitSimplifiedType(did) } else { AdtSimplifiedType(did) };
for &did in tcx.incoherent_impls(type_) {
build_impl(cx, parent_module, did, attrs, ret);
build_impl(cx, did, attrs, ret);
}
}
}

/// `parent_module` refers to the parent of the re-export, not the original item
pub(crate) fn merge_attrs(
cx: &mut DocContext<'_>,
parent_module: Option<DefId>,
old_attrs: &[ast::Attribute],
new_attrs: Option<&[ast::Attribute]>,
new_attrs: Option<(&[ast::Attribute], Option<DefId>)>,
) -> (clean::Attributes, Option<Arc<clean::cfg::Cfg>>) {
// NOTE: If we have additional attributes (from a re-export),
// always insert them first. This ensure that re-export
// doc comments show up before the original doc comments
// when we render them.
if let Some(inner) = new_attrs {
if let Some((inner, item_id)) = new_attrs {
let mut both = inner.to_vec();
both.extend_from_slice(old_attrs);
(
if let Some(new_id) = parent_module {
Attributes::from_ast_with_additional(old_attrs, (inner, new_id))
if let Some(item_id) = item_id {
Attributes::from_ast_with_additional(old_attrs, (inner, item_id))
} else {
Attributes::from_ast(&both)
},
@@ -375,9 +347,8 @@ pub(crate) fn merge_attrs(
/// Inline an `impl`, inherent or of a trait. The `did` must be for an `impl`.
pub(crate) fn build_impl(
cx: &mut DocContext<'_>,
parent_module: Option<DefId>,
did: DefId,
attrs: Option<&[ast::Attribute]>,
attrs: Option<(&[ast::Attribute], Option<DefId>)>,
ret: &mut Vec<clean::Item>,
) {
if !cx.inlined.insert(did.into()) {
@@ -539,7 +510,7 @@ pub(crate) fn build_impl(
record_extern_trait(cx, did);
}

let (merged_attrs, cfg) = merge_attrs(cx, parent_module, load_attrs(cx, did), attrs);
let (merged_attrs, cfg) = merge_attrs(cx, load_attrs(cx, did), attrs);
trace!("merged_attrs={:?}", merged_attrs);

trace!(
@@ -635,7 +606,7 @@ fn build_module_items(
cfg: None,
inline_stmt_id: None,
});
} else if let Some(i) = try_inline(cx, did, None, res, item.ident.name, None, visited) {
} else if let Some(i) = try_inline(cx, res, item.ident.name, None, visited) {
items.extend(i)
}
}
26 changes: 8 additions & 18 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
@@ -2388,12 +2388,12 @@ fn clean_maybe_renamed_item<'tcx>(
target_attrs.extend_from_slice(inline::load_attrs(cx, def_id));
}

let import_parent = import_id.map(|import_id| cx.tcx.local_parent(import_id).to_def_id());
let (attrs, cfg) = merge_attrs(cx, import_parent, &target_attrs, Some(&import_attrs));
let import_id = import_id.map(|def_id| def_id.to_def_id());
let (attrs, cfg) = merge_attrs(cx, &target_attrs, Some((&import_attrs, import_id)));

let mut item =
Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg);
item.inline_stmt_id = import_id.map(|def_id| def_id.to_def_id());
item.inline_stmt_id = import_id;
vec![item]
})
}
@@ -2478,18 +2478,12 @@ fn clean_extern_crate<'tcx>(

let krate_owner_def_id = krate.owner_id.to_def_id();
if please_inline {
let mut visited = DefIdSet::default();

let res = Res::Def(DefKind::Mod, crate_def_id);

if let Some(items) = inline::try_inline(
cx,
cx.tcx.parent_module(krate.hir_id()).to_def_id(),
Some(krate_owner_def_id),
res,
Res::Def(DefKind::Mod, crate_def_id),
name,
Some(attrs),
&mut visited,
Some((attrs, Some(krate_owner_def_id))),
&mut Default::default(),
) {
return items;
}
@@ -2613,17 +2607,13 @@ fn clean_use_statement_inner<'tcx>(
denied = true;
}
if !denied {
let mut visited = DefIdSet::default();
let import_def_id = import.owner_id.to_def_id();

if let Some(mut items) = inline::try_inline(
cx,
cx.tcx.parent_module(import.hir_id()).to_def_id(),
Some(import_def_id),
path.res,
name,
Some(attrs),
&mut visited,
Some((attrs, Some(import_def_id))),
&mut Default::default(),
) {
items.push(Item::from_def_id_and_parts(
import_def_id,
2 changes: 1 addition & 1 deletion src/librustdoc/clean/types/tests.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ use rustc_span::symbol::Symbol;
fn create_doc_fragment(s: &str) -> Vec<DocFragment> {
vec![DocFragment {
span: DUMMY_SP,
parent_module: None,
item_id: None,
doc: Symbol::intern(s),
kind: DocFragmentKind::SugaredDoc,
indent: 0,
4 changes: 2 additions & 2 deletions src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
@@ -195,12 +195,12 @@ pub(crate) fn build_deref_target_impls(
if let Some(prim) = target.primitive_type() {
let _prof_timer = cx.tcx.sess.prof.generic_activity("build_primitive_inherent_impls");
for did in prim.impls(tcx).filter(|did| !did.is_local()) {
inline::build_impl(cx, None, did, None, ret);
inline::build_impl(cx, did, None, ret);
}
} else if let Type::Path { path } = target {
let did = path.def_id();
if !did.is_local() {
inline::build_impls(cx, None, did, None, ret);
inline::build_impls(cx, did, None, ret);
}
}
}
163 changes: 63 additions & 100 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ use std::mem;
use std::ops::Range;

use crate::clean::{self, utils::find_nearest_parent_module};
use crate::clean::{Crate, Item, ItemId, ItemLink, PrimitiveType};
use crate::clean::{Crate, Item, ItemLink, PrimitiveType};
use crate::core::DocContext;
use crate::html::markdown::{markdown_links, MarkdownLink};
use crate::lint::{BROKEN_INTRA_DOC_LINKS, PRIVATE_INTRA_DOC_LINKS};
@@ -42,8 +42,7 @@ pub(crate) const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
};

fn collect_intra_doc_links(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
let mut collector =
LinkCollector { cx, mod_ids: Vec::new(), visited_links: FxHashMap::default() };
let mut collector = LinkCollector { cx, visited_links: FxHashMap::default() };
collector.visit_crate(&krate);
krate
}
@@ -149,7 +148,7 @@ impl TryFrom<ResolveRes> for Res {
#[derive(Debug)]
struct UnresolvedPath<'a> {
/// Item on which the link is resolved, used for resolving `Self`.
item_id: ItemId,
item_id: DefId,
/// The scope the link was resolved in.
module_id: DefId,
/// If part of the link resolved, this has the `Res`.
@@ -225,7 +224,7 @@ impl UrlFragment {

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
struct ResolutionInfo {
item_id: ItemId,
item_id: DefId,
module_id: DefId,
dis: Option<Disambiguator>,
path_str: Box<str>,
@@ -242,11 +241,6 @@ struct DiagnosticInfo<'a> {

struct LinkCollector<'a, 'tcx> {
cx: &'a mut DocContext<'tcx>,
/// A stack of modules used to decide what scope to resolve in.
///
/// The last module will be used if the parent scope of the current item is
/// unknown.
mod_ids: Vec<DefId>,
/// Cache the resolved links so we can avoid resolving (and emitting errors for) the same link.
/// The link will be `None` if it could not be resolved (i.e. the error was cached).
visited_links: FxHashMap<ResolutionInfo, Option<(Res, Option<UrlFragment>)>>,
@@ -262,7 +256,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
fn variant_field<'path>(
&self,
path_str: &'path str,
item_id: ItemId,
item_id: DefId,
module_id: DefId,
) -> Result<(Res, DefId), UnresolvedPath<'path>> {
let tcx = self.cx.tcx;
@@ -333,35 +327,33 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
})
}

fn resolve_self_ty(&self, path_str: &str, ns: Namespace, item_id: ItemId) -> Option<Res> {
fn resolve_self_ty(&self, path_str: &str, ns: Namespace, item_id: DefId) -> Option<Res> {
if ns != TypeNS || path_str != "Self" {
return None;
}

let tcx = self.cx.tcx;
item_id
.as_def_id()
.map(|def_id| match tcx.def_kind(def_id) {
def_kind @ (DefKind::AssocFn
| DefKind::AssocConst
| DefKind::AssocTy
| DefKind::Variant
| DefKind::Field) => {
let parent_def_id = tcx.parent(def_id);
if def_kind == DefKind::Field && tcx.def_kind(parent_def_id) == DefKind::Variant
{
tcx.parent(parent_def_id)
} else {
parent_def_id
}
let self_id = match tcx.def_kind(item_id) {
def_kind @ (DefKind::AssocFn
| DefKind::AssocConst
| DefKind::AssocTy
| DefKind::Variant
| DefKind::Field) => {
let parent_def_id = tcx.parent(item_id);
if def_kind == DefKind::Field && tcx.def_kind(parent_def_id) == DefKind::Variant {
tcx.parent(parent_def_id)
} else {
parent_def_id
}
_ => def_id,
})
.and_then(|self_id| match tcx.def_kind(self_id) {
DefKind::Impl { .. } => self.def_id_to_res(self_id),
DefKind::Use => None,
def_kind => Some(Res::Def(def_kind, self_id)),
})
}
_ => item_id,
};

match tcx.def_kind(self_id) {
DefKind::Impl { .. } => self.def_id_to_res(self_id),
DefKind::Use => None,
def_kind => Some(Res::Def(def_kind, self_id)),
}
}

/// Convenience wrapper around `doc_link_resolutions`.
@@ -373,7 +365,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
&self,
path_str: &str,
ns: Namespace,
item_id: ItemId,
item_id: DefId,
module_id: DefId,
) -> Option<Res> {
if let res @ Some(..) = self.resolve_self_ty(path_str, ns, item_id) {
@@ -400,7 +392,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
&mut self,
path_str: &'path str,
ns: Namespace,
item_id: ItemId,
item_id: DefId,
module_id: DefId,
) -> Result<(Res, Option<DefId>), UnresolvedPath<'path>> {
if let Some(res) = self.resolve_path(path_str, ns, item_id, module_id) {
@@ -779,48 +771,8 @@ fn is_derive_trait_collision<T>(ns: &PerNS<Result<(Res, T), ResolutionFailure<'_

impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> {
fn visit_item(&mut self, item: &Item) {
let parent_node =
item.item_id.as_def_id().and_then(|did| find_nearest_parent_module(self.cx.tcx, did));
if parent_node.is_some() {
trace!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.item_id);
}

let inner_docs = item.inner_docs(self.cx.tcx);

if item.is_mod() && inner_docs {
self.mod_ids.push(item.item_id.expect_def_id());
}

// We want to resolve in the lexical scope of the documentation.
// In the presence of re-exports, this is not the same as the module of the item.
// Rather than merging all documentation into one, resolve it one attribute at a time
// so we know which module it came from.
for (parent_module, doc) in prepare_to_doc_link_resolution(&item.attrs.doc_strings) {
if !may_have_doc_links(&doc) {
continue;
}
debug!("combined_docs={}", doc);
// NOTE: if there are links that start in one crate and end in another, this will not resolve them.
// This is a degenerate case and it's not supported by rustdoc.
let parent_node = parent_module.or(parent_node);
for md_link in preprocessed_markdown_links(&doc) {
let link = self.resolve_link(item, &doc, parent_node, &md_link);
if let Some(link) = link {
self.cx.cache.intra_doc_links.entry(item.item_id).or_default().push(link);
}
}
}

if item.is_mod() {
if !inner_docs {
self.mod_ids.push(item.item_id.expect_def_id());
}

self.visit_item_recur(item);
self.mod_ids.pop();
} else {
self.visit_item_recur(item)
}
self.resolve_links(item);
self.visit_item_recur(item)
}
}

@@ -946,14 +898,41 @@ fn preprocessed_markdown_links(s: &str) -> Vec<PreprocessedMarkdownLink> {
}

impl LinkCollector<'_, '_> {
fn resolve_links(&mut self, item: &Item) {
// We want to resolve in the lexical scope of the documentation.
// In the presence of re-exports, this is not the same as the module of the item.
// Rather than merging all documentation into one, resolve it one attribute at a time
// so we know which module it came from.
for (item_id, doc) in prepare_to_doc_link_resolution(&item.attrs.doc_strings) {
if !may_have_doc_links(&doc) {
continue;
}
debug!("combined_docs={}", doc);
// NOTE: if there are links that start in one crate and end in another, this will not resolve them.
// This is a degenerate case and it's not supported by rustdoc.
let item_id = item_id.unwrap_or_else(|| item.item_id.expect_def_id());
let module_id = match self.cx.tcx.def_kind(item_id) {
DefKind::Mod if item.inner_docs(self.cx.tcx) => item_id,
_ => find_nearest_parent_module(self.cx.tcx, item_id).unwrap(),
};
for md_link in preprocessed_markdown_links(&doc) {
let link = self.resolve_link(item, item_id, module_id, &doc, &md_link);
if let Some(link) = link {
self.cx.cache.intra_doc_links.entry(item.item_id).or_default().push(link);
}
}
}
}

/// This is the entry point for resolving an intra-doc link.
///
/// FIXME(jynelson): this is way too many arguments
fn resolve_link(
&mut self,
item: &Item,
item_id: DefId,
module_id: DefId,
dox: &str,
parent_node: Option<DefId>,
link: &PreprocessedMarkdownLink,
) -> Option<ItemLink> {
let PreprocessedMarkdownLink(pp_link, ori_link) = link;
@@ -970,25 +949,9 @@ impl LinkCollector<'_, '_> {
pp_link.as_ref().map_err(|err| err.report(self.cx, diag_info.clone())).ok()?;
let disambiguator = *disambiguator;

// In order to correctly resolve intra-doc links we need to
// pick a base AST node to work from. If the documentation for
// this module came from an inner comment (//!) then we anchor
// our name resolution *inside* the module. If, on the other
// hand it was an outer comment (///) then we anchor the name
// resolution in the parent module on the basis that the names
// used are more likely to be intended to be parent names. For
// this, we set base_node to None for inner comments since
// we've already pushed this node onto the resolution stack but
// for outer comments we explicitly try and resolve against the
// parent_node first.
let inner_docs = item.inner_docs(self.cx.tcx);
let base_node =
if item.is_mod() && inner_docs { self.mod_ids.last().copied() } else { parent_node };
let module_id = base_node.expect("doc link without parent module");

let (mut res, fragment) = self.resolve_with_disambiguator_cached(
ResolutionInfo {
item_id: item.item_id,
item_id,
module_id,
dis: disambiguator,
path_str: path_str.clone(),
@@ -1229,11 +1192,11 @@ impl LinkCollector<'_, '_> {
let disambiguator = key.dis;
let path_str = &key.path_str;
let item_id = key.item_id;
let base_node = key.module_id;
let module_id = key.module_id;

match disambiguator.map(Disambiguator::ns) {
Some(expected_ns) => {
match self.resolve(path_str, expected_ns, item_id, base_node) {
match self.resolve(path_str, expected_ns, item_id, module_id) {
Ok(res) => Some(res),
Err(err) => {
// We only looked in one namespace. Try to give a better error if possible.
@@ -1243,7 +1206,7 @@ impl LinkCollector<'_, '_> {
for other_ns in [TypeNS, ValueNS, MacroNS] {
if other_ns != expected_ns {
if let Ok(res) =
self.resolve(path_str, other_ns, item_id, base_node)
self.resolve(path_str, other_ns, item_id, module_id)
{
err = ResolutionFailure::WrongNamespace {
res: full_res(self.cx.tcx, res),
@@ -1260,7 +1223,7 @@ impl LinkCollector<'_, '_> {
None => {
// Try everything!
let mut candidate = |ns| {
self.resolve(path_str, ns, item_id, base_node)
self.resolve(path_str, ns, item_id, module_id)
.map_err(ResolutionFailure::NotResolved)
};

6 changes: 3 additions & 3 deletions src/librustdoc/passes/collect_trait_impls.rs
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
let _prof_timer = cx.tcx.sess.prof.generic_activity("build_extern_trait_impls");
for &cnum in cx.tcx.crates(()) {
for &impl_def_id in cx.tcx.trait_impls_in_crate(cnum) {
inline::build_impl(cx, None, impl_def_id, None, &mut new_items_external);
inline::build_impl(cx, impl_def_id, None, &mut new_items_external);
}
}
}
@@ -75,7 +75,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
);
parent = cx.tcx.opt_parent(did);
}
inline::build_impl(cx, None, impl_def_id, Some(&attr_buf), &mut new_items_local);
inline::build_impl(cx, impl_def_id, Some((&attr_buf, None)), &mut new_items_local);
attr_buf.clear();
}
}
@@ -84,7 +84,7 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
for def_id in PrimitiveType::all_impls(cx.tcx) {
// Try to inline primitive impls from other crates.
if !def_id.is_local() {
inline::build_impl(cx, None, def_id, None, &mut new_items_external);
inline::build_impl(cx, def_id, None, &mut new_items_external);
}
}
for (prim, did) in PrimitiveType::primitive_locations(cx.tcx) {
3 changes: 2 additions & 1 deletion src/librustdoc/passes/propagate_doc_cfg.rs
Original file line number Diff line number Diff line change
@@ -57,7 +57,8 @@ impl<'a, 'tcx> CfgPropagator<'a, 'tcx> {
next_def_id = parent_def_id;
}

let (_, cfg) = merge_attrs(self.cx, None, item.attrs.other_attrs.as_slice(), Some(&attrs));
let (_, cfg) =
merge_attrs(self.cx, item.attrs.other_attrs.as_slice(), Some((&attrs, None)));
item.cfg = cfg;
}
}
21 changes: 21 additions & 0 deletions tests/mir-opt/building/custom/composite_return.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#![feature(custom_mir, core_intrinsics)]

extern crate core;
use core::intrinsics::mir::*;

// EMIT_MIR composite_return.tuple.built.after.mir
#[custom_mir(dialect = "runtime", phase = "optimized")]
fn tuple() -> (i32, bool) {
mir!(
type RET = (i32, bool);
{
RET.0 = 1;
RET.1 = true;
Return()
}
)
}

fn main() {
assert_eq!(tuple(), (1, true));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// MIR for `tuple` after built

fn tuple() -> (i32, bool) {
let mut _0: (i32, bool); // return place in scope 0 at $DIR/composite_return.rs:+0:15: +0:26

bb0: {
(_0.0: i32) = const 1_i32; // scope 0 at $DIR/composite_return.rs:+4:13: +4:22
(_0.1: bool) = const true; // scope 0 at $DIR/composite_return.rs:+5:13: +5:25
return; // scope 0 at $DIR/composite_return.rs:+6:13: +6:21
}
}
2 changes: 1 addition & 1 deletion tests/run-make-fulldeps/issue-83045/Makefile
Original file line number Diff line number Diff line change
@@ -29,5 +29,5 @@ all:
--crate-type=rlib \
--edition=2018 \
c.rs 2>&1 | tee $(TMPDIR)/output.txt || exit 0
$(CGREP) E0463 < $(TMPDIR)/output.txt
$(CGREP) E0519 < $(TMPDIR)/output.txt
$(CGREP) -v "internal compiler error" < $(TMPDIR)/output.txt
1 change: 1 addition & 0 deletions tests/rustdoc-ui/intra-doc/auxiliary/inner-crate-doc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//! Inner doc comment
10 changes: 10 additions & 0 deletions tests/rustdoc-ui/intra-doc/import-inline-merge-module.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Test for issue #108501.
// Module parent scope doesn't hijack import's parent scope for the import's doc links.

// check-pass
// aux-build: inner-crate-doc.rs
// compile-flags: --extern inner_crate_doc --edition 2018

/// Import doc comment [inner_crate_doc]
#[doc(inline)]
pub use inner_crate_doc;
1 change: 0 additions & 1 deletion tests/ui-fulldeps/lint-tool-test.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,6 @@
#![cfg_attr(foo, warn(test_lint))]
//~^ WARNING lint name `test_lint` is deprecated and may not have an effect in the future
//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
//~| WARNING lint name `test_lint` is deprecated and may not have an effect in the future
#![deny(clippy_group)]
//~^ WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
//~| WARNING lint name `clippy_group` is deprecated and may not have an effect in the future
32 changes: 13 additions & 19 deletions tests/ui-fulldeps/lint-tool-test.stderr
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
warning: lint name `test_lint` is deprecated and may not have an effect in the future.
--> $DIR/lint-tool-test.rs:9:23
|
LL | #![cfg_attr(foo, warn(test_lint))]
| ^^^^^^^^^ help: change it to: `clippy::test_lint`
|
= note: `#[warn(renamed_and_removed_lints)]` on by default

warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
--> $DIR/lint-tool-test.rs:13:9
--> $DIR/lint-tool-test.rs:12:9
|
LL | #![deny(clippy_group)]
| ^^^^^^^^^^^^ help: change it to: `clippy::group`
|
= note: `#[warn(renamed_and_removed_lints)]` on by default

warning: lint name `test_group` is deprecated and may not have an effect in the future.
--> $DIR/lint-tool-test.rs:29:9
--> $DIR/lint-tool-test.rs:28:9
|
LL | #[allow(test_group)]
| ^^^^^^^^^^ help: change it to: `clippy::test_group`
@@ -25,40 +19,40 @@ LL | #![cfg_attr(foo, warn(test_lint))]
| ^^^^^^^^^ help: change it to: `clippy::test_lint`

warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
--> $DIR/lint-tool-test.rs:13:9
--> $DIR/lint-tool-test.rs:12:9
|
LL | #![deny(clippy_group)]
| ^^^^^^^^^^^^ help: change it to: `clippy::group`

error: item is named 'lintme'
--> $DIR/lint-tool-test.rs:18:1
--> $DIR/lint-tool-test.rs:17:1
|
LL | fn lintme() { }
| ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/lint-tool-test.rs:13:9
--> $DIR/lint-tool-test.rs:12:9
|
LL | #![deny(clippy_group)]
| ^^^^^^^^^^^^
= note: `#[deny(clippy::test_lint)]` implied by `#[deny(clippy::group)]`

error: item is named 'lintmetoo'
--> $DIR/lint-tool-test.rs:26:5
--> $DIR/lint-tool-test.rs:25:5
|
LL | fn lintmetoo() { }
| ^^^^^^^^^^^^^^^^^^
|
= note: `#[deny(clippy::test_group)]` implied by `#[deny(clippy::group)]`

warning: lint name `test_group` is deprecated and may not have an effect in the future.
--> $DIR/lint-tool-test.rs:29:9
--> $DIR/lint-tool-test.rs:28:9
|
LL | #[allow(test_group)]
| ^^^^^^^^^^ help: change it to: `clippy::test_group`

warning: unknown lint: `this_lint_does_not_exist`
--> $DIR/lint-tool-test.rs:33:8
--> $DIR/lint-tool-test.rs:32:8
|
LL | #[deny(this_lint_does_not_exist)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,16 +74,16 @@ LL | #![cfg_attr(foo, warn(test_lint))]
| ^^^^^^^^^ help: change it to: `clippy::test_lint`

warning: lint name `clippy_group` is deprecated and may not have an effect in the future.
--> $DIR/lint-tool-test.rs:13:9
--> $DIR/lint-tool-test.rs:12:9
|
LL | #![deny(clippy_group)]
| ^^^^^^^^^^^^ help: change it to: `clippy::group`

warning: lint name `test_group` is deprecated and may not have an effect in the future.
--> $DIR/lint-tool-test.rs:29:9
--> $DIR/lint-tool-test.rs:28:9
|
LL | #[allow(test_group)]
| ^^^^^^^^^^ help: change it to: `clippy::test_group`

error: aborting due to 2 previous errors; 11 warnings emitted
error: aborting due to 2 previous errors; 10 warnings emitted

6 changes: 6 additions & 0 deletions tests/ui/cfg/auxiliary/cfg_false_lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// It is unclear whether a fully unconfigured crate should link to standard library,
// or what its `no_std`/`no_core`/`compiler_builtins` status, more precisely.
// Currently the usual standard library prelude is added to such crates,
// and therefore they link to libstd.

#![cfg(FALSE)]
20 changes: 20 additions & 0 deletions tests/ui/cfg/cfg-false-feature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// It is unclear which features should be in effect in a fully unconfigured crate (issue #104633).
// Currently none on the features are in effect, so we get the feature gates reported.

// check-pass
// compile-flags: --crate-type lib

#![feature(decl_macro)]
#![cfg(FALSE)]
#![feature(box_syntax)]

macro mac() {} //~ WARN `macro` is experimental
//~| WARN unstable syntax can change at any point in the future

trait A = Clone; //~ WARN trait aliases are experimental
//~| WARN unstable syntax can change at any point in the future

fn main() {
let box _ = Box::new(0); //~ WARN box pattern syntax is experimental
//~| WARN unstable syntax can change at any point in the future
}
35 changes: 35 additions & 0 deletions tests/ui/cfg/cfg-false-feature.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
warning: trait aliases are experimental
--> $DIR/cfg-false-feature.rs:14:1
|
LL | trait A = Clone;
| ^^^^^^^^^^^^^^^^
|
= note: see issue #41517 <https://github.com/rust-lang/rust/issues/41517> for more information
= help: add `#![feature(trait_alias)]` to the crate attributes to enable
= warning: unstable syntax can change at any point in the future, causing a hard error!
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>

warning: `macro` is experimental
--> $DIR/cfg-false-feature.rs:11:1
|
LL | macro mac() {}
| ^^^^^^^^^^^^^^
|
= note: see issue #39412 <https://github.com/rust-lang/rust/issues/39412> for more information
= help: add `#![feature(decl_macro)]` to the crate attributes to enable
= warning: unstable syntax can change at any point in the future, causing a hard error!
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>

warning: box pattern syntax is experimental
--> $DIR/cfg-false-feature.rs:18:9
|
LL | let box _ = Box::new(0);
| ^^^^^
|
= note: see issue #29641 <https://github.com/rust-lang/rust/issues/29641> for more information
= help: add `#![feature(box_patterns)]` to the crate attributes to enable
= warning: unstable syntax can change at any point in the future, causing a hard error!
= note: for more information, see issue #65860 <https://github.com/rust-lang/rust/issues/65860>

warning: 3 warnings emitted

11 changes: 11 additions & 0 deletions tests/ui/cfg/cfg_false_no_std.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Currently no error because the panic handler is supplied by libstd linked though the empty
// library, but the desirable behavior is unclear (see comments in cfg_false_lib.rs).

// check-pass
// aux-build: cfg_false_lib.rs

#![no_std]

extern crate cfg_false_lib as _;

fn main() {}