diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index a2c651d1537b5..09c0983bb9d1a 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -173,6 +173,7 @@ pub fn ident_can_begin_expr(name: Symbol, span: Span, is_raw: bool) -> bool { kw::Move, kw::Return, kw::True, + kw::Try, kw::Unsafe, kw::While, kw::Yield, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 0ee8ef55e61bf..97e6b363eff60 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -608,6 +608,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { pub fn check_crate(krate: &ast::Crate, sess: &Session) { maybe_stage_features(sess, krate); + check_incompatible_features(sess); let mut visitor = PostExpansionVisitor { sess, features: &sess.features_untracked() }; let spans = sess.parse_sess.gated_spans.spans.borrow(); @@ -677,3 +678,36 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) { } } } + +fn check_incompatible_features(sess: &Session) { + let features = sess.features_untracked(); + + let declared_features = features + .declared_lang_features + .iter() + .copied() + .map(|(name, span, _)| (name, span)) + .chain(features.declared_lib_features.iter().copied()); + + for (f1, f2) in rustc_feature::INCOMPATIBLE_FEATURES + .iter() + .filter(|&&(f1, f2)| features.enabled(f1) && features.enabled(f2)) + { + if let Some((f1_name, f1_span)) = declared_features.clone().find(|(name, _)| name == f1) { + if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2) + { + let spans = vec![f1_span, f2_span]; + sess.struct_span_err( + spans.clone(), + &format!( + "features `{}` and `{}` are incompatible, using them at the same time \ + is not allowed", + f1_name, f2_name + ), + ) + .help("remove one of these features") + .emit(); + } + } + } +} diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 64ff6130ddffb..bc3d1ce53bac5 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -87,11 +87,8 @@ where } /// Allows searches to terminate early with a value. -#[derive(Clone, Copy, Debug)] -pub enum ControlFlow { - Break(T), - Continue, -} +// FIXME (#75744): remove the alias once the generics are in a better order and `C=()`. +pub type ControlFlow = std::ops::ControlFlow<(), T>; /// The status of a node in the depth-first search. /// @@ -260,12 +257,12 @@ where _node: G::Node, _prior_status: Option, ) -> ControlFlow { - ControlFlow::Continue + ControlFlow::CONTINUE } /// Called after all nodes reachable from this one have been examined. fn node_settled(&mut self, _node: G::Node) -> ControlFlow { - ControlFlow::Continue + ControlFlow::CONTINUE } /// Behave as if no edges exist from `source` to `target`. @@ -289,8 +286,8 @@ where prior_status: Option, ) -> ControlFlow { match prior_status { - Some(NodeStatus::Visited) => ControlFlow::Break(()), - _ => ControlFlow::Continue, + Some(NodeStatus::Visited) => ControlFlow::BREAK, + _ => ControlFlow::CONTINUE, } } } diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index de4e7a1342431..88c160e93b66a 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -8,6 +8,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![allow(incomplete_features)] +#![feature(control_flow_enum)] #![feature(in_band_lifetimes)] #![feature(unboxed_closures)] #![feature(generators)] diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index e858980738d71..3d7b3da45ccb9 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -605,3 +605,8 @@ pub const INCOMPLETE_FEATURES: &[Symbol] = &[ sym::lazy_normalization_consts, sym::specialization, ]; + +/// Some features are not allowed to be used together at the same time, if +/// the two are present, produce an error +pub const INCOMPATIBLE_FEATURES: &[(Symbol, Symbol)] = + &[(sym::const_generics, sym::min_const_generics)]; diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 4393368cd4524..15564a59658cb 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -131,7 +131,7 @@ pub fn find_feature_issue(feature: Symbol, issue: GateIssue) -> Option FromIterator> for DtorckConstraint<'tcx> { } } -/// This returns true if the type `ty` is "trivial" for -/// dropck-outlives -- that is, if it doesn't require any types to -/// outlive. This is similar but not *quite* the same as the -/// `needs_drop` test in the compiler already -- that is, for every -/// type T for which this function return true, needs-drop would -/// return `false`. But the reverse does not hold: in particular, -/// `needs_drop` returns false for `PhantomData`, but it is not -/// trivial for dropck-outlives. -/// -/// Note also that `needs_drop` requires a "global" type (i.e., one -/// with erased regions), but this function does not. -pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { - match ty.kind() { - // None of these types have a destructor and hence they do not - // require anything in particular to outlive the dtor's - // execution. - ty::Infer(ty::FreshIntTy(_)) - | ty::Infer(ty::FreshFloatTy(_)) - | ty::Bool - | ty::Int(_) - | ty::Uint(_) - | ty::Float(_) - | ty::Never - | ty::FnDef(..) - | ty::FnPtr(_) - | ty::Char - | ty::GeneratorWitness(..) - | ty::RawPtr(_) - | ty::Ref(..) - | ty::Str - | ty::Foreign(..) - | ty::Error(_) => true, - - // [T; N] and [T] have same properties as T. - ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, ty), - - // (T1..Tn) and closures have same properties as T1..Tn -- - // check if *any* of those are trivial. - ty::Tuple(ref tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t.expect_ty())), - ty::Closure(_, ref substs) => { - substs.as_closure().upvar_tys().all(|t| trivial_dropck_outlives(tcx, t)) - } - - ty::Adt(def, _) => { - if Some(def.did) == tcx.lang_items().manually_drop() { - // `ManuallyDrop` never has a dtor. - true - } else { - // Other types might. Moreover, PhantomData doesn't - // have a dtor, but it is considered to own its - // content, so it is non-trivial. Unions can have `impl Drop`, - // and hence are non-trivial as well. - false - } - } - - // The following *might* require a destructor: needs deeper inspection. - ty::Dynamic(..) - | ty::Projection(..) - | ty::Param(_) - | ty::Opaque(..) - | ty::Placeholder(..) - | ty::Infer(_) - | ty::Bound(..) - | ty::Generator(..) => false, - } -} - #[derive(Debug, HashStable)] pub struct CandidateStep<'tcx> { pub self_ty: Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>, diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 313bb979a5161..e55180ff4be52 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -6,6 +6,7 @@ #![feature(box_syntax)] #![feature(const_fn)] #![feature(const_panic)] +#![feature(control_flow_enum)] #![feature(crate_visibility_modifier)] #![feature(bool_to_option)] #![feature(or_patterns)] diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs index 22ce278cee02c..a8d7c612a8419 100644 --- a/compiler/rustc_mir_build/src/lints.rs +++ b/compiler/rustc_mir_build/src/lints.rs @@ -117,7 +117,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> { // A diverging InlineAsm is treated as non-recursing TerminatorKind::InlineAsm { destination, .. } => { if destination.is_some() { - ControlFlow::Continue + ControlFlow::CONTINUE } else { ControlFlow::Break(NonRecursive) } @@ -131,7 +131,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> { | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } | TerminatorKind::Goto { .. } - | TerminatorKind::SwitchInt { .. } => ControlFlow::Continue, + | TerminatorKind::SwitchInt { .. } => ControlFlow::CONTINUE, } } @@ -144,7 +144,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> { } } - ControlFlow::Continue + ControlFlow::CONTINUE } fn ignore_edge(&mut self, bb: BasicBlock, target: BasicBlock) -> bool { diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs index ff559c2bfd684..527a322d56a4f 100644 --- a/compiler/rustc_target/src/spec/avr_gnu_base.rs +++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs @@ -45,6 +45,8 @@ pub fn target(target_cpu: String) -> TargetResult { late_link_args: vec![(LinkerFlavor::Gcc, vec!["-lgcc".to_owned()])] .into_iter() .collect(), + max_atomic_width: Some(0), + atomic_cas: false, ..TargetOptions::default() }, }) diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index 011ea32d0cfc2..eba7ffae22c4c 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -120,6 +120,9 @@ use crate::raw_vec::RawVec; /// assert_eq!(vec, [0, 0, 0, 0, 0]); /// ``` /// +/// For more information, see +/// [Capacity and Reallocation](#capacity-and-reallocation). +/// /// Use a `Vec` as an efficient stack: /// /// ``` diff --git a/library/alloc/tests/borrow.rs b/library/alloc/tests/borrow.rs index 8bfcf323f674a..57976aa6cdfdf 100644 --- a/library/alloc/tests/borrow.rs +++ b/library/alloc/tests/borrow.rs @@ -45,3 +45,16 @@ fn test_from_cow_path() { let path = Path::new("hello"); test_from_cow!(path: &Path); } + +#[test] +fn cow_const() { + // test that the methods of `Cow` are usable in a const context + + const COW: Cow<'_, str> = Cow::Borrowed("moo"); + + const IS_BORROWED: bool = COW.is_borrowed(); + assert!(IS_BORROWED); + + const IS_OWNED: bool = COW.is_owned(); + assert!(!IS_OWNED); +} diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index b1513d1b05655..590639d983481 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -1,5 +1,6 @@ #![feature(allocator_api)] #![feature(box_syntax)] +#![feature(cow_is_borrowed)] #![feature(drain_filter)] #![feature(exact_size_is_empty)] #![feature(new_uninit)] diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 8e66c8a22cec5..53b0d0a271844 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -74,6 +74,42 @@ fn test_zst_capacity() { assert_eq!(Vec::<()>::new().capacity(), usize::MAX); } +#[test] +fn test_indexing() { + let v: Vec = vec![10, 20]; + assert_eq!(v[0], 10); + assert_eq!(v[1], 20); + let mut x: usize = 0; + assert_eq!(v[x], 10); + assert_eq!(v[x + 1], 20); + x = x + 1; + assert_eq!(v[x], 20); + assert_eq!(v[x - 1], 10); +} + +#[test] +fn test_debug_fmt() { + let vec1: Vec = vec![]; + assert_eq!("[]", format!("{:?}", vec1)); + + let vec2 = vec![0, 1]; + assert_eq!("[0, 1]", format!("{:?}", vec2)); + + let slice: &[isize] = &[4, 5]; + assert_eq!("[4, 5]", format!("{:?}", slice)); +} + +#[test] +fn test_push() { + let mut v = vec![]; + v.push(1); + assert_eq!(v, [1]); + v.push(2); + assert_eq!(v, [1, 2]); + v.push(3); + assert_eq!(v, [1, 2, 3]); +} + #[test] fn test_extend() { let mut v = Vec::new(); @@ -119,6 +155,18 @@ fn test_extend() { assert_eq!(count_x, 1); } +#[test] +fn test_extend_from_slice() { + let a: Vec = vec![1, 2, 3, 4, 5]; + let b: Vec = vec![6, 7, 8, 9, 0]; + + let mut v: Vec = a; + + v.extend_from_slice(&b); + + assert_eq!(v, [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]); +} + #[test] fn test_extend_ref() { let mut v = vec![1, 2]; @@ -134,6 +182,14 @@ fn test_extend_ref() { assert_eq!(v, [1, 2, 3, 4, 5, 6, 7]); } +#[test] +fn test_slice_from_ref() { + let values = vec![1, 2, 3, 4, 5]; + let slice = &values[1..3]; + + assert_eq!(slice, [2, 3]); +} + #[test] fn test_slice_from_mut() { let mut values = vec![1, 2, 3, 4, 5]; @@ -345,6 +401,29 @@ fn test_zip_unzip() { assert_eq!((3, 6), (left[2], right[2])); } +#[test] +fn test_cmp() { + let x: &[isize] = &[1, 2, 3, 4, 5]; + let cmp: &[isize] = &[1, 2, 3, 4, 5]; + assert_eq!(&x[..], cmp); + let cmp: &[isize] = &[3, 4, 5]; + assert_eq!(&x[2..], cmp); + let cmp: &[isize] = &[1, 2, 3]; + assert_eq!(&x[..3], cmp); + let cmp: &[isize] = &[2, 3, 4]; + assert_eq!(&x[1..4], cmp); + + let x: Vec = vec![1, 2, 3, 4, 5]; + let cmp: &[isize] = &[1, 2, 3, 4, 5]; + assert_eq!(&x[..], cmp); + let cmp: &[isize] = &[3, 4, 5]; + assert_eq!(&x[2..], cmp); + let cmp: &[isize] = &[1, 2, 3]; + assert_eq!(&x[..3], cmp); + let cmp: &[isize] = &[2, 3, 4]; + assert_eq!(&x[1..4], cmp); +} + #[test] fn test_vec_truncate_drop() { static mut DROPS: u32 = 0; diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index c3f1269401aa9..b411222856edb 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -1273,7 +1273,7 @@ where ) -> impl FnMut((), T) -> ControlFlow<(), B> + '_ { move |(), x| match f(x) { Some(x) => ControlFlow::Break(x), - None => ControlFlow::Continue(()), + None => ControlFlow::CONTINUE, } } @@ -1772,7 +1772,7 @@ impl Peekable { self.peeked.get_or_insert_with(|| iter.next()).as_ref() } - /// Consume the next value of this iterator if a condition is true. + /// Consume and return the next value of this iterator if a condition is true. /// /// If `func` returns `true` for the next value of this iterator, consume and return it. /// Otherwise, return `None`. @@ -1812,7 +1812,7 @@ impl Peekable { } } - /// Consume the next item if it is equal to `expected`. + /// Consume and return the next item if it is equal to `expected`. /// /// # Example /// Consume a number if it's equal to 0. @@ -1827,10 +1827,10 @@ impl Peekable { /// assert_eq!(iter.next(), Some(1)); /// ``` #[unstable(feature = "peekable_next_if", issue = "72480")] - pub fn next_if_eq(&mut self, expected: &R) -> Option + pub fn next_if_eq(&mut self, expected: &T) -> Option where - R: ?Sized, - I::Item: PartialEq, + T: ?Sized, + I::Item: PartialEq, { self.next_if(|next| next == expected) } diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index f50807116bd09..a025bc8b56049 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -310,7 +310,7 @@ pub trait DoubleEndedIterator: Iterator { mut predicate: impl FnMut(&T) -> bool, ) -> impl FnMut((), T) -> ControlFlow<(), T> { move |(), x| { - if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) } + if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } } } diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index b5aa7257cf38e..b8a09f822b6da 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -809,7 +809,7 @@ pub trait Iterator { Enumerate::new(self) } - /// Creates an iterator which can use `peek` to look at the next element of + /// Creates an iterator which can use [`peek`] to look at the next element of /// the iterator without consuming it. /// /// Adds a [`peek`] method to an iterator. See its documentation for @@ -1992,7 +1992,7 @@ pub trait Iterator { /// The same as [`fold()`], but uses the first element in the /// iterator as the initial value, folding every subsequent element into it. - /// If the iterator is empty, return `None`; otherwise, return the result + /// If the iterator is empty, return [`None`]; otherwise, return the result /// of the fold. /// /// [`fold()`]: Iterator::fold @@ -2076,10 +2076,10 @@ pub trait Iterator { #[inline] fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> { move |(), x| { - if f(x) { ControlFlow::Continue(()) } else { ControlFlow::Break(()) } + if f(x) { ControlFlow::CONTINUE } else { ControlFlow::BREAK } } } - self.try_fold((), check(f)) == ControlFlow::Continue(()) + self.try_fold((), check(f)) == ControlFlow::CONTINUE } /// Tests if any element of the iterator matches a predicate. @@ -2129,11 +2129,11 @@ pub trait Iterator { #[inline] fn check(mut f: impl FnMut(T) -> bool) -> impl FnMut((), T) -> ControlFlow<(), ()> { move |(), x| { - if f(x) { ControlFlow::Break(()) } else { ControlFlow::Continue(()) } + if f(x) { ControlFlow::BREAK } else { ControlFlow::CONTINUE } } } - self.try_fold((), check(f)) == ControlFlow::Break(()) + self.try_fold((), check(f)) == ControlFlow::BREAK } /// Searches for an element of an iterator that satisfies a predicate. @@ -2191,7 +2191,7 @@ pub trait Iterator { mut predicate: impl FnMut(&T) -> bool, ) -> impl FnMut((), T) -> ControlFlow<(), T> { move |(), x| { - if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::Continue(()) } + if predicate(&x) { ControlFlow::Break(x) } else { ControlFlow::CONTINUE } } } @@ -2226,7 +2226,7 @@ pub trait Iterator { ) -> impl FnMut((), T) -> ControlFlow<(), B> { move |(), x| match f(x) { Some(x) => ControlFlow::Break(x), - None => ControlFlow::Continue(()), + None => ControlFlow::CONTINUE, } } @@ -2268,7 +2268,7 @@ pub trait Iterator { R: Try, { move |(), x| match f(&x).into_result() { - Ok(false) => ControlFlow::Continue(()), + Ok(false) => ControlFlow::CONTINUE, Ok(true) => ControlFlow::Break(Ok(x)), Err(x) => ControlFlow::Break(Err(x)), } @@ -2821,7 +2821,7 @@ pub trait Iterator { Product::product(self) } - /// Lexicographically compares the elements of this `Iterator` with those + /// Lexicographically compares the elements of this [`Iterator`] with those /// of another. /// /// # Examples @@ -2843,7 +2843,7 @@ pub trait Iterator { self.cmp_by(other, |x, y| x.cmp(&y)) } - /// Lexicographically compares the elements of this `Iterator` with those + /// Lexicographically compares the elements of this [`Iterator`] with those /// of another with respect to the specified comparison function. /// /// # Examples @@ -2895,7 +2895,7 @@ pub trait Iterator { } } - /// Lexicographically compares the elements of this `Iterator` with those + /// Lexicographically compares the elements of this [`Iterator`] with those /// of another. /// /// # Examples @@ -2919,7 +2919,7 @@ pub trait Iterator { self.partial_cmp_by(other, |x, y| x.partial_cmp(&y)) } - /// Lexicographically compares the elements of this `Iterator` with those + /// Lexicographically compares the elements of this [`Iterator`] with those /// of another with respect to the specified comparison function. /// /// # Examples @@ -2980,7 +2980,7 @@ pub trait Iterator { } } - /// Determines if the elements of this `Iterator` are equal to those of + /// Determines if the elements of this [`Iterator`] are equal to those of /// another. /// /// # Examples @@ -2999,7 +2999,7 @@ pub trait Iterator { self.eq_by(other, |x, y| x == y) } - /// Determines if the elements of this `Iterator` are equal to those of + /// Determines if the elements of this [`Iterator`] are equal to those of /// another with respect to the specified equality function. /// /// # Examples @@ -3040,7 +3040,7 @@ pub trait Iterator { } } - /// Determines if the elements of this `Iterator` are unequal to those of + /// Determines if the elements of this [`Iterator`] are unequal to those of /// another. /// /// # Examples @@ -3059,7 +3059,7 @@ pub trait Iterator { !self.eq(other) } - /// Determines if the elements of this `Iterator` are lexicographically + /// Determines if the elements of this [`Iterator`] are lexicographically /// less than those of another. /// /// # Examples @@ -3080,7 +3080,7 @@ pub trait Iterator { self.partial_cmp(other) == Some(Ordering::Less) } - /// Determines if the elements of this `Iterator` are lexicographically + /// Determines if the elements of this [`Iterator`] are lexicographically /// less or equal to those of another. /// /// # Examples @@ -3101,7 +3101,7 @@ pub trait Iterator { matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal)) } - /// Determines if the elements of this `Iterator` are lexicographically + /// Determines if the elements of this [`Iterator`] are lexicographically /// greater than those of another. /// /// # Examples @@ -3122,7 +3122,7 @@ pub trait Iterator { self.partial_cmp(other) == Some(Ordering::Greater) } - /// Determines if the elements of this `Iterator` are lexicographically + /// Determines if the elements of this [`Iterator`] are lexicographically /// greater than or equal to those of another. /// /// # Examples diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 7a88cfbb74dd4..757ad5252bab3 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -2470,7 +2470,7 @@ fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), doc_comment! { concat!("**This method is soft-deprecated.** -Although using it won’t cause compilation warning, +Although using it won’t cause a compilation warning, new code should use [`", stringify!($SelfT), "::MIN", "`](#associatedconstant.MIN) instead. Returns the smallest value that can be represented by this integer type."), @@ -2486,7 +2486,7 @@ Returns the smallest value that can be represented by this integer type."), doc_comment! { concat!("**This method is soft-deprecated.** -Although using it won’t cause compilation warning, +Although using it won’t cause a compilation warning, new code should use [`", stringify!($SelfT), "::MAX", "`](#associatedconstant.MAX) instead. Returns the largest value that can be represented by this integer type."), diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index 687d423dcb635..b0c7dc1a51875 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -65,3 +65,46 @@ impl ControlFlow { } } } + +impl ControlFlow<(), B> { + /// It's frequently the case that there's no value needed with `Continue`, + /// so this provides a way to avoid typing `(())`, if you prefer it. + /// + /// # Examples + /// + /// ``` + /// #![feature(control_flow_enum)] + /// use std::ops::ControlFlow; + /// + /// let mut partial_sum = 0; + /// let last_used = (1..10).chain(20..25).try_for_each(|x| { + /// partial_sum += x; + /// if partial_sum > 100 { ControlFlow::Break(x) } + /// else { ControlFlow::CONTINUE } + /// }); + /// assert_eq!(last_used.break_value(), Some(22)); + /// ``` + #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] + pub const CONTINUE: Self = ControlFlow::Continue(()); +} + +impl ControlFlow { + /// APIs like `try_for_each` don't need values with `Break`, + /// so this provides a way to avoid typing `(())`, if you prefer it. + /// + /// # Examples + /// + /// ``` + /// #![feature(control_flow_enum)] + /// use std::ops::ControlFlow; + /// + /// let mut partial_sum = 0; + /// (1..10).chain(20..25).try_for_each(|x| { + /// if partial_sum > 100 { ControlFlow::BREAK } + /// else { partial_sum += x; ControlFlow::CONTINUE } + /// }); + /// assert_eq!(partial_sum, 108); + /// ``` + #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] + pub const BREAK: Self = ControlFlow::Break(()); +} diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 68977a983aa37..aa9ad395b1840 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -66,7 +66,6 @@ impl [T] { #[rustc_const_stable(feature = "const_slice_len", since = "1.32.0")] #[inline] // SAFETY: const sound because we transmute out the length field as a usize (which it must be) - #[allow(unused_attributes)] #[allow_internal_unstable(const_fn_union)] pub const fn len(&self) -> usize { // SAFETY: this is safe because `&[T]` and `FatPtr` have the same layout. @@ -3358,8 +3357,9 @@ mod private_slice_index { on(T = "str", label = "string indices are ranges of `usize`",), on( all(any(T = "str", T = "&str", T = "std::string::String"), _Self = "{integer}"), - note = "you can use `.chars().nth()` or `.bytes().nth()` -see chapter in The Book " + note = "you can use `.chars().nth()` or `.bytes().nth()`\n\ + for more information, see chapter 8 in The Book: \ + " ), message = "the type `{T}` cannot be indexed by `{Self}`", label = "slice indices are of type `usize` or ranges of `usize`" diff --git a/library/core/tests/ascii.rs b/library/core/tests/ascii.rs index 0b97508394789..3244bbc2d670d 100644 --- a/library/core/tests/ascii.rs +++ b/library/core/tests/ascii.rs @@ -397,3 +397,14 @@ fn test_is_ascii_align_size_thoroughly() { } } } + +#[test] +fn ascii_const() { + // test that the `is_ascii` methods of `char` and `u8` are usable in a const context + + const CHAR_IS_ASCII: bool = 'a'.is_ascii(); + assert!(CHAR_IS_ASCII); + + const BYTE_IS_ASCII: bool = 97u8.is_ascii(); + assert!(BYTE_IS_ASCII); +} diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index 48aec6d718d3d..825e5e63b59bc 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -195,3 +195,20 @@ fn test_nonzero_from_int_on_err() { assert!(NonZeroI8::try_from(0).is_err()); assert!(NonZeroI32::try_from(0).is_err()); } + +#[test] +fn nonzero_const() { + // test that the methods of `NonZeroX>` are usable in a const context + // Note: only tests NonZero8 + + const NONZERO: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(5) }; + + const GET: u8 = NONZERO.get(); + assert_eq!(GET, 5); + + const ZERO: Option = NonZeroU8::new(0); + assert!(ZERO.is_none()); + + const ONE: Option = NonZeroU8::new(1); + assert!(ONE.is_some()); +} diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 970dea6b2991b..b0fceb9b2f669 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -695,21 +695,21 @@ pub struct ArgsOs { inner: sys::args::Args, } -/// Returns the arguments which this program was started with (normally passed +/// Returns the arguments that this program was started with (normally passed /// via the command line). /// /// The first element is traditionally the path of the executable, but it can be /// set to arbitrary text, and may not even exist. This means this property should /// not be relied upon for security purposes. /// -/// On Unix systems shell usually expands unquoted arguments with glob patterns +/// On Unix systems the shell usually expands unquoted arguments with glob patterns /// (such as `*` and `?`). On Windows this is not done, and such arguments are /// passed as-is. /// -/// On glibc Linux systems, arguments are retrieved by placing a function in ".init_array". -/// Glibc passes argc, argv, and envp to functions in ".init_array", as a non-standard extension. -/// This allows `std::env::args` to work even in a `cdylib` or `staticlib`, as it does on macOS -/// and Windows. +/// On glibc Linux systems, arguments are retrieved by placing a function in `.init_array`. +/// Glibc passes `argc`, `argv`, and `envp` to functions in `.init_array`, as a non-standard +/// extension. This allows `std::env::args` to work even in a `cdylib` or `staticlib`, as it +/// does on macOS and Windows. /// /// # Panics /// diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs index a2fba4b4cca95..76a0ae8b9454d 100644 --- a/library/std/src/net/ip/tests.rs +++ b/library/std/src/net/ip/tests.rs @@ -809,3 +809,112 @@ fn is_v6() { assert!(!ip.is_ipv4()); assert!(ip.is_ipv6()); } + +#[test] +fn ipv4_const() { + // test that the methods of `Ipv4Addr` are usable in a const context + + const IP_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1); + assert_eq!(IP_ADDRESS, Ipv4Addr::LOCALHOST); + + const OCTETS: [u8; 4] = IP_ADDRESS.octets(); + assert_eq!(OCTETS, [127, 0, 0, 1]); + + const IS_UNSPECIFIED: bool = IP_ADDRESS.is_unspecified(); + assert!(!IS_UNSPECIFIED); + + const IS_LOOPBACK: bool = IP_ADDRESS.is_loopback(); + assert!(IS_LOOPBACK); + + const IS_PRIVATE: bool = IP_ADDRESS.is_private(); + assert!(!IS_PRIVATE); + + const IS_LINK_LOCAL: bool = IP_ADDRESS.is_link_local(); + assert!(!IS_LINK_LOCAL); + + const IS_GLOBAL: bool = IP_ADDRESS.is_global(); + assert!(!IS_GLOBAL); + + const IS_SHARED: bool = IP_ADDRESS.is_shared(); + assert!(!IS_SHARED); + + const IS_IETF_PROTOCOL_ASSIGNMENT: bool = IP_ADDRESS.is_ietf_protocol_assignment(); + assert!(!IS_IETF_PROTOCOL_ASSIGNMENT); + + const IS_BENCHMARKING: bool = IP_ADDRESS.is_benchmarking(); + assert!(!IS_BENCHMARKING); + + const IS_RESERVED: bool = IP_ADDRESS.is_reserved(); + assert!(!IS_RESERVED); + + const IS_MULTICAST: bool = IP_ADDRESS.is_multicast(); + assert!(!IS_MULTICAST); + + const IS_BROADCAST: bool = IP_ADDRESS.is_broadcast(); + assert!(!IS_BROADCAST); + + const IS_DOCUMENTATION: bool = IP_ADDRESS.is_documentation(); + assert!(!IS_DOCUMENTATION); + + const IP_V6_COMPATIBLE: Ipv6Addr = IP_ADDRESS.to_ipv6_compatible(); + assert_eq!( + IP_V6_COMPATIBLE, + Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1]) + ); + + const IP_V6_MAPPED: Ipv6Addr = IP_ADDRESS.to_ipv6_mapped(); + assert_eq!( + IP_V6_MAPPED, + Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1]) + ); +} + +#[test] +fn ipv6_const() { + // test that the methods of `Ipv6Addr` are usable in a const context + + const IP_ADDRESS: Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); + assert_eq!(IP_ADDRESS, Ipv6Addr::LOCALHOST); + + const SEGMENTS: [u16; 8] = IP_ADDRESS.segments(); + assert_eq!(SEGMENTS, [0, 0, 0, 0, 0, 0, 0, 1]); + + const OCTETS: [u8; 16] = IP_ADDRESS.octets(); + assert_eq!(OCTETS, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); + + const IS_UNSPECIFIED: bool = IP_ADDRESS.is_unspecified(); + assert!(!IS_UNSPECIFIED); + + const IS_LOOPBACK: bool = IP_ADDRESS.is_loopback(); + assert!(IS_LOOPBACK); + + const IS_GLOBAL: bool = IP_ADDRESS.is_global(); + assert!(!IS_GLOBAL); + + const IS_UNIQUE_LOCAL: bool = IP_ADDRESS.is_unique_local(); + assert!(!IS_UNIQUE_LOCAL); + + const IS_UNICAST_LINK_LOCAL_STRICT: bool = IP_ADDRESS.is_unicast_link_local_strict(); + assert!(!IS_UNICAST_LINK_LOCAL_STRICT); + + const IS_UNICAST_LINK_LOCAL: bool = IP_ADDRESS.is_unicast_link_local(); + assert!(!IS_UNICAST_LINK_LOCAL); + + const IS_UNICAST_SITE_LOCAL: bool = IP_ADDRESS.is_unicast_site_local(); + assert!(!IS_UNICAST_SITE_LOCAL); + + const IS_DOCUMENTATION: bool = IP_ADDRESS.is_documentation(); + assert!(!IS_DOCUMENTATION); + + const IS_UNICAST_GLOBAL: bool = IP_ADDRESS.is_unicast_global(); + assert!(!IS_UNICAST_GLOBAL); + + const MULTICAST_SCOPE: Option = IP_ADDRESS.multicast_scope(); + assert_eq!(MULTICAST_SCOPE, None); + + const IS_MULTICAST: bool = IP_ADDRESS.is_multicast(); + assert!(!IS_MULTICAST); + + const IP_V4: Option = IP_ADDRESS.to_ipv4(); + assert_eq!(IP_V4.unwrap(), Ipv4Addr::new(0, 0, 0, 1)); +} diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs index 1fe27a3460000..83e8853fe7923 100644 --- a/library/std/src/os/raw/mod.rs +++ b/library/std/src/os/raw/mod.rs @@ -9,7 +9,6 @@ #![stable(feature = "raw_os", since = "1.1.0")] #[cfg(test)] -#[allow(unused_imports)] mod tests; #[doc(include = "char.md")] diff --git a/library/std/src/os/raw/tests.rs b/library/std/src/os/raw/tests.rs index e808faf81d657..e7bb7d7e73e80 100644 --- a/library/std/src/os/raw/tests.rs +++ b/library/std/src/os/raw/tests.rs @@ -1,5 +1,4 @@ use crate::any::TypeId; -use crate::mem; macro_rules! ok { ($($t:ident)*) => {$( diff --git a/library/std/src/sys/unix/ext/fs.rs b/library/std/src/sys/unix/ext/fs.rs index e48e950928a50..487ac266ee9cd 100644 --- a/library/std/src/sys/unix/ext/fs.rs +++ b/library/std/src/sys/unix/ext/fs.rs @@ -428,7 +428,7 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; - /// use std::io; + /// use std::io; /// /// fn main() -> io::Result<()> { /// let meta = fs::metadata("some_file")?; diff --git a/library/std/src/sys/vxworks/ext/fs.rs b/library/std/src/sys/vxworks/ext/fs.rs index 4ff86daf0dd73..9b4c64bdb6d84 100644 --- a/library/std/src/sys/vxworks/ext/fs.rs +++ b/library/std/src/sys/vxworks/ext/fs.rs @@ -427,7 +427,7 @@ pub trait MetadataExt { /// ```no_run /// use std::fs; /// use std::os::unix::fs::MetadataExt; - /// use std::io; + /// use std::io; /// /// fn main() -> io::Result<()> { /// let meta = fs::metadata("some_file")?; diff --git a/library/std/src/time.rs b/library/std/src/time.rs index 73c0a7b403a7b..575882eb459fc 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -159,7 +159,7 @@ pub struct Instant(time::Instant); /// | CloudABI | [clock_time_get (Realtime Clock)] | /// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] | /// | UNIX | [clock_gettime (Realtime Clock)] | -/// | DARWIN | [gettimeofday] | +/// | Darwin | [gettimeofday] | /// | VXWorks | [clock_gettime (Realtime Clock)] | /// | WASI | [__wasi_clock_time_get (Realtime Clock)] | /// | Windows | [GetSystemTimePreciseAsFileTime] / [GetSystemTimeAsFileTime] | diff --git a/src/test/ui/array-slice-vec/slice-2.rs b/src/test/ui/array-slice-vec/slice-2.rs deleted file mode 100644 index 01733f48234f9..0000000000000 --- a/src/test/ui/array-slice-vec/slice-2.rs +++ /dev/null @@ -1,62 +0,0 @@ -// run-pass - -// Test slicing expressions on slices and Vecs. - - -fn main() { - let x: &[isize] = &[1, 2, 3, 4, 5]; - let cmp: &[isize] = &[1, 2, 3, 4, 5]; - assert_eq!(&x[..], cmp); - let cmp: &[isize] = &[3, 4, 5]; - assert_eq!(&x[2..], cmp); - let cmp: &[isize] = &[1, 2, 3]; - assert_eq!(&x[..3], cmp); - let cmp: &[isize] = &[2, 3, 4]; - assert_eq!(&x[1..4], cmp); - - let x: Vec = vec![1, 2, 3, 4, 5]; - let cmp: &[isize] = &[1, 2, 3, 4, 5]; - assert_eq!(&x[..], cmp); - let cmp: &[isize] = &[3, 4, 5]; - assert_eq!(&x[2..], cmp); - let cmp: &[isize] = &[1, 2, 3]; - assert_eq!(&x[..3], cmp); - let cmp: &[isize] = &[2, 3, 4]; - assert_eq!(&x[1..4], cmp); - - let x: &mut [isize] = &mut [1, 2, 3, 4, 5]; - { - let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5]; - assert_eq!(&mut x[..], cmp); - } - { - let cmp: &mut [isize] = &mut [3, 4, 5]; - assert_eq!(&mut x[2..], cmp); - } - { - let cmp: &mut [isize] = &mut [1, 2, 3]; - assert_eq!(&mut x[..3], cmp); - } - { - let cmp: &mut [isize] = &mut [2, 3, 4]; - assert_eq!(&mut x[1..4], cmp); - } - - let mut x: Vec = vec![1, 2, 3, 4, 5]; - { - let cmp: &mut [isize] = &mut [1, 2, 3, 4, 5]; - assert_eq!(&mut x[..], cmp); - } - { - let cmp: &mut [isize] = &mut [3, 4, 5]; - assert_eq!(&mut x[2..], cmp); - } - { - let cmp: &mut [isize] = &mut [1, 2, 3]; - assert_eq!(&mut x[..3], cmp); - } - { - let cmp: &mut [isize] = &mut [2, 3, 4]; - assert_eq!(&mut x[1..4], cmp); - } -} diff --git a/src/test/ui/array-slice-vec/vec-concat.rs b/src/test/ui/array-slice-vec/vec-concat.rs deleted file mode 100644 index 1f493679b7947..0000000000000 --- a/src/test/ui/array-slice-vec/vec-concat.rs +++ /dev/null @@ -1,14 +0,0 @@ -// run-pass - -use std::vec; - -pub fn main() { - let a: Vec = vec![1, 2, 3, 4, 5]; - let b: Vec = vec![6, 7, 8, 9, 0]; - let mut v: Vec = a; - v.extend_from_slice(&b); - println!("{}", v[9]); - assert_eq!(v[0], 1); - assert_eq!(v[7], 8); - assert_eq!(v[9], 0); -} diff --git a/src/test/ui/array-slice-vec/vec-growth.rs b/src/test/ui/array-slice-vec/vec-growth.rs deleted file mode 100644 index b09f08bb85a82..0000000000000 --- a/src/test/ui/array-slice-vec/vec-growth.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass - - - -pub fn main() { - let mut v = vec![1]; - v.push(2); - v.push(3); - v.push(4); - v.push(5); - assert_eq!(v[0], 1); - assert_eq!(v[1], 2); - assert_eq!(v[2], 3); - assert_eq!(v[3], 4); - assert_eq!(v[4], 5); -} diff --git a/src/test/ui/array-slice-vec/vec-push.rs b/src/test/ui/array-slice-vec/vec-push.rs deleted file mode 100644 index 466ab3fab1cab..0000000000000 --- a/src/test/ui/array-slice-vec/vec-push.rs +++ /dev/null @@ -1,3 +0,0 @@ -// run-pass - -pub fn main() { let mut v = vec![1, 2, 3]; v.push(1); } diff --git a/src/test/ui/array-slice-vec/vec-slice.rs b/src/test/ui/array-slice-vec/vec-slice.rs deleted file mode 100644 index 1f090ddd9c97d..0000000000000 --- a/src/test/ui/array-slice-vec/vec-slice.rs +++ /dev/null @@ -1,9 +0,0 @@ -// run-pass - - -pub fn main() { - let v = vec![1,2,3,4,5]; - let v2 = &v[1..3]; - assert_eq!(v2[0], 2); - assert_eq!(v2[1], 3); -} diff --git a/src/test/ui/array-slice-vec/vec-to_str.rs b/src/test/ui/array-slice-vec/vec-to_str.rs deleted file mode 100644 index a11cfc8e9b5c9..0000000000000 --- a/src/test/ui/array-slice-vec/vec-to_str.rs +++ /dev/null @@ -1,12 +0,0 @@ -// run-pass - - -pub fn main() { - assert_eq!(format!("{:?}", vec![0, 1]), "[0, 1]".to_string()); - - let foo = vec![3, 4]; - let bar: &[isize] = &[4, 5]; - - assert_eq!(format!("{:?}", foo), "[3, 4]"); - assert_eq!(format!("{:?}", bar), "[4, 5]"); -} diff --git a/src/test/ui/array-slice-vec/vec.rs b/src/test/ui/array-slice-vec/vec.rs deleted file mode 100644 index e76c1ab440e6e..0000000000000 --- a/src/test/ui/array-slice-vec/vec.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - - - -pub fn main() { - let v: Vec = vec![10, 20]; - assert_eq!(v[0], 10); - assert_eq!(v[1], 20); - let mut x: usize = 0; - assert_eq!(v[x], 10); - assert_eq!(v[x + 1], 20); - x = x + 1; - assert_eq!(v[x], 20); - assert_eq!(v[x - 1], 10); -} diff --git a/src/test/ui/const-generics/min-and-full-same-time.rs b/src/test/ui/const-generics/min-and-full-same-time.rs new file mode 100644 index 0000000000000..2365adc3a861f --- /dev/null +++ b/src/test/ui/const-generics/min-and-full-same-time.rs @@ -0,0 +1,7 @@ +#![feature(const_generics)] +//~^ ERROR features `const_generics` and `min_const_generics` are incompatible +#![allow(incomplete_features)] +#![feature(min_const_generics)] + + +fn main() {} diff --git a/src/test/ui/const-generics/min-and-full-same-time.stderr b/src/test/ui/const-generics/min-and-full-same-time.stderr new file mode 100644 index 0000000000000..907fec9bbe17a --- /dev/null +++ b/src/test/ui/const-generics/min-and-full-same-time.stderr @@ -0,0 +1,13 @@ +error: features `const_generics` and `min_const_generics` are incompatible, using them at the same time is not allowed + --> $DIR/min-and-full-same-time.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ +... +LL | #![feature(min_const_generics)] + | ^^^^^^^^^^^^^^^^^^ + | + = help: remove one of these features + +error: aborting due to previous error + diff --git a/src/test/ui/consts/const-nonzero.rs b/src/test/ui/consts/const-nonzero.rs deleted file mode 100644 index cf6f8c8d69a26..0000000000000 --- a/src/test/ui/consts/const-nonzero.rs +++ /dev/null @@ -1,16 +0,0 @@ -// run-pass - -use std::num::NonZeroU8; - -const X: NonZeroU8 = unsafe { NonZeroU8::new_unchecked(5) }; -const Y: u8 = X.get(); - -const ZERO: Option = NonZeroU8::new(0); -const ONE: Option = NonZeroU8::new(1); - -fn main() { - assert_eq!(Y, 5); - - assert!(ZERO.is_none()); - assert_eq!(ONE.unwrap().get(), 1); -} diff --git a/src/test/ui/consts/cow-is-borrowed.rs b/src/test/ui/consts/cow-is-borrowed.rs deleted file mode 100644 index adebe20f5a255..0000000000000 --- a/src/test/ui/consts/cow-is-borrowed.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -#![feature(cow_is_borrowed)] - -use std::borrow::Cow; - -fn main() { - const COW: Cow = Cow::Borrowed("moo"); - - const IS_BORROWED: bool = COW.is_borrowed(); - assert!(IS_BORROWED); - - const IS_OWNED: bool = COW.is_owned(); - assert!(!IS_OWNED); -} diff --git a/src/test/ui/consts/is_ascii.rs b/src/test/ui/consts/is_ascii.rs deleted file mode 100644 index d8424549f93e6..0000000000000 --- a/src/test/ui/consts/is_ascii.rs +++ /dev/null @@ -1,15 +0,0 @@ -// run-pass - -static X: bool = 'a'.is_ascii(); -static Y: bool = 'ä'.is_ascii(); - -static BX: bool = b'a'.is_ascii(); -static BY: bool = 192u8.is_ascii(); - -fn main() { - assert!(X); - assert!(!Y); - - assert!(BX); - assert!(!BY); -} diff --git a/src/test/ui/consts/std/net/ipv4.rs b/src/test/ui/consts/std/net/ipv4.rs deleted file mode 100644 index 8c676999ae734..0000000000000 --- a/src/test/ui/consts/std/net/ipv4.rs +++ /dev/null @@ -1,58 +0,0 @@ -// run-pass - -#![feature(ip)] -#![feature(const_ipv4)] - -use std::net::{Ipv4Addr, Ipv6Addr}; - -fn main() { - const IP_ADDRESS: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1); - assert_eq!(IP_ADDRESS, Ipv4Addr::LOCALHOST); - - const OCTETS: [u8; 4] = IP_ADDRESS.octets(); - assert_eq!(OCTETS, [127, 0, 0, 1]); - - const IS_UNSPECIFIED : bool = IP_ADDRESS.is_unspecified(); - assert!(!IS_UNSPECIFIED); - - const IS_LOOPBACK : bool = IP_ADDRESS.is_loopback(); - assert!(IS_LOOPBACK); - - const IS_PRIVATE : bool = IP_ADDRESS.is_private(); - assert!(!IS_PRIVATE); - - const IS_LINK_LOCAL : bool = IP_ADDRESS.is_link_local(); - assert!(!IS_LINK_LOCAL); - - const IS_GLOBAL : bool = IP_ADDRESS.is_global(); - assert!(!IS_GLOBAL); - - const IS_SHARED : bool = IP_ADDRESS.is_shared(); - assert!(!IS_SHARED); - - const IS_IETF_PROTOCOL_ASSIGNMENT : bool = IP_ADDRESS.is_ietf_protocol_assignment(); - assert!(!IS_IETF_PROTOCOL_ASSIGNMENT); - - const IS_BENCHMARKING : bool = IP_ADDRESS.is_benchmarking(); - assert!(!IS_BENCHMARKING); - - const IS_RESERVED : bool = IP_ADDRESS.is_reserved(); - assert!(!IS_RESERVED); - - const IS_MULTICAST : bool = IP_ADDRESS.is_multicast(); - assert!(!IS_MULTICAST); - - const IS_BROADCAST : bool = IP_ADDRESS.is_broadcast(); - assert!(!IS_BROADCAST); - - const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation(); - assert!(!IS_DOCUMENTATION); - - const IP_V6_COMPATIBLE : Ipv6Addr = IP_ADDRESS.to_ipv6_compatible(); - assert_eq!(IP_V6_COMPATIBLE, - Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, 0, 0, 1])); - - const IP_V6_MAPPED : Ipv6Addr = IP_ADDRESS.to_ipv6_mapped(); - assert_eq!(IP_V6_MAPPED, - Ipv6Addr::from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1])); -} diff --git a/src/test/ui/consts/std/net/ipv6.rs b/src/test/ui/consts/std/net/ipv6.rs deleted file mode 100644 index e3841c38c2231..0000000000000 --- a/src/test/ui/consts/std/net/ipv6.rs +++ /dev/null @@ -1,53 +0,0 @@ -// run-pass - -#![feature(ip)] -#![feature(const_ipv6)] - -use std::net::{Ipv4Addr, Ipv6Addr, Ipv6MulticastScope}; - -fn main() { - const IP_ADDRESS : Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); - assert_eq!(IP_ADDRESS, Ipv6Addr::LOCALHOST); - - const SEGMENTS : [u16; 8] = IP_ADDRESS.segments(); - assert_eq!(SEGMENTS, [0 ,0 ,0 ,0 ,0 ,0 ,0, 1]); - - const OCTETS : [u8; 16] = IP_ADDRESS.octets(); - assert_eq!(OCTETS, [0 ,0 ,0 ,0 ,0 ,0 ,0, 0 ,0 ,0 ,0 ,0 ,0 ,0, 0, 1]); - - const IS_UNSPECIFIED : bool = IP_ADDRESS.is_unspecified(); - assert!(!IS_UNSPECIFIED); - - const IS_LOOPBACK : bool = IP_ADDRESS.is_loopback(); - assert!(IS_LOOPBACK); - - const IS_GLOBAL : bool = IP_ADDRESS.is_global(); - assert!(!IS_GLOBAL); - - const IS_UNIQUE_LOCAL : bool = IP_ADDRESS.is_unique_local(); - assert!(!IS_UNIQUE_LOCAL); - - const IS_UNICAST_LINK_LOCAL_STRICT : bool = IP_ADDRESS.is_unicast_link_local_strict(); - assert!(!IS_UNICAST_LINK_LOCAL_STRICT); - - const IS_UNICAST_LINK_LOCAL : bool = IP_ADDRESS.is_unicast_link_local(); - assert!(!IS_UNICAST_LINK_LOCAL); - - const IS_UNICAST_SITE_LOCAL : bool = IP_ADDRESS.is_unicast_site_local(); - assert!(!IS_UNICAST_SITE_LOCAL); - - const IS_DOCUMENTATION : bool = IP_ADDRESS.is_documentation(); - assert!(!IS_DOCUMENTATION); - - const IS_UNICAST_GLOBAL : bool = IP_ADDRESS.is_unicast_global(); - assert!(!IS_UNICAST_GLOBAL); - - const MULTICAST_SCOPE : Option = IP_ADDRESS.multicast_scope(); - assert_eq!(MULTICAST_SCOPE, None); - - const IS_MULTICAST : bool = IP_ADDRESS.is_multicast(); - assert!(!IS_MULTICAST); - - const IP_V4 : Option = IP_ADDRESS.to_ipv4(); - assert_eq!(IP_V4.unwrap(), Ipv4Addr::new(0, 0, 0, 1)); -} diff --git a/src/test/ui/str/str-idx.stderr b/src/test/ui/str/str-idx.stderr index ef7ce735868cb..f323ba03c012c 100644 --- a/src/test/ui/str/str-idx.stderr +++ b/src/test/ui/str/str-idx.stderr @@ -6,7 +6,7 @@ LL | let _: u8 = s[4]; | = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` - see chapter in The Book + for more information, see chapter 8 in The Book: = note: required because of the requirements on the impl of `Index<{integer}>` for `str` error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -17,7 +17,7 @@ LL | let _ = s.get(4); | = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` - see chapter in The Book + for more information, see chapter 8 in The Book: error[E0277]: the type `str` cannot be indexed by `{integer}` --> $DIR/str-idx.rs:5:29 @@ -27,7 +27,7 @@ LL | let _ = s.get_unchecked(4); | = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` - see chapter in The Book + for more information, see chapter 8 in The Book: error[E0277]: the type `str` cannot be indexed by `char` --> $DIR/str-idx.rs:6:17 diff --git a/src/test/ui/str/str-mut-idx.stderr b/src/test/ui/str/str-mut-idx.stderr index abb9b09cf3871..405542820a394 100644 --- a/src/test/ui/str/str-mut-idx.stderr +++ b/src/test/ui/str/str-mut-idx.stderr @@ -39,7 +39,7 @@ LL | s.get_mut(1); | = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` - see chapter in The Book + for more information, see chapter 8 in The Book: error[E0277]: the type `str` cannot be indexed by `{integer}` --> $DIR/str-mut-idx.rs:11:25 @@ -49,7 +49,7 @@ LL | s.get_unchecked_mut(1); | = help: the trait `SliceIndex` is not implemented for `{integer}` = note: you can use `.chars().nth()` or `.bytes().nth()` - see chapter in The Book + for more information, see chapter 8 in The Book: error[E0277]: the type `str` cannot be indexed by `char` --> $DIR/str-mut-idx.rs:13:5 diff --git a/src/test/ui/try-block/try-block-in-return.rs b/src/test/ui/try-block/try-block-in-return.rs new file mode 100644 index 0000000000000..a15bfeef1c12d --- /dev/null +++ b/src/test/ui/try-block/try-block-in-return.rs @@ -0,0 +1,12 @@ +// run-pass +// compile-flags: --edition 2018 + +#![feature(try_blocks)] + +fn issue_76271() -> Option { + return try { 4 } +} + +fn main() { + assert_eq!(issue_76271(), Some(4)); +}