Skip to content

Commit

Permalink
Auto merge of #101716 - Dylan-DPC:rollup-ayvh6nd, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - #100293 (Add inline-llvm option for disabling/enabling LLVM inlining)
 - #100767 (Remove manual <[u8]>::escape_ascii)
 - #101668 (Suggest pub instead of public for const type item)
 - #101671 (Fix naming format of IEEE 754 standard)
 - #101676 (Check that the types in return position `impl Trait` in traits are well-formed)
 - #101681 (Deny return-position `impl Trait` in traits for object safety)
 - #101693 (Update browser UI test 0 10)
 - #101701 (Rustdoc-Json: Add tests for trait impls.)
 - #101706 (rustdoc: remove no-op `#search`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Sep 12, 2022
2 parents a93214e + 9bf89e7 commit 7f115e3
Show file tree
Hide file tree
Showing 41 changed files with 372 additions and 105 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ impl Token {
kw::Extern,
kw::Impl,
kw::Unsafe,
kw::Const,
kw::Static,
kw::Union,
kw::Macro,
Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_ast/src/util/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,7 @@ impl LitKind {
}
LitKind::Str(symbol, ast::StrStyle::Raw(n)) => (token::StrRaw(n), symbol, None),
LitKind::ByteStr(ref bytes) => {
let string = bytes
.iter()
.cloned()
.flat_map(ascii::escape_default)
.map(Into::<char>::into)
.collect::<String>();
let string = bytes.escape_ascii().to_string();
(token::ByteStr, Symbol::intern(&string), None)
}
LitKind::Byte(byte) => {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ pub fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[&Attrib
/// Get LLVM attribute for the provided inline heuristic.
#[inline]
fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll Attribute> {
if !cx.tcx.sess.opts.unstable_opts.inline_llvm {
// disable LLVM inlining
return Some(AttributeKind::NoInline.create_attr(cx.llcx));
}
match inline {
InlineAttr::Hint => Some(AttributeKind::InlineHint.create_attr(cx.llcx)),
InlineAttr::Always => Some(AttributeKind::AlwaysInline.create_attr(cx.llcx)),
Expand Down
25 changes: 8 additions & 17 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use std::io::{BufWriter, Write};
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::process::{ExitStatus, Output, Stdio};
use std::{ascii, char, env, fmt, fs, io, mem, str};
use std::{env, fmt, fs, io, mem, str};

pub fn ensure_removed(diag_handler: &Handler, path: &Path) {
if let Err(e) = fs::remove_file(path) {
Expand Down Expand Up @@ -552,14 +552,6 @@ fn link_staticlib<'a>(
Ok(())
}

fn escape_stdout_stderr_string(s: &[u8]) -> String {
str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
let mut x = "Non-UTF-8 output: ".to_string();
x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
x
})
}

/// Use `thorin` (rust implementation of a dwarf packaging utility) to link DWARF objects into a
/// DWARF package.
fn link_dwarf_object<'a>(
Expand Down Expand Up @@ -866,7 +858,7 @@ fn link_natively<'a>(
if !prog.status.success() {
let mut output = prog.stderr.clone();
output.extend_from_slice(&prog.stdout);
let escaped_output = escape_stdout_stderr_string(&output);
let escaped_output = escape_string(&output);
let mut err = sess.struct_err(&format!(
"linking with `{}` failed: {}",
linker_path.display(),
Expand Down Expand Up @@ -934,8 +926,8 @@ fn link_natively<'a>(

sess.abort_if_errors();
}
info!("linker stderr:\n{}", escape_stdout_stderr_string(&prog.stderr));
info!("linker stdout:\n{}", escape_stdout_stderr_string(&prog.stdout));
info!("linker stderr:\n{}", escape_string(&prog.stderr));
info!("linker stdout:\n{}", escape_string(&prog.stdout));
}
Err(e) => {
let linker_not_found = e.kind() == io::ErrorKind::NotFound;
Expand Down Expand Up @@ -1065,11 +1057,10 @@ fn strip_symbols_in_osx<'a>(sess: &'a Session, out_filename: &Path, option: Opti
}

fn escape_string(s: &[u8]) -> String {
str::from_utf8(s).map(|s| s.to_owned()).unwrap_or_else(|_| {
let mut x = "Non-UTF-8 output: ".to_string();
x.extend(s.iter().flat_map(|&b| ascii::escape_default(b)).map(char::from));
x
})
match str::from_utf8(s) {
Ok(s) => s.to_owned(),
Err(_) => format!("Non-UTF-8 output: {}", s.escape_ascii()),
}
}

fn add_sanitizer_libraries(sess: &Session, crate_type: CrateType, linker: &mut dyn Linker) {
Expand Down
10 changes: 1 addition & 9 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2633,15 +2633,7 @@ fn pretty_print_const<'tcx>(
}

fn pretty_print_byte_str(fmt: &mut Formatter<'_>, byte_str: &[u8]) -> fmt::Result {
fmt.write_str("b\"")?;
for &c in byte_str {
for e in std::ascii::escape_default(c) {
fmt.write_char(e as char)?;
}
}
fmt.write_str("\"")?;

Ok(())
write!(fmt, "b\"{}\"", byte_str.escape_ascii())
}

fn comma_sep<'tcx>(fmt: &mut Formatter<'_>, elems: Vec<ConstantKind<'tcx>>) -> fmt::Result {
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,12 @@ impl ObjectSafetyViolation {
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelfOutput, _) => {
format!("method `{}` references the `Self` type in its return type", name).into()
}
ObjectSafetyViolation::Method(
name,
MethodViolationCode::ReferencesImplTraitInTrait,
_,
) => format!("method `{}` references an `impl Trait` type in its return type", name)
.into(),
ObjectSafetyViolation::Method(
name,
MethodViolationCode::WhereClauseReferencesSelf,
Expand Down Expand Up @@ -1021,6 +1027,9 @@ pub enum MethodViolationCode {
/// e.g., `fn foo(&self) -> Self`
ReferencesSelfOutput,

/// e.g., `fn foo(&self) -> impl Sized`
ReferencesImplTraitInTrait,

/// e.g., `fn foo(&self) where Self: Clone`
WhereClauseReferencesSelf,

Expand Down
9 changes: 1 addition & 8 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1405,14 +1405,7 @@ pub trait PrettyPrinter<'tcx>:
}

fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result<Self::Const, Self::Error> {
define_scoped_cx!(self);
p!("b\"");
for &c in byte_str {
for e in std::ascii::escape_default(c) {
self.write_char(e as char)?;
}
}
p!("\"");
write!(self, "b\"{}\"", byte_str.escape_ascii())?;
Ok(self)
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1345,6 +1345,8 @@ options! {
"hash spans relative to their parent item for incr. comp. (default: no)"),
incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED],
"verify incr. comp. hashes of green query instances (default: no)"),
inline_llvm: bool = (true, parse_bool, [TRACKED],
"enable LLVM inlining (default: yes)"),
inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED],
"enable MIR inlining (default: no)"),
inline_mir_threshold: Option<usize> = (None, parse_opt_number, [TRACKED],
Expand Down
26 changes: 26 additions & 0 deletions compiler/rustc_trait_selection/src/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use super::elaborate_predicates;
use crate::infer::TyCtxtInferExt;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
use crate::traits::{self, Obligation, ObligationCause};
use hir::def::DefKind;
use rustc_errors::{FatalError, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
Expand Down Expand Up @@ -431,6 +432,9 @@ fn virtual_call_violation_for_method<'tcx>(
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
return Some(MethodViolationCode::ReferencesSelfOutput);
}
if contains_illegal_impl_trait_in_trait(tcx, sig.output()) {
return Some(MethodViolationCode::ReferencesImplTraitInTrait);
}

// We can't monomorphize things like `fn foo<A>(...)`.
let own_counts = tcx.generics_of(method.def_id).own_counts();
Expand Down Expand Up @@ -793,6 +797,12 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
ControlFlow::CONTINUE
}
}
ty::Projection(ref data)
if self.tcx.def_kind(data.item_def_id) == DefKind::ImplTraitPlaceholder =>
{
// We'll deny these later in their own pass
ControlFlow::CONTINUE
}
ty::Projection(ref data) => {
// This is a projected type `<Foo as SomeTrait>::X`.

Expand Down Expand Up @@ -861,6 +871,22 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
.is_break()
}

pub fn contains_illegal_impl_trait_in_trait<'tcx>(
tcx: TyCtxt<'tcx>,
ty: ty::Binder<'tcx, Ty<'tcx>>,
) -> bool {
// FIXME(RPITIT): Perhaps we should use a visitor here?
ty.skip_binder().walk().any(|arg| {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(proj) = ty.kind()
{
tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
} else {
false
}
})
}

pub fn provide(providers: &mut ty::query::Providers) {
*providers = ty::query::Providers { object_safety_violations, ..*providers };
}
44 changes: 44 additions & 0 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::constrained_generic_params::{identify_constrained_generic_params, Parameter};
use hir::def::DefKind;
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed};
Expand Down Expand Up @@ -1530,6 +1531,49 @@ fn check_fn_or_method<'tcx>(
);

check_where_clauses(wfcx, span, def_id);

check_return_position_impl_trait_in_trait_bounds(
tcx,
wfcx,
def_id,
sig.output(),
hir_decl.output.span(),
);
}

/// Basically `check_associated_type_bounds`, but separated for now and should be
/// deduplicated when RPITITs get lowered into real associated items.
fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
wfcx: &WfCheckingCtxt<'_, 'tcx>,
fn_def_id: LocalDefId,
fn_output: Ty<'tcx>,
span: Span,
) {
if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id())
&& assoc_item.container == ty::AssocItemContainer::TraitContainer
{
for arg in fn_output.walk() {
if let ty::GenericArgKind::Type(ty) = arg.unpack()
&& let ty::Projection(proj) = ty.kind()
&& tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
&& tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id()
{
let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id);
let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| {
let normalized_bound = wfcx.normalize(span, None, bound);
traits::wf::predicate_obligations(
wfcx.infcx,
wfcx.param_env,
wfcx.body_id,
normalized_bound,
bound_span,
)
});
wfcx.register_obligations(wf_obligations);
}
}
}
}

const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/ffi/c_double.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Equivalent to C's `double` type.

This type will almost always be [`f64`], which is guaranteed to be an [IEEE-754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.
This type will almost always be [`f64`], which is guaranteed to be an [IEEE 754 double-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number with at least the precision of a [`float`], and it may be `f32` or something entirely different from the IEEE-754 standard.

[IEEE-754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
[IEEE 754 double-precision float]: https://en.wikipedia.org/wiki/IEEE_754
[`float`]: c_float
4 changes: 2 additions & 2 deletions library/core/src/ffi/c_float.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Equivalent to C's `float` type.

This type will almost always be [`f32`], which is guaranteed to be an [IEEE-754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all.
This type will almost always be [`f32`], which is guaranteed to be an [IEEE 754 single-precision float] in Rust. That said, the standard technically only guarantees that it be a floating-point number, and it may have less precision than `f32` or not follow the IEEE-754 standard at all.

[IEEE-754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754
[IEEE 754 single-precision float]: https://en.wikipedia.org/wiki/IEEE_754
9 changes: 2 additions & 7 deletions library/core/src/ffi/c_str.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::ascii;
use crate::cmp::Ordering;
use crate::ffi::c_char;
use crate::fmt::{self, Write};
use crate::fmt;
use crate::intrinsics;
use crate::ops;
use crate::slice;
Expand Down Expand Up @@ -161,11 +160,7 @@ impl fmt::Display for FromBytesUntilNulError {
#[stable(feature = "cstr_debug", since = "1.3.0")]
impl fmt::Debug for CStr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\"")?;
for byte in self.to_bytes().iter().flat_map(|&b| ascii::escape_default(b)) {
f.write_char(byte as char)?;
}
write!(f, "\"")
write!(f, "\"{}\"", self.to_bytes().escape_ascii())
}
}

Expand Down
2 changes: 1 addition & 1 deletion library/core/src/num/dec2flt/decimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl Default for Decimal {
impl Decimal {
/// The maximum number of digits required to unambiguously round a float.
///
/// For a double-precision IEEE-754 float, this required 767 digits,
/// For a double-precision IEEE 754 float, this required 767 digits,
/// so we store the max digits + 1.
///
/// We can exactly represent a float in radix `b` from radix 2 if
Expand Down
14 changes: 7 additions & 7 deletions library/core/src/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ impl f32 {

/// Not a Number (NaN).
///
/// Note that IEEE-754 doesn't define just a single NaN value;
/// Note that IEEE 754 doesn't define just a single NaN value;
/// a plethora of bit patterns are considered to be NaN.
/// Furthermore, the standard makes a difference
/// between a "signaling" and a "quiet" NaN,
Expand Down Expand Up @@ -632,7 +632,7 @@ impl f32 {
}

/// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
/// positive sign bit and positive infinity. Note that IEEE-754 doesn't assign any
/// positive sign bit and positive infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
Expand All @@ -654,7 +654,7 @@ impl f32 {
}

/// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
/// negative sign bit and negative infinity. Note that IEEE-754 doesn't assign any
/// negative sign bit and negative infinity. Note that IEEE 754 doesn't assign any
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
/// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
Expand Down Expand Up @@ -833,7 +833,7 @@ impl f32 {
/// Returns the maximum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
/// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs;
/// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
/// This also matches the behavior of libm’s fmax.
///
Expand All @@ -853,7 +853,7 @@ impl f32 {
/// Returns the minimum of the two numbers, ignoring NaN.
///
/// If one of the arguments is NaN, then the other argument is returned.
/// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs;
/// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;
/// this function handles all NaNs the same way and avoids minNum's problems with associativity.
/// This also matches the behavior of libm’s fmin.
///
Expand Down Expand Up @@ -1051,9 +1051,9 @@ impl f32 {
/// It turns out this is incredibly portable, for two reasons:
///
/// * Floats and Ints have the same endianness on all supported platforms.
/// * IEEE-754 very precisely specifies the bit layout of floats.
/// * IEEE 754 very precisely specifies the bit layout of floats.
///
/// However there is one caveat: prior to the 2008 version of IEEE-754, how
/// However there is one caveat: prior to the 2008 version of IEEE 754, how
/// to interpret the NaN signaling bit wasn't actually specified. Most platforms
/// (notably x86 and ARM) picked the interpretation that was ultimately
/// standardized in 2008, but some didn't (notably MIPS). As a result, all
Expand Down
Loading

0 comments on commit 7f115e3

Please sign in to comment.