Skip to content

Commit

Permalink
Auto merge of rust-lang#109547 - matthiaskrgr:rollup-zczqgdk, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 9 pull requests

Successful merges:

 - rust-lang#108629 (rustdoc: add support for type filters in arguments and generics)
 - rust-lang#108924 (panic_immediate_abort requires abort as a panic strategy)
 - rust-lang#108961 (Refine error spans for const args in hir typeck)
 - rust-lang#108986 (sync LVI tests)
 - rust-lang#109142 (Add block-based mutex unlocking example)
 - rust-lang#109368 (fix typo in the creation of OpenOption for RustyHermit)
 - rust-lang#109493 (Return nested obligations from canonical response var unification)
 - rust-lang#109515 (Add AixLinker to support linking on AIX)
 - rust-lang#109536 (resolve: Rename some cstore methods to match queries and add comments)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 24, 2023
2 parents cf073ec + 4d21d30 commit 4c0f500
Show file tree
Hide file tree
Showing 48 changed files with 718 additions and 290 deletions.
174 changes: 174 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ pub fn get_linker<'a>(
LinkerFlavor::Unix(Cc::No) if sess.target.os == "l4re" => {
Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>
}
LinkerFlavor::Unix(Cc::No) if sess.target.os == "aix" => {
Box::new(AixLinker::new(cmd, sess)) as Box<dyn Linker>
}
LinkerFlavor::WasmLld(Cc::No) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
LinkerFlavor::Gnu(cc, _)
| LinkerFlavor::Darwin(cc, _)
Expand Down Expand Up @@ -1474,6 +1477,177 @@ impl<'a> L4Bender<'a> {
}
}

/// Linker for AIX.
pub struct AixLinker<'a> {
cmd: Command,
sess: &'a Session,
hinted_static: bool,
}

impl<'a> AixLinker<'a> {
pub fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> {
AixLinker { cmd: cmd, sess: sess, hinted_static: false }
}

fn hint_static(&mut self) {
if !self.hinted_static {
self.cmd.arg("-bstatic");
self.hinted_static = true;
}
}

fn hint_dynamic(&mut self) {
if self.hinted_static {
self.cmd.arg("-bdynamic");
self.hinted_static = false;
}
}

fn build_dylib(&mut self, _out_filename: &Path) {
self.cmd.arg("-bM:SRE");
self.cmd.arg("-bnoentry");
// FIXME: Use CreateExportList utility to create export list
// and remove -bexpfull.
self.cmd.arg("-bexpfull");
}
}

impl<'a> Linker for AixLinker<'a> {
fn link_dylib(&mut self, lib: &str, _verbatim: bool, _as_needed: bool) {
self.hint_dynamic();
self.cmd.arg(format!("-l{}", lib));
}

fn link_staticlib(&mut self, lib: &str, _verbatim: bool) {
self.hint_static();
self.cmd.arg(format!("-l{}", lib));
}

fn link_rlib(&mut self, lib: &Path) {
self.hint_static();
self.cmd.arg(lib);
}

fn include_path(&mut self, path: &Path) {
self.cmd.arg("-L").arg(path);
}

fn framework_path(&mut self, _: &Path) {
bug!("frameworks are not supported on AIX");
}

fn output_filename(&mut self, path: &Path) {
self.cmd.arg("-o").arg(path);
}

fn add_object(&mut self, path: &Path) {
self.cmd.arg(path);
}

fn full_relro(&mut self) {}

fn partial_relro(&mut self) {}

fn no_relro(&mut self) {}

fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}

fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) {
match output_kind {
LinkOutputKind::DynamicDylib => {
self.hint_dynamic();
self.build_dylib(out_filename);
}
LinkOutputKind::StaticDylib => {
self.hint_static();
self.build_dylib(out_filename);
}
_ => {}
}
}

fn link_rust_dylib(&mut self, lib: &str, _: &Path) {
self.hint_dynamic();
self.cmd.arg(format!("-l{}", lib));
}

fn link_framework(&mut self, _framework: &str, _as_needed: bool) {
bug!("frameworks not supported on AIX");
}

fn link_whole_staticlib(&mut self, lib: &str, verbatim: bool, search_path: &[PathBuf]) {
self.hint_static();
let lib = find_native_static_library(lib, verbatim, search_path, &self.sess);
self.cmd.arg(format!("-bkeepfile:{}", lib.to_str().unwrap()));
}

fn link_whole_rlib(&mut self, lib: &Path) {
self.hint_static();
self.cmd.arg(format!("-bkeepfile:{}", lib.to_str().unwrap()));
}

fn gc_sections(&mut self, _keep_metadata: bool) {
self.cmd.arg("-bgc");
}

fn no_gc_sections(&mut self) {
self.cmd.arg("-bnogc");
}

fn optimize(&mut self) {}

fn pgo_gen(&mut self) {}

fn control_flow_guard(&mut self) {}

fn debuginfo(&mut self, strip: Strip, _: &[PathBuf]) {
match strip {
Strip::None => {}
// FIXME: -s strips the symbol table, line number information
// and relocation information.
Strip::Debuginfo | Strip::Symbols => {
self.cmd.arg("-s");
}
}
}

fn no_crt_objects(&mut self) {}

fn no_default_libraries(&mut self) {}

fn export_symbols(&mut self, tmpdir: &Path, _crate_type: CrateType, symbols: &[String]) {
let path = tmpdir.join("list.exp");
let res: io::Result<()> = try {
let mut f = BufWriter::new(File::create(&path)?);
// TODO: use llvm-nm to generate export list.
for symbol in symbols {
debug!(" _{}", symbol);
writeln!(f, " {}", symbol)?;
}
};
if let Err(e) = res {
self.sess.fatal(&format!("failed to write export file: {}", e));
}
self.cmd.arg(format!("-bE:{}", path.to_str().unwrap()));
}

fn subsystem(&mut self, _subsystem: &str) {}

fn reset_per_library_state(&mut self) {
self.hint_dynamic();
}

fn linker_plugin_lto(&mut self) {}

fn add_eh_frame_header(&mut self) {}

fn add_no_exec(&mut self) {}

fn add_as_needed(&mut self) {}
}

fn for_each_exported_symbols_include_dep<'tcx>(
tcx: TyCtxt<'tcx>,
crate_type: CrateType,
Expand Down
46 changes: 28 additions & 18 deletions compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc_hir::def::Res;
use rustc_hir::def_id::DefId;
use rustc_infer::traits::ObligationCauseCode;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_span::{self, Span};
use rustc_span::{self, symbol::kw, Span};
use rustc_trait_selection::traits;

use std::ops::ControlFlow;
Expand All @@ -25,17 +25,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

let generics = self.tcx.generics_of(def_id);
let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => pred.trait_ref.substs,
ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => pred.projection_ty.substs,
_ => ty::List::empty(),
ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => pred.trait_ref.substs.to_vec(),
ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => {
pred.projection_ty.substs.to_vec()
}
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(arg, ty)) => {
vec![ty.into(), arg.into()]
}
ty::PredicateKind::ConstEvaluatable(e) => vec![e.into()],
_ => return false,
};

let find_param_matching = |matches: &dyn Fn(&ty::ParamTy) -> bool| {
predicate_substs.types().find_map(|ty| {
ty.walk().find_map(|arg| {
let find_param_matching = |matches: &dyn Fn(ty::ParamTerm) -> bool| {
predicate_substs.iter().find_map(|arg| {
arg.walk().find_map(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Param(param_ty) = ty.kind()
&& matches(param_ty)
&& let ty::Param(param_ty) = *ty.kind()
&& matches(ty::ParamTerm::Ty(param_ty))
{
Some(arg)
} else if let ty::GenericArgKind::Const(ct) = arg.unpack()
&& let ty::ConstKind::Param(param_ct) = ct.kind()
&& matches(ty::ParamTerm::Const(param_ct))
{
Some(arg)
} else {
Expand All @@ -47,21 +58,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Prefer generics that are local to the fn item, since these are likely
// to be the cause of the unsatisfied predicate.
let mut param_to_point_at = find_param_matching(&|param_ty| {
self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id
let mut param_to_point_at = find_param_matching(&|param_term| {
self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) == def_id
});
// Fall back to generic that isn't local to the fn item. This will come
// from a trait or impl, for example.
let mut fallback_param_to_point_at = find_param_matching(&|param_ty| {
self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id
&& param_ty.name != rustc_span::symbol::kw::SelfUpper
let mut fallback_param_to_point_at = find_param_matching(&|param_term| {
self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) != def_id
&& !matches!(param_term, ty::ParamTerm::Ty(ty) if ty.name == kw::SelfUpper)
});
// Finally, the `Self` parameter is possibly the reason that the predicate
// is unsatisfied. This is less likely to be true for methods, because
// method probe means that we already kinda check that the predicates due
// to the `Self` type are true.
let mut self_param_to_point_at =
find_param_matching(&|param_ty| param_ty.name == rustc_span::symbol::kw::SelfUpper);
let mut self_param_to_point_at = find_param_matching(
&|param_term| matches!(param_term, ty::ParamTerm::Ty(ty) if ty.name == kw::SelfUpper),
);

// Finally, for ambiguity-related errors, we actually want to look
// for a parameter that is the source of the inference type left
Expand Down Expand Up @@ -225,14 +237,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.own_substs(ty::InternalSubsts::identity_for_item(self.tcx, def_id));
let Some((index, _)) = own_substs
.iter()
.filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
.enumerate()
.find(|(_, arg)| **arg == param_to_point_at) else { return false };
let Some(arg) = segment
.args()
.args
.iter()
.filter(|arg| matches!(arg, hir::GenericArg::Type(_)))
.nth(index) else { return false; };
error.obligation.cause.span = arg
.span()
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1041,13 +1041,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.root.tables.optimized_mir.get(self, id).is_some()
}

fn module_expansion(self, id: DefIndex, sess: &Session) -> ExpnId {
match self.def_kind(id) {
DefKind::Mod | DefKind::Enum | DefKind::Trait => self.get_expn_that_defined(id, sess),
_ => panic!("Expected module, found {:?}", self.local_def_id(id)),
}
}

fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool {
self.root
.tables
Expand Down
11 changes: 7 additions & 4 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,9 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
.alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE))
},
crates: |tcx, ()| {
// The list of loaded crates is now frozen in query cache,
// so make sure cstore is not mutably accessed from here on.
tcx.untracked().cstore.leak();
tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).iter_crate_data().map(|(cnum, _)| cnum))
},
..*providers
Expand Down Expand Up @@ -537,16 +540,16 @@ impl CStore {
)
}

pub fn get_span_untracked(&self, def_id: DefId, sess: &Session) -> Span {
pub fn def_span_untracked(&self, def_id: DefId, sess: &Session) -> Span {
self.get_crate_data(def_id.krate).get_span(def_id.index, sess)
}

pub fn def_kind(&self, def: DefId) -> DefKind {
pub fn def_kind_untracked(&self, def: DefId) -> DefKind {
self.get_crate_data(def.krate).def_kind(def.index)
}

pub fn module_expansion_untracked(&self, def_id: DefId, sess: &Session) -> ExpnId {
self.get_crate_data(def_id.krate).module_expansion(def_id.index, sess)
pub fn expn_that_defined_untracked(&self, def_id: DefId, sess: &Session) -> ExpnId {
self.get_crate_data(def_id.krate).get_expn_that_defined(def_id.index, sess)
}

/// Only public-facing way to traverse all the definitions in a non-local crate.
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1051,6 +1051,21 @@ impl<'tcx> TermKind<'tcx> {
}
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ParamTerm {
Ty(ParamTy),
Const(ParamConst),
}

impl ParamTerm {
pub fn index(self) -> usize {
match self {
ParamTerm::Ty(ty) => ty.index as usize,
ParamTerm::Const(ct) => ct.index as usize,
}
}
}

/// This kind of predicate has no *direct* correspondent in the
/// syntax, but it roughly corresponds to the syntactic forms:
///
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_resolve/src/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}

if !def_id.is_local() {
let def_kind = self.cstore().def_kind(def_id);
// Query `def_kind` is not used because query system overhead is too expensive here.
let def_kind = self.cstore().def_kind_untracked(def_id);
if let DefKind::Mod | DefKind::Enum | DefKind::Trait = def_kind {
let parent = self
.tcx
.opt_parent(def_id)
.map(|parent_id| self.get_nearest_non_block_module(parent_id));
let expn_id = self.cstore().module_expansion_untracked(def_id, &self.tcx.sess);
// Query `expn_that_defined` is not used because
// hashing spans in its result is expensive.
let expn_id = self.cstore().expn_that_defined_untracked(def_id, &self.tcx.sess);
return Some(self.new_module(
parent,
ModuleKind::Def(def_kind, def_id, self.tcx.item_name(def_id)),
Expand Down Expand Up @@ -194,6 +197,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}

pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) {
// Query `module_children` is not used because hashing spans in its result is expensive.
let children =
Vec::from_iter(self.cstore().module_children_untracked(module.def_id(), self.tcx.sess));
for child in children {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1875,7 +1875,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn def_span(&self, def_id: DefId) -> Span {
match def_id.as_local() {
Some(def_id) => self.tcx.source_span(def_id),
None => self.cstore().get_span_untracked(def_id, self.tcx.sess),
// Query `def_span` is not used because hashing its result span is expensive.
None => self.cstore().def_span_untracked(def_id, self.tcx.sess),
}
}

Expand Down
Loading

0 comments on commit 4c0f500

Please sign in to comment.