mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 22:12:15 +00:00
Auto merge of #103714 - matthiaskrgr:rollup-kajt3i8, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #102961 (Make `CStr::from_ptr` `const`.) - #103342 (Add test for issue 98634) - #103383 (Note scope of TAIT more accurately) - #103656 (Specialize ToString for Symbol) - #103663 (rustdoc: remove redundant CSS/DOM `div.search-container`) - #103664 (rustdoc-json-types: Improve ItemSummary::path docs) - #103704 (Add a test for TAIT used with impl/dyn Trait inside RPIT) Failed merges: - #103618 (Rename some `OwnerId` fields.) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
33b530e040
@ -93,7 +93,7 @@ hir_analysis_expected_default_return_type = expected `()` because of default ret
|
||||
hir_analysis_expected_return_type = expected `{$expected}` because of return type
|
||||
|
||||
hir_analysis_unconstrained_opaque_type = unconstrained opaque type
|
||||
.note = `{$name}` must be used in combination with a concrete type within the same module
|
||||
.note = `{$name}` must be used in combination with a concrete type within the same {$what}
|
||||
|
||||
hir_analysis_missing_type_params =
|
||||
the type {$parameterCount ->
|
||||
|
@ -701,6 +701,12 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T
|
||||
tcx.sess.emit_err(UnconstrainedOpaqueType {
|
||||
span: tcx.def_span(def_id),
|
||||
name: tcx.item_name(tcx.local_parent(def_id).to_def_id()),
|
||||
what: match tcx.hir().get(scope) {
|
||||
_ if scope == hir::CRATE_HIR_ID => "module",
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Mod(_), .. }) => "module",
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }) => "impl",
|
||||
_ => "item",
|
||||
},
|
||||
});
|
||||
return tcx.ty_error();
|
||||
};
|
||||
|
@ -143,6 +143,7 @@ pub struct UnconstrainedOpaqueType {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub name: Symbol,
|
||||
pub what: &'static str,
|
||||
}
|
||||
|
||||
pub struct MissingTypeParams {
|
||||
|
@ -1901,6 +1901,13 @@ impl fmt::Display for Symbol {
|
||||
}
|
||||
}
|
||||
|
||||
// takes advantage of `str::to_string` specialization
|
||||
impl ToString for Symbol {
|
||||
fn to_string(&self) -> String {
|
||||
self.as_str().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Encoder> Encodable<S> for Symbol {
|
||||
default fn encode(&self, s: &mut S) {
|
||||
s.emit_str(self.as_str());
|
||||
|
@ -221,9 +221,7 @@ impl CStr {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```ignore (extern-declaration)
|
||||
/// # fn main() {
|
||||
/// use std::ffi::CStr;
|
||||
/// use std::os::raw::c_char;
|
||||
/// use std::ffi::{c_char, CStr};
|
||||
///
|
||||
/// extern "C" {
|
||||
/// fn my_string() -> *const c_char;
|
||||
@ -233,14 +231,26 @@ impl CStr {
|
||||
/// let slice = CStr::from_ptr(my_string());
|
||||
/// println!("string returned: {}", slice.to_str().unwrap());
|
||||
/// }
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(const_cstr_methods)]
|
||||
///
|
||||
/// use std::ffi::{c_char, CStr};
|
||||
///
|
||||
/// const HELLO_PTR: *const c_char = {
|
||||
/// const BYTES: &[u8] = b"Hello, world!\0";
|
||||
/// BYTES.as_ptr().cast()
|
||||
/// };
|
||||
/// const HELLO: &CStr = unsafe { CStr::from_ptr(HELLO_PTR) };
|
||||
/// ```
|
||||
///
|
||||
/// [valid]: core::ptr#safety
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
|
||||
#[rustc_const_unstable(feature = "const_cstr_methods", issue = "101719")]
|
||||
pub const unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
|
||||
// SAFETY: The caller has provided a pointer that points to a valid C
|
||||
// string with a NUL terminator of size less than `isize::MAX`, whose
|
||||
// content remain valid and doesn't change for the lifetime of the
|
||||
@ -252,13 +262,29 @@ impl CStr {
|
||||
//
|
||||
// The cast from c_char to u8 is ok because a c_char is always one byte.
|
||||
unsafe {
|
||||
extern "C" {
|
||||
/// Provided by libc or compiler_builtins.
|
||||
fn strlen(s: *const c_char) -> usize;
|
||||
const fn strlen_ct(s: *const c_char) -> usize {
|
||||
let mut len = 0;
|
||||
|
||||
// SAFETY: Outer caller has provided a pointer to a valid C string.
|
||||
while unsafe { *s.add(len) } != 0 {
|
||||
len += 1;
|
||||
}
|
||||
|
||||
len
|
||||
}
|
||||
let len = strlen(ptr);
|
||||
let ptr = ptr as *const u8;
|
||||
CStr::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr, len as usize + 1))
|
||||
|
||||
fn strlen_rt(s: *const c_char) -> usize {
|
||||
extern "C" {
|
||||
/// Provided by libc or compiler_builtins.
|
||||
fn strlen(s: *const c_char) -> usize;
|
||||
}
|
||||
|
||||
// SAFETY: Outer caller has provided a pointer to a valid C string.
|
||||
unsafe { strlen(s) }
|
||||
}
|
||||
|
||||
let len = intrinsics::const_eval_select((ptr,), strlen_ct, strlen_rt);
|
||||
Self::from_bytes_with_nul_unchecked(slice::from_raw_parts(ptr.cast(), len + 1))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -683,13 +683,16 @@ nav.sub {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
nav.sub form {
|
||||
.search-form {
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: 34px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.source nav.sub {
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
.source nav.sub form {
|
||||
.source .search-form {
|
||||
margin-left: 32px;
|
||||
}
|
||||
|
||||
@ -780,11 +783,6 @@ table,
|
||||
padding-right: 1.25rem;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
height: 34px;
|
||||
}
|
||||
.search-results-title {
|
||||
margin-top: 0;
|
||||
white-space: nowrap;
|
||||
@ -860,15 +858,12 @@ so that we can apply CSS-filters to change the arrow color in themes */
|
||||
-webkit-appearance: textfield for search inputs. That
|
||||
causes rounded corners and no border on iOS Safari. */
|
||||
-webkit-appearance: none;
|
||||
/* Override Normalize.css: we have margins and do
|
||||
not want to overflow */
|
||||
box-sizing: border-box !important;
|
||||
outline: none;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 2px;
|
||||
padding: 8px;
|
||||
font-size: 1rem;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
background-color: var(--button-background-color);
|
||||
color: var(--search-color);
|
||||
}
|
||||
@ -1957,7 +1952,7 @@ in storage.js
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
nav.sub form {
|
||||
.search-form {
|
||||
align-self: stretch;
|
||||
}
|
||||
|
||||
|
@ -932,7 +932,7 @@ function loadCss(cssFileName) {
|
||||
* Hide all the popover menus.
|
||||
*/
|
||||
window.hidePopoverMenus = function() {
|
||||
onEachLazy(document.querySelectorAll(".search-container .popover"), elem => {
|
||||
onEachLazy(document.querySelectorAll(".search-form .popover"), elem => {
|
||||
elem.style.display = "none";
|
||||
});
|
||||
};
|
||||
|
@ -115,24 +115,22 @@
|
||||
</a> {#- -#}
|
||||
{%- endif -%}
|
||||
<form class="search-form"> {#- -#}
|
||||
<div class="search-container"> {#- -#}
|
||||
<span></span> {#- This empty span is a hacky fix for Safari - See #93184 -#}
|
||||
<input {# -#}
|
||||
class="search-input" {# -#}
|
||||
name="search" {# -#}
|
||||
autocomplete="off" {# -#}
|
||||
spellcheck="false" {# -#}
|
||||
placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
|
||||
type="search"> {#- -#}
|
||||
<div id="help-button" title="help" tabindex="-1"> {#- -#}
|
||||
<a href="{{page.root_path|safe}}help.html">?</a> {#- -#}
|
||||
</div> {#- -#}
|
||||
<div id="settings-menu" tabindex="-1"> {#- -#}
|
||||
<a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
|
||||
<img width="22" height="22" alt="Change settings" {# -#}
|
||||
src="{{static_root_path|safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
|
||||
</a> {#- -#}
|
||||
</div> {#- -#}
|
||||
<span></span> {#- This empty span is a hacky fix for Safari - See #93184 -#}
|
||||
<input {# -#}
|
||||
class="search-input" {# -#}
|
||||
name="search" {# -#}
|
||||
autocomplete="off" {# -#}
|
||||
spellcheck="false" {# -#}
|
||||
placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#}
|
||||
type="search"> {#- -#}
|
||||
<div id="help-button" title="help" tabindex="-1"> {#- -#}
|
||||
<a href="{{page.root_path|safe}}help.html">?</a> {#- -#}
|
||||
</div> {#- -#}
|
||||
<div id="settings-menu" tabindex="-1"> {#- -#}
|
||||
<a href="{{page.root_path|safe}}settings.html" title="settings"> {#- -#}
|
||||
<img width="22" height="22" alt="Change settings" {# -#}
|
||||
src="{{static_root_path|safe}}wheel{{page.resource_suffix}}.svg"> {#- -#}
|
||||
</a> {#- -#}
|
||||
</div> {#- -#}
|
||||
</form> {#- -#}
|
||||
</nav> {#- -#}
|
||||
|
@ -51,6 +51,11 @@ pub struct ItemSummary {
|
||||
pub crate_id: u32,
|
||||
/// The list of path components for the fully qualified path of this item (e.g.
|
||||
/// `["std", "io", "lazy", "Lazy"]` for `std::io::lazy::Lazy`).
|
||||
///
|
||||
/// Note that items can appear in multiple paths, and the one chosen is implementation
|
||||
/// defined. Currenty, this is the full path to where the item was defined. Eg
|
||||
/// [`String`] is currently `["alloc", "string", "String"]` and [`HashMap`] is
|
||||
/// `["std", "collections", "hash", "map", "HashMap"]`, but this is subject to change.
|
||||
pub path: Vec<String>,
|
||||
/// Whether this item is a struct, trait, macro, etc.
|
||||
pub kind: ItemKind,
|
||||
|
50
src/test/ui/async-await/issue-98634.rs
Normal file
50
src/test/ui/async-await/issue-98634.rs
Normal file
@ -0,0 +1,50 @@
|
||||
// edition: 2021
|
||||
|
||||
use std::{
|
||||
future::Future,
|
||||
pin::Pin,
|
||||
task::{Context, Poll, Waker},
|
||||
};
|
||||
|
||||
pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
|
||||
pub callback: F,
|
||||
}
|
||||
|
||||
impl<F> Future for StructAsync<F>
|
||||
where
|
||||
F: Fn() -> Pin<Box<dyn Future<Output = ()>>>,
|
||||
{
|
||||
type Output = ();
|
||||
|
||||
fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
async fn callback() {}
|
||||
|
||||
struct Runtime;
|
||||
|
||||
fn waker() -> &'static Waker {
|
||||
todo!()
|
||||
}
|
||||
|
||||
impl Runtime {
|
||||
#[track_caller]
|
||||
pub fn block_on<F: Future>(&self, mut future: F) -> F::Output {
|
||||
loop {
|
||||
unsafe {
|
||||
Pin::new_unchecked(&mut future).poll(&mut Context::from_waker(waker()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
Runtime.block_on(async {
|
||||
StructAsync { callback }.await;
|
||||
//~^ ERROR expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
|
||||
//~| ERROR expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
|
||||
//~| ERROR expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
|
||||
});
|
||||
}
|
60
src/test/ui/async-await/issue-98634.stderr
Normal file
60
src/test/ui/async-await/issue-98634.stderr
Normal file
@ -0,0 +1,60 @@
|
||||
error[E0271]: expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
|
||||
--> $DIR/issue-98634.rs:45:23
|
||||
|
|
||||
LL | StructAsync { callback }.await;
|
||||
| ^^^^^^^^ expected struct `Pin`, found opaque type
|
||||
|
|
||||
note: while checking the return type of the `async fn`
|
||||
--> $DIR/issue-98634.rs:24:21
|
||||
|
|
||||
LL | async fn callback() {}
|
||||
| ^ checked the `Output` of this `async fn`, found opaque type
|
||||
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
|
||||
found opaque type `impl Future<Output = ()>`
|
||||
note: required by a bound in `StructAsync`
|
||||
--> $DIR/issue-98634.rs:9:35
|
||||
|
|
||||
LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`
|
||||
|
||||
error[E0271]: expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
|
||||
--> $DIR/issue-98634.rs:45:9
|
||||
|
|
||||
LL | StructAsync { callback }.await;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Pin`, found opaque type
|
||||
|
|
||||
note: while checking the return type of the `async fn`
|
||||
--> $DIR/issue-98634.rs:24:21
|
||||
|
|
||||
LL | async fn callback() {}
|
||||
| ^ checked the `Output` of this `async fn`, found opaque type
|
||||
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
|
||||
found opaque type `impl Future<Output = ()>`
|
||||
note: required by a bound in `StructAsync`
|
||||
--> $DIR/issue-98634.rs:9:35
|
||||
|
|
||||
LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`
|
||||
|
||||
error[E0271]: expected `fn() -> impl Future<Output = ()> {callback}` to be a fn item that returns `Pin<Box<(dyn Future<Output = ()> + 'static)>>`, but it returns `impl Future<Output = ()>`
|
||||
--> $DIR/issue-98634.rs:45:33
|
||||
|
|
||||
LL | StructAsync { callback }.await;
|
||||
| ^^^^^^ expected struct `Pin`, found opaque type
|
||||
|
|
||||
note: while checking the return type of the `async fn`
|
||||
--> $DIR/issue-98634.rs:24:21
|
||||
|
|
||||
LL | async fn callback() {}
|
||||
| ^ checked the `Output` of this `async fn`, found opaque type
|
||||
= note: expected struct `Pin<Box<(dyn Future<Output = ()> + 'static)>>`
|
||||
found opaque type `impl Future<Output = ()>`
|
||||
note: required by a bound in `StructAsync`
|
||||
--> $DIR/issue-98634.rs:9:35
|
||||
|
|
||||
LL | pub struct StructAsync<F: Fn() -> Pin<Box<dyn Future<Output = ()>>>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StructAsync`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
@ -4,7 +4,7 @@ error: unconstrained opaque type
|
||||
LL | type FooFuture<'a> = impl Trait1;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: `FooFuture` must be used in combination with a concrete type within the same module
|
||||
= note: `FooFuture` must be used in combination with a concrete type within the same impl
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -67,7 +67,7 @@ error: unconstrained opaque type
|
||||
LL | type U = impl Trait;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `U` must be used in combination with a concrete type within the same module
|
||||
= note: `U` must be used in combination with a concrete type within the same impl
|
||||
|
||||
error: aborting due to 6 previous errors; 2 warnings emitted
|
||||
|
||||
|
@ -94,7 +94,7 @@ error: unconstrained opaque type
|
||||
LL | type U = impl Trait;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `U` must be used in combination with a concrete type within the same module
|
||||
= note: `U` must be used in combination with a concrete type within the same impl
|
||||
|
||||
error: aborting due to 7 previous errors; 6 warnings emitted
|
||||
|
||||
|
@ -4,7 +4,7 @@ error: unconstrained opaque type
|
||||
LL | type Future = impl Trait;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `Future` must be used in combination with a concrete type within the same module
|
||||
= note: `Future` must be used in combination with a concrete type within the same impl
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
37
src/test/ui/type-alias-impl-trait/issue-101750.rs
Normal file
37
src/test/ui/type-alias-impl-trait/issue-101750.rs
Normal file
@ -0,0 +1,37 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
// check-pass
|
||||
|
||||
trait Trait {}
|
||||
|
||||
type TAIT = impl Trait;
|
||||
|
||||
struct Concrete;
|
||||
impl Trait for Concrete {}
|
||||
|
||||
fn tait() -> TAIT {
|
||||
Concrete
|
||||
}
|
||||
|
||||
trait OuterTrait {
|
||||
type Item;
|
||||
}
|
||||
struct Dummy<T> {
|
||||
t: T,
|
||||
}
|
||||
impl<T> OuterTrait for Dummy<T> {
|
||||
type Item = T;
|
||||
}
|
||||
|
||||
fn tait_and_impl_trait() -> impl OuterTrait<Item = (TAIT, impl Trait)> {
|
||||
Dummy {
|
||||
t: (tait(), Concrete),
|
||||
}
|
||||
}
|
||||
|
||||
fn tait_and_dyn_trait() -> impl OuterTrait<Item = (TAIT, Box<dyn Trait>)> {
|
||||
let b: Box<dyn Trait> = Box::new(Concrete);
|
||||
Dummy { t: (tait(), b) }
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user