Skip to content

Commit

Permalink
Auto merge of #89903 - matthiaskrgr:rollup-s0c69xl, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 7 pull requests

Successful merges:

 - #86011 (move implicit `Sized` predicate to end of list)
 - #89821 (Add a strange test for `unsafe_code` lint.)
 - #89859 (add dedicated error variant for writing the discriminant of an uninhabited enum variant)
 - #89870 (Suggest Box::pin when Pin::new is used instead)
 - #89880 (Use non-checking TLS relocation in aarch64 asm! sym test.)
 - #89885 (add long explanation for E0183)
 - #89894 (Remove unused dependencies from rustc_const_eval)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Oct 15, 2021
2 parents 313e71a + e45c222 commit 72d6606
Show file tree
Hide file tree
Showing 35 changed files with 236 additions and 114 deletions.
2 changes: 0 additions & 2 deletions Cargo.lock
Expand Up @@ -3736,8 +3736,6 @@ dependencies = [
name = "rustc_const_eval"
version = "0.0.0"
dependencies = [
"either",
"gsgdt",
"rustc_apfloat",
"rustc_ast",
"rustc_attr",
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_const_eval/Cargo.toml
Expand Up @@ -7,8 +7,6 @@ edition = "2021"
doctest = false

[dependencies]
either = "1.5.0"
gsgdt = "0.1.2"
tracing = "0.1"
rustc_apfloat = { path = "../rustc_apfloat" }
rustc_ast = { path = "../rustc_ast" }
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Expand Up @@ -618,6 +618,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}

/// Read discriminant, return the runtime value as well as the variant index.
/// Can also legally be called on non-enums (e.g. through the discriminant_value intrinsic)!
pub fn read_discriminant(
&self,
op: &OpTy<'tcx, M::PointerTag>,
Expand Down
15 changes: 14 additions & 1 deletion compiler/rustc_const_eval/src/interpret/place.rs
Expand Up @@ -988,10 +988,23 @@ where
variant_index: VariantIdx,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
// This must be an enum or generator.
match dest.layout.ty.kind() {
ty::Adt(adt, _) => assert!(adt.is_enum()),
ty::Generator(..) => {}
_ => span_bug!(
self.cur_span(),
"write_discriminant called on non-variant-type (neither enum nor generator)"
),
}
// Layout computation excludes uninhabited variants from consideration
// therefore there's no way to represent those variants in the given layout.
// Essentially, uninhabited variants do not have a tag that corresponds to their
// discriminant, so we cannot do anything here.
// When evaluating we will always error before even getting here, but ConstProp 'executes'
// dead code, so we cannot ICE here.
if dest.layout.for_variant(self, variant_index).abi.is_uninhabited() {
throw_ub!(Unreachable);
throw_ub!(UninhabitedEnumVariantWritten)
}

match dest.layout.variants {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes.rs
Expand Up @@ -92,6 +92,7 @@ E0164: include_str!("./error_codes/E0164.md"),
E0165: include_str!("./error_codes/E0165.md"),
E0170: include_str!("./error_codes/E0170.md"),
E0178: include_str!("./error_codes/E0178.md"),
E0183: include_str!("./error_codes/E0183.md"),
E0184: include_str!("./error_codes/E0184.md"),
E0185: include_str!("./error_codes/E0185.md"),
E0186: include_str!("./error_codes/E0186.md"),
Expand Down Expand Up @@ -513,7 +514,6 @@ E0785: include_str!("./error_codes/E0785.md"),
// E0173, // manual implementations of unboxed closure traits are experimental
// E0174,
// E0182, // merged into E0229
E0183,
// E0187, // cannot infer the kind of the closure
// E0188, // can not cast an immutable reference to a mutable pointer
// E0189, // deprecated: can only cast a boxed pointer to a boxed object
Expand Down
39 changes: 39 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0183.md
@@ -0,0 +1,39 @@
Manual implemetation of a `Fn*` trait.

Erroneous code example:

```compile_fail,E0183
struct MyClosure {
foo: i32
}
impl FnOnce<()> for MyClosure { // error
type Output = ();
extern "rust-call" fn call_once(self, args: ()) -> Self::Output {
println!("{}", self.foo);
}
}
```

Manually implementing `Fn`, `FnMut` or `FnOnce` is unstable
and requires `#![feature(fn_traits, unboxed_closures)]`.

```
#![feature(fn_traits, unboxed_closures)]
struct MyClosure {
foo: i32
}
impl FnOnce<()> for MyClosure { // ok!
type Output = ();
extern "rust-call" fn call_once(self, args: ()) -> Self::Output {
println!("{}", self.foo);
}
}
```

The argumements must be a tuple representing the argument list.
For more info, see the [tracking issue][iss29625]:

[iss29625]: https://github.com/rust-lang/rust/issues/29625
5 changes: 5 additions & 0 deletions compiler/rustc_middle/src/mir/interpret/error.rs
Expand Up @@ -287,6 +287,8 @@ pub enum UndefinedBehaviorInfo<'tcx> {
target_size: u64,
data_size: u64,
},
/// A discriminant of an uninhabited enum variant is written.
UninhabitedEnumVariantWritten,
}

impl fmt::Display for UndefinedBehaviorInfo<'_> {
Expand Down Expand Up @@ -391,6 +393,9 @@ impl fmt::Display for UndefinedBehaviorInfo<'_> {
"scalar size mismatch: expected {} bytes but got {} bytes instead",
target_size, data_size
),
UninhabitedEnumVariantWritten => {
write!(f, "writing discriminant of an uninhabited enum")
}
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_typeck/src/bounds.rs
Expand Up @@ -64,16 +64,16 @@ impl<'tcx> Bounds<'tcx> {
})
});

sized_predicate
.into_iter()
.chain(self.region_bounds.iter().map(|&(region_bound, span)| {
self.region_bounds
.iter()
.map(|&(region_bound, span)| {
(
region_bound
.map_bound(|region_bound| ty::OutlivesPredicate(param_ty, region_bound))
.to_predicate(tcx),
span,
)
}))
})
.chain(self.trait_bounds.iter().map(|&(bound_trait_ref, span, constness)| {
let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx);
(predicate, span)
Expand All @@ -83,6 +83,7 @@ impl<'tcx> Bounds<'tcx> {
.iter()
.map(|&(projection, span)| (projection.to_predicate(tcx), span)),
)
.chain(sized_predicate.into_iter())
.collect()
}
}
90 changes: 60 additions & 30 deletions compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
Expand Up @@ -8,11 +8,11 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{Expr, ExprKind, ItemKind, Node, Stmt, StmtKind};
use rustc_hir::{Expr, ExprKind, ItemKind, Node, Path, QPath, Stmt, StmtKind, TyKind};
use rustc_infer::infer;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, Binder, Ty};
use rustc_span::symbol::kw;
use rustc_span::symbol::{kw, sym};

use std::iter;

Expand Down Expand Up @@ -350,6 +350,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

/// When encountering an `impl Future` where `BoxFuture` is expected, suggest `Box::pin`.
#[instrument(skip(self, err))]
pub(in super::super) fn suggest_calling_boxed_future_when_appropriate(
&self,
err: &mut DiagnosticBuilder<'_>,
Expand All @@ -368,41 +369,70 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() {
return false;
}
match expected.kind() {
ty::Adt(def, _) if Some(def.did) == pin_did => (),
_ => return false,
}
let box_found = self.tcx.mk_box(found);
let pin_box_found = self.tcx.mk_lang_item(box_found, LangItem::Pin).unwrap();
let pin_found = self.tcx.mk_lang_item(found, LangItem::Pin).unwrap();
if self.can_coerce(pin_box_found, expected) {
debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected);
match found.kind() {
ty::Adt(def, _) if def.is_box() => {
err.help("use `Box::pin`");
}
_ => {
err.multipart_suggestion(
"you need to pin and box this expression",
vec![
(expr.span.shrink_to_lo(), "Box::pin(".to_string()),
(expr.span.shrink_to_hi(), ")".to_string()),
],
Applicability::MaybeIncorrect,
);
match expected.kind() {
ty::Adt(def, _) if Some(def.did) == pin_did => {
if self.can_coerce(pin_box_found, expected) {
debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected);
match found.kind() {
ty::Adt(def, _) if def.is_box() => {
err.help("use `Box::pin`");
}
_ => {
err.multipart_suggestion(
"you need to pin and box this expression",
vec![
(expr.span.shrink_to_lo(), "Box::pin(".to_string()),
(expr.span.shrink_to_hi(), ")".to_string()),
],
Applicability::MaybeIncorrect,
);
}
}
true
} else if self.can_coerce(pin_found, expected) {
match found.kind() {
ty::Adt(def, _) if def.is_box() => {
err.help("use `Box::pin`");
true
}
_ => false,
}
} else {
false
}
}
true
} else if self.can_coerce(pin_found, expected) {
match found.kind() {
ty::Adt(def, _) if def.is_box() => {
err.help("use `Box::pin`");
true
ty::Adt(def, _) if def.is_box() && self.can_coerce(box_found, expected) => {
// Check if the parent expression is a call to Pin::new. If it
// is and we were expecting a Box, ergo Pin<Box<expected>>, we
// can suggest Box::pin.
let parent = self.tcx.hir().get_parent_node(expr.hir_id);
let fn_name = match self.tcx.hir().find(parent) {
Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) => fn_name,
_ => return false,
};
match fn_name.kind {
ExprKind::Path(QPath::TypeRelative(
hir::Ty {
kind: TyKind::Path(QPath::Resolved(_, Path { res: recv_ty, .. })),
..
},
method,
)) if Some(recv_ty.def_id()) == pin_did && method.ident.name == sym::new => {
err.span_suggestion(
fn_name.span,
"use `Box::pin` to pin and box this expression",
"Box::pin".to_string(),
Applicability::MachineApplicable,
);
true
}
_ => false,
}
_ => false,
}
} else {
false
_ => false,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/asm/aarch64/sym.rs
Expand Up @@ -55,7 +55,7 @@ macro_rules! static_tls_addr {
// Add the top 12 bits of the symbol's offset
"add {out}, {out}, :tprel_hi12:{sym}",
// And the bottom 12 bits
"add {out}, {out}, :tprel_lo12:{sym}",
"add {out}, {out}, :tprel_lo12_nc:{sym}",
out = out(reg) result,
sym = sym $s
);
Expand Down
Expand Up @@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
|
LL | fn hash<H: Hasher>(&self, state: &mut H);
| ^ required by this bound in `std::hash::Hash::hash`
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/derives/derives-span-Hash-enum.stderr
Expand Up @@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
|
LL | fn hash<H: Hasher>(&self, state: &mut H);
| ^ required by this bound in `std::hash::Hash::hash`
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/derives/derives-span-Hash-struct.stderr
Expand Up @@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
|
LL | fn hash<H: Hasher>(&self, state: &mut H);
| ^ required by this bound in `std::hash::Hash::hash`
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/derives/derives-span-Hash-tuple-struct.stderr
Expand Up @@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
|
LL | fn hash<H: Hasher>(&self, state: &mut H);
| ^ required by this bound in `std::hash::Hash::hash`
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error
Expand Down
Expand Up @@ -101,5 +101,5 @@ LL | impl FnOnce<()> for Baz {

error: aborting due to 12 previous errors

Some errors have detailed explanations: E0229, E0658.
For more information about an error, try `rustc --explain E0229`.
Some errors have detailed explanations: E0183, E0229, E0658.
For more information about an error, try `rustc --explain E0183`.
Expand Up @@ -26,4 +26,5 @@ LL | impl FnOnce<(u32, u32)> for Test {

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.
Some errors have detailed explanations: E0183, E0658.
For more information about an error, try `rustc --explain E0183`.
24 changes: 12 additions & 12 deletions src/test/ui/generic-associated-types/issue-74816.stderr
@@ -1,34 +1,34 @@
error[E0277]: the trait bound `Self: Trait1` is not satisfied
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/issue-74816.rs:9:5
|
LL | type Associated: Trait1 = Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait1` is not implemented for `Self`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
note: required by a bound in `Trait2::Associated`
--> $DIR/issue-74816.rs:9:22
--> $DIR/issue-74816.rs:9:5
|
LL | type Associated: Trait1 = Self;
| ^^^^^^ required by this bound in `Trait2::Associated`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
help: consider further restricting `Self`
|
LL | trait Trait2: Trait1 {
| ++++++++
LL | trait Trait2: Sized {
| +++++++

error[E0277]: the size for values of type `Self` cannot be known at compilation time
error[E0277]: the trait bound `Self: Trait1` is not satisfied
--> $DIR/issue-74816.rs:9:5
|
LL | type Associated: Trait1 = Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait1` is not implemented for `Self`
|
note: required by a bound in `Trait2::Associated`
--> $DIR/issue-74816.rs:9:5
--> $DIR/issue-74816.rs:9:22
|
LL | type Associated: Trait1 = Self;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
| ^^^^^^ required by this bound in `Trait2::Associated`
help: consider further restricting `Self`
|
LL | trait Trait2: Sized {
| +++++++
LL | trait Trait2: Trait1 {
| ++++++++

error: aborting due to 2 previous errors

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/generic-associated-types/issue-86483.stderr
Expand Up @@ -20,13 +20,13 @@ LL | for<'a> T: 'a,
| ^^

error[E0311]: the parameter type `T` may not live long enough
--> $DIR/issue-86483.rs:9:5
--> $DIR/issue-86483.rs:9:19
|
LL | pub trait IceIce<T>
| - help: consider adding an explicit lifetime bound...: `T: 'a`
...
LL | type Ice<'v>: IntoIterator<Item = &'v T>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/issue-86483.rs:7:16
Expand Down

0 comments on commit 72d6606

Please sign in to comment.