mirror of
https://git.proxmox.com/git/rustc
synced 2026-02-01 18:03:40 +00:00
New upstream version 1.49.0+dfsg1
This commit is contained in:
parent
29967ef60b
commit
b985613438
134
RELEASES.md
134
RELEASES.md
@ -1,3 +1,131 @@
|
||||
Version 1.49.0 (2020-12-31)
|
||||
============================
|
||||
|
||||
Language
|
||||
-----------------------
|
||||
|
||||
- [Unions can now implement `Drop`, and you can now have a field in a union
|
||||
with `ManuallyDrop<T>`.][77547]
|
||||
- [You can now cast uninhabited enums to integers.][76199]
|
||||
- [You can now bind by reference and by move in patterns.][76119] This
|
||||
allows you to selectively borrow individual components of a type. E.g.
|
||||
```rust
|
||||
#[derive(Debug)]
|
||||
struct Person {
|
||||
name: String,
|
||||
age: u8,
|
||||
}
|
||||
|
||||
let person = Person {
|
||||
name: String::from("Alice"),
|
||||
age: 20,
|
||||
};
|
||||
|
||||
// `name` is moved out of person, but `age` is referenced.
|
||||
let Person { name, ref age } = person;
|
||||
println!("{} {}", name, age);
|
||||
```
|
||||
|
||||
Compiler
|
||||
-----------------------
|
||||
|
||||
- [Added tier 1\* support for `aarch64-unknown-linux-gnu`.][78228]
|
||||
- [Added tier 2 support for `aarch64-apple-darwin`.][75991]
|
||||
- [Added tier 2 support for `aarch64-pc-windows-msvc`.][75914]
|
||||
- [Added tier 3 support for `mipsel-unknown-none`.][78676]
|
||||
- [Raised the minimum supported LLVM version to LLVM 9.][78848]
|
||||
- [Output from threads spawned in tests is now captured.][78227]
|
||||
- [Change os and vendor values to "none" and "unknown" for some targets][78951]
|
||||
|
||||
\* Refer to Rust's [platform support page][forge-platform-support] for more
|
||||
information on Rust's tiered platform support.
|
||||
|
||||
Libraries
|
||||
-----------------------
|
||||
|
||||
- [`RangeInclusive` now checks for exhaustion when calling `contains` and indexing.][78109]
|
||||
- [`ToString::to_string` now no longer shrinks the internal buffer in the default implementation.][77997]
|
||||
- [`ops::{Index, IndexMut}` are now implemented for fixed sized arrays of any length.][74989]
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`slice::select_nth_unstable`]
|
||||
- [`slice::select_nth_unstable_by`]
|
||||
- [`slice::select_nth_unstable_by_key`]
|
||||
|
||||
The following previously stable methods are now `const`.
|
||||
|
||||
- [`Poll::is_ready`]
|
||||
- [`Poll::is_pending`]
|
||||
|
||||
Cargo
|
||||
-----------------------
|
||||
- [Building a crate with `cargo-package` should now be independently reproducible.][cargo/8864]
|
||||
- [`cargo-tree` now marks proc-macro crates.][cargo/8765]
|
||||
- [Added `CARGO_PRIMARY_PACKAGE` build-time environment variable.][cargo/8758] This
|
||||
variable will be set if the crate being built is one the user selected to build, either
|
||||
with `-p` or through defaults.
|
||||
- [You can now use glob patterns when specifying packages & targets.][cargo/8752]
|
||||
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
- [Demoted `i686-unknown-freebsd` from host tier 2 to target tier 2 support.][78746]
|
||||
- [Macros that end with a semi-colon are now treated as statements even if they expand to nothing.][78376]
|
||||
- [Rustc will now check for the validity of some built-in attributes on enum variants.][77015]
|
||||
Previously such invalid or unused attributes could be ignored.
|
||||
- Leading whitespace is stripped more uniformly in documentation comments, which may change behavior. You
|
||||
read [this post about the changes][rustdoc-ws-post] for more details.
|
||||
- [Trait bounds are no longer inferred for associated types.][79904]
|
||||
|
||||
Internal Only
|
||||
-------------
|
||||
These changes provide no direct user facing benefits, but represent significant
|
||||
improvements to the internals and overall performance of rustc and
|
||||
related tools.
|
||||
|
||||
- [rustc's internal crates are now compiled using the `initial-exec` Thread
|
||||
Local Storage model.][78201]
|
||||
- [Calculate visibilities once in resolve.][78077]
|
||||
- [Added `system` to the `llvm-libunwind` bootstrap config option.][77703]
|
||||
- [Added `--color` for configuring terminal color support to bootstrap.][79004]
|
||||
|
||||
|
||||
[75991]: https://github.com/rust-lang/rust/pull/75991
|
||||
[78951]: https://github.com/rust-lang/rust/pull/78951
|
||||
[78848]: https://github.com/rust-lang/rust/pull/78848
|
||||
[78746]: https://github.com/rust-lang/rust/pull/78746
|
||||
[78376]: https://github.com/rust-lang/rust/pull/78376
|
||||
[78228]: https://github.com/rust-lang/rust/pull/78228
|
||||
[78227]: https://github.com/rust-lang/rust/pull/78227
|
||||
[78201]: https://github.com/rust-lang/rust/pull/78201
|
||||
[78109]: https://github.com/rust-lang/rust/pull/78109
|
||||
[78077]: https://github.com/rust-lang/rust/pull/78077
|
||||
[77997]: https://github.com/rust-lang/rust/pull/77997
|
||||
[77703]: https://github.com/rust-lang/rust/pull/77703
|
||||
[77547]: https://github.com/rust-lang/rust/pull/77547
|
||||
[77015]: https://github.com/rust-lang/rust/pull/77015
|
||||
[76199]: https://github.com/rust-lang/rust/pull/76199
|
||||
[76119]: https://github.com/rust-lang/rust/pull/76119
|
||||
[75914]: https://github.com/rust-lang/rust/pull/75914
|
||||
[74989]: https://github.com/rust-lang/rust/pull/74989
|
||||
[79004]: https://github.com/rust-lang/rust/pull/79004
|
||||
[78676]: https://github.com/rust-lang/rust/pull/78676
|
||||
[79904]: https://github.com/rust-lang/rust/issues/79904
|
||||
[cargo/8864]: https://github.com/rust-lang/cargo/pull/8864
|
||||
[cargo/8765]: https://github.com/rust-lang/cargo/pull/8765
|
||||
[cargo/8758]: https://github.com/rust-lang/cargo/pull/8758
|
||||
[cargo/8752]: https://github.com/rust-lang/cargo/pull/8752
|
||||
[`slice::select_nth_unstable`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable
|
||||
[`slice::select_nth_unstable_by`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable_by
|
||||
[`slice::select_nth_unstable_by_key`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.select_nth_unstable_by_key
|
||||
[`hint::spin_loop`]: https://doc.rust-lang.org/stable/std/hint/fn.spin_loop.html
|
||||
[`Poll::is_ready`]: https://doc.rust-lang.org/stable/std/task/enum.Poll.html#method.is_ready
|
||||
[`Poll::is_pending`]: https://doc.rust-lang.org/stable/std/task/enum.Poll.html#method.is_pending
|
||||
[rustdoc-ws-post]: https://blog.guillaume-gomez.fr/articles/2020-11-11+New+doc+comment+handling+in+rustdoc
|
||||
|
||||
Version 1.48.0 (2020-11-19)
|
||||
==========================
|
||||
|
||||
@ -10,7 +138,7 @@ Language
|
||||
Compiler
|
||||
--------
|
||||
- [Stabilised the `-C link-self-contained=<yes|no>` compiler flag.][76158] This tells
|
||||
`rustc` whether to link its own C runtime and libraries or to rely on a external
|
||||
`rustc` whether to link its own C runtime and libraries or to rely on a external
|
||||
linker to find them. (Supported only on `windows-gnu`, `linux-musl`, and `wasi` platforms.)
|
||||
- [You can now use `-C target-feature=+crt-static` on `linux-gnu` targets.][77386]
|
||||
Note: If you're using cargo you must explicitly pass the `--target` flag.
|
||||
@ -82,7 +210,7 @@ Compatibility Notes
|
||||
- [Foreign exceptions are now caught by `catch_unwind` and will cause an abort.][70212]
|
||||
Note: This behaviour is not guaranteed and is still considered undefined behaviour,
|
||||
see the [`catch_unwind`] documentation for further information.
|
||||
|
||||
|
||||
|
||||
|
||||
Internal Only
|
||||
@ -102,7 +230,7 @@ related tools.
|
||||
[76030]: https://github.com/rust-lang/rust/pull/76030/
|
||||
[70212]: https://github.com/rust-lang/rust/pull/70212/
|
||||
[27675]: https://github.com/rust-lang/rust/issues/27675/
|
||||
[54121]: https://github.com/rust-lang/rust/issues/54121/
|
||||
[54121]: https://github.com/rust-lang/rust/issues/54121/
|
||||
[71274]: https://github.com/rust-lang/rust/pull/71274/
|
||||
[77386]: https://github.com/rust-lang/rust/pull/77386/
|
||||
[77153]: https://github.com/rust-lang/rust/pull/77153/
|
||||
|
||||
@ -84,7 +84,7 @@ enum TokenTree {
|
||||
/// e.g., `$var`
|
||||
MetaVar(Span, Ident),
|
||||
/// e.g., `$var:expr`. This is only used in the left hand side of MBE macros.
|
||||
MetaVarDecl(Span, Ident /* name to bind */, NonterminalKind),
|
||||
MetaVarDecl(Span, Ident /* name to bind */, Option<NonterminalKind>),
|
||||
}
|
||||
|
||||
impl TokenTree {
|
||||
|
||||
@ -378,6 +378,11 @@ fn nameize<I: Iterator<Item = NamedMatch>>(
|
||||
n_rec(sess, next_m, res.by_ref(), ret_val)?;
|
||||
}
|
||||
}
|
||||
TokenTree::MetaVarDecl(span, _, None) => {
|
||||
if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
|
||||
return Err((span, "missing fragment specifier".to_string()));
|
||||
}
|
||||
}
|
||||
TokenTree::MetaVarDecl(sp, bind_name, _) => match ret_val
|
||||
.entry(MacroRulesNormalizedIdent::new(bind_name))
|
||||
{
|
||||
@ -437,6 +442,7 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
|
||||
///
|
||||
/// A `ParseResult`. Note that matches are kept track of through the items generated.
|
||||
fn inner_parse_loop<'root, 'tt>(
|
||||
sess: &ParseSess,
|
||||
cur_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
|
||||
next_items: &mut Vec<MatcherPosHandle<'root, 'tt>>,
|
||||
eof_items: &mut SmallVec<[MatcherPosHandle<'root, 'tt>; 1]>,
|
||||
@ -554,9 +560,16 @@ fn inner_parse_loop<'root, 'tt>(
|
||||
})));
|
||||
}
|
||||
|
||||
// We need to match a metavar (but the identifier is invalid)... this is an error
|
||||
TokenTree::MetaVarDecl(span, _, None) => {
|
||||
if sess.missing_fragment_specifiers.borrow_mut().remove(&span).is_some() {
|
||||
return Error(span, "missing fragment specifier".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// We need to match a metavar with a valid ident... call out to the black-box
|
||||
// parser by adding an item to `bb_items`.
|
||||
TokenTree::MetaVarDecl(_, _, kind) => {
|
||||
TokenTree::MetaVarDecl(_, _, Some(kind)) => {
|
||||
// Built-in nonterminals never start with these tokens,
|
||||
// so we can eliminate them from consideration.
|
||||
if Parser::nonterminal_may_begin_with(kind, token) {
|
||||
@ -627,6 +640,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
|
||||
// parsing from the black-box parser done. The result is that `next_items` will contain a
|
||||
// bunch of possible next matcher positions in `next_items`.
|
||||
match inner_parse_loop(
|
||||
parser.sess,
|
||||
&mut cur_items,
|
||||
&mut next_items,
|
||||
&mut eof_items,
|
||||
@ -688,7 +702,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
|
||||
let nts = bb_items
|
||||
.iter()
|
||||
.map(|item| match item.top_elts.get_tt(item.idx) {
|
||||
TokenTree::MetaVarDecl(_, bind, kind) => format!("{} ('{}')", kind, bind),
|
||||
TokenTree::MetaVarDecl(_, bind, Some(kind)) => format!("{} ('{}')", kind, bind),
|
||||
_ => panic!(),
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
@ -718,7 +732,7 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
|
||||
assert_eq!(bb_items.len(), 1);
|
||||
|
||||
let mut item = bb_items.pop().unwrap();
|
||||
if let TokenTree::MetaVarDecl(span, _, kind) = item.top_elts.get_tt(item.idx) {
|
||||
if let TokenTree::MetaVarDecl(span, _, Some(kind)) = item.top_elts.get_tt(item.idx) {
|
||||
let match_cur = item.match_cur;
|
||||
let nt = match parser.to_mut().parse_nonterminal(kind) {
|
||||
Err(mut err) => {
|
||||
|
||||
@ -401,7 +401,7 @@ pub fn compile_declarative_macro(
|
||||
let diag = &sess.parse_sess.span_diagnostic;
|
||||
let lhs_nm = Ident::new(sym::lhs, def.span);
|
||||
let rhs_nm = Ident::new(sym::rhs, def.span);
|
||||
let tt_spec = NonterminalKind::TT;
|
||||
let tt_spec = Some(NonterminalKind::TT);
|
||||
|
||||
// Parse the macro_rules! invocation
|
||||
let (macro_rules, body) = match &def.kind {
|
||||
@ -578,7 +578,7 @@ fn check_lhs_no_empty_seq(sess: &ParseSess, tts: &[mbe::TokenTree]) -> bool {
|
||||
TokenTree::Sequence(span, ref seq) => {
|
||||
if seq.separator.is_none()
|
||||
&& seq.tts.iter().all(|seq_tt| match *seq_tt {
|
||||
TokenTree::MetaVarDecl(_, _, NonterminalKind::Vis) => true,
|
||||
TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Vis)) => true,
|
||||
TokenTree::Sequence(_, ref sub_seq) => {
|
||||
sub_seq.kleene.op == mbe::KleeneOp::ZeroOrMore
|
||||
|| sub_seq.kleene.op == mbe::KleeneOp::ZeroOrOne
|
||||
@ -961,7 +961,7 @@ fn check_matcher_core(
|
||||
// Now `last` holds the complete set of NT tokens that could
|
||||
// end the sequence before SUFFIX. Check that every one works with `suffix`.
|
||||
for token in &last.tokens {
|
||||
if let TokenTree::MetaVarDecl(_, name, kind) = *token {
|
||||
if let TokenTree::MetaVarDecl(_, name, Some(kind)) = *token {
|
||||
for next_token in &suffix_first.tokens {
|
||||
match is_in_follow(next_token, kind) {
|
||||
IsInFollow::Yes => {}
|
||||
@ -1019,7 +1019,7 @@ fn check_matcher_core(
|
||||
}
|
||||
|
||||
fn token_can_be_followed_by_any(tok: &mbe::TokenTree) -> bool {
|
||||
if let mbe::TokenTree::MetaVarDecl(_, _, kind) = *tok {
|
||||
if let mbe::TokenTree::MetaVarDecl(_, _, Some(kind)) = *tok {
|
||||
frag_can_be_followed_by_any(kind)
|
||||
} else {
|
||||
// (Non NT's can always be followed by anything in matchers.)
|
||||
@ -1123,7 +1123,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
||||
}
|
||||
_ => IsInFollow::No(TOKENS),
|
||||
},
|
||||
TokenTree::MetaVarDecl(_, _, NonterminalKind::Block) => IsInFollow::Yes,
|
||||
TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes,
|
||||
_ => IsInFollow::No(TOKENS),
|
||||
}
|
||||
}
|
||||
@ -1158,7 +1158,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
|
||||
TokenTree::MetaVarDecl(
|
||||
_,
|
||||
_,
|
||||
NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path,
|
||||
Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path),
|
||||
) => IsInFollow::Yes,
|
||||
_ => IsInFollow::No(TOKENS),
|
||||
}
|
||||
@ -1171,7 +1171,8 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String {
|
||||
match *tt {
|
||||
mbe::TokenTree::Token(ref token) => pprust::token_to_string(&token),
|
||||
mbe::TokenTree::MetaVar(_, name) => format!("${}", name),
|
||||
mbe::TokenTree::MetaVarDecl(_, name, kind) => format!("${}:{}", name, kind),
|
||||
mbe::TokenTree::MetaVarDecl(_, name, Some(kind)) => format!("${}:{}", name, kind),
|
||||
mbe::TokenTree::MetaVarDecl(_, name, None) => format!("${}:", name),
|
||||
_ => panic!(
|
||||
"unexpected mbe::TokenTree::{{Sequence or Delimited}} \
|
||||
in follow set checker"
|
||||
|
||||
@ -3,7 +3,7 @@ use crate::mbe::{Delimited, KleeneOp, KleeneToken, SequenceRepetition, TokenTree
|
||||
|
||||
use rustc_ast::token::{self, Token};
|
||||
use rustc_ast::tokenstream;
|
||||
use rustc_ast::NodeId;
|
||||
use rustc_ast::{NodeId, DUMMY_NODE_ID};
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::symbol::{kw, Ident};
|
||||
@ -73,7 +73,7 @@ pub(super) fn parse(
|
||||
.emit();
|
||||
token::NonterminalKind::Ident
|
||||
});
|
||||
result.push(TokenTree::MetaVarDecl(span, ident, kind));
|
||||
result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
|
||||
continue;
|
||||
}
|
||||
_ => token.span,
|
||||
@ -83,8 +83,11 @@ pub(super) fn parse(
|
||||
}
|
||||
tree => tree.as_ref().map(tokenstream::TokenTree::span).unwrap_or(start_sp),
|
||||
};
|
||||
sess.span_diagnostic.struct_span_err(span, "missing fragment specifier").emit();
|
||||
continue;
|
||||
if node_id != DUMMY_NODE_ID {
|
||||
// Macros loaded from other crates have dummy node ids.
|
||||
sess.missing_fragment_specifiers.borrow_mut().insert(span, node_id);
|
||||
}
|
||||
result.push(TokenTree::MetaVarDecl(span, ident, None));
|
||||
}
|
||||
|
||||
// Not a metavar or no matchers allowed, so just return the tree
|
||||
|
||||
@ -90,6 +90,7 @@ impl ProjectionCacheKey<'tcx> {
|
||||
pub enum ProjectionCacheEntry<'tcx> {
|
||||
InProgress,
|
||||
Ambiguous,
|
||||
Recur,
|
||||
Error,
|
||||
NormalizedTy(NormalizedTy<'tcx>),
|
||||
}
|
||||
@ -143,7 +144,12 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
|
||||
"ProjectionCacheEntry::insert_ty: adding cache entry: key={:?}, value={:?}",
|
||||
key, value
|
||||
);
|
||||
let fresh_key = self.map().insert(key, ProjectionCacheEntry::NormalizedTy(value));
|
||||
let mut map = self.map();
|
||||
if let Some(ProjectionCacheEntry::Recur) = map.get(&key) {
|
||||
debug!("Not overwriting Recur");
|
||||
return;
|
||||
}
|
||||
let fresh_key = map.insert(key, ProjectionCacheEntry::NormalizedTy(value));
|
||||
assert!(!fresh_key, "never started projecting `{:?}`", key);
|
||||
}
|
||||
|
||||
@ -197,6 +203,14 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
|
||||
assert!(!fresh, "never started projecting `{:?}`", key);
|
||||
}
|
||||
|
||||
/// Indicates that while trying to normalize `key`, `key` was required to
|
||||
/// be normalized again. Selection or evaluation should eventually report
|
||||
/// an error here.
|
||||
pub fn recur(&mut self, key: ProjectionCacheKey<'tcx>) {
|
||||
let fresh = self.map().insert(key, ProjectionCacheEntry::Recur);
|
||||
assert!(!fresh, "never started projecting `{:?}`", key);
|
||||
}
|
||||
|
||||
/// Indicates that trying to normalize `key` resulted in
|
||||
/// error.
|
||||
pub fn error(&mut self, key: ProjectionCacheKey<'tcx>) {
|
||||
|
||||
@ -29,6 +29,7 @@ use rustc_passes::{self, hir_stats, layout_test};
|
||||
use rustc_plugin_impl as plugin;
|
||||
use rustc_resolve::{Resolver, ResolverArenas};
|
||||
use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType, PpMode, PpSourceMode};
|
||||
use rustc_session::lint;
|
||||
use rustc_session::output::{filename_for_input, filename_for_metadata};
|
||||
use rustc_session::search_paths::PathKind;
|
||||
use rustc_session::Session;
|
||||
@ -310,11 +311,27 @@ fn configure_and_expand_inner<'a>(
|
||||
ecx.check_unused_macros();
|
||||
});
|
||||
|
||||
let mut missing_fragment_specifiers: Vec<_> = ecx
|
||||
.sess
|
||||
.parse_sess
|
||||
.missing_fragment_specifiers
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|(span, node_id)| (*span, *node_id))
|
||||
.collect();
|
||||
missing_fragment_specifiers.sort_unstable_by_key(|(span, _)| *span);
|
||||
|
||||
let recursion_limit_hit = ecx.reduced_recursion_limit.is_some();
|
||||
|
||||
for (span, node_id) in missing_fragment_specifiers {
|
||||
let lint = lint::builtin::MISSING_FRAGMENT_SPECIFIER;
|
||||
let msg = "missing fragment specifier";
|
||||
resolver.lint_buffer().buffer_lint(lint, node_id, span, msg);
|
||||
}
|
||||
if cfg!(windows) {
|
||||
env::set_var("PATH", &old_path);
|
||||
}
|
||||
|
||||
let recursion_limit_hit = ecx.reduced_recursion_limit.is_some();
|
||||
if recursion_limit_hit {
|
||||
// If we hit a recursion limit, exit early to avoid later passes getting overwhelmed
|
||||
// with a large AST
|
||||
|
||||
@ -1228,6 +1228,50 @@ declare_lint! {
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `missing_fragment_specifier` lint is issued when an unused pattern in a
|
||||
/// `macro_rules!` macro definition has a meta-variable (e.g. `$e`) that is not
|
||||
/// followed by a fragment specifier (e.g. `:expr`).
|
||||
///
|
||||
/// This warning can always be fixed by removing the unused pattern in the
|
||||
/// `macro_rules!` macro definition.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,compile_fail
|
||||
/// macro_rules! foo {
|
||||
/// () => {};
|
||||
/// ($name) => { };
|
||||
/// }
|
||||
///
|
||||
/// fn main() {
|
||||
/// foo!();
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// To fix this, remove the unused pattern from the `macro_rules!` macro definition:
|
||||
///
|
||||
/// ```rust
|
||||
/// macro_rules! foo {
|
||||
/// () => {};
|
||||
/// }
|
||||
/// fn main() {
|
||||
/// foo!();
|
||||
/// }
|
||||
/// ```
|
||||
pub MISSING_FRAGMENT_SPECIFIER,
|
||||
Deny,
|
||||
"detects missing fragment specifiers in unused `macro_rules!` patterns",
|
||||
@future_incompatible = FutureIncompatibleInfo {
|
||||
reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
|
||||
edition: None,
|
||||
};
|
||||
}
|
||||
|
||||
declare_lint! {
|
||||
/// The `late_bound_lifetime_arguments` lint detects generic lifetime
|
||||
/// arguments in path segments with late bound lifetime parameters.
|
||||
@ -2784,6 +2828,7 @@ declare_lint_pass! {
|
||||
CONST_ITEM_MUTATION,
|
||||
SAFE_PACKED_BORROWS,
|
||||
PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
MISSING_FRAGMENT_SPECIFIER,
|
||||
LATE_BOUND_LIFETIME_ARGUMENTS,
|
||||
ORDER_DEPENDENT_TRAIT_OBJECTS,
|
||||
COHERENCE_LEAK_CHECK,
|
||||
|
||||
@ -27,6 +27,8 @@ impl<'a> Parser<'a> {
|
||||
token.can_begin_expr()
|
||||
// This exception is here for backwards compatibility.
|
||||
&& !token.is_keyword(kw::Let)
|
||||
// This exception is here for backwards compatibility.
|
||||
&& !token.is_keyword(kw::Const)
|
||||
}
|
||||
NonterminalKind::Ty => token.can_begin_type(),
|
||||
NonterminalKind::Ident => get_macro_ident(token).is_some(),
|
||||
|
||||
@ -119,6 +119,7 @@ pub struct ParseSess {
|
||||
pub unstable_features: UnstableFeatures,
|
||||
pub config: CrateConfig,
|
||||
pub edition: Edition,
|
||||
pub missing_fragment_specifiers: Lock<FxHashMap<Span, NodeId>>,
|
||||
/// Places where raw identifiers were used. This is used for feature-gating raw identifiers.
|
||||
pub raw_identifier_spans: Lock<Vec<Span>>,
|
||||
/// Used to determine and report recursive module inclusions.
|
||||
@ -153,6 +154,7 @@ impl ParseSess {
|
||||
unstable_features: UnstableFeatures::from_environment(),
|
||||
config: FxHashSet::default(),
|
||||
edition: ExpnId::root().expn_data().edition,
|
||||
missing_fragment_specifiers: Default::default(),
|
||||
raw_identifier_spans: Lock::new(Vec::new()),
|
||||
included_mod_stack: Lock::new(vec![]),
|
||||
source_map,
|
||||
|
||||
@ -496,12 +496,6 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
|
||||
return Ok(None);
|
||||
}
|
||||
Err(ProjectionCacheEntry::InProgress) => {
|
||||
// If while normalized A::B, we are asked to normalize
|
||||
// A::B, just return A::B itself. This is a conservative
|
||||
// answer, in the sense that A::B *is* clearly equivalent
|
||||
// to A::B, though there may be a better value we can
|
||||
// find.
|
||||
|
||||
// Under lazy normalization, this can arise when
|
||||
// bootstrapping. That is, imagine an environment with a
|
||||
// where-clause like `A::B == u32`. Now, if we are asked
|
||||
@ -512,6 +506,14 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
|
||||
|
||||
debug!("found cache entry: in-progress");
|
||||
|
||||
// Cache that normalizing this projection resulted in a cycle. This
|
||||
// should ensure that, unless this happens within a snapshot that's
|
||||
// rolled back, fulfillment or evaluation will notice the cycle.
|
||||
|
||||
infcx.inner.borrow_mut().projection_cache().recur(cache_key);
|
||||
return Err(InProgress);
|
||||
}
|
||||
Err(ProjectionCacheEntry::Recur) => {
|
||||
return Err(InProgress);
|
||||
}
|
||||
Err(ProjectionCacheEntry::NormalizedTy(ty)) => {
|
||||
@ -734,7 +736,14 @@ fn project_type<'cx, 'tcx>(
|
||||
|
||||
if !selcx.tcx().sess.recursion_limit().value_within_limit(obligation.recursion_depth) {
|
||||
debug!("project: overflow!");
|
||||
return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow));
|
||||
match selcx.query_mode() {
|
||||
super::TraitQueryMode::Standard => {
|
||||
selcx.infcx().report_overflow_error(&obligation, true);
|
||||
}
|
||||
super::TraitQueryMode::Canonical => {
|
||||
return Err(ProjectionTyError::TraitSelectionError(SelectionError::Overflow));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let obligation_trait_ref = &obligation.predicate.trait_ref(selcx.tcx());
|
||||
|
||||
@ -335,7 +335,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
fn vtable_impl(
|
||||
&mut self,
|
||||
impl_def_id: DefId,
|
||||
mut substs: Normalized<'tcx, SubstsRef<'tcx>>,
|
||||
substs: Normalized<'tcx, SubstsRef<'tcx>>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
recursion_depth: usize,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
@ -357,9 +357,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// relying on projections in the impl-trait-ref.
|
||||
//
|
||||
// e.g., `impl<U: Tr, V: Iterator<Item=U>> Foo<<U as Tr>::T> for V`
|
||||
substs.obligations.append(&mut impl_obligations);
|
||||
impl_obligations.extend(substs.obligations);
|
||||
|
||||
ImplSourceUserDefinedData { impl_def_id, substs: substs.value, nested: substs.obligations }
|
||||
ImplSourceUserDefinedData { impl_def_id, substs: substs.value, nested: impl_obligations }
|
||||
}
|
||||
|
||||
fn confirm_object_candidate(
|
||||
|
||||
@ -290,6 +290,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
pub(super) fn query_mode(&self) -> TraitQueryMode {
|
||||
self.query_mode
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Selection
|
||||
//
|
||||
|
||||
@ -1 +1 @@
|
||||
877c7cbe142a373f93d38a23741dcc3a0a17a2af
|
||||
e1884a8e3c3e813aada8254edfa120e85bf5ffca
|
||||
@ -1749,7 +1749,7 @@ struct WeakInner<'a> {
|
||||
strong: &'a Cell<usize>,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Weak<T> {
|
||||
impl<T> Weak<T> {
|
||||
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
|
||||
///
|
||||
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
|
||||
@ -1882,7 +1882,9 @@ impl<T: ?Sized> Weak<T> {
|
||||
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
|
||||
Weak { ptr: unsafe { NonNull::new_unchecked(ptr) } }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Weak<T> {
|
||||
/// Attempts to upgrade the `Weak` pointer to an [`Rc`], delaying
|
||||
/// dropping of the inner value if successful.
|
||||
///
|
||||
|
||||
@ -208,30 +208,6 @@ fn into_from_weak_raw() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_from_weak_raw_unsized() {
|
||||
use std::fmt::Display;
|
||||
use std::string::ToString;
|
||||
|
||||
let arc: Rc<str> = Rc::from("foo");
|
||||
let weak: Weak<str> = Rc::downgrade(&arc);
|
||||
|
||||
let ptr = Weak::into_raw(weak.clone());
|
||||
let weak2 = unsafe { Weak::from_raw(ptr) };
|
||||
|
||||
assert_eq!(unsafe { &*ptr }, "foo");
|
||||
assert!(weak.ptr_eq(&weak2));
|
||||
|
||||
let arc: Rc<dyn Display> = Rc::new(123);
|
||||
let weak: Weak<dyn Display> = Rc::downgrade(&arc);
|
||||
|
||||
let ptr = Weak::into_raw(weak.clone());
|
||||
let weak2 = unsafe { Weak::from_raw(ptr) };
|
||||
|
||||
assert_eq!(unsafe { &*ptr }.to_string(), "123");
|
||||
assert!(weak.ptr_eq(&weak2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn get_mut() {
|
||||
let mut x = Rc::new(3);
|
||||
|
||||
@ -1535,7 +1535,7 @@ struct WeakInner<'a> {
|
||||
strong: &'a atomic::AtomicUsize,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Weak<T> {
|
||||
impl<T> Weak<T> {
|
||||
/// Returns a raw pointer to the object `T` pointed to by this `Weak<T>`.
|
||||
///
|
||||
/// The pointer is valid only if there are some strong references. The pointer may be dangling,
|
||||
@ -1668,7 +1668,9 @@ impl<T: ?Sized> Weak<T> {
|
||||
// SAFETY: we now have recovered the original Weak pointer, so can create the Weak.
|
||||
unsafe { Weak { ptr: NonNull::new_unchecked(ptr) } }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Weak<T> {
|
||||
/// Attempts to upgrade the `Weak` pointer to an [`Arc`], delaying
|
||||
/// dropping of the inner value if successful.
|
||||
///
|
||||
|
||||
@ -158,30 +158,6 @@ fn into_from_weak_raw() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_from_weak_raw_unsized() {
|
||||
use std::fmt::Display;
|
||||
use std::string::ToString;
|
||||
|
||||
let arc: Arc<str> = Arc::from("foo");
|
||||
let weak: Weak<str> = Arc::downgrade(&arc);
|
||||
|
||||
let ptr = Weak::into_raw(weak.clone());
|
||||
let weak2 = unsafe { Weak::from_raw(ptr) };
|
||||
|
||||
assert_eq!(unsafe { &*ptr }, "foo");
|
||||
assert!(weak.ptr_eq(&weak2));
|
||||
|
||||
let arc: Arc<dyn Display> = Arc::new(123);
|
||||
let weak: Weak<dyn Display> = Arc::downgrade(&arc);
|
||||
|
||||
let ptr = Weak::into_raw(weak.clone());
|
||||
let weak2 = unsafe { Weak::from_raw(ptr) };
|
||||
|
||||
assert_eq!(unsafe { &*ptr }.to_string(), "123");
|
||||
assert!(weak.ptr_eq(&weak2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_cowarc_clone_make_mut() {
|
||||
let mut cow0 = Arc::new(75);
|
||||
|
||||
@ -63,7 +63,7 @@ fi
|
||||
#
|
||||
# FIXME: need a scheme for changing this `nightly` value to `beta` and `stable`
|
||||
# either automatically or manually.
|
||||
export RUST_RELEASE_CHANNEL=beta
|
||||
export RUST_RELEASE_CHANNEL=stable
|
||||
|
||||
# Always set the release channel for bootstrap; this is normally not important (i.e., only dist
|
||||
# builds would seem to matter) but in practice bootstrap wants to know whether we're targeting
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
# Deny-by-default lints
|
||||
|
||||
This file is auto-generated by the lint-docs script.
|
||||
@ -24,13 +24,13 @@ impl Tr for u32 {
|
||||
// ...but not in an impl that redefines one of the types.
|
||||
impl Tr for bool {
|
||||
type A = Box<Self::B>;
|
||||
//~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
|
||||
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
|
||||
}
|
||||
// (the error is shown twice for some reason)
|
||||
|
||||
impl Tr for usize {
|
||||
type B = &'static Self::A;
|
||||
//~^ ERROR type mismatch resolving `<usize as Tr>::A == _`
|
||||
//~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
|
||||
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
|
||||
--> $DIR/defaults-cyclic-fail-1.rs:26:5
|
||||
|
|
||||
LL | type A = Box<Self::B>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0271]: type mismatch resolving `<usize as Tr>::A == _`
|
||||
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
|
||||
--> $DIR/defaults-cyclic-fail-1.rs:32:5
|
||||
|
|
||||
LL | type B = &'static Self::A;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
|
||||
@ -25,13 +25,13 @@ impl Tr for u32 {
|
||||
|
||||
impl Tr for bool {
|
||||
type A = Box<Self::B>;
|
||||
//~^ ERROR type mismatch resolving `<bool as Tr>::B == _`
|
||||
//~^ ERROR overflow evaluating the requirement `<bool as Tr>::B == _`
|
||||
}
|
||||
// (the error is shown twice for some reason)
|
||||
|
||||
impl Tr for usize {
|
||||
type B = &'static Self::A;
|
||||
//~^ ERROR type mismatch resolving `<usize as Tr>::A == _`
|
||||
//~^ ERROR overflow evaluating the requirement `<usize as Tr>::A == _`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
error[E0271]: type mismatch resolving `<bool as Tr>::B == _`
|
||||
error[E0275]: overflow evaluating the requirement `<bool as Tr>::B == _`
|
||||
--> $DIR/defaults-cyclic-fail-2.rs:27:5
|
||||
|
|
||||
LL | type A = Box<Self::B>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0271]: type mismatch resolving `<usize as Tr>::A == _`
|
||||
error[E0275]: overflow evaluating the requirement `<usize as Tr>::A == _`
|
||||
--> $DIR/defaults-cyclic-fail-2.rs:33:5
|
||||
|
|
||||
LL | type B = &'static Self::A;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
|
||||
29
src/test/ui/associated-types/impl-wf-cycle-1.rs
Normal file
29
src/test/ui/associated-types/impl-wf-cycle-1.rs
Normal file
@ -0,0 +1,29 @@
|
||||
// Regression test for #79714
|
||||
|
||||
trait Baz {}
|
||||
impl Baz for () {}
|
||||
impl<T> Baz for (T,) {}
|
||||
|
||||
trait Fiz {}
|
||||
impl Fiz for bool {}
|
||||
|
||||
trait Grault {
|
||||
type A;
|
||||
type B;
|
||||
}
|
||||
|
||||
impl<T: Grault> Grault for (T,)
|
||||
where
|
||||
Self::A: Baz,
|
||||
Self::B: Fiz,
|
||||
{
|
||||
type A = ();
|
||||
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
type B = bool;
|
||||
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
}
|
||||
//~^^^^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
|
||||
fn main() {
|
||||
let x: <(_,) as Grault>::A = ();
|
||||
}
|
||||
36
src/test/ui/associated-types/impl-wf-cycle-1.stderr
Normal file
36
src/test/ui/associated-types/impl-wf-cycle-1.stderr
Normal file
@ -0,0 +1,36 @@
|
||||
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
--> $DIR/impl-wf-cycle-1.rs:15:1
|
||||
|
|
||||
LL | / impl<T: Grault> Grault for (T,)
|
||||
LL | | where
|
||||
LL | | Self::A: Baz,
|
||||
LL | | Self::B: Fiz,
|
||||
... |
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
--> $DIR/impl-wf-cycle-1.rs:20:5
|
||||
|
|
||||
LL | type A = ();
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
--> $DIR/impl-wf-cycle-1.rs:22:5
|
||||
|
|
||||
LL | type B = bool;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
16
src/test/ui/associated-types/impl-wf-cycle-2.rs
Normal file
16
src/test/ui/associated-types/impl-wf-cycle-2.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// Regression test for #79714
|
||||
|
||||
trait Grault {
|
||||
type A;
|
||||
}
|
||||
|
||||
impl<T: Grault> Grault for (T,)
|
||||
where
|
||||
Self::A: Copy,
|
||||
{
|
||||
type A = ();
|
||||
//~^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
}
|
||||
//~^^^^^^^ ERROR overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
|
||||
fn main() {}
|
||||
25
src/test/ui/associated-types/impl-wf-cycle-2.stderr
Normal file
25
src/test/ui/associated-types/impl-wf-cycle-2.stderr
Normal file
@ -0,0 +1,25 @@
|
||||
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
--> $DIR/impl-wf-cycle-2.rs:7:1
|
||||
|
|
||||
LL | / impl<T: Grault> Grault for (T,)
|
||||
LL | | where
|
||||
LL | | Self::A: Copy,
|
||||
LL | | {
|
||||
LL | | type A = ();
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
|
||||
--> $DIR/impl-wf-cycle-2.rs:11:5
|
||||
|
|
||||
LL | type A = ();
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Grault` for `(T,)`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
20
src/test/ui/inline-const/macro-with-const.rs
Normal file
20
src/test/ui/inline-const/macro-with-const.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// check-pass
|
||||
|
||||
macro_rules! exp {
|
||||
(const $n:expr) => {
|
||||
$n
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! stmt {
|
||||
(exp $e:expr) => {
|
||||
$e
|
||||
};
|
||||
(exp $($t:tt)+) => {
|
||||
exp!($($t)+)
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
stmt!(exp const 1);
|
||||
}
|
||||
@ -1,11 +1,10 @@
|
||||
error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
|
||||
error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next`
|
||||
--> $DIR/issue-23122-2.rs:9:5
|
||||
|
|
||||
LL | type Next = <GetNext<T::Next> as Next>::Next;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding a `#![recursion_limit="256"]` attribute to your crate (`issue_23122_2`)
|
||||
= note: required because of the requirements on the impl of `Next` for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@ -5,6 +5,10 @@ macro_rules! foo {
|
||||
( $($i:ident)* ) => { $($i)+ }; //~ WARN meta-variable repeats with different Kleene operator
|
||||
}
|
||||
|
||||
#[warn(missing_fragment_specifier)]
|
||||
macro_rules! m { ($i) => {} } //~ WARN missing fragment specifier
|
||||
//~| WARN this was previously accepted
|
||||
|
||||
#[warn(soft_unstable)]
|
||||
mod benches {
|
||||
#[bench] //~ WARN use of unstable library feature 'test'
|
||||
|
||||
@ -12,14 +12,28 @@ note: the lint level is defined here
|
||||
LL | #[warn(meta_variable_misuse)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: missing fragment specifier
|
||||
--> $DIR/expansion-time.rs:9:19
|
||||
|
|
||||
LL | macro_rules! m { ($i) => {} }
|
||||
| ^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/expansion-time.rs:8:8
|
||||
|
|
||||
LL | #[warn(missing_fragment_specifier)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
||||
|
||||
warning: use of unstable library feature 'test': `bench` is a part of custom test frameworks which are unstable
|
||||
--> $DIR/expansion-time.rs:10:7
|
||||
--> $DIR/expansion-time.rs:14:7
|
||||
|
|
||||
LL | #[bench]
|
||||
| ^^^^^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/expansion-time.rs:8:8
|
||||
--> $DIR/expansion-time.rs:12:8
|
||||
|
|
||||
LL | #[warn(soft_unstable)]
|
||||
| ^^^^^^^^^^^^^
|
||||
@ -33,10 +47,10 @@ LL | 2
|
||||
| ^
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/expansion-time.rs:15:8
|
||||
--> $DIR/expansion-time.rs:19:8
|
||||
|
|
||||
LL | #[warn(incomplete_include)]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: 3 warnings emitted
|
||||
warning: 4 warnings emitted
|
||||
|
||||
|
||||
@ -2,5 +2,6 @@
|
||||
|
||||
macro_rules! m { ($i) => {} }
|
||||
//~^ ERROR missing fragment specifier
|
||||
//~| WARN previously accepted
|
||||
|
||||
fn main() {}
|
||||
|
||||
@ -3,6 +3,10 @@ error: missing fragment specifier
|
||||
|
|
||||
LL | macro_rules! m { ($i) => {} }
|
||||
| ^^
|
||||
|
|
||||
= note: `#[deny(missing_fragment_specifier)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ macro_rules! test {
|
||||
($a, $b) => {
|
||||
//~^ ERROR missing fragment
|
||||
//~| ERROR missing fragment
|
||||
//~| WARN this was previously accepted
|
||||
()
|
||||
};
|
||||
}
|
||||
|
||||
@ -9,6 +9,10 @@ error: missing fragment specifier
|
||||
|
|
||||
LL | ($a, $b) => {
|
||||
| ^^
|
||||
|
|
||||
= note: `#[deny(missing_fragment_specifier)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #40107 <https://github.com/rust-lang/rust/issues/40107>
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ macro_rules! foo {
|
||||
{ $+ } => { //~ ERROR expected identifier, found `+`
|
||||
//~^ ERROR missing fragment specifier
|
||||
$(x)(y) //~ ERROR expected one of: `*`, `+`, or `?`
|
||||
//~^ ERROR attempted to repeat an expression containing no syntax variables
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -4,23 +4,17 @@ error: expected identifier, found `+`
|
||||
LL | { $+ } => {
|
||||
| ^
|
||||
|
||||
error: missing fragment specifier
|
||||
--> $DIR/issue-33569.rs:2:8
|
||||
|
|
||||
LL | { $+ } => {
|
||||
| ^
|
||||
|
||||
error: expected one of: `*`, `+`, or `?`
|
||||
--> $DIR/issue-33569.rs:4:13
|
||||
|
|
||||
LL | $(x)(y)
|
||||
| ^^^
|
||||
|
||||
error: attempted to repeat an expression containing no syntax variables matched as repeating at this depth
|
||||
--> $DIR/issue-33569.rs:4:10
|
||||
error: missing fragment specifier
|
||||
--> $DIR/issue-33569.rs:2:8
|
||||
|
|
||||
LL | $(x)(y)
|
||||
| ^^^
|
||||
LL | { $+ } => {
|
||||
| ^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
||||
39
src/test/ui/traits/impl-evaluation-order.rs
Normal file
39
src/test/ui/traits/impl-evaluation-order.rs
Normal file
@ -0,0 +1,39 @@
|
||||
// Regression test for #79902
|
||||
|
||||
// Check that evaluation (which is used to determine whether to copy a type in
|
||||
// MIR building) evaluates bounds from normalizing an impl after evaluating
|
||||
// any bounds on the impl.
|
||||
|
||||
// check-pass
|
||||
|
||||
trait A {
|
||||
type B;
|
||||
}
|
||||
trait M {}
|
||||
|
||||
struct G<T, U>(*const T, *const U);
|
||||
|
||||
impl<T, U> Clone for G<T, U> {
|
||||
fn clone(&self) -> Self {
|
||||
G { ..*self }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> Copy for G<T, U::B>
|
||||
where
|
||||
T: A<B = U>,
|
||||
U: A,
|
||||
{
|
||||
}
|
||||
|
||||
impl A for () {
|
||||
type B = ();
|
||||
}
|
||||
|
||||
fn is_m<T: M>(_: T) {}
|
||||
|
||||
fn main() {
|
||||
let x = G(&(), &());
|
||||
drop(x);
|
||||
drop(x);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user