Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 6 pull requests #97939

Merged
merged 15 commits into from
Jun 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,9 @@ struct HandlerInner {
emitter: Box<dyn Emitter + sync::Send>,
delayed_span_bugs: Vec<Diagnostic>,
delayed_good_path_bugs: Vec<DelayedDiagnostic>,
/// This flag indicates that an expected diagnostic was emitted and suppressed.
/// This is used for the `delayed_good_path_bugs` check.
suppressed_expected_diag: bool,

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

for mut diag in diags.into_iter() {
diag.update_unstable_expectation_id(unstable_to_stable);
if !diags.is_empty() {
inner.suppressed_expected_diag = true;
for mut diag in diags.into_iter() {
diag.update_unstable_expectation_id(unstable_to_stable);

let stable_id = diag
.level
.get_expectation_id()
.expect("all diagnostics inside `unstable_expect_diagnostics` must have a `LintExpectationId`");
inner.fulfilled_expectations.insert(stable_id);
let stable_id = diag
.level
.get_expectation_id()
.expect("all diagnostics inside `unstable_expect_diagnostics` must have a `LintExpectationId`");
inner.fulfilled_expectations.insert(stable_id);

(*TRACK_DIAGNOSTICS)(&diag);
(*TRACK_DIAGNOSTICS)(&diag);
}
}

inner
Expand Down Expand Up @@ -1100,6 +1104,7 @@ impl HandlerInner {
(*TRACK_DIAGNOSTICS)(diagnostic);

if let Level::Expect(expectation_id) = diagnostic.level {
self.suppressed_expected_diag = true;
self.fulfilled_expectations.insert(expectation_id);
return None;
} else if diagnostic.level == Allow {
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1981,7 +1981,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
continue;
}
};
let res = Res::Def(def_kind, def_id.to_def_id());

let res = match kind {
ItemRibKind(..) | AssocItemRibKind => Res::Def(def_kind, def_id.to_def_id()),
NormalRibKind => Res::Err,
_ => bug!("Unexpected rib kind {:?}", kind),
};
self.r.record_partial_res(param.id, PartialRes::new(res));
rib.bindings.insert(ident, res);
}
Expand Down
119 changes: 119 additions & 0 deletions library/core/src/future/into_future.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,109 @@
use crate::future::Future;

/// Conversion into a `Future`.
///
/// By implementing `Intofuture` for a type, you define how it will be
/// converted to a future.
///
/// # `.await` desugaring
///
/// The `.await` keyword desugars into a call to `IntoFuture::into_future`
/// first before polling the future to completion. `IntoFuture` is implemented
/// for all `T: Future` which means the `into_future` method will be available
/// on all futures.
///
/// ```no_run
/// #![feature(into_future)]
///
/// use std::future::IntoFuture;
///
/// # async fn foo() {
/// let v = async { "meow" };
/// let mut fut = v.into_future();
/// assert_eq!("meow", fut.await);
/// # }
/// ```
///
/// # Async builders
///
/// When implementing futures manually there will often be a choice between
/// implementing `Future` or `IntoFuture` for a type. Implementing `Future` is a
/// good choice in most cases. But implementing `IntoFuture` is most useful when
/// implementing "async builder" types, which allows the type to be modified
/// multiple times before being `.await`ed.
///
/// ```rust
/// #![feature(into_future)]
///
/// use std::future::{ready, Ready, IntoFuture};
///
/// /// Eventually multiply two numbers
/// pub struct Multiply {
/// num: u16,
/// factor: u16,
/// }
///
/// impl Multiply {
/// /// Construct a new instance of `Multiply`.
/// pub fn new(num: u16, factor: u16) -> Self {
/// Self { num, factor }
/// }
///
/// /// Set the number to multiply by the factor.
/// pub fn number(mut self, num: u16) -> Self {
/// self.num = num;
/// self
/// }
///
/// /// Set the factor to multiply the number with.
/// pub fn factor(mut self, factor: u16) -> Self {
/// self.factor = factor;
/// self
/// }
/// }
///
/// impl IntoFuture for Multiply {
/// type Output = u16;
/// type IntoFuture = Ready<Self::Output>;
///
/// fn into_future(self) -> Self::IntoFuture {
/// ready(self.num * self.factor)
/// }
/// }
///
/// // NOTE: Rust does not yet have an `async fn main` function, that functionality
/// // currently only exists in the ecosystem.
/// async fn run() {
/// let num = Multiply::new(0, 0) // initialize the builder to number: 0, factor: 0
/// .number(2) // change the number to 2
/// .factor(2) // change the factor to 2
/// .await; // convert to future and .await
///
/// assert_eq!(num, 4);
/// }
/// ```
///
/// # Usage in trait bounds
///
/// Using `IntoFuture` in trait bounds allows a function to be generic over both
/// `Future` and `IntoFuture`. This is convenient for users of the function, so
/// when they are using it they don't have to make an extra call to
/// `IntoFuture::into_future` to obtain an instance of `Future`:
///
/// ```rust
/// #![feature(into_future)]
///
/// use std::future::IntoFuture;
///
/// /// Convert the output of a future to a string.
/// async fn fut_to_string<Fut>(fut: Fut) -> String
/// where
/// Fut: IntoFuture,
/// Fut::Output: std::fmt::Debug,
/// {
/// format!("{:?}", fut.await)
/// }
/// ```
#[unstable(feature = "into_future", issue = "67644")]
pub trait IntoFuture {
/// The output that the future will produce on completion.
Expand All @@ -12,6 +115,22 @@ pub trait IntoFuture {
type IntoFuture: Future<Output = Self::Output>;

/// Creates a future from a value.
///
/// # Examples
///
/// Basic usage:
///
/// ```no_run
/// #![feature(into_future)]
///
/// use std::future::IntoFuture;
///
/// # async fn foo() {
/// let v = async { "meow" };
/// let mut fut = v.into_future();
/// assert_eq!("meow", fut.await);
/// # }
/// ```
#[unstable(feature = "into_future", issue = "67644")]
#[lang = "into_future"]
fn into_future(self) -> Self::IntoFuture;
Expand Down
23 changes: 10 additions & 13 deletions library/panic_unwind/src/emcc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,19 @@ extern "C" fn exception_cleanup(ptr: *mut libc::c_void) -> *mut libc::c_void {
}
}

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

extern "C" {
Expand All @@ -125,11 +129,4 @@ extern "C" {
tinfo: *const TypeInfo,
dest: extern "C" fn(*mut libc::c_void) -> *mut libc::c_void,
) -> !;
fn __gxx_personality_v0(
version: c_int,
actions: uw::_Unwind_Action,
exception_class: uw::_Unwind_Exception_Class,
exception_object: *mut uw::_Unwind_Exception,
context: *mut uw::_Unwind_Context,
) -> uw::_Unwind_Reason_Code;
}
2 changes: 0 additions & 2 deletions library/std/src/io/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,14 +441,12 @@ impl<A: Allocator> Read for VecDeque<u8, A> {
impl<A: Allocator> Write for VecDeque<u8, A> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.reserve(buf.len());
self.extend(buf);
Ok(buf.len())
}

#[inline]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.reserve(buf.len());
self.extend(buf);
Ok(())
}
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/higher-rank-trait-bounds/hrtb-wrong-kind.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn a() where for<T> T: Copy {}
//~^ ERROR only lifetime parameters can be used in this context

fn b() where for<const C: usize> [(); C]: Copy {}
//~^ ERROR only lifetime parameters can be used in this context

fn main() {}
14 changes: 14 additions & 0 deletions src/test/ui/higher-rank-trait-bounds/hrtb-wrong-kind.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: only lifetime parameters can be used in this context
--> $DIR/hrtb-wrong-kind.rs:1:18
|
LL | fn a() where for<T> T: Copy {}
| ^

error: only lifetime parameters can be used in this context
--> $DIR/hrtb-wrong-kind.rs:4:24
|
LL | fn b() where for<const C: usize> [(); C]: Copy {}
| ^

error: aborting due to 2 previous errors

2 changes: 1 addition & 1 deletion src/test/ui/hrtb/hrtb-just-for-static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ fn give_static() {
want_hrtb::<StaticInt>() //~ ERROR
}

// AnyInt implements Foo<&'a isize> for any 'a, so it is a match.
// &'a u32 only implements Foo<&'a isize> for specific 'a, so it is an error.
impl<'a> Foo<&'a isize> for &'a u32 { }
fn give_some<'a>() {
want_hrtb::<&'a u32>()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// check-pass
#![feature(lint_reasons)]

#[expect(drop_bounds)]
fn trigger_rustc_lints<T: Drop>() {
}

fn main() {}