Skip to content

Commit b509d9b

Browse files
committed
Auto merge of #67063 - Mark-Simulacrum:beta-backports, r=Mark-Simulacrum
[beta] backports This pull request backports the following pull requests, which have all been beta-accepted by the compiler team. * Handle non_exhaustive in borrow checking #66722 * Do not ICE on trait aliases with missing obligations #66392 * Do not ICE in `if` without `else` in `async fn` #66391 * Fix ICE when trying to suggest `Type<>` instead of `Type()` #66390 * Do not ICE on recovery from unmet associated type bound obligation #66388 * find_deprecation: deprecation attr may be ill-formed meta. #66381 * parser: don't use `unreachable!()` in `fn unexpected`. #66361 * Undo an assert causing an ICE until we fix the underlying problem #66250 * Do not ICE with a precision flag in formatting str and no format arguments #66093 * Fix two OOM issues related to `ConstProp` #66394
2 parents 1463fed + d8612f3 commit b509d9b

29 files changed

+335
-38
lines changed

src/librustc/hir/lowering.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -1874,15 +1874,16 @@ impl<'a> LoweringContext<'a> {
18741874
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
18751875
// Do not suggest going from `Trait()` to `Trait<>`
18761876
if data.inputs.len() > 0 {
1877-
let split = snippet.find('(').unwrap();
1878-
let trait_name = &snippet[0..split];
1879-
let args = &snippet[split + 1 .. snippet.len() - 1];
1880-
err.span_suggestion(
1881-
data.span,
1882-
"use angle brackets instead",
1883-
format!("{}<{}>", trait_name, args),
1884-
Applicability::MaybeIncorrect,
1885-
);
1877+
if let Some(split) = snippet.find('(') {
1878+
let trait_name = &snippet[0..split];
1879+
let args = &snippet[split + 1 .. snippet.len() - 1];
1880+
err.span_suggestion(
1881+
data.span,
1882+
"use angle brackets instead",
1883+
format!("{}<{}>", trait_name, args),
1884+
Applicability::MaybeIncorrect,
1885+
);
1886+
}
18861887
}
18871888
};
18881889
err.emit();

src/librustc_mir/build/matches/simplify.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
164164
self.hir.tcx().features().exhaustive_patterns &&
165165
!v.uninhabited_from(self.hir.tcx(), substs, adt_def.adt_kind()).is_empty()
166166
}
167-
});
167+
}) && (adt_def.did.is_local() || !adt_def.is_variant_list_non_exhaustive());
168168
if irrefutable {
169169
let place = tcx.mk_place_downcast(match_pair.place, adt_def, variant_index);
170170
candidate.match_pairs.extend(self.field_match_pairs(place, subpatterns));

src/librustc_mir/transform/const_prop.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc::ty::subst::InternalSubsts;
2222
use rustc_data_structures::fx::FxHashMap;
2323
use rustc_index::vec::IndexVec;
2424
use rustc::ty::layout::{
25-
LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout,
25+
LayoutOf, TyLayout, LayoutError, HasTyCtxt, TargetDataLayout, HasDataLayout, Size,
2626
};
2727

2828
use crate::interpret::{
@@ -34,6 +34,9 @@ use crate::interpret::{
3434
use crate::const_eval::error_to_const_error;
3535
use crate::transform::{MirPass, MirSource};
3636

37+
/// The maximum number of bytes that we'll allocate space for a return value.
38+
const MAX_ALLOC_LIMIT: u64 = 1024;
39+
3740
pub struct ConstProp;
3841

3942
impl<'tcx> MirPass<'tcx> for ConstProp {
@@ -434,6 +437,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
434437
) -> Option<()> {
435438
let span = source_info.span;
436439

440+
// #66397: Don't try to eval into large places as that can cause an OOM
441+
if place_layout.size >= Size::from_bytes(MAX_ALLOC_LIMIT) {
442+
return None;
443+
}
444+
437445
let overflow_check = self.tcx.sess.overflow_checks();
438446

439447
// Perform any special handling for specific Rvalue types.

src/librustc_target/abi/mod.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -738,11 +738,7 @@ impl FieldPlacement {
738738

739739
pub fn offset(&self, i: usize) -> Size {
740740
match *self {
741-
FieldPlacement::Union(count) => {
742-
assert!(i < count,
743-
"Tried to access field {} of union with {} fields", i, count);
744-
Size::ZERO
745-
},
741+
FieldPlacement::Union(_) => Size::ZERO,
746742
FieldPlacement::Array { stride, count } => {
747743
let i = i as u64;
748744
assert!(i < count);

src/librustc_typeck/astconv.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -1221,16 +1221,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
12211221
)
12221222
}
12231223

1224-
/// Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by
1225-
/// removing the dummy `Self` type (`trait_object_dummy_self`).
1226-
fn trait_ref_to_existential(&self, trait_ref: ty::TraitRef<'tcx>)
1227-
-> ty::ExistentialTraitRef<'tcx> {
1228-
if trait_ref.self_ty() != self.tcx().types.trait_object_dummy_self {
1229-
bug!("trait_ref_to_existential called on {:?} with non-dummy Self", trait_ref);
1230-
}
1231-
ty::ExistentialTraitRef::erase_self_ty(self.tcx(), trait_ref)
1232-
}
1233-
12341224
fn conv_object_ty_poly_trait_ref(&self,
12351225
span: Span,
12361226
trait_bounds: &[hir::PolyTraitRef],
@@ -1412,13 +1402,30 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14121402
debug!("regular_traits: {:?}", regular_traits);
14131403
debug!("auto_traits: {:?}", auto_traits);
14141404

1405+
// Transform a `PolyTraitRef` into a `PolyExistentialTraitRef` by
1406+
// removing the dummy `Self` type (`trait_object_dummy_self`).
1407+
let trait_ref_to_existential = |trait_ref: ty::TraitRef<'tcx>| {
1408+
if trait_ref.self_ty() != dummy_self {
1409+
// FIXME: There appears to be a missing filter on top of `expand_trait_aliases`,
1410+
// which picks up non-supertraits where clauses - but also, the object safety
1411+
// completely ignores trait aliases, which could be object safety hazards. We
1412+
// `delay_span_bug` here to avoid an ICE in stable even when the feature is
1413+
// disabled. (#66420)
1414+
tcx.sess.delay_span_bug(DUMMY_SP, &format!(
1415+
"trait_ref_to_existential called on {:?} with non-dummy Self",
1416+
trait_ref,
1417+
));
1418+
}
1419+
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
1420+
};
1421+
14151422
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
14161423
let existential_trait_refs = regular_traits.iter().map(|i| {
1417-
i.trait_ref().map_bound(|trait_ref| self.trait_ref_to_existential(trait_ref))
1424+
i.trait_ref().map_bound(|trait_ref| trait_ref_to_existential(trait_ref))
14181425
});
14191426
let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| {
14201427
bound.map_bound(|b| {
1421-
let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
1428+
let trait_ref = trait_ref_to_existential(b.projection_ty.trait_ref(tcx));
14221429
ty::ExistentialProjection {
14231430
ty: b.ty,
14241431
item_def_id: b.projection_ty.item_def_id,

src/librustc_typeck/check/generator_interior.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,13 @@ impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
244244
// can be reborrowed without needing to spill to a temporary.
245245
// If this were not the case, then we could conceivably have
246246
// to create intermediate temporaries.)
247-
let ty = self.fcx.tables.borrow().expr_ty(expr);
248-
self.record(ty, scope, Some(expr), expr.span);
247+
//
248+
// The type table might not have information for this expression
249+
// if it is in a malformed scope. (#66387)
250+
if let Some(ty) = self.fcx.tables.borrow().expr_ty_opt(expr) {
251+
self.record(ty, scope, Some(expr), expr.span);
252+
} else {
253+
self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node");
254+
}
249255
}
250256
}

src/librustc_typeck/check/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3010,7 +3010,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
30103010
fallback_has_occurred: bool,
30113011
mutate_fullfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
30123012
) {
3013-
if let Err(mut errors) = self.fulfillment_cx.borrow_mut().select_where_possible(self) {
3013+
let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
3014+
if let Err(mut errors) = result {
30143015
mutate_fullfillment_errors(&mut errors);
30153016
self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
30163017
}

src/libsyntax/attr/builtin.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,10 @@ fn find_deprecation_generic<'a, I>(sess: &ParseSess,
655655
break
656656
}
657657

658-
let meta = attr.meta().unwrap();
658+
let meta = match attr.meta() {
659+
Some(meta) => meta,
660+
None => continue,
661+
};
659662
depr = match &meta.kind {
660663
MetaItemKind::Word => Some(Deprecation { since: None, note: None }),
661664
MetaItemKind::NameValue(..) => {

src/libsyntax/parse/parser.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,9 @@ impl<'a> Parser<'a> {
442442
crate fn unexpected<T>(&mut self) -> PResult<'a, T> {
443443
match self.expect_one_of(&[], &[]) {
444444
Err(e) => Err(e),
445-
Ok(_) => unreachable!(),
445+
// We can get `Ok(true)` from `recover_closing_delimiter`
446+
// which is called in `expected_one_of_not_found`.
447+
Ok(_) => FatalError.raise(),
446448
}
447449
}
448450

src/libsyntax_ext/format.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,12 @@ impl<'a, 'b> Context<'a, 'b> {
374374
format!("are {} arguments", count)
375375
},
376376
));
377-
e.span_label(
378-
self.args[pos].span,
379-
"this parameter corresponds to the precision flag",
380-
);
377+
if let Some(arg) = self.args.get(pos) {
378+
e.span_label(
379+
arg.span,
380+
"this parameter corresponds to the precision flag",
381+
);
382+
}
381383
zero_based_note = true;
382384
}
383385
_ => {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// edition:2018
2+
async fn f() -> i32 {
3+
if true { //~ ERROR if may be missing an else clause
4+
return 0;
5+
}
6+
// An `if` block without `else` causes the type table not to have a type for this expr.
7+
// Check that we do not unconditionally access the type table and we don't ICE.
8+
}
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0317]: if may be missing an else clause
2+
--> $DIR/issue-66387-if-without-else.rs:3:5
3+
|
4+
LL | / if true {
5+
LL | | return 0;
6+
LL | | }
7+
| |_____^ expected (), found i32
8+
|
9+
= note: expected type `()`
10+
found type `i32`
11+
= note: `if` expressions without `else` evaluate to `()`
12+
= help: consider adding an `else` block that evaluates to the expected type
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0317`.

src/test/ui/consts/issue-66342.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// check-pass
2+
// only-x86_64
3+
4+
// Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash.
5+
6+
fn foo() -> [u8; 4 * 1024 * 1024 * 1024 * 1024] {
7+
unimplemented!()
8+
}
9+
10+
fn main() {
11+
foo();
12+
}

src/test/ui/consts/issue-66397.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// check-pass
2+
// only-x86_64
3+
4+
// Checks that the compiler does not actually try to allocate 4 TB during compilation and OOM crash.
5+
6+
fn main() {
7+
[0; 4 * 1024 * 1024 * 1024 * 1024];
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// The original problem in #66340 was that `find_deprecation_generic`
2+
// called `attr.meta().unwrap()` under the assumption that the attribute
3+
// was a well-formed `MetaItem`.
4+
5+
fn main() {
6+
foo()
7+
}
8+
9+
#[deprecated(note = test)]
10+
//~^ ERROR expected unsuffixed literal or identifier, found `test`
11+
fn foo() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected unsuffixed literal or identifier, found `test`
2+
--> $DIR/issue-66340-deprecated-attr-non-meta-grammar.rs:9:21
3+
|
4+
LL | #[deprecated(note = test)]
5+
| ^^^^
6+
7+
error: aborting due to previous error
8+

src/test/ui/if/ifmt-bad-arg.rs

+5
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,9 @@ tenth number: {}",
8686
println!("{:foo}", 1); //~ ERROR unknown format trait `foo`
8787
println!("{5} {:4$} {6:7$}", 1);
8888
//~^ ERROR invalid reference to positional arguments 4, 5, 6 and 7 (there is 1 argument)
89+
90+
// We used to ICE here because we tried to unconditionally access the first argument, which
91+
// doesn't exist.
92+
println!("{:.*}");
93+
//~^ ERROR 2 positional arguments in format string, but no arguments were given
8994
}

src/test/ui/if/ifmt-bad-arg.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,17 @@ LL | println!("{5} {:4$} {6:7$}", 1);
285285
= note: positional arguments are zero-based
286286
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
287287

288+
error: 2 positional arguments in format string, but no arguments were given
289+
--> $DIR/ifmt-bad-arg.rs:92:15
290+
|
291+
LL | println!("{:.*}");
292+
| ^^--^
293+
| |
294+
| this precision flag adds an extra required argument at position 0, which is why there are 2 arguments expected
295+
|
296+
= note: positional arguments are zero-based
297+
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
298+
288299
error[E0308]: mismatched types
289300
--> $DIR/ifmt-bad-arg.rs:78:32
290301
|
@@ -303,6 +314,6 @@ LL | println!("{} {:07$.*} {}", 1, 3.2, 4);
303314
= note: expected type `&usize`
304315
found type `&{float}`
305316

306-
error: aborting due to 35 previous errors
317+
error: aborting due to 36 previous errors
307318

308319
For more information about this error, try `rustc --explain E0308`.

src/test/ui/issues/issue-65462.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// build-pass
2+
3+
enum Empty {}
4+
enum Enum {
5+
Empty( Empty )
6+
}
7+
8+
fn foobar() -> Option< Enum > {
9+
let value: Option< Empty > = None;
10+
Some( Enum::Empty( value? ) )
11+
}
12+
13+
fn main() {
14+
foobar();
15+
}

src/test/ui/issues/issue-65673.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(trait_alias)] // Enabled to reduce stderr output, but can be triggered even if disabled.
2+
trait Trait {}
3+
trait WithType {
4+
type Ctx;
5+
}
6+
trait Alias<T> = where T: Trait;
7+
8+
impl<T> WithType for T {
9+
type Ctx = dyn Alias<T>;
10+
//~^ ERROR the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
11+
}
12+
fn main() {}

src/test/ui/issues/issue-65673.stderr

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
2+
--> $DIR/issue-65673.rs:9:5
3+
|
4+
LL | type Ctx;
5+
| --- associated type defined here
6+
...
7+
LL | impl<T> WithType for T {
8+
| ---------------------- in this `impl` item
9+
LL | type Ctx = dyn Alias<T>;
10+
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
11+
|
12+
= help: the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)`
13+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
14+
15+
error: aborting due to previous error
16+
17+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/issues/issue-66353.rs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// #66353: ICE when trying to recover from incorrect associated type
2+
3+
trait _Func<T> {
4+
fn func(_: Self);
5+
}
6+
7+
trait _A {
8+
type AssocT;
9+
}
10+
11+
fn main() {
12+
_Func::< <() as _A>::AssocT >::func(());
13+
//~^ ERROR the trait bound `(): _A` is not satisfied
14+
//~| ERROR the trait bound `(): _Func<_>` is not satisfied
15+
}

src/test/ui/issues/issue-66353.stderr

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
error[E0277]: the trait bound `(): _A` is not satisfied
2+
--> $DIR/issue-66353.rs:12:14
3+
|
4+
LL | _Func::< <() as _A>::AssocT >::func(());
5+
| ^^^^^^^^^^^^^^^^^^ the trait `_A` is not implemented for `()`
6+
7+
error[E0277]: the trait bound `(): _Func<_>` is not satisfied
8+
--> $DIR/issue-66353.rs:12:41
9+
|
10+
LL | fn func(_: Self);
11+
| ----------------- required by `_Func::func`
12+
...
13+
LL | _Func::< <() as _A>::AssocT >::func(());
14+
| ^^ the trait `_Func<_>` is not implemented for `()`
15+
16+
error: aborting due to 2 previous errors
17+
18+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// The problem in #66357 was that the call trace:
2+
//
3+
// - parse_fn_block_decl
4+
// - expect_or
5+
// - unexpected
6+
// - expect_one_of
7+
// - expected_one_of_not_found
8+
// - recover_closing_delimiter
9+
//
10+
// ended up bubbling up `Ok(true)` to `unexpected` which then used `unreachable!()`.
11+
12+
fn f() { |[](* }
13+
//~^ ERROR expected one of `,` or `:`, found `(`
14+
//~| ERROR expected one of `)`, `-`, `_`, `box`, `mut`, `ref`, `|`, identifier, or path, found `*`

0 commit comments

Comments
 (0)