Skip to content

Commit 41d97c8

Browse files
committed
Auto merge of rust-lang#122012 - matthiaskrgr:rollup-bzqjj2n, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - rust-lang#121213 (Add an example to demonstrate how Rc::into_inner works) - rust-lang#121262 (Add vector time complexity) - rust-lang#121287 (Clarify/add `must_use` message for Rc/Arc/Weak::into_raw.) - rust-lang#121664 (Adjust error `yield`/`await` lowering) - rust-lang#121826 (Use root obligation on E0277 for some cases) - rust-lang#121838 (Use the correct logic for nested impl trait in assoc types) - rust-lang#121913 (Don't panic when waiting on poisoned queries) - rust-lang#121987 (pattern analysis: abort on arity mismatch) - rust-lang#121993 (Avoid using unnecessary queries when printing the query stack in panics) - rust-lang#121997 (interpret/cast: make more matches on FloatTy properly exhaustive) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5a1e544 + 92ff43d commit 41d97c8

File tree

71 files changed

+435
-284
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+435
-284
lines changed

compiler/rustc_ast_lowering/src/expr.rs

+43-9
Original file line numberDiff line numberDiff line change
@@ -760,10 +760,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
760760
Some(hir::CoroutineKind::Coroutine(_))
761761
| Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _))
762762
| None => {
763-
return hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks {
764-
await_kw_span,
765-
item_span: self.current_item,
766-
}));
763+
// Lower to a block `{ EXPR; <error> }` so that the awaited expr
764+
// is not accidentally orphaned.
765+
let stmt_id = self.next_id();
766+
let expr_err = self.expr(
767+
expr.span,
768+
hir::ExprKind::Err(self.dcx().emit_err(AwaitOnlyInAsyncFnAndBlocks {
769+
await_kw_span,
770+
item_span: self.current_item,
771+
})),
772+
);
773+
return hir::ExprKind::Block(
774+
self.block_all(
775+
expr.span,
776+
arena_vec![self; hir::Stmt {
777+
hir_id: stmt_id,
778+
kind: hir::StmtKind::Semi(expr),
779+
span: expr.span,
780+
}],
781+
Some(self.arena.alloc(expr_err)),
782+
),
783+
None,
784+
);
767785
}
768786
};
769787

@@ -1496,12 +1514,31 @@ impl<'hir> LoweringContext<'_, 'hir> {
14961514
}
14971515

14981516
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> {
1517+
let yielded =
1518+
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
1519+
14991520
let is_async_gen = match self.coroutine_kind {
15001521
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => false,
15011522
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
15021523
Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Async, _)) => {
1503-
return hir::ExprKind::Err(
1504-
self.dcx().emit_err(AsyncCoroutinesNotSupported { span }),
1524+
// Lower to a block `{ EXPR; <error> }` so that the awaited expr
1525+
// is not accidentally orphaned.
1526+
let stmt_id = self.next_id();
1527+
let expr_err = self.expr(
1528+
yielded.span,
1529+
hir::ExprKind::Err(self.dcx().emit_err(AsyncCoroutinesNotSupported { span })),
1530+
);
1531+
return hir::ExprKind::Block(
1532+
self.block_all(
1533+
yielded.span,
1534+
arena_vec![self; hir::Stmt {
1535+
hir_id: stmt_id,
1536+
kind: hir::StmtKind::Semi(yielded),
1537+
span: yielded.span,
1538+
}],
1539+
Some(self.arena.alloc(expr_err)),
1540+
),
1541+
None,
15051542
);
15061543
}
15071544
Some(hir::CoroutineKind::Coroutine(_)) => {
@@ -1531,9 +1568,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
15311568
}
15321569
};
15331570

1534-
let yielded =
1535-
opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
1536-
15371571
if is_async_gen {
15381572
// `yield $expr` is transformed into `task_context = yield async_gen_ready($expr)`.
15391573
// This ensures that we store our resumed `ResumeContext` correctly, and also that

compiler/rustc_const_eval/src/interpret/cast.rs

+35-23
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
182182
) -> InterpResult<'tcx, ImmTy<'tcx, M::Provenance>> {
183183
use rustc_type_ir::TyKind::*;
184184

185-
let val = match src.layout.ty.kind() {
186-
// Floating point
187-
Float(FloatTy::F32) => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty),
188-
Float(FloatTy::F64) => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty),
189-
_ => {
190-
bug!("Can't cast 'Float' type into {}", cast_to.ty);
191-
}
185+
let Float(fty) = src.layout.ty.kind() else {
186+
bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty)
187+
};
188+
let val = match fty {
189+
FloatTy::F16 => unimplemented!("f16_f128"),
190+
FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty),
191+
FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty),
192+
FloatTy::F128 => unimplemented!("f16_f128"),
192193
};
193194
Ok(ImmTy::from_scalar(val, cast_to))
194195
}
@@ -275,6 +276,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
275276
trace!("cast_from_scalar: {}, {} -> {}", v, src_layout.ty, cast_ty);
276277

277278
Ok(match *cast_ty.kind() {
279+
// int -> int
278280
Int(_) | Uint(_) => {
279281
let size = match *cast_ty.kind() {
280282
Int(t) => Integer::from_int_ty(self, t).size(),
@@ -285,15 +287,26 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
285287
Scalar::from_uint(v, size)
286288
}
287289

288-
Float(FloatTy::F32) if signed => Scalar::from_f32(Single::from_i128(v as i128).value),
289-
Float(FloatTy::F64) if signed => Scalar::from_f64(Double::from_i128(v as i128).value),
290-
Float(FloatTy::F32) => Scalar::from_f32(Single::from_u128(v).value),
291-
Float(FloatTy::F64) => Scalar::from_f64(Double::from_u128(v).value),
292-
293-
Char => {
294-
// `u8` to `char` cast
295-
Scalar::from_u32(u8::try_from(v).unwrap().into())
290+
// signed int -> float
291+
Float(fty) if signed => {
292+
let v = v as i128;
293+
match fty {
294+
FloatTy::F16 => unimplemented!("f16_f128"),
295+
FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value),
296+
FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value),
297+
FloatTy::F128 => unimplemented!("f16_f128"),
298+
}
296299
}
300+
// unsigned int -> float
301+
Float(fty) => match fty {
302+
FloatTy::F16 => unimplemented!("f16_f128"),
303+
FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value),
304+
FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value),
305+
FloatTy::F128 => unimplemented!("f16_f128"),
306+
},
307+
308+
// u8 -> char
309+
Char => Scalar::from_u32(u8::try_from(v).unwrap().into()),
297310

298311
// Casts to bool are not permitted by rustc, no need to handle them here.
299312
_ => span_bug!(self.cur_span(), "invalid int to {} cast", cast_ty),
@@ -339,14 +352,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
339352
let v = f.to_i128(size.bits_usize()).value;
340353
Scalar::from_int(v, size)
341354
}
342-
// float -> f32
343-
Float(FloatTy::F32) => {
344-
Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value))
345-
}
346-
// float -> f64
347-
Float(FloatTy::F64) => {
348-
Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value))
349-
}
355+
// float -> float
356+
Float(fty) => match fty {
357+
FloatTy::F16 => unimplemented!("f16_f128"),
358+
FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)),
359+
FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)),
360+
FloatTy::F128 => unimplemented!("f16_f128"),
361+
},
350362
// That's it.
351363
_ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty),
352364
}

compiler/rustc_hir_typeck/src/method/suggest.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
166166
return false;
167167
}
168168

169-
match ty.kind() {
169+
match ty.peel_refs().kind() {
170170
ty::Param(param) => {
171171
let generics = self.tcx.generics_of(self.body_id);
172172
let generic_param = generics.type_param(&param, self.tcx);
@@ -184,7 +184,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
184184
}
185185
}
186186
}
187-
ty::Alias(ty::AliasKind::Opaque, _) => {
187+
ty::Slice(..) | ty::Adt(..) | ty::Alias(ty::AliasKind::Opaque, _) => {
188188
for unsatisfied in unsatisfied_predicates.iter() {
189189
if is_iterator_predicate(unsatisfied.0, self.tcx) {
190190
return true;

compiler/rustc_pattern_analysis/src/usefulness.rs

+15-7
Original file line numberDiff line numberDiff line change
@@ -1001,19 +1001,26 @@ impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
10011001
/// Only call if `ctor.is_covered_by(self.head().ctor())` is true.
10021002
fn pop_head_constructor(
10031003
&self,
1004+
cx: &Cx,
10041005
ctor: &Constructor<Cx>,
10051006
ctor_arity: usize,
10061007
ctor_is_relevant: bool,
1007-
) -> PatStack<'p, Cx> {
1008+
) -> Result<PatStack<'p, Cx>, Cx::Error> {
10081009
// We pop the head pattern and push the new fields extracted from the arguments of
10091010
// `self.head()`.
10101011
let mut new_pats = self.head().specialize(ctor, ctor_arity);
1012+
if new_pats.len() != ctor_arity {
1013+
return Err(cx.bug(format_args!(
1014+
"uncaught type error: pattern {:?} has inconsistent arity (expected arity {ctor_arity})",
1015+
self.head().as_pat().unwrap()
1016+
)));
1017+
}
10111018
new_pats.extend_from_slice(&self.pats[1..]);
10121019
// `ctor` is relevant for this row if it is the actual constructor of this row, or if the
10131020
// row has a wildcard and `ctor` is relevant for wildcards.
10141021
let ctor_is_relevant =
10151022
!matches!(self.head().ctor(), Constructor::Wildcard) || ctor_is_relevant;
1016-
PatStack { pats: new_pats, relevant: self.relevant && ctor_is_relevant }
1023+
Ok(PatStack { pats: new_pats, relevant: self.relevant && ctor_is_relevant })
10171024
}
10181025
}
10191026

@@ -1083,18 +1090,19 @@ impl<'p, Cx: TypeCx> MatrixRow<'p, Cx> {
10831090
/// Only call if `ctor.is_covered_by(self.head().ctor())` is true.
10841091
fn pop_head_constructor(
10851092
&self,
1093+
cx: &Cx,
10861094
ctor: &Constructor<Cx>,
10871095
ctor_arity: usize,
10881096
ctor_is_relevant: bool,
10891097
parent_row: usize,
1090-
) -> MatrixRow<'p, Cx> {
1091-
MatrixRow {
1092-
pats: self.pats.pop_head_constructor(ctor, ctor_arity, ctor_is_relevant),
1098+
) -> Result<MatrixRow<'p, Cx>, Cx::Error> {
1099+
Ok(MatrixRow {
1100+
pats: self.pats.pop_head_constructor(cx, ctor, ctor_arity, ctor_is_relevant)?,
10931101
parent_row,
10941102
is_under_guard: self.is_under_guard,
10951103
useful: false,
10961104
intersects: BitSet::new_empty(0), // Initialized in `Matrix::expand_and_push`.
1097-
}
1105+
})
10981106
}
10991107
}
11001108

@@ -1217,7 +1225,7 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
12171225
};
12181226
for (i, row) in self.rows().enumerate() {
12191227
if ctor.is_covered_by(pcx.cx, row.head().ctor())? {
1220-
let new_row = row.pop_head_constructor(ctor, arity, ctor_is_relevant, i);
1228+
let new_row = row.pop_head_constructor(pcx.cx, ctor, arity, ctor_is_relevant, i)?;
12211229
matrix.expand_and_push(new_row);
12221230
}
12231231
}

compiler/rustc_query_impl/src/plumbing.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_middle::dep_graph::{
1717
use rustc_middle::query::on_disk_cache::AbsoluteBytePos;
1818
use rustc_middle::query::on_disk_cache::{CacheDecoder, CacheEncoder, EncodedDepNodeIndex};
1919
use rustc_middle::query::Key;
20+
use rustc_middle::ty::print::with_reduced_queries;
2021
use rustc_middle::ty::tls::{self, ImplicitCtxt};
2122
use rustc_middle::ty::{self, TyCtxt};
2223
use rustc_query_system::dep_graph::{DepNodeParams, HasDepContext};
@@ -304,22 +305,26 @@ pub(crate) fn create_query_frame<
304305
kind: DepKind,
305306
name: &'static str,
306307
) -> QueryStackFrame {
308+
// If reduced queries are requested, we may be printing a query stack due
309+
// to a panic. Avoid using `default_span` and `def_kind` in that case.
310+
let reduce_queries = with_reduced_queries();
311+
307312
// Avoid calling queries while formatting the description
308313
let description = ty::print::with_no_queries!(do_describe(tcx, key));
309314
let description = if tcx.sess.verbose_internals() {
310315
format!("{description} [{name:?}]")
311316
} else {
312317
description
313318
};
314-
let span = if kind == dep_graph::dep_kinds::def_span {
319+
let span = if kind == dep_graph::dep_kinds::def_span || reduce_queries {
315320
// The `def_span` query is used to calculate `default_span`,
316321
// so exit to avoid infinite recursion.
317322
None
318323
} else {
319324
Some(key.default_span(tcx))
320325
};
321326
let def_id = key.key_as_def_id();
322-
let def_kind = if kind == dep_graph::dep_kinds::def_kind {
327+
let def_kind = if kind == dep_graph::dep_kinds::def_kind || reduce_queries {
323328
// Try to avoid infinite recursion.
324329
None
325330
} else {

compiler/rustc_query_system/src/query/plumbing.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,8 @@ where
285285
let lock = query.query_state(qcx).active.get_shard_by_value(&key).lock();
286286

287287
match lock.get(&key) {
288-
Some(QueryResult::Poisoned) => {
289-
panic!("query '{}' not cached due to poisoning", query.name())
290-
}
288+
// The query we waited on panicked. Continue unwinding here.
289+
Some(QueryResult::Poisoned) => FatalError.raise(),
291290
_ => panic!(
292291
"query '{}' result must be in the cache or the query must be poisoned after a wait",
293292
query.name()

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+54-5
Original file line numberDiff line numberDiff line change
@@ -416,9 +416,59 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
416416
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
417417
let trait_predicate = bound_predicate.rebind(trait_predicate);
418418
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
419-
let trait_ref = trait_predicate.to_poly_trait_ref();
420419

421-
if let Some(guar) = self.emit_specialized_closure_kind_error(&obligation, trait_ref) {
420+
// Let's use the root obligation as the main message, when we care about the
421+
// most general case ("X doesn't implement Pattern<'_>") over the case that
422+
// happened to fail ("char doesn't implement Fn(&mut char)").
423+
//
424+
// We rely on a few heuristics to identify cases where this root
425+
// obligation is more important than the leaf obligation:
426+
let (main_trait_predicate, o) = if let ty::PredicateKind::Clause(
427+
ty::ClauseKind::Trait(root_pred)
428+
) = root_obligation.predicate.kind().skip_binder()
429+
&& !trait_predicate.self_ty().skip_binder().has_escaping_bound_vars()
430+
&& !root_pred.self_ty().has_escaping_bound_vars()
431+
// The type of the leaf predicate is (roughly) the same as the type
432+
// from the root predicate, as a proxy for "we care about the root"
433+
// FIXME: this doesn't account for trivial derefs, but works as a first
434+
// approximation.
435+
&& (
436+
// `T: Trait` && `&&T: OtherTrait`, we want `OtherTrait`
437+
self.can_eq(
438+
obligation.param_env,
439+
trait_predicate.self_ty().skip_binder(),
440+
root_pred.self_ty().peel_refs(),
441+
)
442+
// `&str: Iterator` && `&str: IntoIterator`, we want `IntoIterator`
443+
|| self.can_eq(
444+
obligation.param_env,
445+
trait_predicate.self_ty().skip_binder(),
446+
root_pred.self_ty(),
447+
)
448+
)
449+
// The leaf trait and the root trait are different, so as to avoid
450+
// talking about `&mut T: Trait` and instead remain talking about
451+
// `T: Trait` instead
452+
&& trait_predicate.def_id() != root_pred.def_id()
453+
// The root trait is not `Unsize`, as to avoid talking about it in
454+
// `tests/ui/coercion/coerce-issue-49593-box-never.rs`.
455+
&& Some(root_pred.def_id()) != self.tcx.lang_items().unsize_trait()
456+
{
457+
(
458+
self.resolve_vars_if_possible(
459+
root_obligation.predicate.kind().rebind(root_pred),
460+
),
461+
root_obligation,
462+
)
463+
} else {
464+
(trait_predicate, &obligation)
465+
};
466+
let trait_ref = main_trait_predicate.to_poly_trait_ref();
467+
468+
if let Some(guar) = self.emit_specialized_closure_kind_error(
469+
&obligation,
470+
trait_ref,
471+
) {
422472
return guar;
423473
}
424474

@@ -459,8 +509,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
459509
notes,
460510
parent_label,
461511
append_const_msg,
462-
} = self.on_unimplemented_note(trait_ref, &obligation, &mut long_ty_file);
463-
512+
} = self.on_unimplemented_note(trait_ref, o, &mut long_ty_file);
464513
let have_alt_message = message.is_some() || label.is_some();
465514
let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id());
466515
let is_unsize =
@@ -483,7 +532,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
483532
};
484533

485534
let err_msg = self.get_standard_error_message(
486-
&trait_predicate,
535+
&main_trait_predicate,
487536
message,
488537
predicate_is_const,
489538
append_const_msg,

0 commit comments

Comments
 (0)