Auto merge of #70617 - Centril:rollup-063ycso, r=Centril

Rollup of 9 pull requests

Successful merges:

 - #69784 (Optimize strip_prefix and strip_suffix with str patterns)
 - #70548 (Add long error code for error E0226)
 - #70555 (resolve, `try_resolve_as_non_binding`: use `delay_span_bug` due to parser recovery)
 - #70561 (remove obsolete comment)
 - #70562 (infer array len from pattern)
 - #70585 (std: Fix over-aligned allocations on wasm32-wasi)
 - #70587 (Add `Rust` to the code snippet)
 - #70588 (Fix incorrect documentation for `str::{split_at, split_at_mut}`)
 - #70613 (more clippy fixes)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-03-31 14:00:55 +00:00
commit 75ff3110ac
39 changed files with 470 additions and 196 deletions

View File

@ -14,7 +14,7 @@ http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/
### Code
```
```Rust
<code>
```

View File

@ -1849,6 +1849,21 @@ impl<'a, 'b> Pattern<'a> for &'b String {
fn is_prefix_of(self, haystack: &'a str) -> bool {
self[..].is_prefix_of(haystack)
}
#[inline]
fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
self[..].strip_prefix_of(haystack)
}
#[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool {
self[..].is_suffix_of(haystack)
}
#[inline]
fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> {
self[..].strip_suffix_of(haystack)
}
}
#[stable(feature = "rust1", since = "1.0.0")]

View File

@ -9,7 +9,7 @@
#![stable(feature = "rust1", since = "1.0.0")]
use self::pattern::Pattern;
use self::pattern::{DoubleEndedSearcher, ReverseSearcher, SearchStep, Searcher};
use self::pattern::{DoubleEndedSearcher, ReverseSearcher, Searcher};
use crate::char;
use crate::fmt::{self, Write};
@ -2642,7 +2642,7 @@ impl str {
/// # Panics
///
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
/// beyond the last code point of the string slice.
/// past the end of the last code point of the string slice.
///
/// # Examples
///
@ -2683,7 +2683,7 @@ impl str {
/// # Panics
///
/// Panics if `mid` is not on a UTF-8 code point boundary, or if it is
/// beyond the last code point of the string slice.
/// past the end of the last code point of the string slice.
///
/// # Examples
///
@ -3986,26 +3986,15 @@ impl str {
/// ```
/// #![feature(str_strip)]
///
/// assert_eq!("foobar".strip_prefix("foo"), Some("bar"));
/// assert_eq!("foobar".strip_prefix("bar"), None);
/// assert_eq!("foo:bar".strip_prefix("foo:"), Some("bar"));
/// assert_eq!("foo:bar".strip_prefix("bar"), None);
/// assert_eq!("foofoo".strip_prefix("foo"), Some("foo"));
/// ```
#[must_use = "this returns the remaining substring as a new slice, \
without modifying the original"]
#[unstable(feature = "str_strip", reason = "newly added", issue = "67302")]
pub fn strip_prefix<'a, P: Pattern<'a>>(&'a self, prefix: P) -> Option<&'a str> {
let mut matcher = prefix.into_searcher(self);
if let SearchStep::Match(start, len) = matcher.next() {
debug_assert_eq!(
start, 0,
"The first search step from Searcher \
must include the first character"
);
// SAFETY: `Searcher` is known to return valid indices.
unsafe { Some(self.get_unchecked(len..)) }
} else {
None
}
prefix.strip_prefix_of(self)
}
/// Returns a string slice with the suffix removed.
@ -4020,8 +4009,8 @@ impl str {
///
/// ```
/// #![feature(str_strip)]
/// assert_eq!("barfoo".strip_suffix("foo"), Some("bar"));
/// assert_eq!("barfoo".strip_suffix("bar"), None);
/// assert_eq!("bar:foo".strip_suffix(":foo"), Some("bar"));
/// assert_eq!("bar:foo".strip_suffix("bar"), None);
/// assert_eq!("foofoo".strip_suffix("foo"), Some("foo"));
/// ```
#[must_use = "this returns the remaining substring as a new slice, \
@ -4032,19 +4021,7 @@ impl str {
P: Pattern<'a>,
<P as Pattern<'a>>::Searcher: ReverseSearcher<'a>,
{
let mut matcher = suffix.into_searcher(self);
if let SearchStep::Match(start, end) = matcher.next_back() {
debug_assert_eq!(
end,
self.len(),
"The first search step from ReverseSearcher \
must include the last character"
);
// SAFETY: `Searcher` is known to return valid indices.
unsafe { Some(self.get_unchecked(..start)) }
} else {
None
}
suffix.strip_suffix_of(self)
}
/// Returns a string slice with all suffixes that match a pattern

View File

@ -47,6 +47,22 @@ pub trait Pattern<'a>: Sized {
matches!(self.into_searcher(haystack).next(), SearchStep::Match(0, _))
}
/// Removes the pattern from the front of haystack, if it matches.
#[inline]
fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
if let SearchStep::Match(start, len) = self.into_searcher(haystack).next() {
debug_assert_eq!(
start, 0,
"The first search step from Searcher \
must include the first character"
);
// SAFETY: `Searcher` is known to return valid indices.
unsafe { Some(haystack.get_unchecked(len..)) }
} else {
None
}
}
/// Checks whether the pattern matches at the back of the haystack
#[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool
@ -55,6 +71,26 @@ pub trait Pattern<'a>: Sized {
{
matches!(self.into_searcher(haystack).next_back(), SearchStep::Match(_, j) if haystack.len() == j)
}
/// Removes the pattern from the back of haystack, if it matches.
#[inline]
fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>
where
Self::Searcher: ReverseSearcher<'a>,
{
if let SearchStep::Match(start, end) = self.into_searcher(haystack).next_back() {
debug_assert_eq!(
end,
haystack.len(),
"The first search step from ReverseSearcher \
must include the last character"
);
// SAFETY: `Searcher` is known to return valid indices.
unsafe { Some(haystack.get_unchecked(..start)) }
} else {
None
}
}
}
// Searcher
@ -448,6 +484,11 @@ impl<'a> Pattern<'a> for char {
self.encode_utf8(&mut [0u8; 4]).is_prefix_of(haystack)
}
#[inline]
fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
self.encode_utf8(&mut [0u8; 4]).strip_prefix_of(haystack)
}
#[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool
where
@ -455,6 +496,14 @@ impl<'a> Pattern<'a> for char {
{
self.encode_utf8(&mut [0u8; 4]).is_suffix_of(haystack)
}
#[inline]
fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>
where
Self::Searcher: ReverseSearcher<'a>,
{
self.encode_utf8(&mut [0u8; 4]).strip_suffix_of(haystack)
}
}
/////////////////////////////////////////////////////////////////////////////
@ -569,6 +618,11 @@ macro_rules! pattern_methods {
($pmap)(self).is_prefix_of(haystack)
}
#[inline]
fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
($pmap)(self).strip_prefix_of(haystack)
}
#[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool
where
@ -576,6 +630,14 @@ macro_rules! pattern_methods {
{
($pmap)(self).is_suffix_of(haystack)
}
#[inline]
fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str>
where
$t: ReverseSearcher<'a>,
{
($pmap)(self).strip_suffix_of(haystack)
}
};
}
@ -715,11 +777,34 @@ impl<'a, 'b> Pattern<'a> for &'b str {
haystack.as_bytes().starts_with(self.as_bytes())
}
/// Removes the pattern from the front of haystack, if it matches.
#[inline]
fn strip_prefix_of(self, haystack: &'a str) -> Option<&'a str> {
if self.is_prefix_of(haystack) {
// SAFETY: prefix was just verified to exist.
unsafe { Some(haystack.get_unchecked(self.as_bytes().len()..)) }
} else {
None
}
}
/// Checks whether the pattern matches at the back of the haystack
#[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool {
haystack.as_bytes().ends_with(self.as_bytes())
}
/// Removes the pattern from the back of haystack, if it matches.
#[inline]
fn strip_suffix_of(self, haystack: &'a str) -> Option<&'a str> {
if self.is_suffix_of(haystack) {
let i = haystack.len() - self.as_bytes().len();
// SAFETY: suffix was just verified to exist.
unsafe { Some(haystack.get_unchecked(..i)) }
} else {
None
}
}
}
/////////////////////////////////////////////////////////////////////////////

View File

@ -119,6 +119,7 @@ E0222: include_str!("./error_codes/E0222.md"),
E0223: include_str!("./error_codes/E0223.md"),
E0224: include_str!("./error_codes/E0224.md"),
E0225: include_str!("./error_codes/E0225.md"),
E0226: include_str!("./error_codes/E0226.md"),
E0229: include_str!("./error_codes/E0229.md"),
E0230: include_str!("./error_codes/E0230.md"),
E0231: include_str!("./error_codes/E0231.md"),
@ -475,7 +476,6 @@ E0751: include_str!("./error_codes/E0751.md"),
// E0217, // ambiguous associated type, defined in multiple supertraits
// E0218, // no associated type defined
// E0219, // associated type defined in higher-ranked supertrait
E0226, // only a single explicit lifetime bound is permitted
E0227, // ambiguous lifetime bound, explicit lifetime bound required
E0228, // explicit lifetime bound required
// E0233,

View File

@ -0,0 +1,21 @@
More than one explicit lifetime bound was used on a trait object.
Example of erroneous code:
```compile_fail,E0226
trait Foo {}
type T<'a, 'b> = dyn Foo + 'a + 'b; // error: Trait object `arg` has two
// lifetime bound, 'a and 'b.
```
Here `T` is a trait object with two explicit lifetime bounds, 'a and 'b.
Only a single explicit lifetime bound is permitted on trait objects.
To fix this error, consider removing one of the lifetime bounds:
```
trait Foo {}
type T<'a> = dyn Foo + 'a;
```

View File

@ -7,8 +7,8 @@ Example of erroneous code:
fn is_123<const N: usize>(x: [u32; N]) -> bool {
match x {
[1, 2, 3] => true, // error: cannot pattern-match on an
// array without a fixed length
[1, 2, ..] => true, // error: cannot pattern-match on an
// array without a fixed length
_ => false
}
}

View File

@ -711,7 +711,7 @@ impl<'tcx> QueryContext<'tcx> {
}
pub fn print_stats(&mut self) {
self.enter(|tcx| ty::query::print_stats(tcx))
self.enter(ty::query::print_stats)
}
}

View File

@ -30,7 +30,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
trace!("SwitchInt({:?})", *discr);
// Branch to the `otherwise` case by default, if no match is found.
assert!(targets.len() > 0);
assert!(!targets.is_empty());
let mut target_block = targets[targets.len() - 1];
for (index, &const_int) in values.iter().enumerate() {

View File

@ -93,9 +93,6 @@ impl<'a> StringReader<'a> {
}
/// Returns the next token, including trivia like whitespace or comments.
///
/// `Err(())` means that some errors were encountered, which can be
/// retrieved using `buffer_fatal_errors`.
pub fn next_token(&mut self) -> Token {
let start_src_index = self.src_index(self.pos);
let text: &str = &self.src[start_src_index..self.end_src_index];

View File

@ -1536,20 +1536,18 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
let is_syntactic_ambiguity = !has_sub && bm == BindingMode::ByValue(Mutability::Not);
match res {
Res::Def(DefKind::Ctor(_, CtorKind::Const), _)
| Res::Def(DefKind::Const, _)
| Res::Def(DefKind::ConstParam, _)
if is_syntactic_ambiguity =>
{
Res::SelfCtor(_) // See #70549.
| Res::Def(
DefKind::Ctor(_, CtorKind::Const) | DefKind::Const | DefKind::ConstParam,
_,
) if is_syntactic_ambiguity => {
// Disambiguate in favor of a unit struct/variant or constant pattern.
if let Some(binding) = binding {
self.r.record_use(ident, ValueNS, binding, false);
}
Some(res)
}
Res::Def(DefKind::Ctor(..), _)
| Res::Def(DefKind::Const, _)
| Res::Def(DefKind::Static, _) => {
Res::Def(DefKind::Ctor(..) | DefKind::Const | DefKind::Static, _) => {
// This is unambiguously a fresh binding, either syntactically
// (e.g., `IDENT @ PAT` or `ref IDENT`) or because `IDENT` resolves
// to something unusable as a pattern (e.g., constructor function),
@ -1572,7 +1570,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
_ => span_bug!(
ident.span,
"unexpected resolution for an identifier in pattern: {:?}",
res
res,
),
}
}

View File

@ -10,6 +10,7 @@
#![feature(bool_to_option)]
#![feature(crate_visibility_modifier)]
#![feature(nll)]
#![feature(or_patterns)]
#![recursion_limit = "256"]
pub use rustc_hir::def::{Namespace, PerNS};

View File

@ -591,7 +591,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
Some(Data::RefData(Ref {
kind: RefKind::Function,
span,
ref_id: def_id.or(decl_id).map(id_from_def_id).unwrap_or_else(|| null_id()),
ref_id: def_id.or(decl_id).map(id_from_def_id).unwrap_or_else(null_id),
}))
}
ast::ExprKind::Path(_, ref path) => {

View File

@ -1650,7 +1650,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
check_thread_count(&debugging_opts, error_format);
let incremental = cg.incremental.as_ref().map(|m| PathBuf::from(m));
let incremental = cg.incremental.as_ref().map(PathBuf::from);
if debugging_opts.profile && incremental.is_some() {
early_error(

View File

@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
let llvm_target = super::apple_base::macos_llvm_target(&arch);
Ok(Target {
llvm_target: llvm_target,
llvm_target,
target_endian: "little".to_string(),
target_pointer_width: "32".to_string(),
target_c_int_width: "32".to_string(),

View File

@ -16,7 +16,7 @@ pub fn target() -> TargetResult {
let llvm_target = super::apple_base::macos_llvm_target(&arch);
Ok(Target {
llvm_target: llvm_target,
llvm_target,
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
target_c_int_width: "32".to_string(),

View File

@ -1355,16 +1355,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) -> Ty<'tcx> {
let err = self.tcx.types.err;
let expected = self.structurally_resolved_type(span, expected);
let (inner_ty, slice_ty, expected) = match expected.kind {
let (element_ty, slice_ty, inferred) = match expected.kind {
// An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.
ty::Array(inner_ty, len) => {
ty::Array(element_ty, len) => {
let min = before.len() as u64 + after.len() as u64;
let slice_ty = self
.check_array_pat_len(span, slice, len, min)
.map_or(err, |len| self.tcx.mk_array(inner_ty, len));
(inner_ty, slice_ty, expected)
let (slice_ty, expected) =
self.check_array_pat_len(span, element_ty, expected, slice, len, min);
(element_ty, slice_ty, expected)
}
ty::Slice(inner_ty) => (inner_ty, expected, expected),
ty::Slice(element_ty) => (element_ty, expected, expected),
// The expected type must be an array or slice, but was neither, so error.
_ => {
if !expected.references_error() {
@ -1376,7 +1375,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Type check all the patterns before `slice`.
for elt in before {
self.check_pat(&elt, inner_ty, def_bm, ti);
self.check_pat(&elt, element_ty, def_bm, ti);
}
// Type check the `slice`, if present, against its expected type.
if let Some(slice) = slice {
@ -1384,22 +1383,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
// Type check the elements after `slice`, if present.
for elt in after {
self.check_pat(&elt, inner_ty, def_bm, ti);
self.check_pat(&elt, element_ty, def_bm, ti);
}
expected
inferred
}
/// Type check the length of an array pattern.
///
/// Return the length of the variable length pattern,
/// if it exists and there are no errors.
/// Returns both the type of the variable length pattern
/// (or `tcx.err` in case there is none),
/// and the potentially inferred array type.
fn check_array_pat_len(
&self,
span: Span,
element_ty: Ty<'tcx>,
arr_ty: Ty<'tcx>,
slice: Option<&'tcx Pat<'tcx>>,
len: &ty::Const<'tcx>,
min_len: u64,
) -> Option<u64> {
) -> (Ty<'tcx>, Ty<'tcx>) {
if let Some(len) = len.try_eval_usize(self.tcx, self.param_env) {
// Now we know the length...
if slice.is_none() {
@ -1409,21 +1411,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if min_len != len {
self.error_scrutinee_inconsistent_length(span, min_len, len);
}
} else if let r @ Some(_) = len.checked_sub(min_len) {
} else if let Some(pat_len) = len.checked_sub(min_len) {
// The variable-length pattern was there,
// so it has an array type with the remaining elements left as its size...
return r;
return (self.tcx.mk_array(element_ty, pat_len), arr_ty);
} else {
// ...however, in this case, there were no remaining elements.
// That is, the slice pattern requires more than the array type offers.
self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len);
}
} else if slice.is_none() {
// We have a pattern with a fixed length,
// which we can use to infer the length of the array.
let updated_arr_ty = self.tcx.mk_array(element_ty, min_len);
self.demand_eqtype(span, updated_arr_ty, arr_ty);
return (self.tcx.types.err, updated_arr_ty);
} else {
// No idea what the length is, which happens if we have e.g.,
// `let [a, b] = arr` where `arr: [T; N]` where `const N: usize`.
// We have a variable-length pattern and don't know the array length.
// This happens if we have e.g.,
// `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`.
self.error_scrutinee_unfixed_length(span);
}
None
(self.tcx.types.err, arr_ty)
}
fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) {

View File

@ -497,11 +497,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
// of the type.
// Therefore, we make sure that we never add a ?Sized
// bound for projections
match &ty {
&Type::QPath { .. } => {
has_sized.insert(ty.clone());
}
_ => {}
if let Type::QPath { .. } = ty {
has_sized.insert(ty.clone());
}
if bounds.is_empty() {

View File

@ -521,11 +521,8 @@ impl<'tcx> Clean<Option<WherePredicate>>
fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
let ty::OutlivesPredicate(ref a, ref b) = *self;
match (a, b) {
(ty::ReEmpty(_), ty::ReEmpty(_)) => {
return None;
}
_ => {}
if let (ty::ReEmpty(_), ty::ReEmpty(_)) = (a, b) {
return None;
}
Some(WherePredicate::RegionPredicate {
@ -539,9 +536,8 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty:
fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
let ty::OutlivesPredicate(ref ty, ref lt) = *self;
match lt {
ty::ReEmpty(_) => return None,
_ => {}
if let ty::ReEmpty(_) = lt {
return None;
}
Some(WherePredicate::BoundPredicate {
@ -2239,15 +2235,12 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
} else {
let name = self.name;
if !please_inline {
match path.res {
Res::Def(DefKind::Mod, did) => {
if !did.is_local() && did.index == CRATE_DEF_INDEX {
// if we're `pub use`ing an extern crate root, don't inline it unless we
// were specifically asked for it
denied = true;
}
if let Res::Def(DefKind::Mod, did) = path.res {
if !did.is_local() && did.index == CRATE_DEF_INDEX {
// if we're `pub use`ing an extern crate root, don't inline it unless we
// were specifically asked for it
denied = true;
}
_ => {}
}
}
if !denied {
@ -2426,10 +2419,9 @@ impl From<GenericBound> for SimpleBound {
GenericBound::TraitBound(t, mod_) => match t.trait_ {
Type::ResolvedPath { path, param_names, .. } => SimpleBound::TraitBound(
path.segments,
param_names.map_or_else(
|| Vec::new(),
|v| v.iter().map(|p| SimpleBound::from(p.clone())).collect(),
),
param_names.map_or_else(Vec::new, |v| {
v.iter().map(|p| SimpleBound::from(p.clone())).collect()
}),
t.generic_params,
mod_,
),

View File

@ -121,7 +121,7 @@ pub fn external_generic_args(
let args: Vec<_> = substs
.iter()
.filter_map(|kind| match kind.unpack() {
GenericArgKind::Lifetime(lt) => lt.clean(cx).map(|lt| GenericArg::Lifetime(lt)),
GenericArgKind::Lifetime(lt) => lt.clean(cx).map(GenericArg::Lifetime),
GenericArgKind::Type(_) if skip_self => {
skip_self = false;
None
@ -198,27 +198,24 @@ pub fn get_real_types(
}) {
let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]);
for bound in bounds.iter() {
match *bound {
GenericBound::TraitBound(ref poly_trait, _) => {
for x in poly_trait.generic_params.iter() {
if !x.is_type() {
continue;
}
if let Some(ty) = x.get_type() {
let adds = get_real_types(generics, &ty, cx, recurse + 1);
if !adds.is_empty() {
res.extend(adds);
} else if !ty.is_full_generic() {
if let Some(did) = ty.def_id() {
if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
res.insert((ty, kind));
}
if let GenericBound::TraitBound(ref poly_trait, _) = *bound {
for x in poly_trait.generic_params.iter() {
if !x.is_type() {
continue;
}
if let Some(ty) = x.get_type() {
let adds = get_real_types(generics, &ty, cx, recurse + 1);
if !adds.is_empty() {
res.extend(adds);
} else if !ty.is_full_generic() {
if let Some(did) = ty.def_id() {
if let Some(kind) = cx.tcx.def_kind(did).clean(cx) {
res.insert((ty, kind));
}
}
}
}
}
_ => {}
}
}
}

View File

@ -448,7 +448,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for SummaryLine<'a, I> {
if !self.started {
self.started = true;
}
while let Some(event) = self.inner.next() {
if let Some(event) = self.inner.next() {
let mut is_start = true;
let is_allowed_tag = match event {
Event::Start(Tag::CodeBlock(_)) | Event::End(Tag::CodeBlock(_)) => {
@ -944,75 +944,70 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
let mut p = Parser::new_ext(md, opts()).into_offset_iter();
while let Some((event, offset)) = p.next() {
match event {
Event::Start(Tag::CodeBlock(syntax)) => {
let (syntax, code_start, code_end, range, is_fenced) = match syntax {
CodeBlockKind::Fenced(syntax) => {
let syntax = syntax.as_ref();
let lang_string = if syntax.is_empty() {
LangString::all_false()
} else {
LangString::parse(&*syntax, ErrorCodes::Yes, false)
};
if !lang_string.rust {
if let Event::Start(Tag::CodeBlock(syntax)) = event {
let (syntax, code_start, code_end, range, is_fenced) = match syntax {
CodeBlockKind::Fenced(syntax) => {
let syntax = syntax.as_ref();
let lang_string = if syntax.is_empty() {
LangString::all_false()
} else {
LangString::parse(&*syntax, ErrorCodes::Yes, false)
};
if !lang_string.rust {
continue;
}
let syntax = if syntax.is_empty() { None } else { Some(syntax.to_owned()) };
let (code_start, mut code_end) = match p.next() {
Some((Event::Text(_), offset)) => (offset.start, offset.end),
Some((_, sub_offset)) => {
let code = Range { start: sub_offset.start, end: sub_offset.start };
code_blocks.push(RustCodeBlock {
is_fenced: true,
range: offset,
code,
syntax,
});
continue;
}
let syntax = if syntax.is_empty() { None } else { Some(syntax.to_owned()) };
let (code_start, mut code_end) = match p.next() {
Some((Event::Text(_), offset)) => (offset.start, offset.end),
Some((_, sub_offset)) => {
let code = Range { start: sub_offset.start, end: sub_offset.start };
code_blocks.push(RustCodeBlock {
is_fenced: true,
range: offset,
code,
syntax,
});
continue;
}
None => {
let code = Range { start: offset.end, end: offset.end };
code_blocks.push(RustCodeBlock {
is_fenced: true,
range: offset,
code,
syntax,
});
continue;
}
};
while let Some((Event::Text(_), offset)) = p.next() {
code_end = offset.end;
None => {
let code = Range { start: offset.end, end: offset.end };
code_blocks.push(RustCodeBlock {
is_fenced: true,
range: offset,
code,
syntax,
});
continue;
}
(syntax, code_start, code_end, offset, true)
};
while let Some((Event::Text(_), offset)) = p.next() {
code_end = offset.end;
}
CodeBlockKind::Indented => {
// The ending of the offset goes too far sometime so we reduce it by one in
// these cases.
if offset.end > offset.start
&& md.get(offset.end..=offset.end) == Some(&"\n")
{
(
None,
offset.start,
offset.end,
Range { start: offset.start, end: offset.end - 1 },
false,
)
} else {
(None, offset.start, offset.end, offset, false)
}
(syntax, code_start, code_end, offset, true)
}
CodeBlockKind::Indented => {
// The ending of the offset goes too far sometime so we reduce it by one in
// these cases.
if offset.end > offset.start && md.get(offset.end..=offset.end) == Some(&"\n") {
(
None,
offset.start,
offset.end,
Range { start: offset.start, end: offset.end - 1 },
false,
)
} else {
(None, offset.start, offset.end, offset, false)
}
};
}
};
code_blocks.push(RustCodeBlock {
is_fenced,
range,
code: Range { start: code_start, end: code_end },
syntax,
});
}
_ => (),
code_blocks.push(RustCodeBlock {
is_fenced,
range,
code: Range { start: code_start, end: code_end },
syntax,
});
}
}

View File

@ -782,7 +782,7 @@ themePicker.onblur = handleThemeButtonsBlur;
.split('"')
.next()
.map(|s| s.to_owned())
.unwrap_or_else(|| String::new()),
.unwrap_or_else(String::new),
);
}
}
@ -2158,7 +2158,7 @@ fn item_module(w: &mut Buffer, cx: &Context, item: &clean::Item, items: &[clean:
docs = MarkdownSummaryLine(doc_value, &myitem.links()).to_string(),
class = myitem.type_(),
add = add,
stab = stab.unwrap_or_else(|| String::new()),
stab = stab.unwrap_or_else(String::new),
unsafety_flag = unsafety_flag,
href = item_path(myitem.type_(), myitem.name.as_ref().unwrap()),
title = [full_path(cx, myitem), myitem.type_().to_string()]
@ -4593,12 +4593,9 @@ fn collect_paths_for_type(first_ty: clean::Type) -> Vec<String> {
let get_extern = || cache.external_paths.get(&did).map(|s| s.0.clone());
let fqp = cache.exact_paths.get(&did).cloned().or_else(get_extern);
match fqp {
Some(path) => {
out.push(path.join("::"));
}
_ => {}
};
if let Some(path) = fqp {
out.push(path.join("::"));
}
}
clean::Type::Tuple(tys) => {
work.extend(tys.into_iter());

View File

@ -590,7 +590,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
for item in search_index {
item.parent_idx = item.parent.and_then(|defid| {
if defid_to_pathid.contains_key(&defid) {
defid_to_pathid.get(&defid).map(|x| *x)
defid_to_pathid.get(&defid).copied()
} else {
let pathid = lastpathid;
defid_to_pathid.insert(defid, pathid);

View File

@ -496,7 +496,7 @@ pub fn stdout() -> Stdout {
unsafe {
let ret = Arc::new(ReentrantMutex::new(RefCell::new(LineWriter::new(stdout))));
ret.init();
return ret;
ret
}
}
}
@ -664,7 +664,7 @@ pub fn stderr() -> Stderr {
*INSTANCE.lock().borrow_mut() = Maybe::Real(stderr);
}
});
return Stderr { inner: &INSTANCE };
Stderr { inner: &INSTANCE }
}
impl Stderr {

View File

@ -72,7 +72,7 @@ impl Command {
}
};
let mut p = Process { pid: pid, status: None };
let mut p = Process { pid, status: None };
drop(output);
let mut bytes = [0; 8];

View File

@ -10,7 +10,7 @@ unsafe impl GlobalAlloc for System {
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
libc::malloc(layout.size()) as *mut u8
} else {
libc::aligned_alloc(layout.size(), layout.align()) as *mut u8
libc::aligned_alloc(layout.align(), layout.size()) as *mut u8
}
}

View File

@ -0,0 +1,21 @@
// see issue #70529
struct A;
impl From<A> for [u8; 2] {
fn from(a: A) -> Self {
[0; 2]
}
}
impl From<A> for [u8; 3] {
fn from(a: A) -> Self {
[0; 3]
}
}
fn main() {
let a = A;
let [_, _] = a.into();
//~^ ERROR type annotations needed
}

View File

@ -0,0 +1,11 @@
error[E0282]: type annotations needed
--> $DIR/infer_array_len.rs:19:9
|
LL | let [_, _] = a.into();
| ^^^^^^ consider giving this pattern a type
|
= note: type must be known at this point
error: aborting due to previous error
For more information about this error, try `rustc --explain E0282`.

View File

@ -0,0 +1,11 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
fn is_123<const N: usize>(x: [u32; N]) -> bool {
match x {
[1, 2] => true, //~ ERROR mismatched types
_ => false
}
}
fn main() {}

View File

@ -0,0 +1,20 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/match_arr_unknown_len.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
error[E0308]: mismatched types
--> $DIR/match_arr_unknown_len.rs:6:9
|
LL | [1, 2] => true,
| ^^^^^^ expected `2usize`, found `N`
|
= note: expected array `[u32; 2]`
found array `[u32; _]`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,27 @@
// run-pass
//
// see issue #70529
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
struct A<const N: usize> {
arr: [u8; N],
}
impl<const N: usize> A<N> {
fn new() -> Self {
A {
arr: [0; N],
}
}
fn value(&self) -> usize {
N
}
}
fn main() {
let a = A::new();
let [_, _] = a.arr;
assert_eq!(a.value(), 2);
}

View File

@ -0,0 +1,8 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/infer_arg_from_pat.rs:4:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

View File

@ -0,0 +1,13 @@
// check-pass
//
// see issue #70529
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
fn as_chunks<const N: usize>() -> [u8; N] {
loop {}
}
fn main() {
let [_, _] = as_chunks();
}

View File

@ -0,0 +1,8 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/infer_arr_len_from_pat.rs:4:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default

View File

@ -3,7 +3,7 @@
fn is_123<const N: usize>(x: [u32; N]) -> bool {
match x {
[1, 2, 3] => true, //~ ERROR cannot pattern-match on an array without a fixed length
[1, 2, ..] => true, //~ ERROR cannot pattern-match on an array without a fixed length
_ => false
}
}

View File

@ -9,8 +9,8 @@ LL | #![feature(const_generics)]
error[E0730]: cannot pattern-match on an array without a fixed length
--> $DIR/E0730.rs:6:9
|
LL | [1, 2, 3] => true,
| ^^^^^^^^^
LL | [1, 2, ..] => true,
| ^^^^^^^^^^
error: aborting due to previous error

View File

@ -0,0 +1,18 @@
struct S {}
impl S {
fn foo(&mur Self) {}
//~^ ERROR expected identifier, found keyword `Self`
//~| ERROR expected one of `:`, `@`
//~| ERROR the `Self` constructor can only be used with
fn bar(&'static mur Self) {}
//~^ ERROR unexpected lifetime
//~| ERROR expected identifier, found keyword `Self`
//~| ERROR expected one of `:`, `@`
//~| ERROR the `Self` constructor can only be used with
fn baz(&mur Self @ _) {}
//~^ ERROR expected one of `:`, `@`
}
fn main() {}

View File

@ -0,0 +1,56 @@
error: expected identifier, found keyword `Self`
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
|
LL | fn foo(&mur Self) {}
| ^^^^ expected identifier, found keyword
error: expected one of `:`, `@`, or `|`, found keyword `Self`
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
|
LL | fn foo(&mur Self) {}
| -----^^^^
| | |
| | expected one of `:`, `@`, or `|`
| help: declare the type after the parameter binding: `<identifier>: <type>`
error: unexpected lifetime `'static` in pattern
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:13
|
LL | fn bar(&'static mur Self) {}
| ^^^^^^^ help: remove the lifetime
error: expected identifier, found keyword `Self`
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
|
LL | fn bar(&'static mur Self) {}
| ^^^^ expected identifier, found keyword
error: expected one of `:`, `@`, or `|`, found keyword `Self`
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
|
LL | fn bar(&'static mur Self) {}
| -------------^^^^
| | |
| | expected one of `:`, `@`, or `|`
| help: declare the type after the parameter binding: `<identifier>: <type>`
error: expected one of `:`, `@`, or `|`, found keyword `Self`
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:14:17
|
LL | fn baz(&mur Self @ _) {}
| ^^^^ expected one of `:`, `@`, or `|`
error: the `Self` constructor can only be used with tuple or unit structs
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
|
LL | fn foo(&mur Self) {}
| ^^^^ help: use curly brackets: `Self { /* fields */ }`
error: the `Self` constructor can only be used with tuple or unit structs
--> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
|
LL | fn bar(&'static mur Self) {}
| ^^^^ help: use curly brackets: `Self { /* fields */ }`
error: aborting due to 8 previous errors

View File

@ -31,5 +31,5 @@ LL | struct Foo<'a,'b,'c> {
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0392, E0478.
For more information about an error, try `rustc --explain E0392`.
Some errors have detailed explanations: E0226, E0392, E0478.
For more information about an error, try `rustc --explain E0226`.