Skip to content

Rollup of 6 pull requests #89435

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

Merged
merged 15 commits into from
Oct 1, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -1660,7 +1660,7 @@ checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
dependencies = [
"bitmaps",
"rand_core 0.5.1",
"rand_xoshiro",
"rand_xoshiro 0.4.0",
"sized-chunks",
"typenum",
"version_check",
@@ -2256,7 +2256,7 @@ dependencies = [
"libc",
"log",
"measureme",
"rand 0.8.3",
"rand 0.8.4",
"rustc-workspace-hack",
"rustc_version",
"shell-escape",
@@ -2852,9 +2852,9 @@ dependencies = [

[[package]]
name = "rand"
version = "0.8.3"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha 0.3.0",
@@ -2945,6 +2945,15 @@ dependencies = [
"rand_core 0.5.1",
]

[[package]]
name = "rand_xoshiro"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
dependencies = [
"rand_core 0.6.2",
]

[[package]]
name = "rayon"
version = "1.3.1"
@@ -4087,6 +4096,8 @@ dependencies = [
"either",
"gsgdt",
"polonius-engine",
"rand 0.8.4",
"rand_xoshiro 0.6.0",
"rustc-rayon-core",
"rustc_apfloat",
"rustc_arena",
@@ -5097,7 +5108,7 @@ checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
dependencies = [
"cfg-if 1.0.0",
"libc",
"rand 0.8.3",
"rand 0.8.4",
"redox_syscall",
"remove_dir_all",
"winapi",
26 changes: 21 additions & 5 deletions compiler/rustc_builtin_macros/src/format.rs
Original file line number Diff line number Diff line change
@@ -1154,11 +1154,12 @@ pub fn expand_preparsed_format_args(
// account for `"` and account for raw strings `r#`
let padding = str_style.map(|i| i + 2).unwrap_or(1);
for sub in foreign::$kind::iter_subs(fmt_str, padding) {
let trn = match sub.translate() {
Some(trn) => trn,
let (trn, success) = match sub.translate() {
Ok(trn) => (trn, true),
Err(Some(msg)) => (msg, false),

// If it has no translation, don't call it out specifically.
None => continue,
_ => continue,
};

let pos = sub.position();
@@ -1175,9 +1176,24 @@ pub fn expand_preparsed_format_args(

if let Some(inner_sp) = pos {
let sp = fmt_sp.from_inner(inner_sp);
suggestions.push((sp, trn));

if success {
suggestions.push((sp, trn));
} else {
diag.span_note(
sp,
&format!("format specifiers use curly braces, and {}", trn),
);
}
} else {
diag.help(&format!("`{}` should be written as `{}`", sub, trn));
if success {
diag.help(&format!("`{}` should be written as `{}`", sub, trn));
} else {
diag.note(&format!(
"`{}` should use curly braces, and {}",
sub, trn
));
}
}
}

65 changes: 48 additions & 17 deletions compiler/rustc_builtin_macros/src/format_foreign.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod printf {
pub(crate) mod printf {
use super::strcursor::StrCursor as Cur;
use rustc_span::InnerSpan;

@@ -36,10 +36,10 @@ pub mod printf {
///
/// This ignores cases where the substitution does not have an exact equivalent, or where
/// the substitution would be unnecessary.
pub fn translate(&self) -> Option<String> {
pub fn translate(&self) -> Result<String, Option<String>> {
match *self {
Substitution::Format(ref fmt) => fmt.translate(),
Substitution::Escape => None,
Substitution::Escape => Err(None),
}
}
}
@@ -68,9 +68,9 @@ pub mod printf {
impl Format<'_> {
/// Translate this directive into an equivalent Rust formatting directive.
///
/// Returns `None` in cases where the `printf` directive does not have an exact Rust
/// Returns `Err` in cases where the `printf` directive does not have an exact Rust
/// equivalent, rather than guessing.
pub fn translate(&self) -> Option<String> {
pub fn translate(&self) -> Result<String, Option<String>> {
use std::fmt::Write;

let (c_alt, c_zero, c_left, c_plus) = {
@@ -84,7 +84,12 @@ pub mod printf {
'0' => c_zero = true,
'-' => c_left = true,
'+' => c_plus = true,
_ => return None,
_ => {
return Err(Some(format!(
"the flag `{}` is unknown or unsupported",
c
)));
}
}
}
(c_alt, c_zero, c_left, c_plus)
@@ -104,7 +109,9 @@ pub mod printf {
let width = match self.width {
Some(Num::Next) => {
// NOTE: Rust doesn't support this.
return None;
return Err(Some(
"you have to use a positional or named parameter for the width".to_string(),
));
}
w @ Some(Num::Arg(_)) => w,
w @ Some(Num::Num(_)) => w,
@@ -125,13 +132,21 @@ pub mod printf {
"p" => (Some(self.type_), false, true),
"g" => (Some("e"), true, false),
"G" => (Some("E"), true, false),
_ => return None,
_ => {
return Err(Some(format!(
"the conversion specifier `{}` is unknown or unsupported",
self.type_
)));
}
};

let (fill, width, precision) = match (is_int, width, precision) {
(true, Some(_), Some(_)) => {
// Rust can't duplicate this insanity.
return None;
return Err(Some(
"width and precision cannot both be specified for integer conversions"
.to_string(),
));
}
(true, None, Some(p)) => (Some("0"), Some(p), None),
(true, w, None) => (fill, w, None),
@@ -169,7 +184,17 @@ pub mod printf {
s.push('{');

if let Some(arg) = self.parameter {
write!(s, "{}", arg.checked_sub(1)?).ok()?;
match write!(
s,
"{}",
match arg.checked_sub(1) {
Some(a) => a,
None => return Err(None),
}
) {
Err(_) => return Err(None),
_ => {}
}
}

if has_options {
@@ -199,12 +224,18 @@ pub mod printf {
}

if let Some(width) = width {
width.translate(&mut s).ok()?;
match width.translate(&mut s) {
Err(_) => return Err(None),
_ => {}
}
}

if let Some(precision) = precision {
s.push('.');
precision.translate(&mut s).ok()?;
match precision.translate(&mut s) {
Err(_) => return Err(None),
_ => {}
}
}

if let Some(type_) = type_ {
@@ -213,7 +244,7 @@ pub mod printf {
}

s.push('}');
Some(s)
Ok(s)
}
}

@@ -623,11 +654,11 @@ pub mod shell {
}
}

pub fn translate(&self) -> Option<String> {
pub fn translate(&self) -> Result<String, Option<String>> {
match *self {
Substitution::Ordinal(n, _) => Some(format!("{{{}}}", n)),
Substitution::Name(n, _) => Some(format!("{{{}}}", n)),
Substitution::Escape(_) => None,
Substitution::Ordinal(n, _) => Ok(format!("{{{}}}", n)),
Substitution::Name(n, _) => Ok(format!("{{{}}}", n)),
Substitution::Escape(_) => Err(None),
}
}
}
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ use super::{iter_subs, parse_next_substitution as pns, Format as F, Num as N, Su
macro_rules! assert_eq_pnsat {
($lhs:expr, $rhs:expr) => {
assert_eq!(
pns($lhs).and_then(|(s, _)| s.translate()),
pns($lhs).and_then(|(s, _)| s.translate().ok()),
$rhs.map(<String as From<&str>>::from)
)
};
@@ -98,7 +98,7 @@ fn test_parse() {
#[test]
fn test_iter() {
let s = "The %d'th word %% is: `%.*s` %!\n";
let subs: Vec<_> = iter_subs(s, 0).map(|sub| sub.translate()).collect();
let subs: Vec<_> = iter_subs(s, 0).map(|sub| sub.translate().ok()).collect();
assert_eq!(
subs.iter().map(|ms| ms.as_ref().map(|s| &s[..])).collect::<Vec<_>>(),
vec![Some("{}"), None, Some("{:.*}"), None]
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ use super::{parse_next_substitution as pns, Substitution as S};
macro_rules! assert_eq_pnsat {
($lhs:expr, $rhs:expr) => {
assert_eq!(
pns($lhs).and_then(|(f, _)| f.translate()),
pns($lhs).and_then(|(f, _)| f.translate().ok()),
$rhs.map(<String as From<&str>>::from)
)
};
@@ -37,7 +37,7 @@ fn test_parse() {
fn test_iter() {
use super::iter_subs;
let s = "The $0'th word $$ is: `$WORD` $!\n";
let subs: Vec<_> = iter_subs(s, 0).map(|sub| sub.translate()).collect();
let subs: Vec<_> = iter_subs(s, 0).map(|sub| sub.translate().ok()).collect();
assert_eq!(
subs.iter().map(|ms| ms.as_ref().map(|s| &s[..])).collect::<Vec<_>>(),
vec![Some("{0}"), None, Some("{WORD}")]
3 changes: 2 additions & 1 deletion compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
@@ -129,7 +129,8 @@ fn to_pass_builder_opt_level(cfg: config::OptLevel) -> llvm::PassBuilderOptLevel
fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
match relocation_model {
RelocModel::Static => llvm::RelocModel::Static,
RelocModel::Pic => llvm::RelocModel::PIC,
// LLVM doesn't have a PIE relocation model, it represents PIE as PIC with an extra attribute.
RelocModel::Pic | RelocModel::Pie => llvm::RelocModel::PIC,
RelocModel::DynamicNoPic => llvm::RelocModel::DynamicNoPic,
RelocModel::Ropi => llvm::RelocModel::ROPI,
RelocModel::Rwpi => llvm::RelocModel::RWPI,
7 changes: 5 additions & 2 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
@@ -195,11 +195,14 @@ pub unsafe fn create_module(
let llvm_target = SmallCStr::new(&sess.target.llvm_target);
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());

if sess.relocation_model() == RelocModel::Pic {
let reloc_model = sess.relocation_model();
if matches!(reloc_model, RelocModel::Pic | RelocModel::Pie) {
llvm::LLVMRustSetModulePICLevel(llmod);
// PIE is potentially more effective than PIC, but can only be used in executables.
// If all our outputs are executables, then we can relax PIC to PIE.
if sess.crate_types().iter().all(|ty| *ty == CrateType::Executable) {
if reloc_model == RelocModel::Pie
|| sess.crate_types().iter().all(|ty| *ty == CrateType::Executable)
{
llvm::LLVMRustSetModulePIELevel(llmod);
}
}
13 changes: 10 additions & 3 deletions compiler/rustc_codegen_llvm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -211,9 +211,16 @@ impl CodegenBackend for LlvmCodegenBackend {
match req {
PrintRequest::RelocationModels => {
println!("Available relocation models:");
for name in
&["static", "pic", "dynamic-no-pic", "ropi", "rwpi", "ropi-rwpi", "default"]
{
for name in &[
"static",
"pic",
"pie",
"dynamic-no-pic",
"ropi",
"rwpi",
"ropi-rwpi",
"default",
] {
println!(" {}", name);
}
println!();
6 changes: 6 additions & 0 deletions compiler/rustc_codegen_llvm/src/mono_item.rs
Original file line number Diff line number Diff line change
@@ -143,6 +143,12 @@ impl CodegenCx<'ll, 'tcx> {
return true;
}

// With pie relocation model calls of functions defined in the translation
// unit can use copy relocations.
if self.tcx.sess.relocation_model() == RelocModel::Pie && !is_declaration {
return true;
}

return false;
}
}
8 changes: 6 additions & 2 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
@@ -1490,9 +1490,13 @@ fn exec_linker(
fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
let kind = match (crate_type, sess.crt_static(Some(crate_type)), sess.relocation_model()) {
(CrateType::Executable, _, _) if sess.is_wasi_reactor() => LinkOutputKind::WasiReactorExe,
(CrateType::Executable, false, RelocModel::Pic) => LinkOutputKind::DynamicPicExe,
(CrateType::Executable, false, RelocModel::Pic | RelocModel::Pie) => {
LinkOutputKind::DynamicPicExe
}
(CrateType::Executable, false, _) => LinkOutputKind::DynamicNoPicExe,
(CrateType::Executable, true, RelocModel::Pic) => LinkOutputKind::StaticPicExe,
(CrateType::Executable, true, RelocModel::Pic | RelocModel::Pie) => {
LinkOutputKind::StaticPicExe
}
(CrateType::Executable, true, _) => LinkOutputKind::StaticNoPicExe,
(_, true, _) => LinkOutputKind::StaticDylib,
(_, false, _) => LinkOutputKind::DynamicDylib,
10 changes: 10 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
@@ -384,6 +384,16 @@ impl GenericArgs<'_> {
self.args.iter().any(|arg| matches!(arg, GenericArg::Type(_)))
}

pub fn has_err(&self) -> bool {
self.args.iter().any(|arg| match arg {
GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err),
_ => false,
}) || self.bindings.iter().any(|arg| match arg.kind {
TypeBindingKind::Equality { ty } => matches!(ty.kind, TyKind::Err),
_ => false,
})
}

#[inline]
pub fn num_type_params(&self) -> usize {
self.args.iter().filter(|arg| matches!(arg, GenericArg::Type(_))).count()
2 changes: 2 additions & 0 deletions compiler/rustc_middle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -32,3 +32,5 @@ chalk-ir = "0.55.0"
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
rustc_session = { path = "../rustc_session" }
rustc_type_ir = { path = "../rustc_type_ir" }
rand = "0.8.4"
rand_xoshiro = "0.6.0"
Loading