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 7 pull requests #73733

Closed
wants to merge 15 commits into from
Closed
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
2 changes: 0 additions & 2 deletions src/libcore/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ impl<T: ?Sized> *const T {
/// differently have not been explored. This method should not be used to introduce such
/// differences, and it should also not be stabilized before we have a better understanding
/// of this issue.
/// ```
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
Expand Down Expand Up @@ -349,7 +348,6 @@ impl<T: ?Sized> *const T {
/// differently have not been explored. This method should not be used to introduce such
/// differences, and it should also not be stabilized before we have a better understanding
/// of this issue.
/// ```
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
Expand Down
2 changes: 0 additions & 2 deletions src/libcore/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,6 @@ impl<T: ?Sized> *mut T {
/// differently have not been explored. This method should not be used to introduce such
/// differences, and it should also not be stabilized before we have a better understanding
/// of this issue.
/// ```
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
Expand Down Expand Up @@ -327,7 +326,6 @@ impl<T: ?Sized> *mut T {
/// differently have not been explored. This method should not be used to introduce such
/// differences, and it should also not be stabilized before we have a better understanding
/// of this issue.
/// ```
#[unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
#[inline]
Expand Down
82 changes: 82 additions & 0 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1459,6 +1459,86 @@ impl<T> [T] {
m >= n && needle == &self[m - n..]
}

/// Returns a subslice with the prefix removed.
///
/// Returns [`None`] if slice does not start with `prefix`.
///
/// # Examples
///
/// ```
/// #![feature(slice_strip)]
/// let v = [10, 40, 30];
/// assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30]));
/// assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30]));
/// assert_eq!(v.strip_prefix(&[50]), None);
/// assert_eq!(v.strip_prefix(&[10, 50]), None);
/// ```
///
/// This method returns the original slice if `prefix` is an empty slice:
///
/// ```
/// #![feature(slice_strip)]
/// let v = &[10, 40, 30];
/// assert_eq!(v.strip_prefix(&[]), Some(v));
/// let v: &[u8] = &[];
/// assert_eq!(v.strip_prefix(&[]), Some(v));
/// ```
#[must_use = "returns the subslice without modifying the original"]
#[unstable(feature = "slice_strip", issue = "73413")]
pub fn strip_prefix(&self, prefix: &[T]) -> Option<&[T]>
where
T: PartialEq,
{
let n = prefix.len();
if n <= self.len() {
let (head, tail) = self.split_at(n);
if head == prefix {
return Some(tail);
}
}
None
}

/// Returns a subslice with the suffix removed.
///
/// Returns [`None`] if slice does not end with `suffix`.
///
/// # Examples
///
/// ```
/// #![feature(slice_strip)]
/// let v = [10, 40, 30];
/// assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40]));
/// assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10]));
/// assert_eq!(v.strip_suffix(&[50]), None);
/// assert_eq!(v.strip_suffix(&[50, 30]), None);
/// ```
///
/// This method returns the original slice if `suffix` is an empty slice:
///
/// ```
/// #![feature(slice_strip)]
/// let v = &[10, 40, 30];
/// assert_eq!(v.strip_suffix(&[]), Some(v));
/// let v: &[u8] = &[];
/// assert_eq!(v.strip_suffix(&[]), Some(v));
/// ```
#[must_use = "returns the subslice without modifying the original"]
#[unstable(feature = "slice_strip", issue = "73413")]
pub fn strip_suffix(&self, suffix: &[T]) -> Option<&[T]>
where
T: PartialEq,
{
let (len, n) = (self.len(), suffix.len());
if n <= len {
let (head, tail) = self.split_at(len - n);
if tail == suffix {
return Some(head);
}
}
None
}

/// Binary searches this sorted slice for a given element.
///
/// If the value is found then [`Result::Ok`] is returned, containing the
Expand Down Expand Up @@ -2817,6 +2897,7 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
/// performing any bounds checking.
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
/// even if the resulting reference is not used.
///
/// [undefined behavior]: ../../reference/behavior-considered-undefined.html
#[unstable(feature = "slice_index_methods", issue = "none")]
unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
Expand All @@ -2825,6 +2906,7 @@ pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
/// performing any bounds checking.
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
/// even if the resulting reference is not used.
///
/// [undefined behavior]: ../../reference/behavior-considered-undefined.html
#[unstable(feature = "slice_index_methods", issue = "none")]
unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
Expand Down
18 changes: 11 additions & 7 deletions src/librustc_builtin_macros/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ pub fn expand_option_env<'cx>(
};

let sp = cx.with_def_site_ctxt(sp);
let e = match env::var(&var.as_str()) {
Err(..) => {
let value = env::var(&var.as_str()).ok().as_deref().map(Symbol::intern);
cx.parse_sess.env_depinfo.borrow_mut().insert((Symbol::intern(&var), value));
let e = match value {
None => {
let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp));
cx.expr_path(cx.path_all(
sp,
Expand All @@ -37,10 +39,10 @@ pub fn expand_option_env<'cx>(
))],
))
}
Ok(s) => cx.expr_call_global(
Some(value) => cx.expr_call_global(
sp,
cx.std_path(&[sym::option, sym::Option, sym::Some]),
vec![cx.expr_str(sp, Symbol::intern(&s))],
vec![cx.expr_str(sp, value)],
),
};
MacEager::expr(e)
Expand Down Expand Up @@ -78,12 +80,14 @@ pub fn expand_env<'cx>(
}

let sp = cx.with_def_site_ctxt(sp);
let e = match env::var(&*var.as_str()) {
Err(_) => {
let value = env::var(&*var.as_str()).ok().as_deref().map(Symbol::intern);
cx.parse_sess.env_depinfo.borrow_mut().insert((var, value));
let e = match value {
None => {
cx.span_err(sp, &msg.as_str());
return DummyResult::any(sp);
}
Ok(s) => cx.expr_str(sp, Symbol::intern(&s)),
Some(value) => cx.expr_str(sp, value),
};
MacEager::expr(e)
}
1 change: 1 addition & 0 deletions src/librustc_builtin_macros/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(decl_macro)]
#![feature(inner_deref)]
#![feature(nll)]
#![feature(or_patterns)]
#![feature(proc_macro_internals)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_error_codes/error_codes/E0701.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
This error indicates that a `#[non_exhaustive]` attribute was incorrectly placed
on something other than a struct or enum.

Examples of erroneous code:
Erroneous code example:

```compile_fail,E0701
#[non_exhaustive]
Expand Down
10 changes: 7 additions & 3 deletions src/librustc_errors/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ use std::path::Path;
use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream};
use termcolor::{Buffer, Color, WriteColor};

/// Default column width, used in tests and when terminal dimensions cannot be determined.
const DEFAULT_COLUMN_WIDTH: usize = 140;

/// Describes the way the content of the `rendered` field of the json output is generated
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum HumanReadableErrorType {
Expand Down Expand Up @@ -74,7 +77,8 @@ struct Margin {
pub computed_left: usize,
/// The end of the line to be displayed.
pub computed_right: usize,
/// The current width of the terminal. 140 by default and in tests.
/// The current width of the terminal. Uses value of `DEFAULT_COLUMN_WIDTH` constant by default
/// and in tests.
pub column_width: usize,
/// The end column of a span label, including the span. Doesn't account for labels not in the
/// same line as the span.
Expand Down Expand Up @@ -1414,11 +1418,11 @@ impl EmitterWriter {
let column_width = if let Some(width) = self.terminal_width {
width.saturating_sub(code_offset)
} else if self.ui_testing {
140
DEFAULT_COLUMN_WIDTH
} else {
termize::dimensions()
.map(|(w, _)| w.saturating_sub(code_offset))
.unwrap_or(usize::MAX)
.unwrap_or(DEFAULT_COLUMN_WIDTH)
};

let margin = Margin::new(
Expand Down
35 changes: 35 additions & 0 deletions src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,22 @@ fn escape_dep_filename(filename: &FileName) -> String {
filename.to_string().replace(" ", "\\ ")
}

// Makefile comments only need escaping newlines and `\`.
// The result can be unescaped by anything that can unescape `escape_default` and friends.
fn escape_dep_env(symbol: Symbol) -> String {
let s = symbol.as_str();
let mut escaped = String::with_capacity(s.len());
for c in s.chars() {
match c {
'\n' => escaped.push_str(r"\n"),
'\r' => escaped.push_str(r"\r"),
'\\' => escaped.push_str(r"\\"),
_ => escaped.push(c),
}
}
escaped
}

fn write_out_deps(
sess: &Session,
boxed_resolver: &Steal<Rc<RefCell<BoxedResolver>>>,
Expand Down Expand Up @@ -604,6 +620,25 @@ fn write_out_deps(
for path in files {
writeln!(file, "{}:", path)?;
}

// Emit special comments with information about accessed environment variables.
let env_depinfo = sess.parse_sess.env_depinfo.borrow();
if !env_depinfo.is_empty() {
let mut envs: Vec<_> = env_depinfo
.iter()
.map(|(k, v)| (escape_dep_env(*k), v.map(escape_dep_env)))
.collect();
envs.sort_unstable();
writeln!(file)?;
for (k, v) in envs {
write!(file, "# env-dep:{}", k)?;
if let Some(v) = v {
write!(file, "={}", v)?;
}
writeln!(file)?;
}
}

Ok(())
})();

Expand Down
3 changes: 3 additions & 0 deletions src/librustc_session/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ pub struct ParseSess {
pub symbol_gallery: SymbolGallery,
/// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors.
pub reached_eof: Lock<bool>,
/// Environment variables accessed during the build and their values when they exist.
pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>,
}

impl ParseSess {
Expand All @@ -160,6 +162,7 @@ impl ParseSess {
gated_spans: GatedSpans::default(),
symbol_gallery: SymbolGallery::default(),
reached_eof: Lock::new(false),
env_depinfo: Default::default(),
}
}

Expand Down
56 changes: 53 additions & 3 deletions src/libstd/keyword_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -965,11 +965,61 @@ mod move_keyword {}

#[doc(keyword = "mut")]
//
/// A mutable binding, reference, or pointer.
/// A mutable variable, reference, or pointer.
///
/// The documentation for this keyword is [not yet complete]. Pull requests welcome!
/// `mut` can be used in several situations. The first is mutable variables,
/// which can be used anywhere you can bind a value to a variable name. Some
/// examples:
///
/// [not yet complete]: https://github.com/rust-lang/rust/issues/34601
/// ```rust
/// // A mutable variable in the parameter list of a function.
/// fn foo(mut x: u8, y: u8) -> u8 {
/// x += y;
/// x
/// }
///
/// // Modifying a mutable variable.
/// # #[allow(unused_assignments)]
/// let mut a = 5;
/// a = 6;
///
/// assert_eq!(foo(3, 4), 7);
/// assert_eq!(a, 6);
/// ```
///
/// The second is mutable references. They can be created from `mut` variables
/// and must be unique: no other variables can have a mutable reference, nor a
/// shared reference.
///
/// ```rust
/// // Taking a mutable reference.
/// fn push_two(v: &mut Vec<u8>) {
/// v.push(2);
/// }
///
/// // A mutable reference cannot be taken to a non-mutable variable.
/// let mut v = vec![0, 1];
/// // Passing a mutable reference.
/// push_two(&mut v);
///
/// assert_eq!(v, vec![0, 1, 2]);
/// ```
///
/// ```rust,compile_fail,E0502
/// let mut v = vec![0, 1];
/// let mut_ref_v = &mut v;
/// ##[allow(unused)]
/// let ref_v = &v;
/// mut_ref_v.push(2);
/// ```
///
/// Mutable raw pointers work much like mutable references, with the added
/// possibility of not pointing to a valid object. The syntax is `*mut Type`.
///
/// More information on mutable references and pointers can be found in```
/// [Reference].
///
/// [Reference]: ../reference/types/pointer.html#mutable-references-mut
mod mut_keyword {}

#[doc(keyword = "pub")]
Expand Down
8 changes: 8 additions & 0 deletions src/test/run-make/env-dep-info/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
-include ../../run-make-fulldeps/tools.mk

all:
EXISTING_ENV=1 EXISTING_OPT_ENV=1 $(RUSTC) --emit dep-info main.rs
$(CGREP) "# env-dep:EXISTING_ENV=1" < $(TMPDIR)/main.d
$(CGREP) "# env-dep:EXISTING_OPT_ENV=1" < $(TMPDIR)/main.d
$(CGREP) "# env-dep:NONEXISTENT_OPT_ENV" < $(TMPDIR)/main.d
$(CGREP) "# env-dep:ESCAPE\nESCAPE\\" < $(TMPDIR)/main.d
6 changes: 6 additions & 0 deletions src/test/run-make/env-dep-info/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn main() {
env!("EXISTING_ENV");
option_env!("EXISTING_OPT_ENV");
option_env!("NONEXISTENT_OPT_ENV");
option_env!("ESCAPE\nESCAPE\\");
}