Skip to content

Commit f19ccc2

Browse files
committedJun 10, 2022
Auto merge of rust-lang#97939 - JohnTitor:rollup-79pxupb, r=JohnTitor
Rollup of 6 pull requests Successful merges: - rust-lang#97718 (Fix `delayed_good_path_bug` ice for expected diagnostics (RFC 2383)) - rust-lang#97876 (update docs for `std::future::IntoFuture`) - rust-lang#97888 (Don't use __gxx_personality_v0 in panic_unwind on emscripten target) - rust-lang#97922 (Remove redundant calls to reserve in impl Write for VecDeque) - rust-lang#97927 (Do not introduce bindings for types and consts in HRTB.) - rust-lang#97937 (Fix a typo in `test/ui/hrtb/hrtb-just-for-static.rs`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3dea003 + 9d25bc3 commit f19ccc2

File tree

9 files changed

+182
-29
lines changed

9 files changed

+182
-29
lines changed
 

‎compiler/rustc_errors/src/lib.rs

+17-12
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@ struct HandlerInner {
400400
emitter: Box<dyn Emitter + sync::Send>,
401401
delayed_span_bugs: Vec<Diagnostic>,
402402
delayed_good_path_bugs: Vec<DelayedDiagnostic>,
403+
/// This flag indicates that an expected diagnostic was emitted and suppressed.
404+
/// This is used for the `delayed_good_path_bugs` check.
405+
suppressed_expected_diag: bool,
403406

404407
/// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
405408
/// emitting the same diagnostic with extended help (`--teach`) twice, which
@@ -495,7 +498,7 @@ impl Drop for HandlerInner {
495498
// instead of "require some error happened". Sadly that isn't ideal, as
496499
// lints can be `#[allow]`'d, potentially leading to this triggering.
497500
// Also, "good path" should be replaced with a better naming.
498-
if !self.has_any_message() {
501+
if !self.has_any_message() && !self.suppressed_expected_diag {
499502
let bugs = std::mem::replace(&mut self.delayed_good_path_bugs, Vec::new());
500503
self.flush_delayed(
501504
bugs.into_iter().map(DelayedDiagnostic::decorate),
@@ -577,6 +580,7 @@ impl Handler {
577580
emitter,
578581
delayed_span_bugs: Vec::new(),
579582
delayed_good_path_bugs: Vec::new(),
583+
suppressed_expected_diag: false,
580584
taught_diagnostics: Default::default(),
581585
emitted_diagnostic_codes: Default::default(),
582586
emitted_diagnostics: Default::default(),
@@ -1000,20 +1004,20 @@ impl Handler {
10001004
let mut inner = self.inner.borrow_mut();
10011005
let diags = std::mem::take(&mut inner.unstable_expect_diagnostics);
10021006
inner.check_unstable_expect_diagnostics = true;
1003-
if diags.is_empty() {
1004-
return;
1005-
}
10061007

1007-
for mut diag in diags.into_iter() {
1008-
diag.update_unstable_expectation_id(unstable_to_stable);
1008+
if !diags.is_empty() {
1009+
inner.suppressed_expected_diag = true;
1010+
for mut diag in diags.into_iter() {
1011+
diag.update_unstable_expectation_id(unstable_to_stable);
10091012

1010-
let stable_id = diag
1011-
.level
1012-
.get_expectation_id()
1013-
.expect("all diagnostics inside `unstable_expect_diagnostics` must have a `LintExpectationId`");
1014-
inner.fulfilled_expectations.insert(stable_id);
1013+
let stable_id = diag
1014+
.level
1015+
.get_expectation_id()
1016+
.expect("all diagnostics inside `unstable_expect_diagnostics` must have a `LintExpectationId`");
1017+
inner.fulfilled_expectations.insert(stable_id);
10151018

1016-
(*TRACK_DIAGNOSTICS)(&diag);
1019+
(*TRACK_DIAGNOSTICS)(&diag);
1020+
}
10171021
}
10181022

10191023
inner
@@ -1100,6 +1104,7 @@ impl HandlerInner {
11001104
(*TRACK_DIAGNOSTICS)(diagnostic);
11011105

11021106
if let Level::Expect(expectation_id) = diagnostic.level {
1107+
self.suppressed_expected_diag = true;
11031108
self.fulfilled_expectations.insert(expectation_id);
11041109
return None;
11051110
} else if diagnostic.level == Allow {

‎compiler/rustc_resolve/src/late.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1981,7 +1981,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
19811981
continue;
19821982
}
19831983
};
1984-
let res = Res::Def(def_kind, def_id.to_def_id());
1984+
1985+
let res = match kind {
1986+
ItemRibKind(..) | AssocItemRibKind => Res::Def(def_kind, def_id.to_def_id()),
1987+
NormalRibKind => Res::Err,
1988+
_ => bug!("Unexpected rib kind {:?}", kind),
1989+
};
19851990
self.r.record_partial_res(param.id, PartialRes::new(res));
19861991
rib.bindings.insert(ident, res);
19871992
}

‎library/core/src/future/into_future.rs

+119
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,109 @@
11
use crate::future::Future;
22

33
/// Conversion into a `Future`.
4+
///
5+
/// By implementing `Intofuture` for a type, you define how it will be
6+
/// converted to a future.
7+
///
8+
/// # `.await` desugaring
9+
///
10+
/// The `.await` keyword desugars into a call to `IntoFuture::into_future`
11+
/// first before polling the future to completion. `IntoFuture` is implemented
12+
/// for all `T: Future` which means the `into_future` method will be available
13+
/// on all futures.
14+
///
15+
/// ```no_run
16+
/// #![feature(into_future)]
17+
///
18+
/// use std::future::IntoFuture;
19+
///
20+
/// # async fn foo() {
21+
/// let v = async { "meow" };
22+
/// let mut fut = v.into_future();
23+
/// assert_eq!("meow", fut.await);
24+
/// # }
25+
/// ```
26+
///
27+
/// # Async builders
28+
///
29+
/// When implementing futures manually there will often be a choice between
30+
/// implementing `Future` or `IntoFuture` for a type. Implementing `Future` is a
31+
/// good choice in most cases. But implementing `IntoFuture` is most useful when
32+
/// implementing "async builder" types, which allows the type to be modified
33+
/// multiple times before being `.await`ed.
34+
///
35+
/// ```rust
36+
/// #![feature(into_future)]
37+
///
38+
/// use std::future::{ready, Ready, IntoFuture};
39+
///
40+
/// /// Eventually multiply two numbers
41+
/// pub struct Multiply {
42+
/// num: u16,
43+
/// factor: u16,
44+
/// }
45+
///
46+
/// impl Multiply {
47+
/// /// Construct a new instance of `Multiply`.
48+
/// pub fn new(num: u16, factor: u16) -> Self {
49+
/// Self { num, factor }
50+
/// }
51+
///
52+
/// /// Set the number to multiply by the factor.
53+
/// pub fn number(mut self, num: u16) -> Self {
54+
/// self.num = num;
55+
/// self
56+
/// }
57+
///
58+
/// /// Set the factor to multiply the number with.
59+
/// pub fn factor(mut self, factor: u16) -> Self {
60+
/// self.factor = factor;
61+
/// self
62+
/// }
63+
/// }
64+
///
65+
/// impl IntoFuture for Multiply {
66+
/// type Output = u16;
67+
/// type IntoFuture = Ready<Self::Output>;
68+
///
69+
/// fn into_future(self) -> Self::IntoFuture {
70+
/// ready(self.num * self.factor)
71+
/// }
72+
/// }
73+
///
74+
/// // NOTE: Rust does not yet have an `async fn main` function, that functionality
75+
/// // currently only exists in the ecosystem.
76+
/// async fn run() {
77+
/// let num = Multiply::new(0, 0) // initialize the builder to number: 0, factor: 0
78+
/// .number(2) // change the number to 2
79+
/// .factor(2) // change the factor to 2
80+
/// .await; // convert to future and .await
81+
///
82+
/// assert_eq!(num, 4);
83+
/// }
84+
/// ```
85+
///
86+
/// # Usage in trait bounds
87+
///
88+
/// Using `IntoFuture` in trait bounds allows a function to be generic over both
89+
/// `Future` and `IntoFuture`. This is convenient for users of the function, so
90+
/// when they are using it they don't have to make an extra call to
91+
/// `IntoFuture::into_future` to obtain an instance of `Future`:
92+
///
93+
/// ```rust
94+
/// #![feature(into_future)]
95+
///
96+
/// use std::future::IntoFuture;
97+
///
98+
/// /// Convert the output of a future to a string.
99+
/// async fn fut_to_string<Fut>(fut: Fut) -> String
100+
/// where
101+
/// Fut: IntoFuture,
102+
/// Fut::Output: std::fmt::Debug,
103+
/// {
104+
/// format!("{:?}", fut.await)
105+
/// }
106+
/// ```
4107
#[unstable(feature = "into_future", issue = "67644")]
5108
pub trait IntoFuture {
6109
/// The output that the future will produce on completion.
@@ -12,6 +115,22 @@ pub trait IntoFuture {
12115
type IntoFuture: Future<Output = Self::Output>;
13116

14117
/// Creates a future from a value.
118+
///
119+
/// # Examples
120+
///
121+
/// Basic usage:
122+
///
123+
/// ```no_run
124+
/// #![feature(into_future)]
125+
///
126+
/// use std::future::IntoFuture;
127+
///
128+
/// # async fn foo() {
129+
/// let v = async { "meow" };
130+
/// let mut fut = v.into_future();
131+
/// assert_eq!("meow", fut.await);
132+
/// # }
133+
/// ```
15134
#[unstable(feature = "into_future", issue = "67644")]
16135
#[lang = "into_future"]
17136
fn into_future(self) -> Self::IntoFuture;

‎library/panic_unwind/src/emcc.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,19 @@ extern "C" fn exception_cleanup(ptr: *mut libc::c_void) -> *mut libc::c_void {
105105
}
106106
}
107107

108+
// This is required by the compiler to exist (e.g., it's a lang item), but it's
109+
// never actually called by the compiler. Emscripten EH doesn't use a
110+
// personality function at all, it instead uses __cxa_find_matching_catch.
111+
// Wasm error handling would use __gxx_personality_wasm0.
108112
#[lang = "eh_personality"]
109113
unsafe extern "C" fn rust_eh_personality(
110-
version: c_int,
111-
actions: uw::_Unwind_Action,
112-
exception_class: uw::_Unwind_Exception_Class,
113-
exception_object: *mut uw::_Unwind_Exception,
114-
context: *mut uw::_Unwind_Context,
114+
_version: c_int,
115+
_actions: uw::_Unwind_Action,
116+
_exception_class: uw::_Unwind_Exception_Class,
117+
_exception_object: *mut uw::_Unwind_Exception,
118+
_context: *mut uw::_Unwind_Context,
115119
) -> uw::_Unwind_Reason_Code {
116-
__gxx_personality_v0(version, actions, exception_class, exception_object, context)
120+
core::intrinsics::abort()
117121
}
118122

119123
extern "C" {
@@ -125,11 +129,4 @@ extern "C" {
125129
tinfo: *const TypeInfo,
126130
dest: extern "C" fn(*mut libc::c_void) -> *mut libc::c_void,
127131
) -> !;
128-
fn __gxx_personality_v0(
129-
version: c_int,
130-
actions: uw::_Unwind_Action,
131-
exception_class: uw::_Unwind_Exception_Class,
132-
exception_object: *mut uw::_Unwind_Exception,
133-
context: *mut uw::_Unwind_Context,
134-
) -> uw::_Unwind_Reason_Code;
135132
}

‎library/std/src/io/impls.rs

-2
Original file line numberDiff line numberDiff line change
@@ -441,14 +441,12 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
441441
impl<A: Allocator> Write for VecDeque<u8, A> {
442442
#[inline]
443443
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
444-
self.reserve(buf.len());
445444
self.extend(buf);
446445
Ok(buf.len())
447446
}
448447

449448
#[inline]
450449
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
451-
self.reserve(buf.len());
452450
self.extend(buf);
453451
Ok(())
454452
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn a() where for<T> T: Copy {}
2+
//~^ ERROR only lifetime parameters can be used in this context
3+
4+
fn b() where for<const C: usize> [(); C]: Copy {}
5+
//~^ ERROR only lifetime parameters can be used in this context
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: only lifetime parameters can be used in this context
2+
--> $DIR/hrtb-wrong-kind.rs:1:18
3+
|
4+
LL | fn a() where for<T> T: Copy {}
5+
| ^
6+
7+
error: only lifetime parameters can be used in this context
8+
--> $DIR/hrtb-wrong-kind.rs:4:24
9+
|
10+
LL | fn b() where for<const C: usize> [(); C]: Copy {}
11+
| ^
12+
13+
error: aborting due to 2 previous errors
14+

‎src/test/ui/hrtb/hrtb-just-for-static.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn give_static() {
2424
want_hrtb::<StaticInt>() //~ ERROR
2525
}
2626

27-
// AnyInt implements Foo<&'a isize> for any 'a, so it is a match.
27+
// &'a u32 only implements Foo<&'a isize> for specific 'a, so it is an error.
2828
impl<'a> Foo<&'a isize> for &'a u32 { }
2929
fn give_some<'a>() {
3030
want_hrtb::<&'a u32>()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// check-pass
2+
#![feature(lint_reasons)]
3+
4+
#[expect(drop_bounds)]
5+
fn trigger_rustc_lints<T: Drop>() {
6+
}
7+
8+
fn main() {}

0 commit comments

Comments
 (0)
Please sign in to comment.