Skip to content

Commit e1e9319

Browse files
committed
Auto merge of rust-lang#89882 - matthiaskrgr:rollup-1dh7pz8, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#89390 (Fix incorrect Box::pin suggestion) - rust-lang#89433 (Fix ctrl-c causing reads of stdin to return empty on Windows.) - rust-lang#89823 (Switch order of terms to prevent overflow) - rust-lang#89865 (Allow static linking LLVM with ThinLTO) - rust-lang#89873 (Add missing word to `FromStr` trait documentation) - rust-lang#89878 (Fix missing remaining compiler specific cfg information) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0a56eb1 + d6eff5a commit e1e9319

File tree

14 files changed

+120
-49
lines changed

14 files changed

+120
-49
lines changed

compiler/rustc_trait_selection/src/traits/project.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> {
558558
fn universe_for(&mut self, debruijn: ty::DebruijnIndex) -> ty::UniverseIndex {
559559
let infcx = self.infcx;
560560
let index =
561-
self.universe_indices.len() - debruijn.as_usize() + self.current_index.as_usize() - 1;
561+
self.universe_indices.len() + self.current_index.as_usize() - debruijn.as_usize() - 1;
562562
let universe = self.universe_indices[index].unwrap_or_else(|| {
563563
for i in self.universe_indices.iter_mut().take(index + 1) {
564564
*i = i.or_else(|| Some(infcx.create_next_universe()))

compiler/rustc_typeck/src/check/coercion.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use rustc_hir as hir;
4242
use rustc_hir::def_id::DefId;
4343
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
4444
use rustc_infer::infer::{Coercion, InferOk, InferResult};
45-
use rustc_infer::traits::Obligation;
45+
use rustc_infer::traits::{Obligation, TraitEngine, TraitEngineExt};
4646
use rustc_middle::lint::in_external_macro;
4747
use rustc_middle::ty::adjustment::{
4848
Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast,
@@ -146,6 +146,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
146146
.and_then(|InferOk { value: ty, obligations }| success(f(ty), ty, obligations))
147147
}
148148

149+
#[instrument(skip(self))]
149150
fn coerce(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
150151
// First, remove any resolved type variables (at the top level, at least):
151152
let a = self.shallow_resolve(a);
@@ -933,14 +934,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
933934
}
934935

935936
/// Same as `try_coerce()`, but without side-effects.
937+
///
938+
/// Returns false if the coercion creates any obligations that result in
939+
/// errors.
936940
pub fn can_coerce(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> bool {
937941
let source = self.resolve_vars_with_obligations(expr_ty);
938-
debug!("coercion::can({:?} -> {:?})", source, target);
942+
debug!("coercion::can_with_predicates({:?} -> {:?})", source, target);
939943

940944
let cause = self.cause(rustc_span::DUMMY_SP, ObligationCauseCode::ExprAssignable);
941945
// We don't ever need two-phase here since we throw out the result of the coercion
942946
let coerce = Coerce::new(self, cause, AllowTwoPhase::No);
943-
self.probe(|_| coerce.coerce(source, target)).is_ok()
947+
self.probe(|_| {
948+
let ok = match coerce.coerce(source, target) {
949+
Ok(ok) => ok,
950+
_ => return false,
951+
};
952+
let mut fcx = traits::FulfillmentContext::new_in_snapshot();
953+
fcx.register_predicate_obligations(self, ok.obligations);
954+
fcx.select_where_possible(&self).is_ok()
955+
})
944956
}
945957

946958
/// Given a type and a target type, this function will calculate and return

compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
341341
for (sp, label) in spans_and_labels {
342342
multi_span.push_span_label(sp, label);
343343
}
344-
err.span_note(multi_span, "closures can only be coerced to `fn` types if they do not capture any variables");
344+
err.span_note(
345+
multi_span,
346+
"closures can only be coerced to `fn` types if they do not capture any variables"
347+
);
345348
}
346349
}
347350
}
@@ -361,15 +364,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
361364
return false;
362365
}
363366
let pin_did = self.tcx.lang_items().pin_type();
367+
// This guards the `unwrap` and `mk_box` below.
368+
if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() {
369+
return false;
370+
}
364371
match expected.kind() {
365-
ty::Adt(def, _) if Some(def.did) != pin_did => return false,
366-
// This guards the `unwrap` and `mk_box` below.
367-
_ if pin_did.is_none() || self.tcx.lang_items().owned_box().is_none() => return false,
368-
_ => {}
372+
ty::Adt(def, _) if Some(def.did) == pin_did => (),
373+
_ => return false,
369374
}
370-
let boxed_found = self.tcx.mk_box(found);
371-
let new_found = self.tcx.mk_lang_item(boxed_found, LangItem::Pin).unwrap();
372-
if self.can_coerce(new_found, expected) {
375+
let box_found = self.tcx.mk_box(found);
376+
let pin_box_found = self.tcx.mk_lang_item(box_found, LangItem::Pin).unwrap();
377+
let pin_found = self.tcx.mk_lang_item(found, LangItem::Pin).unwrap();
378+
if self.can_coerce(pin_box_found, expected) {
379+
debug!("can coerce {:?} to {:?}, suggesting Box::pin", pin_box_found, expected);
373380
match found.kind() {
374381
ty::Adt(def, _) if def.is_box() => {
375382
err.help("use `Box::pin`");
@@ -381,11 +388,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
381388
(expr.span.shrink_to_lo(), "Box::pin(".to_string()),
382389
(expr.span.shrink_to_hi(), ")".to_string()),
383390
],
384-
Applicability::MachineApplicable,
391+
Applicability::MaybeIncorrect,
385392
);
386393
}
387394
}
388395
true
396+
} else if self.can_coerce(pin_found, expected) {
397+
match found.kind() {
398+
ty::Adt(def, _) if def.is_box() => {
399+
err.help("use `Box::pin`");
400+
true
401+
}
402+
_ => false,
403+
}
389404
} else {
390405
false
391406
}

library/alloc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
not(any(test, bootstrap)),
7575
any(not(feature = "miri-test-libstd"), test, doctest),
7676
no_global_oom_handling,
77+
not(no_global_oom_handling),
7778
target_has_atomic = "ptr"
7879
))
7980
)]

library/core/src/str/traits.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ pub trait FromStr: Sized {
536536
///
537537
/// If parsing succeeds, return the value inside [`Ok`], otherwise
538538
/// when the string is ill-formatted return an error specific to the
539-
/// inside [`Err`]. The error type is specific to implementation of the trait.
539+
/// inside [`Err`]. The error type is specific to the implementation of the trait.
540540
///
541541
/// # Examples
542542
///

library/std/src/lib.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,15 @@
195195
test(no_crate_inject, attr(deny(warnings))),
196196
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut)))
197197
)]
198-
#![cfg_attr(not(bootstrap), doc(cfg_hide(not(test), not(any(test, bootstrap)))))]
198+
#![cfg_attr(
199+
not(bootstrap),
200+
doc(cfg_hide(
201+
not(test),
202+
not(any(test, bootstrap)),
203+
no_global_oom_handling,
204+
not(no_global_oom_handling)
205+
))
206+
)]
199207
// Don't link to std. We are std.
200208
#![no_std]
201209
#![warn(deprecated_in_future)]

library/std/src/sys/windows/stdio.rs

+19-9
Original file line numberDiff line numberDiff line change
@@ -291,15 +291,25 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [u16]) -> io::Result<usize> {
291291
};
292292

293293
let mut amount = 0;
294-
cvt(unsafe {
295-
c::ReadConsoleW(
296-
handle,
297-
buf.as_mut_ptr() as c::LPVOID,
298-
buf.len() as u32,
299-
&mut amount,
300-
&mut input_control as c::PCONSOLE_READCONSOLE_CONTROL,
301-
)
302-
})?;
294+
loop {
295+
cvt(unsafe {
296+
c::SetLastError(0);
297+
c::ReadConsoleW(
298+
handle,
299+
buf.as_mut_ptr() as c::LPVOID,
300+
buf.len() as u32,
301+
&mut amount,
302+
&mut input_control as c::PCONSOLE_READCONSOLE_CONTROL,
303+
)
304+
})?;
305+
306+
// ReadConsoleW returns success with ERROR_OPERATION_ABORTED for Ctrl-C or Ctrl-Break.
307+
// Explicitly check for that case here and try again.
308+
if amount == 0 && unsafe { c::GetLastError() } == c::ERROR_OPERATION_ABORTED {
309+
continue;
310+
}
311+
break;
312+
}
303313

304314
if amount > 0 && buf[amount as usize - 1] == CTRL_Z {
305315
amount -= 1;

src/bootstrap/config.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -825,15 +825,10 @@ impl Config {
825825
};
826826
}
827827

828-
if config.llvm_thin_lto {
829-
// If we're building with ThinLTO on, we want to link to LLVM
830-
// shared, to avoid re-doing ThinLTO (which happens in the link
831-
// step) with each stage.
832-
assert_ne!(
833-
llvm.link_shared,
834-
Some(false),
835-
"setting link-shared=false is incompatible with thin-lto=true"
836-
);
828+
if config.llvm_thin_lto && llvm.link_shared.is_none() {
829+
// If we're building with ThinLTO on, by default we want to link
830+
// to LLVM shared, to avoid re-doing ThinLTO (which happens in
831+
// the link step) with each stage.
837832
config.llvm_link_shared = true;
838833
}
839834
}

src/test/ui/cross/cross-borrow-trait.stderr

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ error[E0308]: mismatched types
22
--> $DIR/cross-borrow-trait.rs:10:26
33
|
44
LL | let _y: &dyn Trait = x;
5-
| ---------- ^
6-
| | |
7-
| | expected `&dyn Trait`, found struct `Box`
8-
| | help: consider borrowing here: `&x`
5+
| ---------- ^ expected `&dyn Trait`, found struct `Box`
6+
| |
97
| expected due to this
108
|
119
= note: expected reference `&dyn Trait`

src/test/ui/dst/dst-bad-coercions.stderr

+4-8
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ error[E0308]: mismatched types
1313
--> $DIR/dst-bad-coercions.rs:15:21
1414
|
1515
LL | let y: &dyn T = x;
16-
| ------ ^
17-
| | |
18-
| | expected `&dyn T`, found *-ptr
19-
| | help: consider borrowing here: `&x`
16+
| ------ ^ expected `&dyn T`, found *-ptr
17+
| |
2018
| expected due to this
2119
|
2220
= note: expected reference `&dyn T`
@@ -37,10 +35,8 @@ error[E0308]: mismatched types
3735
--> $DIR/dst-bad-coercions.rs:20:21
3836
|
3937
LL | let y: &dyn T = x;
40-
| ------ ^
41-
| | |
42-
| | expected `&dyn T`, found *-ptr
43-
| | help: consider borrowing here: `&x`
38+
| ------ ^ expected `&dyn T`, found *-ptr
39+
| |
4440
| expected due to this
4541
|
4642
= note: expected reference `&dyn T`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Issue #72117
2+
// edition:2018
3+
4+
use core::future::Future;
5+
use core::pin::Pin;
6+
7+
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
8+
9+
impl<T: ?Sized> FutureExt for T where T: Future {}
10+
trait FutureExt: Future {
11+
fn boxed<'a>(self) -> BoxFuture<'a, Self::Output>
12+
where
13+
Self: Sized + Send + 'a,
14+
{
15+
Box::pin(self)
16+
}
17+
}
18+
19+
fn main() {
20+
let _: BoxFuture<'static, bool> = async {}.boxed();
21+
//~^ ERROR: mismatched types
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/box-future-wrong-output.rs:20:39
3+
|
4+
LL | let _: BoxFuture<'static, bool> = async {}.boxed();
5+
| ------------------------ ^^^^^^^^^^^^^^^^ expected `bool`, found `()`
6+
| |
7+
| expected due to this
8+
|
9+
= note: expected struct `Pin<Box<(dyn Future<Output = bool> + Send + 'static)>>`
10+
found struct `Pin<Box<dyn Future<Output = ()> + Send>>`
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/suggestions/expected-boxed-future-isnt-pinned.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ fn foo<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32>
1111
x //~ ERROR mismatched types
1212
}
1313

14-
// This case is still subpar:
15-
// `Pin::new(x)`: store this in the heap by calling `Box::new`: `Box::new(x)`
16-
// Should suggest changing the code from `Pin::new` to `Box::pin`.
1714
fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
1815
Box::new(x) //~ ERROR mismatched types
1916
}
2017

18+
// This case is still subpar:
19+
// `Pin::new(x)`: store this in the heap by calling `Box::new`: `Box::new(x)`
20+
// Should suggest changing the code from `Pin::new` to `Box::pin`.
2121
fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
2222
Pin::new(x) //~ ERROR mismatched types
2323
//~^ ERROR E0277

src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ LL | Box::pin(x)
1515
| +++++++++ +
1616

1717
error[E0308]: mismatched types
18-
--> $DIR/expected-boxed-future-isnt-pinned.rs:18:5
18+
--> $DIR/expected-boxed-future-isnt-pinned.rs:15:5
1919
|
2020
LL | fn bar<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
2121
| ----------------------- expected `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` because of return type

0 commit comments

Comments
 (0)