mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
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:
commit
75ff3110ac
2
.github/ISSUE_TEMPLATE/ice.md
vendored
2
.github/ISSUE_TEMPLATE/ice.md
vendored
@ -14,7 +14,7 @@ http://blog.pnkfx.org/blog/2019/11/18/rust-bug-minimization-patterns/
|
||||
|
||||
### Code
|
||||
|
||||
```
|
||||
```Rust
|
||||
<code>
|
||||
```
|
||||
|
||||
|
@ -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")]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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,
|
||||
|
21
src/librustc_error_codes/error_codes/E0226.md
Normal file
21
src/librustc_error_codes/error_codes/E0226.md
Normal 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;
|
||||
```
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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];
|
||||
|
@ -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,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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) => {
|
||||
|
@ -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(
|
||||
|
@ -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(),
|
||||
|
@ -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(),
|
||||
|
@ -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) {
|
||||
|
@ -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() {
|
||||
|
@ -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_,
|
||||
),
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
21
src/test/ui/array-slice-vec/infer_array_len.rs
Normal file
21
src/test/ui/array-slice-vec/infer_array_len.rs
Normal 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
|
||||
}
|
11
src/test/ui/array-slice-vec/infer_array_len.stderr
Normal file
11
src/test/ui/array-slice-vec/infer_array_len.stderr
Normal 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`.
|
11
src/test/ui/array-slice-vec/match_arr_unknown_len.rs
Normal file
11
src/test/ui/array-slice-vec/match_arr_unknown_len.rs
Normal 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() {}
|
20
src/test/ui/array-slice-vec/match_arr_unknown_len.stderr
Normal file
20
src/test/ui/array-slice-vec/match_arr_unknown_len.stderr
Normal 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`.
|
27
src/test/ui/const-generics/infer_arg_from_pat.rs
Normal file
27
src/test/ui/const-generics/infer_arg_from_pat.rs
Normal 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);
|
||||
}
|
8
src/test/ui/const-generics/infer_arg_from_pat.stderr
Normal file
8
src/test/ui/const-generics/infer_arg_from_pat.stderr
Normal 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
|
||||
|
13
src/test/ui/const-generics/infer_arr_len_from_pat.rs
Normal file
13
src/test/ui/const-generics/infer_arr_len_from_pat.rs
Normal 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();
|
||||
}
|
8
src/test/ui/const-generics/infer_arr_len_from_pat.stderr
Normal file
8
src/test/ui/const-generics/infer_arr_len_from_pat.stderr
Normal 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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
@ -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
|
||||
|
@ -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`.
|
||||
|
Loading…
Reference in New Issue
Block a user