1
Fork 0

Auto merge of #75421 - tmandry:rollup-ctzmzn1, r=tmandry

Rollup of 7 pull requests

Successful merges:

 - #75036 (Prefer pattern matching over indexing)
 - #75378 (Introduce `rustc_lexer::is_ident` and use it in couple of places)
 - #75393 (Fully handle "?" shortcut)
 - #75403 (Update comment for function)
 - #75407 (Requested changes to [*mut T|*const T]::set_ptr_value)
 - #75408 (Update MinGW comments in ci.yml)
 - #75409 (Fix range term in alloc vec doc)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-08-11 19:29:38 +00:00
commit e5e33ebd2b
15 changed files with 88 additions and 57 deletions

View file

@ -3257,6 +3257,7 @@ dependencies = [
"rustc_data_structures", "rustc_data_structures",
"rustc_errors", "rustc_errors",
"rustc_feature", "rustc_feature",
"rustc_lexer",
"rustc_macros", "rustc_macros",
"rustc_serialize", "rustc_serialize",
"rustc_session", "rustc_session",

View file

@ -2269,7 +2269,7 @@ impl<T> Vec<T> {
/// with the given `replace_with` iterator and yields the removed items. /// with the given `replace_with` iterator and yields the removed items.
/// `replace_with` does not need to be the same length as `range`. /// `replace_with` does not need to be the same length as `range`.
/// ///
/// The element range is removed even if the iterator is not consumed until the end. /// `range` is removed even if the iterator is not consumed until the end.
/// ///
/// It is unspecified how many elements are removed from the vector /// It is unspecified how many elements are removed from the vector
/// if the `Splice` value is leaked. /// if the `Splice` value is leaked.

View file

@ -662,6 +662,11 @@ impl<T: ?Sized> *const T {
/// will only affect the pointer part, whereas for (thin) pointers to /// will only affect the pointer part, whereas for (thin) pointers to
/// sized types, this has the same effect as a simple assignment. /// sized types, this has the same effect as a simple assignment.
/// ///
/// The resulting pointer will have provenance of `val`, i.e., for a fat
/// pointer, this operation is semantically the same as creating a new
/// fat pointer with the data pointer value of `val` but the metadata of
/// `self`.
///
/// # Examples /// # Examples
/// ///
/// This function is primarily useful for allowing byte-wise pointer /// This function is primarily useful for allowing byte-wise pointer
@ -673,13 +678,17 @@ impl<T: ?Sized> *const T {
/// let arr: [i32; 3] = [1, 2, 3]; /// let arr: [i32; 3] = [1, 2, 3];
/// let mut ptr = &arr[0] as *const dyn Debug; /// let mut ptr = &arr[0] as *const dyn Debug;
/// let thin = ptr as *const u8; /// let thin = ptr as *const u8;
/// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() }); /// unsafe {
/// assert_eq!(unsafe { *(ptr as *const i32) }, 3); /// ptr = ptr.set_ptr_value(thin.add(8));
/// # assert_eq!(*(ptr as *const i32), 3);
/// println!("{:?}", &*ptr); // will print "3"
/// }
/// ``` /// ```
#[unstable(feature = "set_ptr_value", issue = "75091")] #[unstable(feature = "set_ptr_value", issue = "75091")]
#[must_use = "returns a new pointer rather than modifying its argument"]
#[inline] #[inline]
pub fn set_ptr_value(mut self, val: *const ()) -> Self { pub fn set_ptr_value(mut self, val: *const u8) -> Self {
let thin = &mut self as *mut *const T as *mut *const (); let thin = &mut self as *mut *const T as *mut *const u8;
// SAFETY: In case of a thin pointer, this operations is identical // SAFETY: In case of a thin pointer, this operations is identical
// to a simple assignment. In case of a fat pointer, with the current // to a simple assignment. In case of a fat pointer, with the current
// fat pointer layout implementation, the first field of such a // fat pointer layout implementation, the first field of such a

View file

@ -718,6 +718,11 @@ impl<T: ?Sized> *mut T {
/// will only affect the pointer part, whereas for (thin) pointers to /// will only affect the pointer part, whereas for (thin) pointers to
/// sized types, this has the same effect as a simple assignment. /// sized types, this has the same effect as a simple assignment.
/// ///
/// The resulting pointer will have provenance of `val`, i.e., for a fat
/// pointer, this operation is semantically the same as creating a new
/// fat pointer with the data pointer value of `val` but the metadata of
/// `self`.
///
/// # Examples /// # Examples
/// ///
/// This function is primarily useful for allowing byte-wise pointer /// This function is primarily useful for allowing byte-wise pointer
@ -729,13 +734,17 @@ impl<T: ?Sized> *mut T {
/// let mut arr: [i32; 3] = [1, 2, 3]; /// let mut arr: [i32; 3] = [1, 2, 3];
/// let mut ptr = &mut arr[0] as *mut dyn Debug; /// let mut ptr = &mut arr[0] as *mut dyn Debug;
/// let thin = ptr as *mut u8; /// let thin = ptr as *mut u8;
/// ptr = ptr.set_ptr_value(unsafe { thin.add(8).cast() }); /// unsafe {
/// assert_eq!(unsafe { *(ptr as *mut i32) }, 3); /// ptr = ptr.set_ptr_value(thin.add(8));
/// # assert_eq!(*(ptr as *mut i32), 3);
/// println!("{:?}", &*ptr); // will print "3"
/// }
/// ``` /// ```
#[unstable(feature = "set_ptr_value", issue = "75091")] #[unstable(feature = "set_ptr_value", issue = "75091")]
#[must_use = "returns a new pointer rather than modifying its argument"]
#[inline] #[inline]
pub fn set_ptr_value(mut self, val: *mut ()) -> Self { pub fn set_ptr_value(mut self, val: *mut u8) -> Self {
let thin = &mut self as *mut *mut T as *mut *mut (); let thin = &mut self as *mut *mut T as *mut *mut u8;
// SAFETY: In case of a thin pointer, this operations is identical // SAFETY: In case of a thin pointer, this operations is identical
// to a simple assignment. In case of a fat pointer, with the current // to a simple assignment. In case of a fat pointer, with the current
// fat pointer layout implementation, the first field of such a // fat pointer layout implementation, the first field of such a

View file

@ -767,10 +767,8 @@ impl Ipv4Addr {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn to_ipv6_compatible(&self) -> Ipv6Addr { pub fn to_ipv6_compatible(&self) -> Ipv6Addr {
let octets = self.octets(); let [a, b, c, d] = self.octets();
Ipv6Addr::from([ Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a, b, c, d])
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, octets[0], octets[1], octets[2], octets[3],
])
} }
/// Converts this address to an IPv4-mapped [IPv6 address]. /// Converts this address to an IPv4-mapped [IPv6 address].
@ -789,10 +787,8 @@ impl Ipv4Addr {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn to_ipv6_mapped(&self) -> Ipv6Addr { pub fn to_ipv6_mapped(&self) -> Ipv6Addr {
let octets = self.octets(); let [a, b, c, d] = self.octets();
Ipv6Addr::from([ Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, a, b, c, d])
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, octets[0], octets[1], octets[2], octets[3],
])
} }
} }
@ -1498,11 +1494,12 @@ impl Ipv6Addr {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn to_ipv4(&self) -> Option<Ipv4Addr> { pub fn to_ipv4(&self) -> Option<Ipv4Addr> {
match self.segments() { if let [0, 0, 0, 0, 0, 0 | 0xffff, ab, cd] = self.segments() {
[0, 0, 0, 0, 0, f, g, h] if f == 0 || f == 0xffff => { let [a, b] = ab.to_be_bytes();
Some(Ipv4Addr::new((g >> 8) as u8, g as u8, (h >> 8) as u8, h as u8)) let [c, d] = cd.to_be_bytes();
} Some(Ipv4Addr::new(a, b, c, d))
_ => None, } else {
None
} }
} }

View file

@ -490,15 +490,17 @@ jobs:
# 32/64-bit MinGW builds. # 32/64-bit MinGW builds.
# #
# We are using MinGW with posix threads since LLVM does not compile with # We are using MinGW with POSIX threads since LLVM requires
# the win32 threads version due to missing support for C++'s std::thread. # C++'s std::thread which is disabled in libstdc++ with win32 threads.
# FIXME: Libc++ doesn't have this limitation so we can avoid
# winpthreads if we switch to it.
# #
# Instead of relying on the MinGW version installed on appveryor we download # Instead of relying on the MinGW version installed on CI we download
# and install one ourselves so we won't be surprised by changes to appveyor's # and install one ourselves so we won't be surprised by changes to CI's
# build image. # build image.
# #
# Finally, note that the downloads below are all in the `rust-lang-ci` S3 # Finally, note that the downloads below are all in the `rust-lang-ci` S3
# bucket, but they cleraly didn't originate there! The downloads originally # bucket, but they clearly didn't originate there! The downloads originally
# came from the mingw-w64 SourceForge download site. Unfortunately # came from the mingw-w64 SourceForge download site. Unfortunately
# SourceForge is notoriously flaky, so we mirror it on our own infrastructure. # SourceForge is notoriously flaky, so we mirror it on our own infrastructure.

View file

@ -16,6 +16,7 @@ rustc_errors = { path = "../librustc_errors" }
rustc_span = { path = "../librustc_span" } rustc_span = { path = "../librustc_span" }
rustc_data_structures = { path = "../librustc_data_structures" } rustc_data_structures = { path = "../librustc_data_structures" }
rustc_feature = { path = "../librustc_feature" } rustc_feature = { path = "../librustc_feature" }
rustc_lexer = { path = "../librustc_lexer" }
rustc_macros = { path = "../librustc_macros" } rustc_macros = { path = "../librustc_macros" }
rustc_session = { path = "../librustc_session" } rustc_session = { path = "../librustc_session" }
rustc_ast = { path = "../librustc_ast" } rustc_ast = { path = "../librustc_ast" }

View file

@ -20,6 +20,7 @@ enum AttrError {
MultipleItem(String), MultipleItem(String),
UnknownMetaItem(String, &'static [&'static str]), UnknownMetaItem(String, &'static [&'static str]),
MissingSince, MissingSince,
NonIdentFeature,
MissingFeature, MissingFeature,
MultipleStabilityLevels, MultipleStabilityLevels,
UnsupportedLiteral(&'static str, /* is_bytestr */ bool), UnsupportedLiteral(&'static str, /* is_bytestr */ bool),
@ -40,6 +41,9 @@ fn handle_errors(sess: &ParseSess, span: Span, error: AttrError) {
AttrError::MissingSince => { AttrError::MissingSince => {
struct_span_err!(diag, span, E0542, "missing 'since'").emit(); struct_span_err!(diag, span, E0542, "missing 'since'").emit();
} }
AttrError::NonIdentFeature => {
struct_span_err!(diag, span, E0546, "'feature' is not an identifier").emit();
}
AttrError::MissingFeature => { AttrError::MissingFeature => {
struct_span_err!(diag, span, E0546, "missing 'feature'").emit(); struct_span_err!(diag, span, E0546, "missing 'feature'").emit();
} }
@ -344,6 +348,14 @@ where
match (feature, reason, issue) { match (feature, reason, issue) {
(Some(feature), reason, Some(_)) => { (Some(feature), reason, Some(_)) => {
if !rustc_lexer::is_ident(&feature.as_str()) {
handle_errors(
&sess.parse_sess,
attr.span,
AttrError::NonIdentFeature,
);
continue;
}
let level = Unstable { reason, issue: issue_num, is_soft }; let level = Unstable { reason, issue: issue_num, is_soft };
if sym::unstable == meta_name { if sym::unstable == meta_name {
stab = Some(Stability { level, feature }); stab = Some(Stability { level, feature });

View file

@ -319,18 +319,10 @@ pub struct Ident {
} }
impl Ident { impl Ident {
fn is_valid(string: &str) -> bool {
let mut chars = string.chars();
if let Some(start) = chars.next() {
rustc_lexer::is_id_start(start) && chars.all(rustc_lexer::is_id_continue)
} else {
false
}
}
fn new(sess: &ParseSess, sym: Symbol, is_raw: bool, span: Span) -> Ident { fn new(sess: &ParseSess, sym: Symbol, is_raw: bool, span: Span) -> Ident {
let sym = nfc_normalize(&sym.as_str()); let sym = nfc_normalize(&sym.as_str());
let string = sym.as_str(); let string = sym.as_str();
if !Self::is_valid(&string) { if !rustc_lexer::is_ident(&string) {
panic!("`{:?}` is not a valid identifier", string) panic!("`{:?}` is not a valid identifier", string)
} }
if is_raw && !sym.can_be_raw() { if is_raw && !sym.can_be_raw() {

View file

@ -274,6 +274,16 @@ pub fn is_id_continue(c: char) -> bool {
|| (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c)) || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
} }
/// The passed string is lexically an identifier.
pub fn is_ident(string: &str) -> bool {
let mut chars = string.chars();
if let Some(start) = chars.next() {
is_id_start(start) && chars.all(is_id_continue)
} else {
false
}
}
impl Cursor<'_> { impl Cursor<'_> {
/// Parses a token from the input string. /// Parses a token from the input string.
fn advance_token(&mut self) -> Token { fn advance_token(&mut self) -> Token {

View file

@ -219,7 +219,7 @@ pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> LintSt
/// Tell the `LintStore` about all the built-in lints (the ones /// Tell the `LintStore` about all the built-in lints (the ones
/// defined in this crate and the ones defined in /// defined in this crate and the ones defined in
/// `rustc::lint::builtin`). /// `rustc_session::lint::builtin`).
fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) { fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
macro_rules! add_lint_group { macro_rules! add_lint_group {
($name:expr, $($lint:ident),*) => ( ($name:expr, $($lint:ident),*) => (

View file

@ -2358,7 +2358,7 @@ impl Clean<Stability> for attr::Stability {
fn clean(&self, _: &DocContext<'_>) -> Stability { fn clean(&self, _: &DocContext<'_>) -> Stability {
Stability { Stability {
level: stability::StabilityLevel::from_attr_level(&self.level), level: stability::StabilityLevel::from_attr_level(&self.level),
feature: Some(self.feature.to_string()).filter(|f| !f.is_empty()), feature: self.feature.to_string(),
since: match self.level { since: match self.level {
attr::Stable { ref since } => since.to_string(), attr::Stable { ref since } => since.to_string(),
_ => String::new(), _ => String::new(),

View file

@ -1525,7 +1525,7 @@ pub struct ProcMacro {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Stability { pub struct Stability {
pub level: stability::StabilityLevel, pub level: stability::StabilityLevel,
pub feature: Option<String>, pub feature: String,
pub since: String, pub since: String,
pub unstable_reason: Option<String>, pub unstable_reason: Option<String>,
pub issue: Option<NonZeroU32>, pub issue: Option<NonZeroU32>,

View file

@ -2144,7 +2144,7 @@ fn stability_tags(item: &clean::Item) -> String {
if item if item
.stability .stability
.as_ref() .as_ref()
.map(|s| s.level == stability::Unstable && s.feature.as_deref() != Some("rustc_private")) .map(|s| s.level == stability::Unstable && s.feature != "rustc_private")
== Some(true) == Some(true)
{ {
tags += &tag_html("unstable", "Experimental"); tags += &tag_html("unstable", "Experimental");
@ -2195,14 +2195,15 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
// Render unstable items. But don't render "rustc_private" crates (internal compiler crates). // Render unstable items. But don't render "rustc_private" crates (internal compiler crates).
// Those crates are permanently unstable so it makes no sense to render "unstable" everywhere. // Those crates are permanently unstable so it makes no sense to render "unstable" everywhere.
if let Some(stab) = item.stability.as_ref().filter(|stab| { if let Some(stab) = item
stab.level == stability::Unstable && stab.feature.as_deref() != Some("rustc_private") .stability
}) { .as_ref()
.filter(|stab| stab.level == stability::Unstable && stab.feature != "rustc_private")
{
let mut message = let mut message =
"<span class='emoji'>🔬</span> This is a nightly-only experimental API.".to_owned(); "<span class='emoji'>🔬</span> This is a nightly-only experimental API.".to_owned();
if let Some(feature) = stab.feature.as_deref() { let mut feature = format!("<code>{}</code>", Escape(&stab.feature));
let mut feature = format!("<code>{}</code>", Escape(&feature));
if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) { if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, stab.issue) {
feature.push_str(&format!( feature.push_str(&format!(
"&nbsp;<a href=\"{url}{issue}\">#{issue}</a>", "&nbsp;<a href=\"{url}{issue}\">#{issue}</a>",
@ -2212,7 +2213,6 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
} }
message.push_str(&format!(" ({})", feature)); message.push_str(&format!(" ({})", feature));
}
if let Some(unstable_reason) = &stab.unstable_reason { if let Some(unstable_reason) = &stab.unstable_reason {
let mut ids = cx.id_map.borrow_mut(); let mut ids = cx.id_map.borrow_mut();

View file

@ -408,9 +408,7 @@ function defocusSearchBar() {
break; break;
case "?": case "?":
if (ev.shiftKey) {
displayHelp(true, ev); displayHelp(true, ev);
}
break; break;
} }
} }