Skip to content

Commit

Permalink
Auto merge of rust-lang#103739 - Mark-Simulacrum:beta-next, r=Mark-Si…
Browse files Browse the repository at this point in the history
…mulacrum

[beta] backport rollup

* poll_fn and Unpin: fix pinning rust-lang#102737
* Support raw-dylib functions being used inside inlined functions rust-lang#102988
* Fix line numbers for MIR inlined code rust-lang#103071
* Add architectures to fn create_object_file rust-lang#103240
* Add eval hack in super_relate_consts back rust-lang#103279
* Mark std::os::wasi::io::AsFd etc. as stable. rust-lang#103308
* Truncate thread names on Linux and Apple targets rust-lang#103379
* Do not consider repeated lifetime params for elision. rust-lang#103450
* rustdoc: add missing URL redirect rust-lang#103588
* Remove commit_if_ok probe from NLL type relation rust-lang#103601

Also includes a copy of the release notes.

r? `@ghost`
  • Loading branch information
bors committed Oct 29, 2022
2 parents 636a78a + 108b32e commit 90b3882
Show file tree
Hide file tree
Showing 38 changed files with 713 additions and 81 deletions.
244 changes: 244 additions & 0 deletions RELEASES.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions compiler/rustc_codegen_cranelift/src/archive.rs
Expand Up @@ -38,6 +38,7 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
_lib_name: &str,
_dll_imports: &[rustc_session::cstore::DllImport],
_tmpdir: &Path,
_is_direct_dependency: bool,
) -> PathBuf {
bug!("creating dll imports is not supported");
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_gcc/src/archive.rs
Expand Up @@ -45,6 +45,7 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
_lib_name: &str,
_dll_imports: &[DllImport],
_tmpdir: &Path,
_is_direct_dependency: bool,
) -> PathBuf {
unimplemented!();
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_codegen_llvm/src/back/archive.rs
Expand Up @@ -104,10 +104,12 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
lib_name: &str,
dll_imports: &[DllImport],
tmpdir: &Path,
is_direct_dependency: bool,
) -> PathBuf {
let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
let output_path = {
let mut output_path: PathBuf = tmpdir.to_path_buf();
output_path.push(format!("{}_imports", lib_name));
output_path.push(format!("{}{}", lib_name, name_suffix));
output_path.with_extension("lib")
};

Expand All @@ -134,7 +136,8 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
// that loaded but crashed with an AV upon calling one of the imported
// functions. Therefore, use binutils to create the import library instead,
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
let def_file_path = tmpdir.join(format!("{}_imports", lib_name)).with_extension("def");
let def_file_path =
tmpdir.join(format!("{}{}", lib_name, name_suffix)).with_extension("def");

let def_file_content = format!(
"EXPORTS\n{}",
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/back/archive.rs
Expand Up @@ -25,6 +25,7 @@ pub trait ArchiveBuilderBuilder {
lib_name: &str,
dll_imports: &[DllImport],
tmpdir: &Path,
is_direct_dependency: bool,
) -> PathBuf;

fn extract_bundled_libs(
Expand Down
41 changes: 36 additions & 5 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Expand Up @@ -376,13 +376,14 @@ fn link_rlib<'a>(
}

for (raw_dylib_name, raw_dylib_imports) in
collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())?
{
let output_path = archive_builder_builder.create_dll_import_lib(
sess,
&raw_dylib_name,
&raw_dylib_imports,
tmpdir.as_ref(),
true,
);

ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|e| {
Expand Down Expand Up @@ -434,9 +435,9 @@ fn link_rlib<'a>(
/// then the CodegenResults value contains one NativeLib instance for each block. However, the
/// linker appears to expect only a single import library for each library used, so we need to
/// collate the symbols together by library name before generating the import libraries.
fn collate_raw_dylibs(
sess: &Session,
used_libraries: &[NativeLib],
fn collate_raw_dylibs<'a, 'b>(
sess: &'a Session,
used_libraries: impl IntoIterator<Item = &'b NativeLib>,
) -> Result<Vec<(String, Vec<DllImport>)>, ErrorGuaranteed> {
// Use index maps to preserve original order of imports and libraries.
let mut dylib_table = FxIndexMap::<String, FxIndexMap<Symbol, &DllImport>>::default();
Expand Down Expand Up @@ -2028,13 +2029,43 @@ fn linker_with_args<'a>(

// Link with the import library generated for any raw-dylib functions.
for (raw_dylib_name, raw_dylib_imports) in
collate_raw_dylibs(sess, &codegen_results.crate_info.used_libraries)?
collate_raw_dylibs(sess, codegen_results.crate_info.used_libraries.iter())?
{
cmd.add_object(&archive_builder_builder.create_dll_import_lib(
sess,
&raw_dylib_name,
&raw_dylib_imports,
tmpdir,
true,
));
}
// As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case
// they are used within inlined functions or instantiated generic functions. We do this *after*
// handling the raw-dylib symbols in the current crate to make sure that those are chosen first
// by the linker.
let (_, dependency_linkage) = codegen_results
.crate_info
.dependency_formats
.iter()
.find(|(ty, _)| *ty == crate_type)
.expect("failed to find crate type in dependency format list");
let native_libraries_from_nonstatics = codegen_results
.crate_info
.native_libraries
.iter()
.filter_map(|(cnum, libraries)| {
(dependency_linkage[cnum.as_usize() - 1] != Linkage::Static).then(|| libraries)
})
.flatten();
for (raw_dylib_name, raw_dylib_imports) in
collate_raw_dylibs(sess, native_libraries_from_nonstatics)?
{
cmd.add_object(&archive_builder_builder.create_dll_import_lib(
sess,
&raw_dylib_name,
&raw_dylib_imports,
tmpdir,
false,
));
}

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/metadata.rs
Expand Up @@ -117,6 +117,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
"riscv32" => Architecture::Riscv32,
"riscv64" => Architecture::Riscv64,
"sparc64" => Architecture::Sparc64,
"avr" => Architecture::Avr,
"msp430" => Architecture::Msp430,
"hexagon" => Architecture::Hexagon,
"bpf" => Architecture::Bpf,
// Unsupported architecture.
_ => return None,
};
Expand Down
11 changes: 9 additions & 2 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Expand Up @@ -591,9 +591,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
val: &mir::ConstantKind<'tcx>,
layout: Option<TyAndLayout<'tcx>>,
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
// FIXME(const_prop): normalization needed b/c const prop lint in
// `mir_drops_elaborated_and_const_checked`, which happens before
// optimized MIR. Only after optimizing the MIR can we guarantee
// that the `RevealAll` pass has happened and that the body's consts
// are normalized, so any call to resolve before that needs to be
// manually normalized.
let val = self.tcx.normalize_erasing_regions(self.param_env, *val);
match val {
mir::ConstantKind::Ty(ct) => self.const_to_op(*ct, layout),
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(*val, *ty, layout),
mir::ConstantKind::Ty(ct) => self.const_to_op(ct, layout),
mir::ConstantKind::Val(val, ty) => self.const_val_to_op(val, ty, layout),
mir::ConstantKind::Unevaluated(uv, _) => {
let instance = self.resolve(uv.def, uv.substs)?;
Ok(self.eval_to_allocation(GlobalId { instance, promoted: uv.promoted })?.into())
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/nll_relate/mod.rs
Expand Up @@ -596,7 +596,7 @@ where
(&ty::Infer(ty::TyVar(vid)), _) => self.relate_ty_var((vid, b)),

(&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => {
infcx.commit_if_ok(|_| infcx.super_combine_tys(self, a, b)).or_else(|err| {
infcx.super_combine_tys(self, a, b).or_else(|err| {
self.tcx().sess.delay_span_bug(
self.delegate.span(),
"failure to relate an opaque to itself should result in an error later on",
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_middle/src/ty/mod.rs
Expand Up @@ -2489,7 +2489,9 @@ impl<'tcx> TyCtxt<'tcx> {
&& if self.features().collapse_debuginfo {
span.in_macro_expansion_with_collapse_debuginfo()
} else {
span.from_expansion()
// Inlined spans should not be collapsed as that leads to all of the
// inlined code being attributed to the inline callsite.
span.from_expansion() && !span.is_inlined()
}
}

Expand Down
15 changes: 13 additions & 2 deletions compiler/rustc_middle/src/ty/relate.rs
Expand Up @@ -574,8 +574,8 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
/// it.
pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
a: ty::Const<'tcx>,
b: ty::Const<'tcx>,
mut a: ty::Const<'tcx>,
mut b: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
debug!("{}.super_relate_consts(a = {:?}, b = {:?})", relation.tag(), a, b);
let tcx = relation.tcx();
Expand All @@ -596,6 +596,17 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>(
);
}

// HACK(const_generics): We still need to eagerly evaluate consts when
// relating them because during `normalize_param_env_or_error`,
// we may relate an evaluated constant in a obligation against
// an unnormalized (i.e. unevaluated) const in the param-env.
// FIXME(generic_const_exprs): Once we always lazily unify unevaluated constants
// these `eval` calls can be removed.
if !relation.tcx().features().generic_const_exprs {
a = a.eval(tcx, relation.param_env());
b = b.eval(tcx, relation.param_env());
}

// Currently, the values that can be unified are primitive types,
// and those that derive both `PartialEq` and `Eq`, corresponding
// to structural-match types.
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_mir_build/src/thir/pattern/mod.rs
Expand Up @@ -481,7 +481,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
// Use `Reveal::All` here because patterns are always monomorphic even if their function
// isn't.
let param_env_reveal_all = self.param_env.with_reveal_all_normalized(self.tcx);
let substs = self.typeck_results.node_substs(id);
// N.B. There is no guarantee that substs collected in typeck results are fully normalized,
// so they need to be normalized in order to pass to `Instance::resolve`, which will ICE
// if given unnormalized types.
let substs = self
.tcx
.normalize_erasing_regions(param_env_reveal_all, self.typeck_results.node_substs(id));
let instance = match ty::Instance::resolve(self.tcx, param_env_reveal_all, def_id, substs) {
Ok(Some(i)) => i,
Ok(None) => {
Expand Down
103 changes: 69 additions & 34 deletions compiler/rustc_resolve/src/late.rs
Expand Up @@ -30,6 +30,7 @@ use rustc_span::{BytePos, Span};
use smallvec::{smallvec, SmallVec};

use rustc_span::source_map::{respan, Spanned};
use std::assert_matches::debug_assert_matches;
use std::collections::{hash_map::Entry, BTreeSet};
use std::mem::{replace, take};

Expand Down Expand Up @@ -557,7 +558,7 @@ struct LateResolutionVisitor<'a, 'b, 'ast> {
/// They will be used to determine the correct lifetime for the fn return type.
/// The `LifetimeElisionCandidate` is used for diagnostics, to suggest introducing named
/// lifetimes.
lifetime_elision_candidates: Option<FxIndexMap<LifetimeRes, LifetimeElisionCandidate>>,
lifetime_elision_candidates: Option<Vec<(LifetimeRes, LifetimeElisionCandidate)>>,

/// The trait that the current context can refer to.
current_trait_ref: Option<(Module<'a>, TraitRef)>,
Expand Down Expand Up @@ -1819,7 +1820,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
match res {
LifetimeRes::Param { .. } | LifetimeRes::Fresh { .. } | LifetimeRes::Static => {
if let Some(ref mut candidates) = self.lifetime_elision_candidates {
candidates.insert(res, candidate);
candidates.push((res, candidate));
}
}
LifetimeRes::Infer | LifetimeRes::Error | LifetimeRes::ElidedAnchor { .. } => {}
Expand Down Expand Up @@ -1872,74 +1873,108 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
has_self: bool,
inputs: impl Iterator<Item = (Option<&'ast Pat>, &'ast Ty)>,
) -> Result<LifetimeRes, (Vec<MissingLifetime>, Vec<ElisionFnParameter>)> {
let outer_candidates =
replace(&mut self.lifetime_elision_candidates, Some(Default::default()));
enum Elision {
/// We have not found any candidate.
None,
/// We have a candidate bound to `self`.
Self_(LifetimeRes),
/// We have a candidate bound to a parameter.
Param(LifetimeRes),
/// We failed elision.
Err,
}

let mut elision_lifetime = None;
let mut lifetime_count = 0;
// Save elision state to reinstate it later.
let outer_candidates = self.lifetime_elision_candidates.take();

// Result of elision.
let mut elision_lifetime = Elision::None;
// Information for diagnostics.
let mut parameter_info = Vec::new();
let mut all_candidates = Vec::new();

let mut bindings = smallvec![(PatBoundCtx::Product, Default::default())];
for (index, (pat, ty)) in inputs.enumerate() {
debug!(?pat, ?ty);
if let Some(pat) = pat {
self.resolve_pattern(pat, PatternSource::FnParam, &mut bindings);
}

// Record elision candidates only for this parameter.
debug_assert_matches!(self.lifetime_elision_candidates, None);
self.lifetime_elision_candidates = Some(Default::default());
self.visit_ty(ty);
let local_candidates = self.lifetime_elision_candidates.take();

if let Some(ref candidates) = self.lifetime_elision_candidates {
let new_count = candidates.len();
let local_count = new_count - lifetime_count;
if local_count != 0 {
if let Some(candidates) = local_candidates {
let distinct: FxHashSet<_> = candidates.iter().map(|(res, _)| *res).collect();
let lifetime_count = distinct.len();
if lifetime_count != 0 {
parameter_info.push(ElisionFnParameter {
index,
ident: if let Some(pat) = pat && let PatKind::Ident(_, ident, _) = pat.kind {
Some(ident)
} else {
None
},
lifetime_count: local_count,
lifetime_count,
span: ty.span,
});
all_candidates.extend(candidates.into_iter().filter_map(|(_, candidate)| {
match candidate {
LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => {
None
}
LifetimeElisionCandidate::Missing(missing) => Some(missing),
}
}));
}
let mut distinct_iter = distinct.into_iter();
if let Some(res) = distinct_iter.next() {
match elision_lifetime {
// We are the first parameter to bind lifetimes.
Elision::None => {
if distinct_iter.next().is_none() {
// We have a single lifetime => success.
elision_lifetime = Elision::Param(res)
} else {
// We have have multiple lifetimes => error.
elision_lifetime = Elision::Err;
}
}
// We have 2 parameters that bind lifetimes => error.
Elision::Param(_) => elision_lifetime = Elision::Err,
// `self` elision takes precedence over everything else.
Elision::Self_(_) | Elision::Err => {}
}
}
lifetime_count = new_count;
}

// Handle `self` specially.
if index == 0 && has_self {
let self_lifetime = self.find_lifetime_for_self(ty);
if let Set1::One(lifetime) = self_lifetime {
elision_lifetime = Some(lifetime);
self.lifetime_elision_candidates = None;
// We found `self` elision.
elision_lifetime = Elision::Self_(lifetime);
} else {
self.lifetime_elision_candidates = Some(Default::default());
lifetime_count = 0;
// We do not have `self` elision: disregard the `Elision::Param` that we may
// have found.
elision_lifetime = Elision::None;
}
}
debug!("(resolving function / closure) recorded parameter");
}

let all_candidates = replace(&mut self.lifetime_elision_candidates, outer_candidates);
debug!(?all_candidates);
// Reinstate elision state.
debug_assert_matches!(self.lifetime_elision_candidates, None);
self.lifetime_elision_candidates = outer_candidates;

if let Some(res) = elision_lifetime {
if let Elision::Param(res) | Elision::Self_(res) = elision_lifetime {
return Ok(res);
}

// We do not have a `self` candidate, look at the full list.
let all_candidates = all_candidates.unwrap();
if all_candidates.len() == 1 {
Ok(*all_candidates.first().unwrap().0)
} else {
let all_candidates = all_candidates
.into_iter()
.filter_map(|(_, candidate)| match candidate {
LifetimeElisionCandidate::Ignore | LifetimeElisionCandidate::Named => None,
LifetimeElisionCandidate::Missing(missing) => Some(missing),
})
.collect();
Err((all_candidates, parameter_info))
}
// We do not have a candidate.
Err((all_candidates, parameter_info))
}

/// List all the lifetimes that appear in the provided type.
Expand Down Expand Up @@ -2411,7 +2446,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// Do not account for the parameters we just bound for function lifetime elision.
if let Some(ref mut candidates) = self.lifetime_elision_candidates {
for (_, res) in function_lifetime_rib.bindings.values() {
candidates.remove(res);
candidates.retain(|(r, _)| r != res);
}
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_resolve/src/lib.rs
Expand Up @@ -7,6 +7,7 @@
//! Type-relative name resolution (methods, fields, associated items) happens in `rustc_typeck`.

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(assert_matches)]
#![feature(box_patterns)]
#![feature(drain_filter)]
#![feature(if_let_guard)]
Expand Down

0 comments on commit 90b3882

Please sign in to comment.