+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)
==========================
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.
- [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
[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/
/// 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 {
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))
{
///
/// 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]>,
})));
}
+ // 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) {
// 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,
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>>()
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) => {
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 {
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
// 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 => {}
}
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.)
}
_ => IsInFollow::No(TOKENS),
},
- TokenTree::MetaVarDecl(_, _, NonterminalKind::Block) => IsInFollow::Yes,
+ TokenTree::MetaVarDecl(_, _, Some(NonterminalKind::Block)) => IsInFollow::Yes,
_ => IsInFollow::No(TOKENS),
}
}
TokenTree::MetaVarDecl(
_,
_,
- NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path,
+ Some(NonterminalKind::Ident | NonterminalKind::Ty | NonterminalKind::Path),
) => IsInFollow::Yes,
_ => IsInFollow::No(TOKENS),
}
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"
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};
.emit();
token::NonterminalKind::Ident
});
- result.push(TokenTree::MetaVarDecl(span, ident, kind));
+ result.push(TokenTree::MetaVarDecl(span, ident, Some(kind)));
continue;
}
_ => token.span,
}
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
pub enum ProjectionCacheEntry<'tcx> {
InProgress,
Ambiguous,
+ Recur,
Error,
NormalizedTy(NormalizedTy<'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);
}
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>) {
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;
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
};
}
+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.
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,
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(),
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.
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,
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
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)) => {
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());
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>,
// 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(
self.infcx.tcx
}
+ pub(super) fn query_mode(&self) -> TraitQueryMode {
+ self.query_mode
+ }
+
///////////////////////////////////////////////////////////////////////////
// Selection
//
-877c7cbe142a373f93d38a23741dcc3a0a17a2af
\ No newline at end of file
+e1884a8e3c3e813aada8254edfa120e85bf5ffca
\ No newline at end of file
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,
// 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.
///
}
}
-#[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);
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,
// 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.
///
}
}
-#[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);
#
# 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
+++ /dev/null
-# Deny-by-default lints
-
-This file is auto-generated by the lint-docs script.
// ...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() {
-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`.
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() {
-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`.
--- /dev/null
+// 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 = ();
+}
--- /dev/null
+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`.
--- /dev/null
+// 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() {}
--- /dev/null
+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`.
--- /dev/null
+// 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);
+}
-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
( $($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'
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)]
| ^^^^^^^^^^^^^
| ^
|
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
macro_rules! m { ($i) => {} }
//~^ ERROR missing fragment specifier
+//~| WARN previously accepted
fn main() {}
|
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
($a, $b) => {
//~^ ERROR missing fragment
//~| ERROR missing fragment
+ //~| WARN this was previously accepted
()
};
}
|
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
{ $+ } => { //~ 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
}
}
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
--- /dev/null
+// 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);
+}
-1.49.0-beta.4 (877c7cbe1 2020-12-10)
\ No newline at end of file
+1.49.0 (e1884a8e3 2020-12-29)
\ No newline at end of file