Skip to content

Commit

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

Rollup of 8 pull requests

Successful merges:

 - rust-lang#107416 (Error code E0794 for late-bound lifetime parameter error.)
 - rust-lang#108772 (Speed up tidy quite a lot)
 - rust-lang#109193 (Add revisions for -Zlower-impl-trait-in-trait-to-assoc-ty fixed tests)
 - rust-lang#109234 (Tweak implementation of overflow checking assertions)
 - rust-lang#109238 (Fix generics mismatch errors for RPITITs on -Zlower-impl-trait-in-trait-to-assoc-ty)
 - rust-lang#109283 (rustdoc: reduce allocations in `visibility_to_src_with_space`)
 - rust-lang#109287 (Use `size_of_val` instead of manual calculation)
 - rust-lang#109288 (Stabilise `unix_socket_abstract`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 18, 2023
2 parents df61fca + 49a1528 commit f177b7c
Show file tree
Hide file tree
Showing 64 changed files with 760 additions and 313 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ no_llvm_build
/llvm/
/mingw-build/
build/
!/compiler/rustc_mir_build/src/build/
/build-rust-analyzer/
/dist/
/unicode-downloads
Expand Down
15 changes: 4 additions & 11 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,17 +346,10 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
crate::abi::codegen_return(fx);
}
TerminatorKind::Assert { cond, expected, msg, target, cleanup: _ } => {
if !fx.tcx.sess.overflow_checks() {
let overflow_not_to_check = match msg {
AssertKind::OverflowNeg(..) => true,
AssertKind::Overflow(op, ..) => op.is_checkable(),
_ => false,
};
if overflow_not_to_check {
let target = fx.get_block(*target);
fx.bcx.ins().jump(target, &[]);
continue;
}
if !fx.tcx.sess.overflow_checks() && msg.is_optional_overflow_check() {
let target = fx.get_block(*target);
fx.bcx.ins().jump(target, &[]);
continue;
}
let cond = codegen_operand(fx, cond).load_scalar(fx);

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
// NOTE: ideally, we want the effects of both `unchecked_smul` and `unchecked_umul`
// (resulting in `mul nsw nuw` in LLVM IR), since we know that the multiplication
// cannot signed wrap, and that both operands are non-negative. But at the time of writing,
// `BuilderMethods` can't do this, and it doesn't seem to enable any further optimizations.
// the `LLVM-C` binding can't do this, and it doesn't seem to enable any further optimizations.
bx.unchecked_smul(info.unwrap(), bx.const_usize(unit.size.bytes())),
bx.const_usize(unit.align.abi.bytes()),
)
Expand Down
11 changes: 2 additions & 9 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,15 +563,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// with #[rustc_inherit_overflow_checks] and inlined from
// another crate (mostly core::num generic/#[inline] fns),
// while the current crate doesn't use overflow checks.
if !bx.cx().check_overflow() {
let overflow_not_to_check = match msg {
AssertKind::OverflowNeg(..) => true,
AssertKind::Overflow(op, ..) => op.is_checkable(),
_ => false,
};
if overflow_not_to_check {
const_cond = Some(expected);
}
if !bx.cx().check_overflow() && msg.is_optional_overflow_check() {
const_cond = Some(expected);
}

// Don't codegen the panic block if success if known.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ pub trait Machine<'mir, 'tcx>: Sized {

/// Whether Assert(OverflowNeg) and Assert(Overflow) MIR terminators should actually
/// check for overflow.
fn ignore_checkable_overflow_assertions(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
fn ignore_optional_overflow_checks(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;

/// Entry point for obtaining the MIR of anything that should get evaluated.
/// So not just functions and shims, but also const/static initializers, anonymous
Expand Down Expand Up @@ -474,7 +474,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
}

#[inline(always)]
fn ignore_checkable_overflow_assertions(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
fn ignore_optional_overflow_checks(_ecx: &InterpCx<$mir, $tcx, Self>) -> bool {
false
}

Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_const_eval/src/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

Assert { ref cond, expected, ref msg, target, cleanup } => {
let ignored = M::ignore_checkable_overflow_assertions(self)
&& match msg {
mir::AssertKind::OverflowNeg(..) => true,
mir::AssertKind::Overflow(op, ..) => op.is_checkable(),
_ => false,
};
let ignored =
M::ignore_optional_overflow_checks(self) && msg.is_optional_overflow_check();
let cond_val = self.read_scalar(&self.eval_operand(cond, None)?)?.to_bool()?;
if ignored || expected == cond_val {
self.go_to_block(target);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,7 @@ E0790: include_str!("./error_codes/E0790.md"),
E0791: include_str!("./error_codes/E0791.md"),
E0792: include_str!("./error_codes/E0792.md"),
E0793: include_str!("./error_codes/E0793.md"),
E0794: include_str!("./error_codes/E0794.md"),
}

// Undocumented removed error codes. Note that many removed error codes are documented.
Expand Down
64 changes: 64 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0794.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
A lifetime parameter of a function definition is called *late-bound* if it both:

1. appears in an argument type
2. does not appear in a generic type constraint

You cannot specify lifetime arguments for late-bound lifetime parameters.

Erroneous code example:

```compile_fail,E0794
fn foo<'a>(x: &'a str) -> &'a str { x }
let _ = foo::<'static>;
```

The type of a concrete instance of a generic function is universally quantified
over late-bound lifetime parameters. This is because we want the function to
work for any lifetime substituted for the late-bound lifetime parameter, no
matter where the function is called. Consequently, it doesn't make sense to
specify arguments for late-bound lifetime parameters, since they are not
resolved until the function's call site(s).

To fix the issue, remove the specified lifetime:

```
fn foo<'a>(x: &'a str) -> &'a str { x }
let _ = foo;
```

### Additional information

Lifetime parameters that are not late-bound are called *early-bound*.
Confusion may arise from the fact that late-bound and early-bound
lifetime parameters are declared the same way in function definitions.
When referring to a function pointer type, universal quantification over
late-bound lifetime parameters can be made explicit:

```
trait BarTrait<'a> {}
struct Bar<'a> {
s: &'a str
}
impl<'a> BarTrait<'a> for Bar<'a> {}
fn bar<'a, 'b, T>(x: &'a str, _t: T) -> &'a str
where T: BarTrait<'b>
{
x
}
let bar_fn: for<'a> fn(&'a str, Bar<'static>) -> &'a str = bar; // OK
let bar_fn2 = bar::<'static, Bar>; // Not allowed
let bar_fn3 = bar::<Bar>; // OK
```

In the definition of `bar`, the lifetime parameter `'a` is late-bound, while
`'b` is early-bound. This is reflected in the type annotation for `bar_fn`,
where `'a` is universally quantified and `'b` is substituted by a specific
lifetime. It is not allowed to explicitly specify early-bound lifetime
arguments when late-bound lifetime parameters are present (as for `bar_fn2`,
see issue #42868: https://github.com/rust-lang/rust/issues/42868), although the
types that are constrained by early-bound parameters can be specified (as for
`bar_fn3`).
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/astconv/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
if position == GenericArgPosition::Value
&& args.num_lifetime_params() != param_counts.lifetimes
{
let mut err = tcx.sess.struct_span_err(span, msg);
let mut err = struct_span_err!(tcx.sess, span, E0794, "{}", msg);
err.span_note(span_late, note);
err.emit();
} else {
Expand Down
11 changes: 11 additions & 0 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,17 @@ fn compare_number_of_generics<'tcx>(
return Ok(());
}

// We never need to emit a separate error for RPITITs, since if an RPITIT
// has mismatched type or const generic arguments, then the method that it's
// inheriting the generics from will also have mismatched arguments, and
// we'll report an error for that instead. Delay a bug for safety, though.
if tcx.opt_rpitit_info(trait_.def_id).is_some() {
return Err(tcx.sess.delay_span_bug(
rustc_span::DUMMY_SP,
"errors comparing numbers of generics of trait/impl functions were not emitted",
));
}

let matchings = [
("type", trait_own_counts.types, impl_own_counts.types),
("const", trait_own_counts.consts, impl_own_counts.consts),
Expand Down
17 changes: 7 additions & 10 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,13 @@ impl<'tcx> BasicBlockData<'tcx> {
}

impl<O> AssertKind<O> {
/// Returns true if this an overflow checking assertion controlled by -C overflow-checks.
pub fn is_optional_overflow_check(&self) -> bool {
use AssertKind::*;
use BinOp::*;
matches!(self, OverflowNeg(..) | Overflow(Add | Sub | Mul | Shl | Shr, ..))
}

/// Getting a description does not require `O` to be printable, and does not
/// require allocation.
/// The caller is expected to handle `BoundsCheck` separately.
Expand Down Expand Up @@ -1992,16 +1999,6 @@ impl BorrowKind {
}
}

impl BinOp {
/// The checkable operators are those whose overflow checking behavior is controlled by
/// -Coverflow-checks option. The remaining operators have either no overflow conditions (e.g.,
/// BitAnd, BitOr, BitXor) or are always checked for overflow (e.g., Div, Rem).
pub fn is_checkable(self) -> bool {
use self::BinOp::*;
matches!(self, Add | Sub | Mul | Shl | Shr)
}
}

impl<'tcx> Debug for Rvalue<'tcx> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
use self::Rvalue::*;
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/mir/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,7 @@ pub enum TerminatorKind<'tcx> {
/// When overflow checking is disabled and this is run-time MIR (as opposed to compile-time MIR
/// that is used for CTFE), the following variants of this terminator behave as `goto target`:
/// - `OverflowNeg(..)`,
/// - `Overflow(op, ..)` if op is a "checkable" operation (add, sub, mul, shl, shr, but NOT
/// div or rem).
/// - `Overflow(op, ..)` if op is add, sub, mul, shl, shr, but NOT div or rem.
Assert {
cond: Operand<'tcx>,
expected: bool,
Expand Down
47 changes: 35 additions & 12 deletions compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,34 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
ExprKind::Binary { op, lhs, rhs } => {
let lhs = unpack!(
block =
this.as_operand(block, scope, &this.thir[lhs], LocalInfo::Boring, NeedsTemporary::Maybe)
block = this.as_operand(
block,
scope,
&this.thir[lhs],
LocalInfo::Boring,
NeedsTemporary::Maybe
)
);
let rhs = unpack!(
block =
this.as_operand(block, scope, &this.thir[rhs], LocalInfo::Boring, NeedsTemporary::No)
block = this.as_operand(
block,
scope,
&this.thir[rhs],
LocalInfo::Boring,
NeedsTemporary::No
)
);
this.build_binary_op(block, op, expr_span, expr.ty, lhs, rhs)
}
ExprKind::Unary { op, arg } => {
let arg = unpack!(
block =
this.as_operand(block, scope, &this.thir[arg], LocalInfo::Boring, NeedsTemporary::No)
block = this.as_operand(
block,
scope,
&this.thir[arg],
LocalInfo::Boring,
NeedsTemporary::No
)
);
// Check for -MIN on signed integers
if this.check_overflow && op == UnOp::Neg && expr.ty.is_signed() {
Expand Down Expand Up @@ -272,8 +287,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}
ExprKind::Pointer { cast, source } => {
let source = unpack!(
block =
this.as_operand(block, scope, &this.thir[source], LocalInfo::Boring, NeedsTemporary::No)
block = this.as_operand(
block,
scope,
&this.thir[source],
LocalInfo::Boring,
NeedsTemporary::No
)
);
block.and(Rvalue::Cast(CastKind::Pointer(cast), source, expr.ty))
}
Expand Down Expand Up @@ -502,8 +522,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
Category::of(&expr.kind),
Some(Category::Rvalue(RvalueFunc::AsRvalue) | Category::Constant)
));
let operand =
unpack!(block = this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::No));
let operand = unpack!(
block =
this.as_operand(block, scope, expr, LocalInfo::Boring, NeedsTemporary::No)
);
block.and(Rvalue::Use(operand))
}
}
Expand Down Expand Up @@ -662,8 +684,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// Repeating a const does nothing
} else {
// For a non-const, we may need to generate an appropriate `Drop`
let value_operand =
unpack!(block = this.as_operand(block, scope, value, LocalInfo::Boring, NeedsTemporary::No));
let value_operand = unpack!(
block = this.as_operand(block, scope, value, LocalInfo::Boring, NeedsTemporary::No)
);
if let Operand::Move(to_drop) = value_operand {
let success = this.cfg.start_new_block();
this.cfg.terminate(
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2252,7 +2252,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
user_ty: None,
source_info,
internal: false,
local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(BindingForm::RefForGuard))),
local_info: ClearCrossCrate::Set(Box::new(LocalInfo::User(
BindingForm::RefForGuard,
))),
});
self.var_debug_info.push(VarDebugInfo {
name,
Expand Down
19 changes: 8 additions & 11 deletions compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -876,21 +876,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
} => {
self.local_decls[local].mutability = mutability;
self.local_decls[local].source_info.scope = self.source_scope;
**self.local_decls[local].local_info.as_mut().assert_crate_local() = if let Some(kind) = param.self_kind {
LocalInfo::User(
BindingForm::ImplicitSelf(kind),
)
} else {
let binding_mode = ty::BindingMode::BindByValue(mutability);
LocalInfo::User(BindingForm::Var(
VarBindingForm {
**self.local_decls[local].local_info.as_mut().assert_crate_local() =
if let Some(kind) = param.self_kind {
LocalInfo::User(BindingForm::ImplicitSelf(kind))
} else {
let binding_mode = ty::BindingMode::BindByValue(mutability);
LocalInfo::User(BindingForm::Var(VarBindingForm {
binding_mode,
opt_ty_info: param.ty_span,
opt_match_place: Some((None, span)),
pat_span: span,
},
))
};
}))
};
self.var_indices.insert(var, LocalsForNode::One(local));
}
_ => {
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/hash/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ mod impls {

#[inline]
fn hash_slice<H: ~const Hasher>(data: &[$ty], state: &mut H) {
let newlen = data.len() * mem::size_of::<$ty>();
let newlen = mem::size_of_val(data);
let ptr = data.as_ptr() as *const u8;
// SAFETY: `ptr` is valid and aligned, as this macro is only used
// for numeric primitives which have no padding. The new slice only
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/os/android/net.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Android-specific networking functionality.
#![unstable(feature = "tcp_quickack", issue = "96256")]
#![stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]

#[unstable(feature = "unix_socket_abstract", issue = "85410")]
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
pub use crate::os::net::linux_ext::addr::SocketAddrExt;

#[unstable(feature = "tcp_quickack", issue = "96256")]
Expand Down
4 changes: 2 additions & 2 deletions library/std/src/os/linux/net.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Linux-specific networking functionality.
#![unstable(feature = "tcp_quickack", issue = "96256")]
#![stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]

#[unstable(feature = "unix_socket_abstract", issue = "85410")]
#[stable(feature = "unix_socket_abstract", since = "CURRENT_RUSTC_VERSION")]
pub use crate::os::net::linux_ext::addr::SocketAddrExt;

#[unstable(feature = "tcp_quickack", issue = "96256")]
Expand Down
Loading

0 comments on commit f177b7c

Please sign in to comment.