Skip to content

Commit

Permalink
Auto merge of #68126 - Centril:rollup-cz5u7xx, r=Centril
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - #67756 (Collector tweaks)
 - #67889 (Compile some CGUs in parallel at the start of codegen)
 - #67930 (Rename Result::as_deref_ok to as_deref)
 - #68018 (feature_gate: Remove `GateStrength`)
 - #68070 (clean up E0185 explanation)
 - #68072 (Fix ICE #68058)
 - #68114 (Don't require `allow_internal_unstable` unless `staged_api` is enabled.)
 - #68120 (Ban `...X` pats, harden tests, and improve diagnostics)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Jan 11, 2020
2 parents 543b7d9 + 4eee796 commit bfd0487
Show file tree
Hide file tree
Showing 57 changed files with 528 additions and 407 deletions.
1 change: 0 additions & 1 deletion src/libcore/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
#![feature(bound_cloned)]
#![feature(cfg_target_has_atomic)]
#![feature(concat_idents)]
#![feature(const_fn)]
#![feature(const_if_match)]
#![feature(const_panic)]
#![feature(const_fn_union)]
Expand Down
27 changes: 2 additions & 25 deletions src/libcore/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1136,7 +1136,7 @@ impl<T: Deref, E> Result<T, E> {
///
/// Leaves the original `Result` in-place, creating a new one containing a reference to the
/// `Ok` type's `Deref::Target` type.
pub fn as_deref_ok(&self) -> Result<&T::Target, &E> {
pub fn as_deref(&self) -> Result<&T::Target, &E> {
self.as_ref().map(|t| t.deref())
}
}
Expand All @@ -1152,24 +1152,13 @@ impl<T, E: Deref> Result<T, E> {
}
}

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T: Deref, E: Deref> Result<T, E> {
/// Converts from `Result<T, E>` (or `&Result<T, E>`) to `Result<&T::Target, &E::Target>`.
///
/// Leaves the original `Result` in-place, creating a new one containing a reference to both
/// the `Ok` and `Err` types' `Deref::Target` types.
pub fn as_deref(&self) -> Result<&T::Target, &E::Target> {
self.as_ref().map(|t| t.deref()).map_err(|e| e.deref())
}
}

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T: DerefMut, E> Result<T, E> {
/// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to `Result<&mut T::Target, &mut E>`.
///
/// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
/// the `Ok` type's `Deref::Target` type.
pub fn as_deref_mut_ok(&mut self) -> Result<&mut T::Target, &mut E> {
pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> {
self.as_mut().map(|t| t.deref_mut())
}
}
Expand All @@ -1185,18 +1174,6 @@ impl<T, E: DerefMut> Result<T, E> {
}
}

#[unstable(feature = "inner_deref", reason = "newly added", issue = "50264")]
impl<T: DerefMut, E: DerefMut> Result<T, E> {
/// Converts from `Result<T, E>` (or `&mut Result<T, E>`) to
/// `Result<&mut T::Target, &mut E::Target>`.
///
/// Leaves the original `Result` in-place, creating a new one containing a mutable reference to
/// both the `Ok` and `Err` types' `Deref::Target` types.
pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E::Target> {
self.as_mut().map(|t| t.deref_mut()).map_err(|e| e.deref_mut())
}
}

impl<T, E> Result<Option<T>, E> {
/// Transposes a `Result` of an `Option` into an `Option` of a `Result`.
///
Expand Down
1 change: 0 additions & 1 deletion src/libcore/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#![feature(slice_internals)]
#![feature(slice_partition_dedup)]
#![feature(int_error_matching)]
#![feature(const_fn)]
#![feature(array_value_iter)]
#![feature(iter_partition_in_place)]
#![feature(iter_is_partitioned)]
Expand Down
85 changes: 27 additions & 58 deletions src/libcore/tests/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,31 +236,17 @@ fn test_try() {

#[test]
fn test_result_as_deref() {
// &Result<T: Deref, E>::Ok(T).as_deref_ok() ->
// &Result<T: Deref, E>::Ok(T).as_deref() ->
// Result<&T::Deref::Target, &E>::Ok(&*T)
let ref_ok = &Result::Ok::<&i32, u8>(&42);
let expected_result = Result::Ok::<&i32, &u8>(&42);
assert_eq!(ref_ok.as_deref_ok(), expected_result);

let ref_ok = &Result::Ok::<String, u32>(String::from("a result"));
let expected_result = Result::Ok::<&str, &u32>("a result");
assert_eq!(ref_ok.as_deref_ok(), expected_result);

let ref_ok = &Result::Ok::<Vec<i32>, u32>(vec![1, 2, 3, 4, 5]);
let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
assert_eq!(ref_ok.as_deref_ok(), expected_result);

// &Result<T: Deref, E: Deref>::Ok(T).as_deref() ->
// Result<&T::Deref::Target, &E::Deref::Target>::Ok(&*T)
let ref_ok = &Result::Ok::<&i32, &u8>(&42);
let expected_result = Result::Ok::<&i32, &u8>(&42);
assert_eq!(ref_ok.as_deref(), expected_result);

let ref_ok = &Result::Ok::<String, &u32>(String::from("a result"));
let ref_ok = &Result::Ok::<String, u32>(String::from("a result"));
let expected_result = Result::Ok::<&str, &u32>("a result");
assert_eq!(ref_ok.as_deref(), expected_result);

let ref_ok = &Result::Ok::<Vec<i32>, &u32>(vec![1, 2, 3, 4, 5]);
let ref_ok = &Result::Ok::<Vec<i32>, u32>(vec![1, 2, 3, 4, 5]);
let expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
assert_eq!(ref_ok.as_deref(), expected_result);

Expand All @@ -281,19 +267,21 @@ fn test_result_as_deref() {
// &Result<T: Deref, E: Deref>::Err(T).as_deref_err() ->
// Result<&T, &E::Deref::Target>::Err(&*E)
let ref_err = &Result::Err::<&u8, &i32>(&41);
let expected_result = Result::Err::<&u8, &i32>(&41);
let expected_result = Result::Err::<&u8, &&i32>(&&41);
assert_eq!(ref_err.as_deref(), expected_result);

let ref_err = &Result::Err::<&u32, String>(String::from("an error"));
let expected_result = Result::Err::<&u32, &str>("an error");
let s = String::from("an error");
let ref_err = &Result::Err::<&u32, String>(s.clone());
let expected_result = Result::Err::<&u32, &String>(&s);
assert_eq!(ref_err.as_deref(), expected_result);

let ref_err = &Result::Err::<&u32, Vec<i32>>(vec![5, 4, 3, 2, 1]);
let expected_result = Result::Err::<&u32, &[i32]>([5, 4, 3, 2, 1].as_slice());
let v = vec![5, 4, 3, 2, 1];
let ref_err = &Result::Err::<&u32, Vec<i32>>(v.clone());
let expected_result = Result::Err::<&u32, &Vec<i32>>(&v);
assert_eq!(ref_err.as_deref(), expected_result);

// The following cases test calling `as_deref_*` with the wrong variant (i.e.
// `as_deref_ok()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`.
// `as_deref()` with a `Result::Err()`, or `as_deref_err()` with a `Result::Ok()`.
// While uncommon, these cases are supported to ensure that an `as_deref_*`
// call can still be made even when one of the Result types does not implement
// `Deref` (for example, std::io::Error).
Expand All @@ -312,56 +300,38 @@ fn test_result_as_deref() {
let expected_result = Result::Ok::<&[i32; 5], &u32>(&[1, 2, 3, 4, 5]);
assert_eq!(ref_ok.as_deref_err(), expected_result);

// &Result<T: Deref, E>::Err(E).as_deref_ok() ->
// &Result<T: Deref, E>::Err(E).as_deref() ->
// Result<&T::Deref::Target, &E>::Err(&E)
let ref_err = &Result::Err::<&u8, i32>(41);
let expected_result = Result::Err::<&u8, &i32>(&41);
assert_eq!(ref_err.as_deref_ok(), expected_result);
assert_eq!(ref_err.as_deref(), expected_result);

let ref_err = &Result::Err::<&u32, &str>("an error");
let expected_result = Result::Err::<&u32, &&str>(&"an error");
assert_eq!(ref_err.as_deref_ok(), expected_result);
assert_eq!(ref_err.as_deref(), expected_result);

let ref_err = &Result::Err::<&u32, [i32; 5]>([5, 4, 3, 2, 1]);
let expected_result = Result::Err::<&u32, &[i32; 5]>(&[5, 4, 3, 2, 1]);
assert_eq!(ref_err.as_deref_ok(), expected_result);
assert_eq!(ref_err.as_deref(), expected_result);
}

#[test]
fn test_result_as_deref_mut() {
// &mut Result<T: Deref, E>::Ok(T).as_deref_mut_ok() ->
// &mut Result<T: Deref, E>::Ok(T).as_deref_mut() ->
// Result<&mut T::Deref::Target, &mut E>::Ok(&mut *T)
let mut val = 42;
let mut expected_val = 42;
let mut_ok = &mut Result::Ok::<&mut i32, u8>(&mut val);
let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);

let mut expected_string = String::from("a result");
let mut_ok = &mut Result::Ok::<String, u32>(expected_string.clone());
let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut());
assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);

let mut expected_vec = vec![1, 2, 3, 4, 5];
let mut_ok = &mut Result::Ok::<Vec<i32>, u32>(expected_vec.clone());
let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
assert_eq!(mut_ok.as_deref_mut_ok(), expected_result);

// &mut Result<T: Deref, E: Deref>::Ok(T).as_deref_mut() ->
// Result<&mut T::Deref::Target, &mut E::Deref::Target>::Ok(&mut *T)
let mut val = 42;
let mut expected_val = 42;
let mut_ok = &mut Result::Ok::<&mut i32, &mut u8>(&mut val);
let expected_result = Result::Ok::<&mut i32, &mut u8>(&mut expected_val);
assert_eq!(mut_ok.as_deref_mut(), expected_result);

let mut expected_string = String::from("a result");
let mut_ok = &mut Result::Ok::<String, &mut u32>(expected_string.clone());
let mut_ok = &mut Result::Ok::<String, u32>(expected_string.clone());
let expected_result = Result::Ok::<&mut str, &mut u32>(expected_string.deref_mut());
assert_eq!(mut_ok.as_deref_mut(), expected_result);

let mut expected_vec = vec![1, 2, 3, 4, 5];
let mut_ok = &mut Result::Ok::<Vec<i32>, &mut u32>(expected_vec.clone());
let mut_ok = &mut Result::Ok::<Vec<i32>, u32>(expected_vec.clone());
let expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
assert_eq!(mut_ok.as_deref_mut(), expected_result);

Expand All @@ -386,23 +356,22 @@ fn test_result_as_deref_mut() {
// &mut Result<T: Deref, E: Deref>::Err(T).as_deref_mut_err() ->
// Result<&mut T, &mut E::Deref::Target>::Err(&mut *E)
let mut val = 41;
let mut expected_val = 41;
let mut_err = &mut Result::Err::<&mut u8, &mut i32>(&mut val);
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
let mut_err = &mut Result::Err::<&mut u8, i32>(val);
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut val);
assert_eq!(mut_err.as_deref_mut(), expected_result);

let mut expected_string = String::from("an error");
let mut_err = &mut Result::Err::<&mut u32, String>(expected_string.clone());
let expected_result = Result::Err::<&mut u32, &mut str>(expected_string.as_mut_str());
let expected_result = Result::Err::<&mut u32, &mut String>(&mut expected_string);
assert_eq!(mut_err.as_deref_mut(), expected_result);

let mut expected_vec = vec![5, 4, 3, 2, 1];
let mut_err = &mut Result::Err::<&mut u32, Vec<i32>>(expected_vec.clone());
let expected_result = Result::Err::<&mut u32, &mut [i32]>(expected_vec.as_mut_slice());
let expected_result = Result::Err::<&mut u32, &mut Vec<i32>>(&mut expected_vec);
assert_eq!(mut_err.as_deref_mut(), expected_result);

// The following cases test calling `as_deref_mut_*` with the wrong variant (i.e.
// `as_deref_mut_ok()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`.
// `as_deref_mut()` with a `Result::Err()`, or `as_deref_mut_err()` with a `Result::Ok()`.
// While uncommon, these cases are supported to ensure that an `as_deref_mut_*`
// call can still be made even when one of the Result types does not implement
// `Deref` (for example, std::io::Error).
Expand All @@ -426,22 +395,22 @@ fn test_result_as_deref_mut() {
let expected_result = Result::Ok::<&mut [i32; 5], &mut u32>(&mut expected_arr);
assert_eq!(mut_ok.as_deref_mut_err(), expected_result);

// &mut Result<T: Deref, E>::Err(E).as_deref_mut_ok() ->
// &mut Result<T: Deref, E>::Err(E).as_deref_mut() ->
// Result<&mut T::Deref::Target, &mut E>::Err(&mut E)
let mut expected_val = 41;
let mut_err = &mut Result::Err::<&mut u8, i32>(expected_val.clone());
let expected_result = Result::Err::<&mut u8, &mut i32>(&mut expected_val);
assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
assert_eq!(mut_err.as_deref_mut(), expected_result);

let string = String::from("an error");
let expected_string = string.clone();
let mut ref_str = expected_string.as_ref();
let mut_err = &mut Result::Err::<&mut u32, &str>(string.as_str());
let expected_result = Result::Err::<&mut u32, &mut &str>(&mut ref_str);
assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
assert_eq!(mut_err.as_deref_mut(), expected_result);

let mut expected_arr = [5, 4, 3, 2, 1];
let mut_err = &mut Result::Err::<&mut u32, [i32; 5]>(expected_arr.clone());
let expected_result = Result::Err::<&mut u32, &mut [i32; 5]>(&mut expected_arr);
assert_eq!(mut_err.as_deref_mut_ok(), expected_result);
assert_eq!(mut_err.as_deref_mut(), expected_result);
}
1 change: 0 additions & 1 deletion src/libproc_macro/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#![feature(nll)]
#![feature(staged_api)]
#![feature(allow_internal_unstable)]
#![feature(const_fn)]
#![feature(decl_macro)]
#![feature(extern_types)]
#![feature(in_band_lifetimes)]
Expand Down
1 change: 0 additions & 1 deletion src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#![feature(bool_to_option)]
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(const_fn)]
#![feature(const_transmute)]
#![feature(core_intrinsics)]
#![feature(drain_filter)]
Expand Down
7 changes: 6 additions & 1 deletion src/librustc_ast_lowering/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
ExprKind::Mac(_) => panic!("Shouldn't exist here"),
};

hir::Expr { hir_id: self.lower_node_id(e.id), kind, span: e.span, attrs: e.attrs.clone() }
hir::Expr {
hir_id: self.lower_node_id(e.id),
kind,
span: e.span,
attrs: e.attrs.iter().map(|a| self.lower_attr(a)).collect::<Vec<_>>().into(),
}
}

fn lower_unop(&mut self, u: UnOp) -> hir::UnOp {
Expand Down
47 changes: 10 additions & 37 deletions src/librustc_ast_passes/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,25 @@ use rustc_span::Span;
use syntax::ast::{self, AssocTyConstraint, AssocTyConstraintKind, NodeId};
use syntax::ast::{GenericParam, GenericParamKind, PatKind, RangeEnd, VariantData};
use syntax::attr;
use syntax::sess::{feature_err, leveled_feature_err, GateStrength, ParseSess};
use syntax::sess::{feature_err, feature_err_issue, ParseSess};
use syntax::visit::{self, FnKind, Visitor};

use log::debug;

macro_rules! gate_feature_fn {
($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{
let (cx, has_feature, span, name, explain, level) =
(&*$cx, $has_feature, $span, $name, $explain, $level);
($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr) => {{
let (cx, has_feature, span, name, explain) = (&*$cx, $has_feature, $span, $name, $explain);
let has_feature: bool = has_feature(&$cx.features);
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature);
if !has_feature && !span.allows_unstable($name) {
leveled_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain, level)
.emit();
feature_err_issue(cx.parse_sess, name, span, GateIssue::Language, explain).emit();
}
}};
}

macro_rules! gate_feature {
macro_rules! gate_feature_post {
($cx: expr, $feature: ident, $span: expr, $explain: expr) => {
gate_feature_fn!(
$cx,
|x: &Features| x.$feature,
$span,
sym::$feature,
$explain,
GateStrength::Hard
)
};
($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {
gate_feature_fn!($cx, |x: &Features| x.$feature, $span, sym::$feature, $explain, $level)
gate_feature_fn!($cx, |x: &Features| x.$feature, $span, sym::$feature, $explain)
};
}

Expand All @@ -51,21 +39,6 @@ struct PostExpansionVisitor<'a> {
features: &'a Features,
}

macro_rules! gate_feature_post {
($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{
let (cx, span) = ($cx, $span);
if !span.allows_unstable(sym::$feature) {
gate_feature!(cx, $feature, span, $explain)
}
}};
($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{
let (cx, span) = ($cx, $span);
if !span.allows_unstable(sym::$feature) {
gate_feature!(cx, $feature, span, $explain, $level)
}
}};
}

impl<'a> PostExpansionVisitor<'a> {
fn check_abi(&self, abi: ast::StrLit) {
let ast::StrLit { symbol_unescaped, span, .. } = abi;
Expand Down Expand Up @@ -257,15 +230,15 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).map(|a| **a);
// Check feature gates for built-in attributes.
if let Some((.., AttributeGate::Gated(_, name, descr, has_feature))) = attr_info {
gate_feature_fn!(self, has_feature, attr.span, name, descr, GateStrength::Hard);
gate_feature_fn!(self, has_feature, attr.span, name, descr);
}
// Check unstable flavors of the `#[doc]` attribute.
if attr.check_name(sym::doc) {
for nested_meta in attr.meta_item_list().unwrap_or_default() {
macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
$(if nested_meta.check_name(sym::$name) {
let msg = concat!("`#[doc(", stringify!($name), ")]` is experimental");
gate_feature!(self, $feature, attr.span, msg);
gate_feature_post!(self, $feature, attr.span, msg);
})*
}}

Expand Down Expand Up @@ -666,7 +639,7 @@ pub fn check_crate(
macro_rules! gate_all {
($gate:ident, $msg:literal) => {
for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
gate_feature!(&visitor, $gate, *span, $msg);
gate_feature_post!(&visitor, $gate, *span, $msg);
}
};
}
Expand All @@ -688,7 +661,7 @@ pub fn check_crate(
// disabling these uses of early feature-gatings.
if false {
for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
gate_feature!(&visitor, $gate, *span, $msg);
gate_feature_post!(&visitor, $gate, *span, $msg);
}
}
};
Expand Down
Loading

0 comments on commit bfd0487

Please sign in to comment.