mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-10 19:16:51 +00:00
Auto merge of #68126 - Centril:rollup-cz5u7xx, r=Centril
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
This commit is contained in:
commit
bfd04876b9
@ -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)]
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
@ -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())
|
||||
}
|
||||
}
|
||||
@ -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`.
|
||||
///
|
||||
|
@ -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)]
|
||||
|
@ -236,32 +236,18 @@ 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);
|
||||
assert_eq!(ref_ok.as_deref(), 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);
|
||||
assert_eq!(ref_ok.as_deref(), 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 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 expected_result = Result::Ok::<&[i32], &u32>([1, 2, 3, 4, 5].as_slice());
|
||||
assert_eq!(ref_ok.as_deref(), expected_result);
|
||||
|
||||
// &Result<T, E: Deref>::Err(T).as_deref_err() ->
|
||||
@ -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).
|
||||
@ -312,57 +300,39 @@ 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);
|
||||
assert_eq!(mut_ok.as_deref_mut(), 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);
|
||||
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>, 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 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 expected_result = Result::Ok::<&mut [i32], &mut u32>(expected_vec.as_mut_slice());
|
||||
assert_eq!(mut_ok.as_deref_mut(), expected_result);
|
||||
|
||||
// &mut Result<T, E: Deref>::Err(T).as_deref_mut_err() ->
|
||||
@ -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).
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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)]
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
};
|
||||
}
|
||||
|
||||
@ -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;
|
||||
@ -257,7 +230,7 @@ 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) {
|
||||
@ -265,7 +238,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
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);
|
||||
})*
|
||||
}}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -13,7 +13,7 @@
|
||||
//! but one `llvm::Type` corresponds to many `Ty`s; for instance, `tup(int, int,
|
||||
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
|
||||
|
||||
use super::{LlvmCodegenBackend, ModuleLlvm};
|
||||
use super::ModuleLlvm;
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::common;
|
||||
@ -29,7 +29,6 @@ use rustc::middle::exported_symbols;
|
||||
use rustc::mir::mono::{Linkage, Visibility};
|
||||
use rustc::session::config::DebugInfo;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_codegen_ssa::back::write::submit_codegened_module_to_llvm;
|
||||
use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
|
||||
use rustc_codegen_ssa::mono_item::MonoItemExt;
|
||||
use rustc_codegen_ssa::traits::*;
|
||||
@ -100,8 +99,7 @@ pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> {
|
||||
pub fn compile_codegen_unit(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cgu_name: Symbol,
|
||||
tx_to_llvm_workers: &std::sync::mpsc::Sender<Box<dyn std::any::Any + Send>>,
|
||||
) {
|
||||
) -> (ModuleCodegen<ModuleLlvm>, u64) {
|
||||
let prof_timer = tcx.prof.generic_activity("codegen_module");
|
||||
let start_time = Instant::now();
|
||||
|
||||
@ -115,8 +113,6 @@ pub fn compile_codegen_unit(
|
||||
// the time we needed for codegenning it.
|
||||
let cost = time_to_codegen.as_secs() * 1_000_000_000 + time_to_codegen.subsec_nanos() as u64;
|
||||
|
||||
submit_codegened_module_to_llvm(&LlvmCodegenBackend(()), tx_to_llvm_workers, module, cost);
|
||||
|
||||
fn module_codegen(tcx: TyCtxt<'_>, cgu_name: Symbol) -> ModuleCodegen<ModuleLlvm> {
|
||||
let cgu = tcx.codegen_unit(cgu_name);
|
||||
// Instantiate monomorphizations without filling out definitions yet...
|
||||
@ -164,6 +160,8 @@ pub fn compile_codegen_unit(
|
||||
kind: ModuleKind::Regular,
|
||||
}
|
||||
}
|
||||
|
||||
(module, cost)
|
||||
}
|
||||
|
||||
pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
#![feature(link_args)]
|
||||
#![feature(static_nobundle)]
|
||||
#![feature(trusted_len)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
use back::write::{create_informational_target_machine, create_target_machine};
|
||||
use rustc_span::symbol::Symbol;
|
||||
@ -108,9 +109,8 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
|
||||
&self,
|
||||
tcx: TyCtxt<'_>,
|
||||
cgu_name: Symbol,
|
||||
tx: &std::sync::mpsc::Sender<Box<dyn Any + Send>>,
|
||||
) {
|
||||
base::compile_codegen_unit(tcx, cgu_name, tx);
|
||||
) -> (ModuleCodegen<ModuleLlvm>, u64) {
|
||||
base::compile_codegen_unit(tcx, cgu_name)
|
||||
}
|
||||
fn target_machine_factory(
|
||||
&self,
|
||||
|
@ -14,8 +14,8 @@
|
||||
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
|
||||
|
||||
use crate::back::write::{
|
||||
start_async_codegen, submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm,
|
||||
OngoingCodegen,
|
||||
start_async_codegen, submit_codegened_module_to_llvm, submit_post_lto_module_to_llvm,
|
||||
submit_pre_lto_module_to_llvm, OngoingCodegen,
|
||||
};
|
||||
use crate::common::{IntPredicate, RealPredicate, TypeKind};
|
||||
use crate::meth;
|
||||
@ -40,6 +40,7 @@ use rustc::ty::{self, Instance, Ty, TyCtxt};
|
||||
use rustc_codegen_utils::{check_for_rustc_errors_attr, symbol_names_test};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::profiling::print_time_passes_entry;
|
||||
use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_index::vec::Idx;
|
||||
@ -606,20 +607,83 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
||||
codegen_units
|
||||
};
|
||||
|
||||
let mut total_codegen_time = Duration::new(0, 0);
|
||||
let total_codegen_time = Lock::new(Duration::new(0, 0));
|
||||
|
||||
for cgu in codegen_units.into_iter() {
|
||||
// The non-parallel compiler can only translate codegen units to LLVM IR
|
||||
// on a single thread, leading to a staircase effect where the N LLVM
|
||||
// threads have to wait on the single codegen threads to generate work
|
||||
// for them. The parallel compiler does not have this restriction, so
|
||||
// we can pre-load the LLVM queue in parallel before handing off
|
||||
// coordination to the OnGoingCodegen scheduler.
|
||||
//
|
||||
// This likely is a temporary measure. Once we don't have to support the
|
||||
// non-parallel compiler anymore, we can compile CGUs end-to-end in
|
||||
// parallel and get rid of the complicated scheduling logic.
|
||||
let pre_compile_cgus = |cgu_reuse: &[CguReuse]| {
|
||||
if cfg!(parallel_compiler) {
|
||||
tcx.sess.time("compile_first_CGU_batch", || {
|
||||
// Try to find one CGU to compile per thread.
|
||||
let cgus: Vec<_> = cgu_reuse
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, reuse)| reuse == &CguReuse::No)
|
||||
.take(tcx.sess.threads())
|
||||
.collect();
|
||||
|
||||
// Compile the found CGUs in parallel.
|
||||
par_iter(cgus)
|
||||
.map(|(i, _)| {
|
||||
let start_time = Instant::now();
|
||||
let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
|
||||
let mut time = total_codegen_time.lock();
|
||||
*time += start_time.elapsed();
|
||||
(i, module)
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
} else {
|
||||
FxHashMap::default()
|
||||
}
|
||||
};
|
||||
|
||||
let mut cgu_reuse = Vec::new();
|
||||
let mut pre_compiled_cgus: Option<FxHashMap<usize, _>> = None;
|
||||
|
||||
for (i, cgu) in codegen_units.iter().enumerate() {
|
||||
ongoing_codegen.wait_for_signal_to_codegen_item();
|
||||
ongoing_codegen.check_for_errors(tcx.sess);
|
||||
|
||||
let cgu_reuse = determine_cgu_reuse(tcx, &cgu);
|
||||
// Do some setup work in the first iteration
|
||||
if pre_compiled_cgus.is_none() {
|
||||
// Calculate the CGU reuse
|
||||
cgu_reuse = tcx.sess.time("find_cgu_reuse", || {
|
||||
codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect()
|
||||
});
|
||||
// Pre compile some CGUs
|
||||
pre_compiled_cgus = Some(pre_compile_cgus(&cgu_reuse));
|
||||
}
|
||||
|
||||
let cgu_reuse = cgu_reuse[i];
|
||||
tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
|
||||
|
||||
match cgu_reuse {
|
||||
CguReuse::No => {
|
||||
let start_time = Instant::now();
|
||||
backend.compile_codegen_unit(tcx, cgu.name(), &ongoing_codegen.coordinator_send);
|
||||
total_codegen_time += start_time.elapsed();
|
||||
let (module, cost) =
|
||||
if let Some(cgu) = pre_compiled_cgus.as_mut().unwrap().remove(&i) {
|
||||
cgu
|
||||
} else {
|
||||
let start_time = Instant::now();
|
||||
let module = backend.compile_codegen_unit(tcx, cgu.name());
|
||||
let mut time = total_codegen_time.lock();
|
||||
*time += start_time.elapsed();
|
||||
module
|
||||
};
|
||||
submit_codegened_module_to_llvm(
|
||||
&backend,
|
||||
&ongoing_codegen.coordinator_send,
|
||||
module,
|
||||
cost,
|
||||
);
|
||||
false
|
||||
}
|
||||
CguReuse::PreLto => {
|
||||
@ -652,7 +716,11 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
|
||||
|
||||
// Since the main thread is sometimes blocked during codegen, we keep track
|
||||
// -Ztime-passes output manually.
|
||||
print_time_passes_entry(tcx.sess.time_passes(), "codegen_to_LLVM_IR", total_codegen_time);
|
||||
print_time_passes_entry(
|
||||
tcx.sess.time_passes(),
|
||||
"codegen_to_LLVM_IR",
|
||||
total_codegen_time.into_inner(),
|
||||
);
|
||||
|
||||
::rustc_incremental::assert_module_sources::assert_module_sources(tcx);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
use super::write::WriteBackendMethods;
|
||||
use super::CodegenObject;
|
||||
use crate::ModuleCodegen;
|
||||
|
||||
use rustc::middle::cstore::EncodedMetadata;
|
||||
use rustc::session::{config, Session};
|
||||
@ -10,7 +11,6 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use syntax::expand::allocator::AllocatorKind;
|
||||
|
||||
use std::sync::mpsc;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub trait BackendTypes {
|
||||
@ -34,7 +34,7 @@ impl<'tcx, T> Backend<'tcx> for T where
|
||||
{
|
||||
}
|
||||
|
||||
pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send {
|
||||
pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync {
|
||||
fn new_metadata(&self, sess: TyCtxt<'_>, mod_name: &str) -> Self::Module;
|
||||
fn write_compressed_metadata<'tcx>(
|
||||
&self,
|
||||
@ -48,12 +48,13 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
|
||||
mods: &mut Self::Module,
|
||||
kind: AllocatorKind,
|
||||
);
|
||||
/// This generates the codegen unit and returns it along with
|
||||
/// a `u64` giving an estimate of the unit's processing cost.
|
||||
fn compile_codegen_unit(
|
||||
&self,
|
||||
tcx: TyCtxt<'_>,
|
||||
cgu_name: Symbol,
|
||||
tx_to_llvm_workers: &mpsc::Sender<Box<dyn std::any::Any + Send>>,
|
||||
);
|
||||
) -> (ModuleCodegen<Self::Module>, u64);
|
||||
// If find_features is true this won't access `sess.crate_types` by assuming
|
||||
// that `is_pie_binary` is false. When we discover LLVM target features
|
||||
// `sess.crate_types` is uninitialized so we cannot access it.
|
||||
|
@ -2,7 +2,7 @@ An associated function for a trait was defined to be static, but an
|
||||
implementation of the trait declared the same function to be a method (i.e., to
|
||||
take a `self` parameter).
|
||||
|
||||
Here's an example of this error:
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0185
|
||||
trait Foo {
|
||||
@ -17,3 +17,19 @@ impl Foo for Bar {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
```
|
||||
|
||||
When a type implements a trait's associated function, it has to use the same
|
||||
signature. So in this case, since `Foo::foo` does not take any argument and
|
||||
does not return anything, its implementation on `Bar` should be the same:
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Foo for Bar {
|
||||
fn foo() {} // ok!
|
||||
}
|
||||
```
|
||||
|
@ -3,7 +3,7 @@
|
||||
//! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html
|
||||
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(const_fn)] // For the unsizing cast on `&[]`
|
||||
#![feature(in_band_lifetimes)]
|
||||
#![feature(specialization)]
|
||||
#![recursion_limit = "256"]
|
||||
|
@ -13,7 +13,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
|
||||
#![feature(box_syntax)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(exhaustive_patterns)]
|
||||
|
@ -194,7 +194,7 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def_id::{DefId, DefIdMap, LOCAL_CRATE};
|
||||
use rustc_hir::itemlikevisit::ItemLikeVisitor;
|
||||
use rustc_index::bit_set::GrowableBitSet;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use std::iter;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
@ -227,12 +227,7 @@ impl<'tcx> InliningMap<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn record_accesses<I>(&mut self, source: MonoItem<'tcx>, new_targets: I)
|
||||
where
|
||||
I: Iterator<Item = (MonoItem<'tcx>, bool)> + ExactSizeIterator,
|
||||
{
|
||||
assert!(!self.index.contains_key(&source));
|
||||
|
||||
fn record_accesses(&mut self, source: MonoItem<'tcx>, new_targets: &[(MonoItem<'tcx>, bool)]) {
|
||||
let start_index = self.targets.len();
|
||||
let new_items_count = new_targets.len();
|
||||
let new_items_count_total = new_items_count + self.targets.len();
|
||||
@ -240,15 +235,15 @@ impl<'tcx> InliningMap<'tcx> {
|
||||
self.targets.reserve(new_items_count);
|
||||
self.inlines.ensure(new_items_count_total);
|
||||
|
||||
for (i, (target, inline)) in new_targets.enumerate() {
|
||||
self.targets.push(target);
|
||||
if inline {
|
||||
for (i, (target, inline)) in new_targets.iter().enumerate() {
|
||||
self.targets.push(*target);
|
||||
if *inline {
|
||||
self.inlines.insert(i + start_index);
|
||||
}
|
||||
}
|
||||
|
||||
let end_index = self.targets.len();
|
||||
self.index.insert(source, (start_index, end_index));
|
||||
assert!(self.index.insert(source, (start_index, end_index)).is_none());
|
||||
}
|
||||
|
||||
// Internally iterate over all items referenced by `source` which will be
|
||||
@ -403,10 +398,15 @@ fn record_accesses<'tcx>(
|
||||
mono_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy
|
||||
};
|
||||
|
||||
let accesses =
|
||||
callees.into_iter().map(|mono_item| (*mono_item, is_inlining_candidate(mono_item)));
|
||||
// We collect this into a `SmallVec` to avoid calling `is_inlining_candidate` in the lock.
|
||||
// FIXME: Call `is_inlining_candidate` when pushing to `neighbors` in `collect_items_rec`
|
||||
// instead to avoid creating this `SmallVec`.
|
||||
let accesses: SmallVec<[_; 128]> = callees
|
||||
.into_iter()
|
||||
.map(|mono_item| (*mono_item, is_inlining_candidate(mono_item)))
|
||||
.collect();
|
||||
|
||||
inlining_map.lock_mut().record_accesses(caller, accesses);
|
||||
inlining_map.lock_mut().record_accesses(caller, &accesses);
|
||||
}
|
||||
|
||||
fn check_recursion_limit<'tcx>(
|
||||
|
@ -104,6 +104,7 @@ use rustc::ty::print::characteristic_def_id_of_type;
|
||||
use rustc::ty::query::Providers;
|
||||
use rustc::ty::{self, DefIdTree, InstanceDef, TyCtxt};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::sync;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||
use rustc_span::symbol::Symbol;
|
||||
@ -796,6 +797,8 @@ where
|
||||
I: Iterator<Item = &'a MonoItem<'tcx>>,
|
||||
'tcx: 'a,
|
||||
{
|
||||
let _prof_timer = tcx.prof.generic_activity("assert_symbols_are_distinct");
|
||||
|
||||
let mut symbols: Vec<_> =
|
||||
mono_items.map(|mono_item| (mono_item, mono_item.symbol_name(tcx))).collect();
|
||||
|
||||
@ -869,18 +872,23 @@ fn collect_and_partition_mono_items(
|
||||
|
||||
tcx.sess.abort_if_errors();
|
||||
|
||||
assert_symbols_are_distinct(tcx, items.iter());
|
||||
let (codegen_units, _) = tcx.sess.time("partition_and_assert_distinct_symbols", || {
|
||||
sync::join(
|
||||
|| {
|
||||
let strategy = if tcx.sess.opts.incremental.is_some() {
|
||||
PartitioningStrategy::PerModule
|
||||
} else {
|
||||
PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units())
|
||||
};
|
||||
|
||||
let strategy = if tcx.sess.opts.incremental.is_some() {
|
||||
PartitioningStrategy::PerModule
|
||||
} else {
|
||||
PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units())
|
||||
};
|
||||
|
||||
let codegen_units = partition(tcx, items.iter().cloned(), strategy, &inlining_map)
|
||||
.into_iter()
|
||||
.map(Arc::new)
|
||||
.collect::<Vec<_>>();
|
||||
partition(tcx, items.iter().cloned(), strategy, &inlining_map)
|
||||
.into_iter()
|
||||
.map(Arc::new)
|
||||
.collect::<Vec<_>>()
|
||||
},
|
||||
|| assert_symbols_are_distinct(tcx, items.iter()),
|
||||
)
|
||||
});
|
||||
|
||||
let mono_items: DefIdSet = items
|
||||
.iter()
|
||||
|
@ -281,8 +281,22 @@ fn check_place(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns whether `allow_internal_unstable(..., <feature_gate>, ...)` is present.
|
||||
/// Returns `true` if the given feature gate is allowed within the function with the given `DefId`.
|
||||
fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
|
||||
// All features require that the corresponding gate be enabled,
|
||||
// even if the function has `#[allow_internal_unstable(the_gate)]`.
|
||||
if !tcx.features().enabled(feature_gate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If this crate is not using stability attributes, or this function is not claiming to be a
|
||||
// stable `const fn`, that is all that is required.
|
||||
if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// However, we cannot allow stable `const fn`s to use unstable features without an explicit
|
||||
// opt-in via `allow_internal_unstable`.
|
||||
attr::allow_internal_unstable(&tcx.get_attrs(def_id), &tcx.sess.diagnostic())
|
||||
.map_or(false, |mut features| features.any(|name| name == feature_gate))
|
||||
}
|
||||
|
@ -1966,7 +1966,7 @@ impl<'a> Parser<'a> {
|
||||
limits: RangeLimits,
|
||||
) -> PResult<'a, ExprKind> {
|
||||
if end.is_none() && limits == RangeLimits::Closed {
|
||||
self.error_inclusive_range_with_no_end(self.token.span);
|
||||
self.error_inclusive_range_with_no_end(self.prev_span);
|
||||
Ok(ExprKind::Err)
|
||||
} else {
|
||||
Ok(ExprKind::Range(start, end, limits))
|
||||
|
@ -661,14 +661,34 @@ impl<'a> Parser<'a> {
|
||||
pub(super) fn error_inclusive_range_with_no_end(&self, span: Span) {
|
||||
use rustc_error_codes::E0586;
|
||||
struct_span_err!(self.sess.span_diagnostic, span, E0586, "inclusive range with no end")
|
||||
.help("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)")
|
||||
.span_suggestion_short(
|
||||
span,
|
||||
"use `..` instead",
|
||||
"..".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.note("inclusive ranges must be bounded at the end (`..=b` or `a..=b`)")
|
||||
.emit();
|
||||
}
|
||||
|
||||
/// Parse a range-to pattern, e.g. `..X` and `..=X` where `X` remains to be parsed.
|
||||
fn parse_pat_range_to(&mut self, re: Spanned<RangeEnd>) -> PResult<'a, PatKind> {
|
||||
/// Parse a range-to pattern, `..X` or `..=X` where `X` remains to be parsed.
|
||||
///
|
||||
/// The form `...X` is prohibited to reduce confusion with the potential
|
||||
/// expression syntax `...expr` for splatting in expressions.
|
||||
fn parse_pat_range_to(&mut self, mut re: Spanned<RangeEnd>) -> PResult<'a, PatKind> {
|
||||
let end = self.parse_pat_range_end()?;
|
||||
self.sess.gated_spans.gate(sym::half_open_range_patterns, re.span.to(self.prev_span));
|
||||
if let RangeEnd::Included(ref mut syn @ RangeSyntax::DotDotDot) = &mut re.node {
|
||||
*syn = RangeSyntax::DotDotEq;
|
||||
self.struct_span_err(re.span, "range-to patterns with `...` are not allowed")
|
||||
.span_suggestion_short(
|
||||
re.span,
|
||||
"use `..=` instead",
|
||||
"..=".to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
Ok(PatKind::Range(None, Some(end), re))
|
||||
}
|
||||
|
||||
|
@ -62,16 +62,6 @@ impl GatedSpans {
|
||||
}
|
||||
}
|
||||
|
||||
/// The strenght of a feature gate.
|
||||
/// Either it is a `Hard` error, or only a `Soft` warning.
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
pub enum GateStrength {
|
||||
/// A hard error. (Most feature gates should use this.)
|
||||
Hard,
|
||||
/// Only a warning. (Use this only as backwards-compatibility demands.)
|
||||
Soft,
|
||||
}
|
||||
|
||||
/// Construct a diagnostic for a language feature error due to the given `span`.
|
||||
/// The `feature`'s `Symbol` is the one you used in `active.rs` and `rustc_span::symbols`.
|
||||
pub fn feature_err<'a>(
|
||||
@ -94,26 +84,7 @@ pub fn feature_err_issue<'a>(
|
||||
issue: GateIssue,
|
||||
explain: &str,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard)
|
||||
}
|
||||
|
||||
/// Construct a diagnostic for a feature gate error / warning.
|
||||
///
|
||||
/// You should typically just use `feature_err` instead.
|
||||
pub fn leveled_feature_err<'a>(
|
||||
sess: &'a ParseSess,
|
||||
feature: Symbol,
|
||||
span: impl Into<MultiSpan>,
|
||||
issue: GateIssue,
|
||||
explain: &str,
|
||||
level: GateStrength,
|
||||
) -> DiagnosticBuilder<'a> {
|
||||
let diag = &sess.span_diagnostic;
|
||||
|
||||
let mut err = match level {
|
||||
GateStrength::Hard => diag.struct_span_err_with_code(span, explain, error_code!(E0658)),
|
||||
GateStrength::Soft => diag.struct_span_warn(span, explain),
|
||||
};
|
||||
let mut err = sess.span_diagnostic.struct_span_err_with_code(span, explain, error_code!(E0658));
|
||||
|
||||
if let Some(n) = find_feature_issue(feature, issue) {
|
||||
err.note(&format!(
|
||||
@ -127,13 +98,6 @@ pub fn leveled_feature_err<'a>(
|
||||
err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature));
|
||||
}
|
||||
|
||||
// If we're on stable and only emitting a "soft" warning, add a note to
|
||||
// clarify that the feature isn't "on" (rather than being on but
|
||||
// warning-worthy).
|
||||
if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft {
|
||||
err.help("a nightly build of the compiler is required to enable this feature");
|
||||
}
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
//! This API is completely unstable and subject to change.
|
||||
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
|
||||
#![feature(const_fn)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(nll)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
@ -12,7 +12,6 @@
|
||||
#![feature(test)]
|
||||
#![feature(ptr_offset_from)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(never_type)]
|
||||
#![feature(unicode_internals)]
|
||||
|
@ -7,7 +7,7 @@
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/", test(attr(deny(warnings))))]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(const_fn)] // For the `transmute` in `P::new`
|
||||
#![feature(const_transmute)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(label_break_value)]
|
||||
|
@ -1,7 +1,6 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_mut_refs)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
struct Foo {
|
||||
x: usize
|
||||
|
@ -3,7 +3,6 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(const_if_match)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
enum E {
|
||||
A,
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/feature-gate-const-if-match.rs:109:1
|
||||
--> $DIR/feature-gate-const-if-match.rs:108:1
|
||||
|
|
||||
LL | / fn main() {
|
||||
LL | | let _ = [0; {
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![cfg_attr(if_match, feature(const_if_match))]
|
||||
#![feature(const_fn)]
|
||||
|
||||
const _: i32 = if true { //[stock]~ ERROR `if` is not allowed in a `const`
|
||||
5
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:11:16
|
||||
--> $DIR/feature-gate-const-if-match.rs:10:16
|
||||
|
|
||||
LL | const _: i32 = if true {
|
||||
| ________________^
|
||||
@ -13,7 +13,7 @@ LL | | };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:17:16
|
||||
--> $DIR/feature-gate-const-if-match.rs:16:16
|
||||
|
|
||||
LL | const _: i32 = if let Some(true) = Some(false) {
|
||||
| ________________^
|
||||
@ -27,7 +27,7 @@ LL | | };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `match` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:23:16
|
||||
--> $DIR/feature-gate-const-if-match.rs:22:16
|
||||
|
|
||||
LL | const _: i32 = match 1 {
|
||||
| ________________^
|
||||
@ -41,7 +41,7 @@ LL | | };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `static`
|
||||
--> $DIR/feature-gate-const-if-match.rs:30:13
|
||||
--> $DIR/feature-gate-const-if-match.rs:29:13
|
||||
|
|
||||
LL | let x = if true { 0 } else { 1 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -50,7 +50,7 @@ LL | let x = if true { 0 } else { 1 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `match` is not allowed in a `static`
|
||||
--> $DIR/feature-gate-const-if-match.rs:32:13
|
||||
--> $DIR/feature-gate-const-if-match.rs:31:13
|
||||
|
|
||||
LL | let x = match x { 0 => 1, _ => 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -59,7 +59,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `static`
|
||||
--> $DIR/feature-gate-const-if-match.rs:34:5
|
||||
--> $DIR/feature-gate-const-if-match.rs:33:5
|
||||
|
|
||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -68,7 +68,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `static mut`
|
||||
--> $DIR/feature-gate-const-if-match.rs:39:13
|
||||
--> $DIR/feature-gate-const-if-match.rs:38:13
|
||||
|
|
||||
LL | let x = if true { 0 } else { 1 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -77,7 +77,7 @@ LL | let x = if true { 0 } else { 1 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `match` is not allowed in a `static mut`
|
||||
--> $DIR/feature-gate-const-if-match.rs:41:13
|
||||
--> $DIR/feature-gate-const-if-match.rs:40:13
|
||||
|
|
||||
LL | let x = match x { 0 => 1, _ => 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -86,7 +86,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `static mut`
|
||||
--> $DIR/feature-gate-const-if-match.rs:43:5
|
||||
--> $DIR/feature-gate-const-if-match.rs:42:5
|
||||
|
|
||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -95,7 +95,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const fn`
|
||||
--> $DIR/feature-gate-const-if-match.rs:48:5
|
||||
--> $DIR/feature-gate-const-if-match.rs:47:5
|
||||
|
|
||||
LL | if true { 5 } else { 6 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -104,7 +104,7 @@ LL | if true { 5 } else { 6 }
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const fn`
|
||||
--> $DIR/feature-gate-const-if-match.rs:52:5
|
||||
--> $DIR/feature-gate-const-if-match.rs:51:5
|
||||
|
|
||||
LL | / if let Some(true) = a {
|
||||
LL | | 0
|
||||
@ -117,7 +117,7 @@ LL | | }
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `match` is not allowed in a `const fn`
|
||||
--> $DIR/feature-gate-const-if-match.rs:60:5
|
||||
--> $DIR/feature-gate-const-if-match.rs:59:5
|
||||
|
|
||||
LL | / match i {
|
||||
LL | | i if i > 10 => i,
|
||||
@ -130,7 +130,7 @@ LL | | }
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const fn`
|
||||
--> $DIR/feature-gate-const-if-match.rs:91:17
|
||||
--> $DIR/feature-gate-const-if-match.rs:90:17
|
||||
|
|
||||
LL | let x = if y { 0 } else { 1 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -139,7 +139,7 @@ LL | let x = if y { 0 } else { 1 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `match` is not allowed in a `const fn`
|
||||
--> $DIR/feature-gate-const-if-match.rs:93:17
|
||||
--> $DIR/feature-gate-const-if-match.rs:92:17
|
||||
|
|
||||
LL | let x = match x { 0 => 1, _ => 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -148,7 +148,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const fn`
|
||||
--> $DIR/feature-gate-const-if-match.rs:95:9
|
||||
--> $DIR/feature-gate-const-if-match.rs:94:9
|
||||
|
|
||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -157,7 +157,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:111:17
|
||||
--> $DIR/feature-gate-const-if-match.rs:110:17
|
||||
|
|
||||
LL | let x = if false { 0 } else { 1 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -166,7 +166,7 @@ LL | let x = if false { 0 } else { 1 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `match` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:113:17
|
||||
--> $DIR/feature-gate-const-if-match.rs:112:17
|
||||
|
|
||||
LL | let x = match x { 0 => 1, _ => 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -175,7 +175,7 @@ LL | let x = match x { 0 => 1, _ => 0 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:115:9
|
||||
--> $DIR/feature-gate-const-if-match.rs:114:9
|
||||
|
|
||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -184,7 +184,7 @@ LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:68:21
|
||||
--> $DIR/feature-gate-const-if-match.rs:67:21
|
||||
|
|
||||
LL | const IF: i32 = if true { 5 } else { 6 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -193,7 +193,7 @@ LL | const IF: i32 = if true { 5 } else { 6 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:71:25
|
||||
--> $DIR/feature-gate-const-if-match.rs:70:25
|
||||
|
|
||||
LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -202,7 +202,7 @@ LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `match` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:74:24
|
||||
--> $DIR/feature-gate-const-if-match.rs:73:24
|
||||
|
|
||||
LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -211,7 +211,7 @@ LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:79:21
|
||||
--> $DIR/feature-gate-const-if-match.rs:78:21
|
||||
|
|
||||
LL | const IF: i32 = if true { 5 } else { 6 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -220,7 +220,7 @@ LL | const IF: i32 = if true { 5 } else { 6 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `if` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:82:25
|
||||
--> $DIR/feature-gate-const-if-match.rs:81:25
|
||||
|
|
||||
LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -229,7 +229,7 @@ LL | const IF_LET: i32 = if let Some(true) = None { 5 } else { 6 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: `match` is not allowed in a `const`
|
||||
--> $DIR/feature-gate-const-if-match.rs:85:24
|
||||
--> $DIR/feature-gate-const-if-match.rs:84:24
|
||||
|
|
||||
LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -238,7 +238,7 @@ LL | const MATCH: i32 = match 0 { 1 => 2, _ => 0 };
|
||||
= help: add `#![feature(const_if_match)]` to the crate attributes to enable
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/feature-gate-const-if-match.rs:115:21
|
||||
--> $DIR/feature-gate-const-if-match.rs:114:21
|
||||
|
|
||||
LL | if let Some(x) = Some(x) { x } else { 1 }
|
||||
| ^
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
#![feature(const_if_match)]
|
||||
#![feature(const_panic)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
const X: i32 = {
|
||||
let mut x = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(const_if_match, const_fn)]
|
||||
#![feature(const_if_match)]
|
||||
|
||||
enum Foo {
|
||||
Prob,
|
||||
|
@ -1,10 +1,10 @@
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/E0586.rs:3:22
|
||||
--> $DIR/E0586.rs:3:19
|
||||
|
|
||||
LL | let x = &tmp[1..=];
|
||||
| ^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -8,6 +8,7 @@ fn foo() {
|
||||
//~^ ERROR half-open range patterns are unstable
|
||||
if let ...5 = 0 {}
|
||||
//~^ ERROR half-open range patterns are unstable
|
||||
//~| ERROR range-to patterns with `...` are not allowed
|
||||
if let ..5 = 0 {}
|
||||
//~^ ERROR half-open range patterns are unstable
|
||||
if let 5.. = 0 {}
|
||||
|
@ -1,18 +1,24 @@
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:15:13
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:9:12
|
||||
|
|
||||
LL | if let 5..= = 0 {}
|
||||
| ^^^
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
LL | if let ...5 = 0 {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:18:13
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:16:13
|
||||
|
|
||||
LL | if let 5..= = 0 {}
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:19:13
|
||||
|
|
||||
LL | if let 5... = 0 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0658]: half-open range patterns are unstable
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:7:12
|
||||
@ -33,7 +39,7 @@ LL | if let ...5 = 0 {}
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: half-open range patterns are unstable
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:11:12
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:12:12
|
||||
|
|
||||
LL | if let ..5 = 0 {}
|
||||
| ^^^
|
||||
@ -42,7 +48,7 @@ LL | if let ..5 = 0 {}
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: half-open range patterns are unstable
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:13:12
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:14:12
|
||||
|
|
||||
LL | if let 5.. = 0 {}
|
||||
| ^^^
|
||||
@ -51,7 +57,7 @@ LL | if let 5.. = 0 {}
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: half-open range patterns are unstable
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:15:12
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:16:12
|
||||
|
|
||||
LL | if let 5..= = 0 {}
|
||||
| ^^^^
|
||||
@ -60,7 +66,7 @@ LL | if let 5..= = 0 {}
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: half-open range patterns are unstable
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:18:12
|
||||
--> $DIR/feature-gate-half-open-range-patterns.rs:19:12
|
||||
|
|
||||
LL | if let 5... = 0 {}
|
||||
| ^^^^
|
||||
@ -68,7 +74,7 @@ LL | if let 5... = 0 {}
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/67264
|
||||
= help: add `#![feature(half_open_range_patterns)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0586, E0658.
|
||||
For more information about an error, try `rustc --explain E0586`.
|
||||
|
@ -0,0 +1,32 @@
|
||||
// Test that `...X` range-to patterns are syntactically invalid.
|
||||
//
|
||||
// See https://github.com/rust-lang/rust/pull/67258#issuecomment-565656155
|
||||
// for the reason why. To summarize, we might want to introduce `...expr` as
|
||||
// an expression form for splatting (or "untupling") in an expression context.
|
||||
// While there is no syntactic ambiguity with `...X` in a pattern context,
|
||||
// there's a potential confusion factor here, and we would prefer to keep patterns
|
||||
// and expressions in-sync. As such, we do not allow `...X` in patterns either.
|
||||
|
||||
#![feature(half_open_range_patterns)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn syntax() {
|
||||
match scrutinee {
|
||||
...X => {} //~ ERROR range-to patterns with `...` are not allowed
|
||||
...0 => {} //~ ERROR range-to patterns with `...` are not allowed
|
||||
...'a' => {} //~ ERROR range-to patterns with `...` are not allowed
|
||||
...0.0f32 => {} //~ ERROR range-to patterns with `...` are not allowed
|
||||
}
|
||||
}
|
||||
|
||||
fn syntax2() {
|
||||
macro_rules! mac {
|
||||
($e:expr) => {
|
||||
let ...$e; //~ ERROR range-to patterns with `...` are not allowed
|
||||
}
|
||||
}
|
||||
|
||||
mac!(0);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:17:9
|
||||
|
|
||||
LL | ...X => {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:18:9
|
||||
|
|
||||
LL | ...0 => {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:19:9
|
||||
|
|
||||
LL | ...'a' => {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:20:9
|
||||
|
|
||||
LL | ...0.0f32 => {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:27:17
|
||||
|
|
||||
LL | let ...$e;
|
||||
| ^^^ help: use `..=` instead
|
||||
...
|
||||
LL | mac!(0);
|
||||
| -------- in this macro invocation
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
@ -13,3 +13,14 @@ fn foo() {
|
||||
if let X... = 1 {} //~ ERROR inclusive range with no end
|
||||
if let X..= = 1 {} //~ ERROR inclusive range with no end
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
macro_rules! mac {
|
||||
($e:expr) => {
|
||||
let $e...; //~ ERROR inclusive range with no end
|
||||
let $e..=; //~ ERROR inclusive range with no end
|
||||
}
|
||||
}
|
||||
|
||||
mac!(0);
|
||||
}
|
||||
|
@ -2,34 +2,56 @@ error[E0586]: inclusive range with no end
|
||||
--> $DIR/half-open-range-pats-inclusive-no-end.rs:10:13
|
||||
|
|
||||
LL | if let 0... = 1 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/half-open-range-pats-inclusive-no-end.rs:11:13
|
||||
|
|
||||
LL | if let 0..= = 1 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/half-open-range-pats-inclusive-no-end.rs:13:13
|
||||
|
|
||||
LL | if let X... = 1 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/half-open-range-pats-inclusive-no-end.rs:14:13
|
||||
|
|
||||
LL | if let X..= = 1 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/half-open-range-pats-inclusive-no-end.rs:20:19
|
||||
|
|
||||
LL | let $e...;
|
||||
| ^^^ help: use `..` instead
|
||||
...
|
||||
LL | mac!(0);
|
||||
| -------- in this macro invocation
|
||||
|
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/half-open-range-pats-inclusive-no-end.rs:21:19
|
||||
|
|
||||
LL | let $e..=;
|
||||
| ^^^ help: use `..` instead
|
||||
...
|
||||
LL | mac!(0);
|
||||
| -------- in this macro invocation
|
||||
|
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0586`.
|
||||
|
@ -20,5 +20,7 @@ fn syntax() {
|
||||
&..=0 | _ => {}
|
||||
//~^ ERROR the range pattern here has ambiguous interpretation
|
||||
&...0 | _ => {}
|
||||
//~^ ERROR the range pattern here has ambiguous interpretation
|
||||
//~| ERROR range-to patterns with `...` are not allowed
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ error[E0586]: inclusive range with no end
|
||||
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:10:11
|
||||
|
|
||||
LL | &0..= | _ => {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: the range pattern here has ambiguous interpretation
|
||||
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:10:10
|
||||
@ -22,9 +22,9 @@ error[E0586]: inclusive range with no end
|
||||
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:13:11
|
||||
|
|
||||
LL | &0... | _ => {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: the range pattern here has ambiguous interpretation
|
||||
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:18:10
|
||||
@ -38,6 +38,18 @@ error: the range pattern here has ambiguous interpretation
|
||||
LL | &..=0 | _ => {}
|
||||
| ^^^^ help: add parentheses to clarify the precedence: `(..=0)`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:22:10
|
||||
|
|
||||
LL | &...0 | _ => {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error: the range pattern here has ambiguous interpretation
|
||||
--> $DIR/half-open-range-pats-ref-ambiguous-interp.rs:22:10
|
||||
|
|
||||
LL | &...0 | _ => {}
|
||||
| ^^^^ help: add parentheses to clarify the precedence: `(..=0)`
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0586`.
|
||||
|
@ -11,22 +11,20 @@ fn main() {}
|
||||
fn syntax() {
|
||||
match scrutinee {
|
||||
X.. | 0.. | 'a'.. | 0.0f32.. => {}
|
||||
..=X | ...X | ..X => {}
|
||||
..=0 | ...0 | ..0 => {}
|
||||
..='a' | ...'a' | ..'a' => {}
|
||||
..=0.0f32 | ...0.0f32 | ..0.0f32 => {}
|
||||
..=X | ..X => {}
|
||||
..=0 | ..0 => {}
|
||||
..='a' | ..'a' => {}
|
||||
..=0.0f32 | ..0.0f32 => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn syntax2() {
|
||||
macro_rules! mac {
|
||||
($e:expr) => {
|
||||
let ..$e;
|
||||
let ...$e;
|
||||
let ..=$e;
|
||||
let $e..;
|
||||
let $e...;
|
||||
let $e..=;
|
||||
match 0u8 { ..$e => {}, _ => {} }
|
||||
match 0u8 { ..=$e => {}, _ => {} }
|
||||
match 0u8 { $e.. => {}, _ => {} }
|
||||
}
|
||||
}
|
||||
|
||||
mac!(0);
|
||||
mac!(42u8);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Make sure that invalid ranges generate an error during HIR lowering, not an ICE
|
||||
// Make sure that invalid ranges generate an error during parsing, not an ICE
|
||||
|
||||
pub fn main() {
|
||||
..;
|
||||
@ -6,12 +6,12 @@ pub fn main() {
|
||||
..1;
|
||||
0..1;
|
||||
..=; //~ERROR inclusive range with no end
|
||||
//~^HELP bounded at the end
|
||||
//~^HELP use `..` instead
|
||||
}
|
||||
|
||||
fn _foo1() {
|
||||
..=1;
|
||||
0..=1;
|
||||
0..=; //~ERROR inclusive range with no end
|
||||
//~^HELP bounded at the end
|
||||
//~^HELP use `..` instead
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/impossible_range.rs:8:8
|
||||
--> $DIR/impossible_range.rs:8:5
|
||||
|
|
||||
LL | ..=;
|
||||
| ^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/impossible_range.rs:15:9
|
||||
--> $DIR/impossible_range.rs:15:6
|
||||
|
|
||||
LL | 0..=;
|
||||
| ^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
10
src/test/ui/internal/internal-unstable-const.rs
Normal file
10
src/test/ui/internal/internal-unstable-const.rs
Normal file
@ -0,0 +1,10 @@
|
||||
#![feature(staged_api)]
|
||||
#![feature(const_if_match)]
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_stable(feature = "rust1", since = "1.0.0")]
|
||||
const fn foo() -> i32 {
|
||||
if true { 4 } else { 5 } //~ loops and conditional expressions are not stable in const fn
|
||||
}
|
||||
|
||||
fn main() {}
|
12
src/test/ui/internal/internal-unstable-const.stderr
Normal file
12
src/test/ui/internal/internal-unstable-const.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0723]: loops and conditional expressions are not stable in const fn
|
||||
--> $DIR/internal-unstable-const.rs:7:5
|
||||
|
|
||||
LL | if true { 4 } else { 5 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
|
||||
= help: add `#![feature(const_fn)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0723`.
|
@ -2,7 +2,7 @@ error[E0599]: no method named `as_deref_err` found for enum `std::result::Result
|
||||
--> $DIR/result-as_deref_err.rs:4:28
|
||||
|
|
||||
LL | let _result = &Err(41).as_deref_err();
|
||||
| ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_ok`
|
||||
| ^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut`
|
||||
|
|
||||
= note: the method `as_deref_err` exists but the following trait bounds were not satisfied:
|
||||
`{integer} : std::ops::Deref`
|
||||
|
@ -2,7 +2,7 @@ error[E0599]: no method named `as_deref_mut_err` found for enum `std::result::Re
|
||||
--> $DIR/result-as_deref_mut_err.rs:4:32
|
||||
|
|
||||
LL | let _result = &mut Err(41).as_deref_mut_err();
|
||||
| ^^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_ok`
|
||||
| ^^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut`
|
||||
|
|
||||
= note: the method `as_deref_mut_err` exists but the following trait bounds were not satisfied:
|
||||
`{integer} : std::ops::DerefMut`
|
||||
|
@ -1,6 +0,0 @@
|
||||
#![feature(inner_deref)]
|
||||
|
||||
fn main() {
|
||||
let _result = &mut Ok(42).as_deref_mut_ok();
|
||||
//~^ ERROR no method named `as_deref_mut_ok` found
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
error[E0599]: no method named `as_deref_mut_ok` found for enum `std::result::Result<{integer}, _>` in the current scope
|
||||
--> $DIR/result-as_deref_mut_ok.rs:4:31
|
||||
|
|
||||
LL | let _result = &mut Ok(42).as_deref_mut_ok();
|
||||
| ^^^^^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_mut_err`
|
||||
|
|
||||
= note: the method `as_deref_mut_ok` exists but the following trait bounds were not satisfied:
|
||||
`{integer} : std::ops::DerefMut`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
@ -1,6 +0,0 @@
|
||||
#![feature(inner_deref)]
|
||||
|
||||
fn main() {
|
||||
let _result = &Ok(42).as_deref_ok();
|
||||
//~^ ERROR no method named `as_deref_ok` found
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
error[E0599]: no method named `as_deref_ok` found for enum `std::result::Result<{integer}, _>` in the current scope
|
||||
--> $DIR/result-as_deref_ok.rs:4:27
|
||||
|
|
||||
LL | let _result = &Ok(42).as_deref_ok();
|
||||
| ^^^^^^^^^^^ help: there is a method with a similar name: `as_deref_err`
|
||||
|
|
||||
= note: the method `as_deref_ok` exists but the following trait bounds were not satisfied:
|
||||
`{integer} : std::ops::Deref`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
14
src/test/ui/macros/issue-68058.rs
Normal file
14
src/test/ui/macros/issue-68058.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// check-pass
|
||||
|
||||
macro_rules! foo {
|
||||
($doc: expr) => {
|
||||
fn f() {
|
||||
#[doc = $doc]
|
||||
()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
foo!("doc");
|
||||
|
||||
fn main() {}
|
@ -342,9 +342,9 @@ error[E0586]: inclusive range with no end
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:94:35
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] 10 => () } }
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:94:38
|
||||
@ -356,9 +356,9 @@ error[E0586]: inclusive range with no end
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:97:35
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] -10 => () } }
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:97:38
|
||||
@ -376,9 +376,9 @@ error[E0586]: inclusive range with no end
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:102:35
|
||||
|
|
||||
LL | #[cfg(FALSE)] fn e() { match 0 { 0..=#[attr] FOO => () } }
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: expected one of `=>`, `if`, or `|`, found `#`
|
||||
--> $DIR/attr-stmt-expr-attr-bad.rs:102:38
|
||||
|
@ -2,5 +2,5 @@
|
||||
|
||||
pub fn main() {
|
||||
for _ in 1..= {} //~ERROR inclusive range with no end
|
||||
//~^HELP bounded at the end
|
||||
//~^HELP use `..` instead
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/range_inclusive.rs:4:19
|
||||
--> $DIR/range_inclusive.rs:4:15
|
||||
|
|
||||
LL | for _ in 1..= {}
|
||||
| ^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -107,15 +107,15 @@ fn inclusive_to() {
|
||||
|
||||
fn inclusive2_to() {
|
||||
if let ...3 = 0 {}
|
||||
//~^ ERROR `...` range patterns are deprecated
|
||||
//~^ ERROR range-to patterns with `...` are not allowed
|
||||
if let ...Y = 0 {}
|
||||
//~^ ERROR `...` range patterns are deprecated
|
||||
//~^ ERROR range-to patterns with `...` are not allowed
|
||||
if let ...true = 0 {}
|
||||
//~^ ERROR `...` range patterns are deprecated
|
||||
//~^ ERROR range-to patterns with `...` are not allowed
|
||||
//~| ERROR only char and numeric types
|
||||
if let ....3 = 0 {}
|
||||
//~^ ERROR float literals must have an integer part
|
||||
//~| ERROR `...` range patterns are deprecated
|
||||
//~| ERROR range-to patterns with `...` are not allowed
|
||||
//~| ERROR mismatched types
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ fn with_macro_expr_var() {
|
||||
($e:expr) => {
|
||||
let ..$e;
|
||||
let ...$e;
|
||||
//~^ ERROR `...` range patterns are deprecated
|
||||
//~^ ERROR range-to patterns with `...` are not allowed
|
||||
let ..=$e;
|
||||
let $e..;
|
||||
let $e...; //~ ERROR inclusive range with no end
|
||||
|
@ -44,25 +44,25 @@ error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:69:13
|
||||
|
|
||||
LL | if let 0..= = 0 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:70:13
|
||||
|
|
||||
LL | if let X..= = 0 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:71:16
|
||||
|
|
||||
LL | if let true..= = 0 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: float literals must have an integer part
|
||||
--> $DIR/recover-range-pats.rs:73:12
|
||||
@ -74,33 +74,33 @@ error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:73:14
|
||||
|
|
||||
LL | if let .0..= = 0 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:79:13
|
||||
|
|
||||
LL | if let 0... = 0 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:80:13
|
||||
|
|
||||
LL | if let X... = 0 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:81:16
|
||||
|
|
||||
LL | if let true... = 0 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: float literals must have an integer part
|
||||
--> $DIR/recover-range-pats.rs:83:12
|
||||
@ -112,9 +112,9 @@ error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:83:14
|
||||
|
|
||||
LL | if let .0... = 0 {}
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: float literals must have an integer part
|
||||
--> $DIR/recover-range-pats.rs:93:15
|
||||
@ -128,33 +128,66 @@ error: float literals must have an integer part
|
||||
LL | if let ..=.0 = 0 {}
|
||||
| ^^ help: must have an integer part: `0.0`
|
||||
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/recover-range-pats.rs:109:12
|
||||
|
|
||||
LL | if let ...3 = 0 {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/recover-range-pats.rs:111:12
|
||||
|
|
||||
LL | if let ...Y = 0 {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/recover-range-pats.rs:113:12
|
||||
|
|
||||
LL | if let ...true = 0 {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error: float literals must have an integer part
|
||||
--> $DIR/recover-range-pats.rs:116:15
|
||||
|
|
||||
LL | if let ....3 = 0 {}
|
||||
| ^^ help: must have an integer part: `0.3`
|
||||
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/recover-range-pats.rs:116:12
|
||||
|
|
||||
LL | if let ....3 = 0 {}
|
||||
| ^^^ help: use `..=` instead
|
||||
|
||||
error: range-to patterns with `...` are not allowed
|
||||
--> $DIR/recover-range-pats.rs:137:17
|
||||
|
|
||||
LL | let ...$e;
|
||||
| ^^^ help: use `..=` instead
|
||||
...
|
||||
LL | mac!(0);
|
||||
| -------- in this macro invocation
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:141:19
|
||||
|
|
||||
LL | let $e...;
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
...
|
||||
LL | mac!(0);
|
||||
| -------- in this macro invocation
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error[E0586]: inclusive range with no end
|
||||
--> $DIR/recover-range-pats.rs:142:19
|
||||
|
|
||||
LL | let $e..=;
|
||||
| ^^^
|
||||
| ^^^ help: use `..` instead
|
||||
...
|
||||
LL | mac!(0);
|
||||
| -------- in this macro invocation
|
||||
|
|
||||
= help: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
= note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
error: `...` range patterns are deprecated
|
||||
--> $DIR/recover-range-pats.rs:42:13
|
||||
@ -210,30 +243,6 @@ error: `...` range patterns are deprecated
|
||||
LL | if let X... .0 = 0 {}
|
||||
| ^^^ help: use `..=` for an inclusive range
|
||||
|
||||
error: `...` range patterns are deprecated
|
||||
--> $DIR/recover-range-pats.rs:109:12
|
||||
|
|
||||
LL | if let ...3 = 0 {}
|
||||
| ^^^ help: use `..=` for an inclusive range
|
||||
|
||||
error: `...` range patterns are deprecated
|
||||
--> $DIR/recover-range-pats.rs:111:12
|
||||
|
|
||||
LL | if let ...Y = 0 {}
|
||||
| ^^^ help: use `..=` for an inclusive range
|
||||
|
||||
error: `...` range patterns are deprecated
|
||||
--> $DIR/recover-range-pats.rs:113:12
|
||||
|
|
||||
LL | if let ...true = 0 {}
|
||||
| ^^^ help: use `..=` for an inclusive range
|
||||
|
||||
error: `...` range patterns are deprecated
|
||||
--> $DIR/recover-range-pats.rs:116:12
|
||||
|
|
||||
LL | if let ....3 = 0 {}
|
||||
| ^^^ help: use `..=` for an inclusive range
|
||||
|
||||
error: `...` range patterns are deprecated
|
||||
--> $DIR/recover-range-pats.rs:126:20
|
||||
|
|
||||
@ -243,15 +252,6 @@ LL | let $e1...$e2;
|
||||
LL | mac2!(0, 1);
|
||||
| ------------ in this macro invocation
|
||||
|
||||
error: `...` range patterns are deprecated
|
||||
--> $DIR/recover-range-pats.rs:137:17
|
||||
|
|
||||
LL | let ...$e;
|
||||
| ^^^ help: use `..=` for an inclusive range
|
||||
...
|
||||
LL | mac!(0);
|
||||
| -------- in this macro invocation
|
||||
|
||||
error[E0029]: only char and numeric types are allowed in range patterns
|
||||
--> $DIR/recover-range-pats.rs:20:12
|
||||
|
|
||||
|
Loading…
Reference in New Issue
Block a user