**node_modules
**package-lock.json
+## Rustdoc GUI tests
+src/test/rustdoc-gui/src/**.lock
+
# Before adding new lines, see the comment at the top.
[submodule "src/llvm-project"]
path = src/llvm-project
url = https://github.com/rust-lang/llvm-project.git
- branch = rustc/12.0-2021-04-15
+ branch = rustc/12.0-2021-07-10
[submodule "src/doc/embedded-book"]
path = src/doc/embedded-book
url = https://github.com/rust-embedded/book.git
[[package]]
name = "regex"
-version = "1.4.3"
+version = "1.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
+checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
- "thread_local",
]
[[package]]
name = "regex-automata"
-version = "0.1.9"
+version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae1ded71d66a4a97f5e961fd0cb25a5f366a42a41570d16a763a69c092c26ae4"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
- "byteorder",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
-version = "0.6.22"
+version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "remote-test-client"
use Destination::*;
-use rustc_lint_defs::FutureBreakage;
use rustc_span::source_map::SourceMap;
use rustc_span::{MultiSpan, SourceFile, Span};
/// other formats can, and will, simply ignore it.
fn emit_artifact_notification(&mut self, _path: &Path, _artifact_type: &str) {}
- fn emit_future_breakage_report(&mut self, _diags: Vec<(FutureBreakage, Diagnostic)>) {}
+ fn emit_future_breakage_report(&mut self, _diags: Vec<Diagnostic>) {}
/// Emit list of unused externs
fn emit_unused_externs(&mut self, _lint_level: &str, _unused_externs: &[&str]) {}
use crate::DiagnosticId;
use crate::ToolMetadata;
use crate::{CodeSuggestion, SubDiagnostic};
-use rustc_lint_defs::{Applicability, FutureBreakage};
+use rustc_lint_defs::Applicability;
use rustc_data_structures::sync::Lrc;
use rustc_span::hygiene::ExpnData;
}
}
- fn emit_future_breakage_report(&mut self, diags: Vec<(FutureBreakage, crate::Diagnostic)>) {
+ fn emit_future_breakage_report(&mut self, diags: Vec<crate::Diagnostic>) {
let data: Vec<FutureBreakageItem> = diags
.into_iter()
- .map(|(breakage, mut diag)| {
+ .map(|mut diag| {
if diag.level == crate::Level::Allow {
diag.level = crate::Level::Warning;
}
- FutureBreakageItem {
- future_breakage_date: breakage.date,
- diagnostic: Diagnostic::from_errors_diagnostic(&diag, self),
- }
+ FutureBreakageItem { diagnostic: Diagnostic::from_errors_diagnostic(&diag, self) }
})
.collect();
let report = FutureIncompatReport { future_incompat_report: data };
#[derive(Encodable)]
struct FutureBreakageItem {
- future_breakage_date: Option<&'static str>,
diagnostic: Diagnostic,
}
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::{self, Lock, Lrc};
use rustc_data_structures::AtomicRef;
-use rustc_lint_defs::FutureBreakage;
pub use rustc_lint_defs::{pluralize, Applicability};
use rustc_serialize::json::Json;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
self.inner.borrow_mut().emit_artifact_notification(path, artifact_type)
}
- pub fn emit_future_breakage_report(&self, diags: Vec<(FutureBreakage, Diagnostic)>) {
+ pub fn emit_future_breakage_report(&self, diags: Vec<Diagnostic>) {
self.inner.borrow_mut().emitter.emit_future_breakage_report(diags)
}
/// Allows qualified paths in struct expressions, struct patterns and tuple struct patterns.
(active, more_qualified_paths, "1.54.0", Some(86935), None),
+ /// Allows `cfg(target_abi = "...")`.
+ (active, cfg_target_abi, "1.55.0", Some(80970), None),
+
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------
/// `cfg(...)`'s that are feature gated.
const GATED_CFGS: &[GatedCfg] = &[
// (name in cfg, feature, function to check if the feature is enabled)
+ (sym::target_abi, sym::cfg_target_abi, cfg_fn!(cfg_target_abi)),
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
(sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
(sym::target_has_atomic_load_store, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)),
),
gated!(cmse_nonsecure_entry, AssumedUsed, template!(Word), experimental!(cmse_nonsecure_entry)),
+ // RFC 2632
+ gated!(
+ default_method_body_is_const, AssumedUsed, template!(Word), const_trait_impl,
+ "`default_method_body_is_const` is a temporary placeholder for declaring default bodies \
+ as `const`, which may be removed or renamed in the future."
+ ),
// ==========================================================================
// Internal attributes: Stability, deprecation, and unsafe:
//! Clippy.
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
-use rustc_ast::{ImplKind, Item, ItemKind};
-use rustc_data_structures::fx::FxHashMap;
+use rustc_ast as ast;
use rustc_errors::Applicability;
use rustc_hir::def::Res;
-use rustc_hir::{GenericArg, HirId, MutTy, Mutability, Path, PathSegment, QPath, Ty, TyKind};
+use rustc_hir::{
+ GenericArg, HirId, Item, ItemKind, MutTy, Mutability, Node, Path, PathSegment, QPath, Ty,
+ TyKind,
+};
use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::hygiene::{ExpnKind, MacroKind};
-use rustc_span::symbol::{kw, sym, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Symbol};
declare_tool_lint! {
pub rustc::DEFAULT_HASH_TYPES,
report_in_external_macro: true
}
-pub struct DefaultHashTypes {
- map: FxHashMap<Symbol, Symbol>,
-}
-
-impl DefaultHashTypes {
- // we are allowed to use `HashMap` and `HashSet` as identifiers for implementing the lint itself
- #[allow(rustc::default_hash_types)]
- pub fn new() -> Self {
- let mut map = FxHashMap::default();
- map.insert(sym::HashMap, sym::FxHashMap);
- map.insert(sym::HashSet, sym::FxHashSet);
- Self { map }
- }
-}
-
-impl_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
+declare_lint_pass!(DefaultHashTypes => [DEFAULT_HASH_TYPES]);
-impl EarlyLintPass for DefaultHashTypes {
- fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
- if let Some(replace) = self.map.get(&ident.name) {
- cx.struct_span_lint(DEFAULT_HASH_TYPES, ident.span, |lint| {
- // FIXME: We can avoid a copy here. Would require us to take String instead of &str.
- let msg = format!("Prefer {} over {}, it has better performance", replace, ident);
- lint.build(&msg)
- .span_suggestion(
- ident.span,
- "use",
- replace.to_string(),
- Applicability::MaybeIncorrect, // FxHashMap, ... needs another import
- )
- .note(&format!(
- "a `use rustc_data_structures::fx::{}` may be necessary",
- replace
- ))
- .emit();
- });
+impl LateLintPass<'_> for DefaultHashTypes {
+ fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, hir_id: HirId) {
+ let def_id = match path.res {
+ Res::Def(rustc_hir::def::DefKind::Struct, id) => id,
+ _ => return,
+ };
+ if matches!(cx.tcx.hir().get(hir_id), Node::Item(Item { kind: ItemKind::Use(..), .. })) {
+ // don't lint imports, only actual usages
+ return;
}
+ let replace = if cx.tcx.is_diagnostic_item(sym::hashmap_type, def_id) {
+ "FxHashMap"
+ } else if cx.tcx.is_diagnostic_item(sym::hashset_type, def_id) {
+ "FxHashSet"
+ } else {
+ return;
+ };
+ cx.struct_span_lint(DEFAULT_HASH_TYPES, path.span, |lint| {
+ let msg = format!(
+ "prefer `{}` over `{}`, it has better performance",
+ replace,
+ cx.tcx.item_name(def_id)
+ );
+ lint.build(&msg)
+ .note(&format!("a `use rustc_data_structures::fx::{}` may be necessary", replace))
+ .emit();
+ });
}
}
declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]);
impl EarlyLintPass for LintPassImpl {
- fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
- if let ItemKind::Impl(box ImplKind { of_trait: Some(lint_pass), .. }) = &item.kind {
+ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
+ if let ast::ItemKind::Impl(box ast::ImplKind { of_trait: Some(lint_pass), .. }) = &item.kind
+ {
if let Some(last) = lint_pass.path.segments.last() {
if last.ident.name == sym::LintPass {
let expn_data = lint_pass.path.span.ctxt().outer_expn_data();
}
fn register_internals(store: &mut LintStore) {
- store.register_lints(&DefaultHashTypes::get_lints());
- store.register_early_pass(|| box DefaultHashTypes::new());
store.register_lints(&LintPassImpl::get_lints());
store.register_early_pass(|| box LintPassImpl);
+ store.register_lints(&DefaultHashTypes::get_lints());
+ store.register_late_pass(|| box DefaultHashTypes);
store.register_lints(&ExistingDocKeyword::get_lints());
store.register_late_pass(|| box ExistingDocKeyword);
store.register_lints(&TyTyKind::get_lints());
//! compiler code, rather than using their own custom pass. Those
//! lints are all available in `rustc_lint::builtin`.
-use crate::{declare_lint, declare_lint_pass, FutureBreakage, FutureIncompatibilityReason};
+use crate::{declare_lint, declare_lint_pass, FutureIncompatibilityReason};
use rustc_span::edition::Edition;
declare_lint! {
"detects usage of old versions of certain proc-macro crates",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #83125 <https://github.com/rust-lang/rust/issues/83125>",
- future_breakage: Some(FutureBreakage {
- date: None
- })
+ reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
};
}
/// Set to false for lints that already include a more detailed
/// explanation.
pub explain_reason: bool,
- /// Information about a future breakage, which will
- /// be emitted in JSON messages to be displayed by Cargo
- /// for upstream deps
- pub future_breakage: Option<FutureBreakage>,
}
/// The reason for future incompatibility
/// This will be an error in a future release
/// for all editions
FutureReleaseError,
+ /// This will be an error in a future release, and
+ /// Cargo should create a report even for dependencies
+ FutureReleaseErrorReportNow,
/// Previously accepted code that will become an
/// error in the provided edition
EditionError(Edition),
}
}
-#[derive(Copy, Clone, Debug)]
-pub struct FutureBreakage {
- pub date: Option<&'static str>,
-}
-
impl FutureIncompatibleInfo {
pub const fn default_fields_for_macro() -> Self {
FutureIncompatibleInfo {
reference: "",
reason: FutureIncompatibilityReason::FutureReleaseError,
explain_reason: true,
- future_breakage: None,
}
}
}
#keyword_stream
}
- #[allow(rustc::default_hash_types)]
+ #[cfg_attr(bootstrap, allow(rustc::default_hash_types))]
#[allow(non_upper_case_globals)]
#[doc(hidden)]
pub mod sym_generated {
self.get_impl_data(id).defaultness
}
+ fn get_impl_constness(&self, id: DefIndex) -> hir::Constness {
+ self.get_impl_data(id).constness
+ }
+
fn get_coerce_unsized_info(&self, id: DefIndex) -> Option<ty::adjustment::CoerceUnsizedInfo> {
self.get_impl_data(id).coerce_unsized_info
}
is_no_builtins => { cdata.root.no_builtins }
symbol_mangling_version => { cdata.root.symbol_mangling_version }
impl_defaultness => { cdata.get_impl_defaultness(def_id.index) }
+ impl_constness => { cdata.get_impl_constness(def_id.index) }
reachable_non_generics => {
let reachable_non_generics = tcx
.exported_symbols(cdata.cnum)
adt_def.repr,
)
}
- hir::ItemKind::Impl(hir::Impl { defaultness, .. }) => {
+ hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
let trait_ref = self.tcx.impl_trait_ref(def_id);
let polarity = self.tcx.impl_polarity(def_id);
let parent = if let Some(trait_ref) = trait_ref {
}
});
- let data =
- ImplData { polarity, defaultness, parent_impl: parent, coerce_unsized_info };
+ let data = ImplData {
+ polarity,
+ defaultness,
+ constness,
+ parent_impl: parent,
+ coerce_unsized_info,
+ };
EntryKind::Impl(self.lazy(data))
}
#[derive(TyEncodable, TyDecodable)]
struct ImplData {
polarity: ty::ImplPolarity,
+ constness: hir::Constness,
defaultness: hir::Defaultness,
parent_impl: Option<DefId>,
use rustc_span::def_id::StableCrateId;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, Ident, Symbol};
+use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span;
use rustc_target::spec::abi::Abi;
/// Returns the `ConstContext` of the body associated with this `LocalDefId`.
///
/// Panics if `LocalDefId` does not have an associated body.
+ ///
+ /// This should only be used for determining the context of a body, a return
+ /// value of `Some` does not always suggest that the owner of the body is `const`.
pub fn body_const_context(&self, did: LocalDefId) -> Option<ConstContext> {
let hir_id = self.local_def_id_to_hir_id(did);
let ccx = match self.body_owner_kind(hir_id) {
BodyOwnerKind::Fn if self.tcx.is_constructor(did.to_def_id()) => return None,
BodyOwnerKind::Fn if self.tcx.is_const_fn_raw(did.to_def_id()) => ConstContext::ConstFn,
+ BodyOwnerKind::Fn
+ if self.tcx.has_attr(did.to_def_id(), sym::default_method_body_is_const) =>
+ {
+ ConstContext::ConstFn
+ }
BodyOwnerKind::Fn | BodyOwnerKind::Closure => return None,
};
use rustc_index::vec::IndexVec;
use rustc_session::lint::{
builtin::{self, FORBIDDEN_LINT_GROUPS},
- FutureIncompatibilityReason, Level, Lint, LintId,
+ FutureIncompatibilityReason, FutureIncompatibleInfo, Level, Lint, LintId,
};
use rustc_session::{DiagnosticMessageId, Session};
use rustc_span::hygiene::MacroKind;
let lint_id = LintId::of(lint);
let future_incompatible = lint.future_incompatible;
- let has_future_breakage =
- future_incompatible.map_or(false, |incompat| incompat.future_breakage.is_some());
+ let has_future_breakage = matches!(
+ future_incompatible,
+ Some(FutureIncompatibleInfo {
+ reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow,
+ ..
+ })
+ );
let mut err = match (level, span) {
(Level::Allow, span) => {
suggestion: Option<Symbol>,
lint: &'static Lint,
span: Span,
+ method_span: Option<Span>,
hir_id: HirId,
def_id: DefId,
) {
if span.in_derive_expansion() {
return;
}
-
- tcx.struct_span_lint_hir(lint, hir_id, span, |lint| {
+ let method_span = method_span.unwrap_or(span);
+ tcx.struct_span_lint_hir(lint, hir_id, method_span, |lint| {
let mut diag = lint.build(message);
if let hir::Node::Expr(_) = tcx.hir().get(hir_id) {
let kind = tcx.def_kind(def_id).descr(def_id);
- deprecation_suggestion(&mut diag, kind, suggestion, span);
+ deprecation_suggestion(&mut diag, kind, suggestion, method_span);
}
diag.emit()
});
let path = &with_no_trimmed_paths(|| self.def_path_str(def_id));
let kind = self.def_kind(def_id).descr(def_id);
let (message, lint) = deprecation_message(&depr_entry.attr, kind, path);
- let span = method_span.unwrap_or(span);
late_report_deprecation(
self,
&message,
depr_entry.attr.suggestion,
lint,
span,
+ method_span,
id,
def_id,
);
/// Transferring the initialization mask to other allocations.
impl<Tag, Extra> Allocation<Tag, Extra> {
/// Creates a run-length encoding of the initialization mask.
- pub fn compress_uninit_range(&self, src: Pointer<Tag>, size: Size) -> InitMaskCompressed {
+ pub fn compress_uninit_range(&self, range: AllocRange) -> InitMaskCompressed {
// Since we are copying `size` bytes from `src` to `dest + i * size` (`for i in 0..repeat`),
// a naive initialization mask copying algorithm would repeatedly have to read the initialization mask from
// the source and write it to the destination. Even if we optimized the memory accesses,
// where each element toggles the state.
let mut ranges = smallvec::SmallVec::<[u64; 1]>::new();
- let initial = self.init_mask.get(src.offset);
+ let initial = self.init_mask.get(range.start);
let mut cur_len = 1;
let mut cur = initial;
- for i in 1..size.bytes() {
+ for i in 1..range.size.bytes() {
// FIXME: optimize to bitshift the current uninitialized block's bits and read the top bit.
- if self.init_mask.get(src.offset + Size::from_bytes(i)) == cur {
+ if self.init_mask.get(range.start + Size::from_bytes(i)) == cur {
cur_len += 1;
} else {
ranges.push(cur_len);
pub fn mark_compressed_init_range(
&mut self,
defined: &InitMaskCompressed,
- dest: Pointer<Tag>,
- size: Size,
+ range: AllocRange,
repeat: u64,
) {
// An optimization where we can just overwrite an entire range of initialization
// bits if they are going to be uniformly `1` or `0`.
if defined.ranges.len() <= 1 {
self.init_mask.set_range_inbounds(
- dest.offset,
- dest.offset + size * repeat, // `Size` operations
+ range.start,
+ range.start + range.size * repeat, // `Size` operations
defined.initial,
);
return;
}
for mut j in 0..repeat {
- j *= size.bytes();
- j += dest.offset.bytes();
+ j *= range.size.bytes();
+ j += range.start.bytes();
let mut cur = defined.initial;
for range in &defined.ranges {
let old_j = j;
desc { |tcx| "looking up whether `{}` is a default impl", tcx.def_path_str(def_id) }
}
+ query impl_constness(def_id: DefId) -> hir::Constness {
+ desc { |tcx| "looking up whether `{}` is a const impl", tcx.def_path_str(def_id) }
+ }
+
query check_item_well_formed(key: LocalDefId) -> () {
desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) }
}
if let Some(desc) = access_place_desc {
item_msg = format!("`{}`", desc);
reason = match error_access {
- AccessKind::Mutate => format!(" which is behind {}", pointer_type),
+ AccessKind::Mutate => format!(", which is behind {}", pointer_type),
AccessKind::MutableBorrow => {
format!(", as it is behind {}", pointer_type)
}
) -> (Span, String) {
if let Some(assignment_rhs_span) = opt_assignment_rhs_span {
if let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) {
+ let is_mutbl = |ty: &str| -> bool {
+ if ty.starts_with("mut") {
+ let rest = &ty[3..];
+ match rest.chars().next() {
+ // e.g. `&mut x`
+ Some(c) if c.is_whitespace() => true,
+ // e.g. `&mut(x)`
+ Some('(') => true,
+ // e.g. `&mutablevar`
+ _ => false,
+ }
+ } else {
+ false
+ }
+ };
if let (true, Some(ws_pos)) =
(src.starts_with("&'"), src.find(|c: char| -> bool { c.is_whitespace() }))
{
let lt_name = &src[1..ws_pos];
- let ty = &src[ws_pos..];
- if !ty.trim_start().starts_with("mut") {
+ let ty = src[ws_pos..].trim_start();
+ if !is_mutbl(ty) {
return (assignment_rhs_span, format!("&{} mut {}", lt_name, ty));
}
} else if let Some(stripped) = src.strip_prefix('&') {
- if !stripped.trim_start().starts_with("mut") {
+ let stripped = stripped.trim_start();
+ if !is_mutbl(stripped) {
return (assignment_rhs_span, format!("&mut {}", stripped));
}
}
// sensitive check here. But we can at least rule out functions that are not const
// at all.
if !ecx.tcx.is_const_fn_raw(def.did) {
- // Some functions we support even if they are non-const -- but avoid testing
- // that for const fn!
- ecx.hook_panic_fn(instance, args)?;
- // We certainly do *not* want to actually call the fn
- // though, so be sure we return here.
- throw_unsup_format!("calling non-const function `{}`", instance)
+ // allow calling functions marked with #[default_method_body_is_const].
+ if !ecx.tcx.has_attr(def.did, sym::default_method_body_is_const) {
+ // Some functions we support even if they are non-const -- but avoid testing
+ // that for const fn!
+ ecx.hook_panic_fn(instance, args)?;
+ // We certainly do *not* want to actually call the fn
+ // though, so be sure we return here.
+ throw_unsup_format!("calling non-const function `{}`", instance)
+ }
}
}
// This is a const fn. Call it.
use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size, TargetDataLayout};
use super::{
- Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, Operand, Place, PlaceTy,
- ScalarMaybeUninit, StackPopJump,
+ Immediate, MPlaceTy, Machine, MemPlace, MemPlaceMeta, Memory, MemoryKind, Operand, Place,
+ PlaceTy, ScalarMaybeUninit, StackPopJump,
};
use crate::transform::validate::equal_up_to_regions;
use crate::util::storage::AlwaysLiveLocals;
// due to the local having ZST type.
let ptr = ptr.assert_ptr();
trace!("deallocating local: {:?}", self.memory.dump_alloc(ptr.alloc_id));
- self.memory.deallocate_local(ptr)?;
+ self.memory.deallocate(ptr, None, MemoryKind::Stack)?;
};
Ok(())
}
Ok(new_ptr)
}
- /// Deallocate a local, or do nothing if that local has been made into a global.
- pub fn deallocate_local(&mut self, ptr: Pointer<M::PointerTag>) -> InterpResult<'tcx> {
- // The allocation might be already removed by global interning.
- // This can only really happen in the CTFE instance, not in miri.
- if self.alloc_map.contains_key(&ptr.alloc_id) {
- self.deallocate(ptr, None, MemoryKind::Stack)
- } else {
- Ok(())
- }
- }
-
pub fn deallocate(
&mut self,
ptr: Pointer<M::PointerTag>,
num_copies,
);
// Prepare a copy of the initialization mask.
- let compressed = src_alloc.compress_uninit_range(src, size);
+ let compressed = src_alloc.compress_uninit_range(alloc_range(src.offset, size));
// This checks relocation edges on the src.
let src_bytes = src_alloc
.get_bytes_with_uninit_and_ptr(&tcx, alloc_range(src.offset, size))
}
// now fill in all the "init" data
- dest_alloc.mark_compressed_init_range(&compressed, dest, size, num_copies);
+ dest_alloc.mark_compressed_init_range(
+ &compressed,
+ alloc_range(dest.offset, size),
+ num_copies,
+ );
// copy the relocations to the destination
dest_alloc.mark_relocation_range(relocations);
}
if !tcx.is_const_fn_raw(callee) {
- self.check_op(ops::FnCallNonConst);
- return;
+ let mut permitted = false;
+
+ let callee_trait = tcx.trait_of_item(callee);
+ if let Some(trait_id) = callee_trait {
+ if tcx.has_attr(caller, sym::default_method_body_is_const) {
+ // permit call to non-const fn when caller has default_method_body_is_const..
+ if tcx.trait_of_item(caller) == callee_trait {
+ // ..and caller and callee are in the same trait.
+ permitted = true;
+ }
+ }
+ let mut const_impls = true;
+ tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
+ if const_impls {
+ if let hir::Constness::NotConst = tcx.impl_constness(imp) {
+ const_impls = false;
+ }
+ }
+ });
+ if const_impls {
+ permitted = true;
+ }
+ }
+
+ if !permitted {
+ self.check_op(ops::FnCallNonConst);
+ return;
+ }
}
// If the `const fn` we are trying to call is not const-stable, ensure that we have
pub mod as_place;
mod as_rvalue;
mod as_temp;
-mod category;
+pub mod category;
mod into;
mod stmt;
mod matches;
mod misc;
mod scope;
+
+pub(crate) use expr::category::Category as ExprCategory;
+use crate::build::ExprCategory;
use crate::thir::visit::{self, Visitor};
use rustc_errors::struct_span_err;
use rustc_hir as hir;
+use rustc_middle::mir::BorrowKind;
use rustc_middle::thir::*;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, ParamEnv, TyCtxt};
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
use rustc_session::lint::Level;
use rustc_span::def_id::{DefId, LocalDefId};
body_target_features: &'tcx Vec<Symbol>,
in_possible_lhs_union_assign: bool,
in_union_destructure: bool,
+ param_env: ParamEnv<'tcx>,
+ inside_adt: bool,
}
impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
}
}
+// Searches for accesses to layout constrained fields.
+struct LayoutConstrainedPlaceVisitor<'a, 'tcx> {
+ found: bool,
+ thir: &'a Thir<'tcx>,
+ tcx: TyCtxt<'tcx>,
+}
+
+impl<'a, 'tcx> LayoutConstrainedPlaceVisitor<'a, 'tcx> {
+ fn new(thir: &'a Thir<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
+ Self { found: false, thir, tcx }
+ }
+}
+
+impl<'a, 'tcx> Visitor<'a, 'tcx> for LayoutConstrainedPlaceVisitor<'a, 'tcx> {
+ fn thir(&self) -> &'a Thir<'tcx> {
+ self.thir
+ }
+
+ fn visit_expr(&mut self, expr: &Expr<'tcx>) {
+ match expr.kind {
+ ExprKind::Field { lhs, .. } => {
+ if let ty::Adt(adt_def, _) = self.thir[lhs].ty.kind() {
+ if (Bound::Unbounded, Bound::Unbounded)
+ != self.tcx.layout_scalar_valid_range(adt_def.did)
+ {
+ self.found = true;
+ }
+ }
+ visit::walk_expr(self, expr);
+ }
+
+ // Keep walking through the expression as long as we stay in the same
+ // place, i.e. the expression is a place expression and not a dereference
+ // (since dereferencing something leads us to a different place).
+ ExprKind::Deref { .. } => {}
+ ref kind if ExprCategory::of(kind).map_or(true, |cat| cat == ExprCategory::Place) => {
+ visit::walk_expr(self, expr);
+ }
+
+ _ => {}
+ }
+ }
+}
+
impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
fn thir(&self) -> &'a Thir<'tcx> {
&self.thir
}
fn visit_pat(&mut self, pat: &Pat<'tcx>) {
- use PatKind::*;
-
if self.in_union_destructure {
match *pat.kind {
// binding to a variable allows getting stuff out of variable
- Binding { .. }
+ PatKind::Binding { .. }
// match is conditional on having this value
- | Constant { .. }
- | Variant { .. }
- | Leaf { .. }
- | Deref { .. }
- | Range { .. }
- | Slice { .. }
- | Array { .. } => {
+ | PatKind::Constant { .. }
+ | PatKind::Variant { .. }
+ | PatKind::Leaf { .. }
+ | PatKind::Deref { .. }
+ | PatKind::Range { .. }
+ | PatKind::Slice { .. }
+ | PatKind::Array { .. } => {
self.requires_unsafe(pat.span, AccessToUnionField);
- return; // don't walk pattern
+ return; // we can return here since this already requires unsafe
}
// wildcard doesn't take anything
- Wild |
+ PatKind::Wild |
// these just wrap other patterns
- Or { .. } |
- AscribeUserType { .. } => {}
+ PatKind::Or { .. } |
+ PatKind::AscribeUserType { .. } => {}
}
};
- if let ty::Adt(adt_def, _) = pat.ty.kind() {
- // check for extracting values from union via destructuring
- if adt_def.is_union() {
- match *pat.kind {
- // assigning the whole union is okay
- // let x = Union { ... };
- // let y = x; // safe
- Binding { .. } |
- // binding to wildcard is okay since that never reads anything and stops double errors
- // with implict wildcard branches from `if let`s
- Wild |
- // doesn't have any effect on semantics
- AscribeUserType { .. } |
- // creating a union literal
- Constant { .. } => {},
- Leaf { .. } | Or { .. } => {
- // pattern matching with a union and not doing something like v = Union { bar: 5 }
- self.in_union_destructure = true;
+ match &*pat.kind {
+ PatKind::Leaf { .. } => {
+ if let ty::Adt(adt_def, ..) = pat.ty.kind() {
+ if adt_def.is_union() {
+ let old_in_union_destructure =
+ std::mem::replace(&mut self.in_union_destructure, true);
+ visit::walk_pat(self, pat);
+ self.in_union_destructure = old_in_union_destructure;
+ } else if (Bound::Unbounded, Bound::Unbounded)
+ != self.tcx.layout_scalar_valid_range(adt_def.did)
+ {
+ let old_inside_adt = std::mem::replace(&mut self.inside_adt, true);
+ visit::walk_pat(self, pat);
+ self.inside_adt = old_inside_adt;
+ } else {
visit::walk_pat(self, pat);
- self.in_union_destructure = false;
- return; // don't walk pattern
}
- Variant { .. } | Deref { .. } | Range { .. } | Slice { .. } | Array { .. } =>
- unreachable!("impossible union destructuring type"),
+ } else {
+ visit::walk_pat(self, pat);
}
}
+ PatKind::Binding { mode: BindingMode::ByRef(borrow_kind), ty, .. } => {
+ if self.inside_adt {
+ if let ty::Ref(_, ty, _) = ty.kind() {
+ match borrow_kind {
+ BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
+ if !ty.is_freeze(self.tcx.at(pat.span), self.param_env) {
+ self.requires_unsafe(pat.span, BorrowOfLayoutConstrainedField);
+ }
+ }
+ BorrowKind::Mut { .. } => {
+ self.requires_unsafe(pat.span, MutationOfLayoutConstrainedField);
+ }
+ }
+ } else {
+ span_bug!(
+ pat.span,
+ "BindingMode::ByRef in pattern, but found non-reference type {}",
+ ty
+ );
+ }
+ }
+ visit::walk_pat(self, pat);
+ }
+ PatKind::Deref { .. } => {
+ let old_inside_adt = std::mem::replace(&mut self.inside_adt, false);
+ visit::walk_pat(self, pat);
+ self.inside_adt = old_inside_adt;
+ }
+ _ => {
+ visit::walk_pat(self, pat);
+ }
}
-
- visit::walk_pat(self, pat);
}
fn visit_expr(&mut self, expr: &Expr<'tcx>) {
}
}
}
- // don't have any special handling for AssignOp since it causes a read *and* write to lhs
- ExprKind::Assign { lhs, rhs } => {
- // assigning to a union is safe, check here so it doesn't get treated as a read later
- self.in_possible_lhs_union_assign = true;
- visit::walk_expr(self, &self.thir()[lhs]);
- self.in_possible_lhs_union_assign = false;
- visit::walk_expr(self, &self.thir()[rhs]);
- return; // don't visit the whole expression
+ ExprKind::Assign { lhs, rhs } | ExprKind::AssignOp { lhs, rhs, .. } => {
+ // First, check whether we are mutating a layout constrained field
+ let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
+ visit::walk_expr(&mut visitor, &self.thir[lhs]);
+ if visitor.found {
+ self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
+ }
+
+ // Second, check for accesses to union fields
+ // don't have any special handling for AssignOp since it causes a read *and* write to lhs
+ if matches!(expr.kind, ExprKind::Assign { .. }) {
+ // assigning to a union is safe, check here so it doesn't get treated as a read later
+ self.in_possible_lhs_union_assign = true;
+ visit::walk_expr(self, &self.thir()[lhs]);
+ self.in_possible_lhs_union_assign = false;
+ visit::walk_expr(self, &self.thir()[rhs]);
+ return; // we have already visited everything by now
+ }
}
+ ExprKind::Borrow { borrow_kind, arg } => match borrow_kind {
+ BorrowKind::Shallow | BorrowKind::Shared | BorrowKind::Unique => {
+ if !self.thir[arg]
+ .ty
+ .is_freeze(self.tcx.at(self.thir[arg].span), self.param_env)
+ {
+ let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
+ visit::walk_expr(&mut visitor, expr);
+ if visitor.found {
+ self.requires_unsafe(expr.span, BorrowOfLayoutConstrainedField);
+ }
+ }
+ }
+ BorrowKind::Mut { .. } => {
+ let mut visitor = LayoutConstrainedPlaceVisitor::new(self.thir, self.tcx);
+ visit::walk_expr(&mut visitor, expr);
+ if visitor.found {
+ self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
+ }
+ }
+ },
_ => {}
}
visit::walk_expr(self, expr);
body_target_features,
in_possible_lhs_union_assign: false,
in_union_destructure: false,
+ param_env: tcx.param_env(def.did),
+ inside_adt: false,
};
visitor.visit_expr(&thir[expr]);
}
// convert the dereferenced constant to a pattern that is the sub-pattern of the
// deref pattern.
_ => {
- let old = self.behind_reference.replace(true);
- // In case there are structural-match violations somewhere in this subpattern,
- // we fall back to a const pattern. If we do not do this, we may end up with
- // a !structural-match constant that is not of reference type, which makes it
- // very hard to invoke `PartialEq::eq` on it as a fallback.
- let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) {
- Ok(subpattern) => PatKind::Deref { subpattern },
- Err(_) => PatKind::Constant { value: cv },
- };
- self.behind_reference.set(old);
- val
+ if !pointee_ty.is_sized(tcx.at(span), param_env) {
+ // `tcx.deref_const()` below will ICE with an unsized type
+ // (except slices, which are handled in a separate arm above).
+ let msg = format!("cannot use unsized non-slice type `{}` in constant patterns", pointee_ty);
+ if self.include_lint_checks {
+ tcx.sess.span_err(span, &msg);
+ } else {
+ tcx.sess.delay_span_bug(span, &msg);
+ }
+ PatKind::Wild
+ } else {
+ let old = self.behind_reference.replace(true);
+ // In case there are structural-match violations somewhere in this subpattern,
+ // we fall back to a const pattern. If we do not do this, we may end up with
+ // a !structural-match constant that is not of reference type, which makes it
+ // very hard to invoke `PartialEq::eq` on it as a fallback.
+ let val = match self.recur(tcx.deref_const(self.param_env.and(cv)), false) {
+ Ok(subpattern) => PatKind::Deref { subpattern },
+ Err(_) => PatKind::Constant { value: cv },
+ };
+ self.behind_reference.set(old);
+ val
+ }
}
},
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::FnDef(..) => {
| sym::rustc_if_this_changed
| sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
+ sym::default_method_body_is_const => {
+ self.check_default_method_body_is_const(attr, span, target)
+ }
_ => true,
};
// lint-only checks
}
}
}
+
+ /// default_method_body_is_const should only be applied to trait methods with default bodies.
+ fn check_default_method_body_is_const(
+ &self,
+ attr: &Attribute,
+ span: &Span,
+ target: Target,
+ ) -> bool {
+ match target {
+ Target::Method(MethodKind::Trait { body: true }) => true,
+ _ => {
+ self.tcx
+ .sess
+ .struct_span_err(
+ attr.span,
+ "attribute should be applied to a trait method with body",
+ )
+ .span_label(*span, "not a trait method or missing a body")
+ .emit();
+ false
+ }
+ }
+ }
}
impl Visitor<'tcx> for CheckAttrVisitor<'tcx> {
//! through, but errors for structured control flow in a `const` should be emitted here.
use rustc_attr as attr;
+use rustc_data_structures::stable_set::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
if let hir::ItemKind::Impl(ref imp) = item.kind {
if let hir::Constness::Const = imp.constness {
let did = imp.of_trait.as_ref()?.trait_def_id()?;
- let trait_fn_cnt = self
- .tcx
- .associated_item_def_ids(did)
- .iter()
- .filter(|did| {
- matches!(
- self.tcx.associated_item(**did),
- ty::AssocItem { kind: ty::AssocKind::Fn, .. }
- )
- })
- .count();
+ let mut to_implement = FxHashSet::default();
+
+ for did in self.tcx.associated_item_def_ids(did) {
+ if let ty::AssocItem {
+ kind: ty::AssocKind::Fn, ident, defaultness, ..
+ } = self.tcx.associated_item(*did)
+ {
+ // we can ignore functions that do not have default bodies:
+ // if those are unimplemented it will be catched by typeck.
+ if defaultness.has_value()
+ && !self.tcx.has_attr(*did, sym::default_method_body_is_const)
+ {
+ to_implement.insert(ident);
+ }
+ }
+ }
- let impl_fn_cnt = imp
+ for it in imp
.items
.iter()
.filter(|it| matches!(it.kind, hir::AssocItemKind::Fn { .. }))
- .count();
+ {
+ to_implement.remove(&it.ident);
+ }
- // number of trait functions unequal to functions in impl,
- // meaning that one or more provided/default functions of the
- // trait are used.
- if trait_fn_cnt != impl_fn_cnt {
+ // all nonconst trait functions (not marked with #[default_method_body_is_const])
+ // must be implemented
+ if !to_implement.is_empty() {
self.tcx
.sess
.struct_span_err(
item.span,
- "const trait implementations may not use default functions",
+ "const trait implementations may not use non-const default functions",
)
+ .note(&format!("`{}` not implemented", to_implement.into_iter().map(|id| id.to_string()).collect::<Vec<_>>().join("`, `")))
.emit();
}
}
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, id: hir::HirId) {
if let Some(def_id) = path.res.opt_def_id() {
- self.tcx.check_stability(def_id, Some(id), path.span, None)
+ let method_span = path.segments.last().map(|s| s.ident.span);
+ self.tcx.check_stability(def_id, Some(id), path.span, method_span)
}
intravisit::walk_path(self, path)
}
let wordsz = sess.target.pointer_width.to_string();
let os = &sess.target.os;
let env = &sess.target.env;
+ let abi = &sess.target.abi;
let vendor = &sess.target.vendor;
let min_atomic_width = sess.target.min_atomic_width();
let max_atomic_width = sess.target.max_atomic_width();
});
let mut ret = FxHashSet::default();
- ret.reserve(6); // the minimum number of insertions
+ ret.reserve(7); // the minimum number of insertions
// Target bindings.
ret.insert((sym::target_os, Some(Symbol::intern(os))));
for fam in &sess.target.families {
ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str()))));
ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
ret.insert((sym::target_env, Some(Symbol::intern(env))));
+ ret.insert((sym::target_abi, Some(Symbol::intern(abi))));
ret.insert((sym::target_vendor, Some(Symbol::intern(vendor))));
if sess.target.has_elf_tls {
ret.insert((sym::target_thread_local, None));
use rustc_errors::emitter::{Emitter, EmitterWriter, HumanReadableErrorType};
use rustc_errors::json::JsonEmitter;
use rustc_errors::registry::Registry;
-use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticId, ErrorReported};
-use rustc_lint_defs::FutureBreakage;
+use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorReported};
use rustc_macros::HashStable_Generic;
pub use rustc_span::def_id::StableCrateId;
use rustc_span::source_map::{FileLoader, MultiSpan, RealFileLoader, SourceMap, Span};
if diags.is_empty() {
return;
}
- // If any future-breakage lints were registered, this lint store
- // should be available
- let lint_store = self.lint_store.get().expect("`lint_store` not initialized!");
- let diags_and_breakage: Vec<(FutureBreakage, Diagnostic)> = diags
- .into_iter()
- .map(|diag| {
- let lint_name = match &diag.code {
- Some(DiagnosticId::Lint { name, has_future_breakage: true, .. }) => name,
- _ => panic!("Unexpected code in diagnostic {:?}", diag),
- };
- let lint = lint_store.name_to_lint(&lint_name);
- let future_breakage =
- lint.lint.future_incompatible.unwrap().future_breakage.unwrap();
- (future_breakage, diag)
- })
- .collect();
- self.parse_sess.span_diagnostic.emit_future_breakage_report(diags_and_breakage);
+ self.parse_sess.span_diagnostic.emit_future_breakage_report(diags);
}
pub fn local_stable_crate_id(&self) -> StableCrateId {
cfg_eval,
cfg_panic,
cfg_sanitize,
+ cfg_target_abi,
cfg_target_feature,
cfg_target_has_atomic,
cfg_target_thread_local,
decode,
default_alloc_error_handler,
default_lib_allocator,
+ default_method_body_is_const,
default_type_parameter_fallback,
default_type_params,
delay_span_bug_from_inside_query,
sync,
sync_trait,
t32,
+ target_abi,
target_arch,
target_endian,
target_env,
pointer_width: 32,
data_layout: "E-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
- options: TargetOptions { mcount: "\u{1}_mcount".to_string(), endian: Endian::Big, ..base },
+ options: TargetOptions {
+ abi: "ilp32".to_string(),
+ mcount: "\u{1}_mcount".to_string(),
+ endian: Endian::Big,
+ ..base
+ },
}
}
data_layout: "e-m:e-p:32:32-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
arch: "aarch64".to_string(),
options: TargetOptions {
+ abi: "ilp32".to_string(),
max_atomic_width: Some(128),
mcount: "\u{1}_mcount".to_string(),
..super::linux_gnu_base::opts()
pub fn target() -> Target {
let opts = TargetOptions {
+ abi: "softfloat".to_string(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
linker: Some("rust-lld".to_owned()),
features: "+strict-align,-neon,-fp-armv8".to_string(),
Arm64_sim,
}
+fn target_abi(arch: Arch) -> String {
+ match arch {
+ Armv7 | Armv7s | Arm64 | I386 | X86_64 => "",
+ X86_64_macabi | Arm64_macabi => "macabi",
+ Arm64_sim => "sim",
+ }
+ .to_string()
+}
+
fn target_cpu(arch: Arch) -> String {
match arch {
Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
pub fn opts(os: &str, arch: Arch) -> TargetOptions {
TargetOptions {
+ abi: target_abi(arch),
cpu: target_cpu(arch),
dynamic_linking: false,
executables: true,
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
// https://developer.android.com/ndk/guides/abis.html#armeabi
features: "+strict-align,+v5te".to_string(),
max_atomic_width: Some(32),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
features: "+strict-align,+v6".to_string(),
max_atomic_width: Some(64),
mcount: "\u{1}__gnu_mcount_nc".to_string(),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
features: "+strict-align,+v6,+vfp2,-d32".to_string(),
max_atomic_width: Some(64),
mcount: "\u{1}__gnu_mcount_nc".to_string(),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
// Most of these settings are copied from the arm_unknown_linux_gnueabi
// target.
features: "+strict-align,+v6".to_string(),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
// Most of these settings are copied from the arm_unknown_linux_gnueabihf
// target.
features: "+strict-align,+v6,+vfp2,-d32".to_string(),
data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
endian: Endian::Big,
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
executables: true,
data_layout: "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
endian: Endian::Big,
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
executables: true,
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
features: "+soft-float,+strict-align".to_string(),
// Atomic operations provided by compiler-builtins
max_atomic_width: Some(32),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
features: "+soft-float,+strict-align".to_string(),
// Atomic operations provided by compiler-builtins
max_atomic_width: Some(32),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
features: "+soft-float,+strict-align".to_string(),
// Atomic operations provided by compiler-builtins
max_atomic_width: Some(32),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
features: "+soft-float,+strict-align".to_string(),
// Atomic operations provided by compiler-builtins
max_atomic_width: Some(32),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
+ // FIXME: change env to "gnu" when cfg_target_abi becomes stable
env: "gnueabihf".to_string(),
features: "+v6,+vfp2,-d32".to_string(),
max_atomic_width: Some(64),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
+ // FIXME: remove env when cfg_target_abi becomes stable
env: "eabihf".to_string(),
features: "+v6,+vfp2,-d32".to_string(),
max_atomic_width: Some(64),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
features: "+v7,+thumb-mode,+thumb2,+vfp3,-d32,-neon".to_string(),
max_atomic_width: Some(64),
..base
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
+ // FIXME: change env to "gnu" when cfg_target_abi becomes stable
env: "gnueabihf".to_string(),
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
max_atomic_width: Some(64),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
features: "+v7,+thumb2,+soft-float,-neon".to_string(),
max_atomic_width: Some(64),
mcount: "\u{1}__gnu_mcount_nc".to_string(),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
// Info about features at https://wiki.debian.org/ArmHardFloatPort
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
max_atomic_width: Some(64),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
features: "+v7,+thumb2,+soft-float,-neon".to_string(),
max_atomic_width: Some(64),
mcount: "\u{1}mcount".to_string(),
// Most of these settings are copied from the armv7_unknown_linux_gnueabihf
// target.
options: TargetOptions {
+ abi: "eabihf".to_string(),
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
max_atomic_width: Some(64),
mcount: "\u{1}mcount".to_string(),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
+ // FIXME: remove env when cfg_target_abi becomes stable
env: "eabihf".to_string(),
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
max_atomic_width: Some(64),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
// Info about features at https://wiki.debian.org/ArmHardFloatPort
features: "+v7,+vfp3,-d32,+thumb2,-neon".to_string(),
max_atomic_width: Some(64),
pub fn target() -> Target {
let opts = TargetOptions {
+ abi: "eabi".to_string(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
linker: Some("rust-lld".to_owned()),
features: "+v7,+thumb2,+soft-float,-neon,+strict-align".to_string(),
pub fn target() -> Target {
let opts = TargetOptions {
+ abi: "eabihf".to_string(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
linker: Some("rust-lld".to_owned()),
features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
executables: true,
linker: Some("rust-lld".to_owned()),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
executables: true,
linker: Some("rust-lld".to_owned()),
data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
options: TargetOptions {
+ abi: "abi64".to_string(),
endian: Endian::Big,
// NOTE(mips64r2) matches C toolchain
cpu: "mips64r2".to_string(),
pointer_width: 64,
data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
- options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
+ options: TargetOptions {
+ abi: "abi64".to_string(),
+ endian: Endian::Big,
+ mcount: "_mcount".to_string(),
+ ..base
+ },
}
}
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
options: TargetOptions {
+ abi: "abi64".to_string(),
// NOTE(mips64r2) matches C toolchain
cpu: "mips64r2".to_string(),
features: "+mips64r2".to_string(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
- options: TargetOptions { mcount: "_mcount".to_string(), ..base },
+ options: TargetOptions { abi: "abi64".to_string(), mcount: "_mcount".to_string(), ..base },
}
}
data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
options: TargetOptions {
+ abi: "abi64".to_string(),
endian: Endian::Big,
// NOTE(mips64r6) matches C toolchain
cpu: "mips64r6".to_string(),
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(),
arch: "mips64".to_string(),
options: TargetOptions {
+ abi: "abi64".to_string(),
// NOTE(mips64r6) matches C toolchain
cpu: "mips64r6".to_string(),
features: "+mips64r6".to_string(),
pub os: String,
/// Environment name to use for conditional compilation (`target_env`). Defaults to "".
pub env: String,
+ /// ABI name to distinguish multiple ABIs on the same OS and architecture. For instance, `"eabi"`
+ /// or `"eabihf"`. Defaults to "".
+ pub abi: String,
/// Vendor name to use for conditional compilation (`target_vendor`). Defaults to "unknown".
pub vendor: String,
/// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed
c_int_width: "32".to_string(),
os: "none".to_string(),
env: String::new(),
+ abi: String::new(),
vendor: "unknown".to_string(),
linker_flavor: LinkerFlavor::Gcc,
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
key!(c_int_width = "target-c-int-width");
key!(os);
key!(env);
+ key!(abi);
key!(vendor);
key!(linker_flavor, LinkerFlavor)?;
key!(linker, optional);
target_option_val!(c_int_width, "target-c-int-width");
target_option_val!(os);
target_option_val!(env);
+ target_option_val!(abi);
target_option_val!(vendor);
target_option_val!(linker_flavor);
target_option_val!(linker);
pointer_width: 32,
data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
arch: "powerpc".to_string(),
- options: TargetOptions { endian: Endian::Big, mcount: "_mcount".to_string(), ..base },
+ options: TargetOptions {
+ abi: "spe".to_string(),
+ endian: Endian::Big,
+ mcount: "_mcount".to_string(),
+ ..base
+ },
}
}
data_layout: "E-m:e-p:32:32-i64:64-n32".to_string(),
arch: "powerpc".to_string(),
options: TargetOptions {
+ abi: "spe".to_string(),
endian: Endian::Big,
// feature msync would disable instruction 'fsync' which is not supported by fsl_p1p2
features: "+secure-plt,+msync".to_string(),
*/
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
linker_flavor: LinkerFlavor::Ld,
linker: Some("arm-none-eabi-ld".to_string()),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
// The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them
// with +strict-align.
features: "+strict-align".to_string(),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
- options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() },
+ options: TargetOptions {
+ abi: "eabi".to_string(),
+ max_atomic_width: Some(32),
+ ..super::thumb_base::opts()
+ },
}
}
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
// `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the
// Cortex-M7 (vfp5)
// `-d32` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
- options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() },
+ options: TargetOptions {
+ abi: "eabi".to_string(),
+ max_atomic_width: Some(32),
+ ..super::thumb_base::opts()
+ },
}
}
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
max_atomic_width: Some(64),
..base
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
// Info about features at https://wiki.debian.org/ArmHardFloatPort
features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
max_atomic_width: Some(64),
// Most of these settings are copied from the thumbv7neon_unknown_linux_gnueabihf
// target.
options: TargetOptions {
+ abi: "eabihf".to_string(),
features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".to_string(),
max_atomic_width: Some(64),
mcount: "\u{1}mcount".to_string(),
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabi".to_string(),
// ARMv8-M baseline doesn't support unaligned loads/stores so we disable them
// with +strict-align.
features: "+strict-align".to_string(),
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".to_string(),
arch: "arm".to_string(),
- options: TargetOptions { max_atomic_width: Some(32), ..super::thumb_base::opts() },
+ options: TargetOptions {
+ abi: "eabi".to_string(),
+ max_atomic_width: Some(32),
+ ..super::thumb_base::opts()
+ },
}
}
arch: "arm".to_string(),
options: TargetOptions {
+ abi: "eabihf".to_string(),
// If the Floating Point extension is implemented in the Cortex-M33
// processor, the Cortex-M33 Technical Reference Manual states that
// the FPU uses the FPv5 architecture, single-precision instructions
late_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), mingw_libs);
TargetOptions {
+ abi: "uwp".to_string(),
vendor: "uwp".to_string(),
executables: false,
limit_rdylib_exports: false,
pub fn opts() -> TargetOptions {
let mut opts = super::windows_msvc_base::opts();
+ opts.abi = "uwp".to_string();
opts.vendor = "uwp".to_string();
let pre_link_args_msvc = vec!["/APPCONTAINER".to_string(), "mincore.lib".to_string()];
opts.pre_link_args.entry(LinkerFlavor::Msvc).or_default().extend(pre_link_args_msvc.clone());
os: "unknown".into(),
env: "sgx".into(),
vendor: "fortanix".into(),
+ abi: "fortanix".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld),
executables: true,
linker: Some("rust-lld".to_owned()),
pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
base.cpu = "x86-64".to_string();
+ base.abi = "x32".to_string();
base.max_atomic_width = Some(64);
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-mx32".to_string());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
}
}
+fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness {
+ let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
+ let item = tcx.hir().expect_item(hir_id);
+ if let hir::ItemKind::Impl(impl_) = &item.kind {
+ impl_.constness
+ } else {
+ bug!("`impl_constness` called on {:?}", item);
+ }
+}
+
/// Calculates the `Sized` constraint.
///
/// In fact, there are only a few options for the types in the constraint:
instance_def_size_estimate,
issue33140_self_ty,
impl_defaultness,
+ impl_constness,
conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw,
..*providers
};
fcx.write_method_call(self.call_expr.hir_id, method_callee);
}
None => {
- span_bug!(
+ // This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once`
+ // lang items are not defined (issue #86238).
+ let mut err = fcx.inh.tcx.sess.struct_span_err(
self.call_expr.span,
- "failed to find an overloaded call trait for closure call"
+ "failed to find an overloaded call trait for closure call",
);
+ err.help(
+ "make sure the `fn`/`fn_mut`/`fn_once` lang items are defined \
+ and have associated `call`/`call_mut`/`call_once` functions",
+ );
+ err.emit();
}
}
}
expected.is_unit(),
pointing_at_return_type,
) {
- // If the block is from an external macro, then do not suggest
- // adding a semicolon, because there's nowhere to put it.
- // See issue #81943.
+ // If the block is from an external macro or try (`?`) desugaring, then
+ // do not suggest adding a semicolon, because there's nowhere to put it.
+ // See issues #81943 and #87051.
if cond_expr.span.desugaring_kind().is_none()
&& !in_external_macro(fcx.tcx.sess, cond_expr.span)
+ && !matches!(
+ cond_expr.kind,
+ hir::ExprKind::Match(.., hir::MatchSource::TryDesugar)
+ )
{
err.span_label(cond_expr.span, "expected this to be `()`");
if expr.can_have_side_effects() {
/// assert_eq!(false.then_some(0), None);
/// assert_eq!(true.then_some(0), Some(0));
/// ```
- #[unstable(feature = "bool_to_option", issue = "64260")]
+ #[unstable(feature = "bool_to_option", issue = "80967")]
#[inline]
pub fn then_some<T>(self, t: T) -> Option<T> {
if self { Some(t) } else { None }
/// // a `MaybeUninit<T>` may be invalid, and hence this is not UB:
/// let mut x = MaybeUninit::<&i32>::uninit();
/// // Set it to a valid value.
-/// unsafe { x.as_mut_ptr().write(&0); }
+/// x.write(&0);
/// // Extract the initialized data -- this is only allowed *after* properly
/// // initializing `x`!
/// let x = unsafe { x.assume_init() };
/// // this loop, we have a memory leak, but there is no memory safety
/// // issue.
/// for elem in &mut data[..] {
-/// *elem = MaybeUninit::new(vec![42]);
+/// elem.write(vec![42]);
/// }
///
/// // Everything is initialized. Transmute the array to the
/// let mut data_len: usize = 0;
///
/// for elem in &mut data[0..500] {
-/// *elem = MaybeUninit::new(String::from("hello"));
+/// elem.write(String::from("hello"));
/// data_len += 1;
/// }
///
/// (now safely initialized) contents of `self`.
///
/// As the content is stored inside a `MaybeUninit`, the destructor is not
- /// ran for the inner data if the MaybeUninit leaves scope without a call to
+ /// run for the inner data if the MaybeUninit leaves scope without a call to
/// [`assume_init`], [`assume_init_drop`], or similar. Code that receives
/// the mutable reference returned by this function needs to keep this in
/// mind. The safety model of Rust regards leaks as safe, but they are
/// Correct usage of this method:
///
/// ```rust
- /// #![feature(maybe_uninit_extra)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u8>>::uninit();
/// This usage of the method causes a leak:
///
/// ```rust
- /// #![feature(maybe_uninit_extra)]
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<String>::uninit();
/// // x is initialized now:
/// let s = unsafe { x.assume_init() };
/// ```
- #[unstable(feature = "maybe_uninit_extra", issue = "63567")]
- #[rustc_const_unstable(feature = "maybe_uninit_extra", issue = "63567")]
+ ///
+ /// This method can be used to avoid unsafe in some cases. The example below
+ /// shows a part of an implementation of a fixed sized arena that lends out
+ /// pinned references.
+ /// With `write`, we can avoid the need to write through a raw pointer:
+ ///
+ /// ```rust
+ /// #![feature(maybe_uninit_extra)]
+ /// use core::pin::Pin;
+ /// use core::mem::MaybeUninit;
+ ///
+ /// struct PinArena<T> {
+ /// memory: Box<[MaybeUninit<T>]>,
+ /// len: usize,
+ /// }
+ ///
+ /// impl <T> PinArena<T> {
+ /// pub fn capacity(&self) -> usize {
+ /// self.memory.len()
+ /// }
+ /// pub fn push(&mut self, val: T) -> Pin<&mut T> {
+ /// if self.len >= self.capacity() {
+ /// panic!("Attempted to push to a full pin arena!");
+ /// }
+ /// let ref_ = self.memory[self.len].write(val);
+ /// self.len += 1;
+ /// unsafe { Pin::new_unchecked(ref_) }
+ /// }
+ /// }
+ /// ```
+ #[stable(feature = "maybe_uninit_write", since = "1.55.0")]
+ #[rustc_const_unstable(feature = "const_maybe_uninit_write", issue = "63567")]
#[inline(always)]
pub const fn write(&mut self, val: T) -> &mut T {
*self = MaybeUninit::new(val);
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
- /// unsafe { x.as_mut_ptr().write(vec![0, 1, 2]); }
+ /// x.write(vec![0, 1, 2]);
/// // Create a reference into the `MaybeUninit<T>`. This is okay because we initialized it.
/// let x_vec = unsafe { &*x.as_ptr() };
/// assert_eq!(x_vec.len(), 3);
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
- /// unsafe { x.as_mut_ptr().write(vec![0, 1, 2]); }
+ /// x.write(vec![0, 1, 2]);
/// // Create a reference into the `MaybeUninit<Vec<u32>>`.
/// // This is okay because we initialized it.
/// let x_vec = unsafe { &mut *x.as_mut_ptr() };
/// use std::mem::MaybeUninit;
///
/// let mut x = MaybeUninit::<bool>::uninit();
- /// unsafe { x.as_mut_ptr().write(true); }
+ /// x.write(true);
/// let x_init = unsafe { x.assume_init() };
/// assert_eq!(x_init, true);
/// ```
///
/// let mut x = MaybeUninit::<Vec<u32>>::uninit();
/// // Initialize `x`:
- /// unsafe { x.as_mut_ptr().write(vec![1, 2, 3]); }
+ /// x.write(vec![1, 2, 3]);
/// // Now that our `MaybeUninit<_>` is known to be initialized, it is okay to
/// // create a shared reference to it:
/// let x: &Vec<u32> = unsafe {
/// use std::mem::MaybeUninit;
///
/// let mut array: [MaybeUninit<i32>; 3] = MaybeUninit::uninit_array();
- /// array[0] = MaybeUninit::new(0);
- /// array[1] = MaybeUninit::new(1);
- /// array[2] = MaybeUninit::new(2);
+ /// array[0].write(0);
+ /// array[1].write(1);
+ /// array[2].write(2);
///
/// // SAFETY: Now safe as we initialised all elements
/// let array = unsafe {
/// Returns the square root of a number.
///
- /// Returns NaN if `self` is a negative number.
+ /// Returns NaN if `self` is a negative number other than `-0.0`.
///
/// # Examples
///
/// ```
/// let positive = 4.0_f32;
/// let negative = -4.0_f32;
+ /// let negative_zero = -0.0_f32;
///
/// let abs_difference = (positive.sqrt() - 2.0).abs();
///
/// assert!(abs_difference <= f32::EPSILON);
/// assert!(negative.sqrt().is_nan());
+ /// assert!(negative_zero.sqrt() == negative_zero);
/// ```
#[must_use = "method returns a new number and does not mutate the original value"]
#[stable(feature = "rust1", since = "1.0.0")]
/// Returns the square root of a number.
///
- /// Returns NaN if `self` is a negative number.
+ /// Returns NaN if `self` is a negative number other than `-0.0`.
///
/// # Examples
///
/// ```
/// let positive = 4.0_f64;
/// let negative = -4.0_f64;
+ /// let negative_zero = -0.0_f64;
///
/// let abs_difference = (positive.sqrt() - 2.0).abs();
///
/// assert!(abs_difference < 1e-10);
/// assert!(negative.sqrt().is_nan());
+ /// assert!(negative_zero.sqrt() == negative_zero);
/// ```
#[must_use = "method returns a new number and does not mutate the original value"]
#[stable(feature = "rust1", since = "1.0.0")]
where
T: AsRef<[u8]>,
{
- /// Returns the remaining length.
- ///
- /// # Examples
- ///
- /// ```
- /// #![feature(cursor_remaining)]
- /// use std::io::Cursor;
- ///
- /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
- ///
- /// assert_eq!(buff.remaining(), 5);
- ///
- /// buff.set_position(2);
- /// assert_eq!(buff.remaining(), 3);
- ///
- /// buff.set_position(4);
- /// assert_eq!(buff.remaining(), 1);
- ///
- /// buff.set_position(6);
- /// assert_eq!(buff.remaining(), 0);
- /// ```
- #[unstable(feature = "cursor_remaining", issue = "86369")]
- pub fn remaining(&self) -> u64 {
- (self.inner.as_ref().len() as u64).checked_sub(self.pos).unwrap_or(0)
- }
-
/// Returns the remaining slice.
///
/// # Examples
pub use self::stdio::set_output_capture;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::stdio::{stderr, stdin, stdout, Stderr, Stdin, Stdout};
-#[unstable(feature = "stdio_locked", issue = "none")]
+#[unstable(feature = "stdio_locked", issue = "86845")]
pub use self::stdio::{stderr_locked, stdin_locked, stdout_locked};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::stdio::{StderrLock, StdinLock, StdoutLock};
/// Ok(())
/// }
/// ```
-#[unstable(feature = "stdio_locked", issue = "none")]
+#[unstable(feature = "stdio_locked", issue = "86845")]
pub fn stdin_locked() -> StdinLock<'static> {
stdin().into_locked()
}
/// Ok(())
/// }
/// ```
- #[unstable(feature = "stdio_locked", issue = "none")]
+ #[unstable(feature = "stdio_locked", issue = "86845")]
pub fn into_locked(self) -> StdinLock<'static> {
self.lock_any()
}
/// Ok(())
/// }
/// ```
-#[unstable(feature = "stdio_locked", issue = "none")]
+#[unstable(feature = "stdio_locked", issue = "86845")]
pub fn stdout_locked() -> StdoutLock<'static> {
stdout().into_locked()
}
/// Ok(())
/// }
/// ```
- #[unstable(feature = "stdio_locked", issue = "none")]
+ #[unstable(feature = "stdio_locked", issue = "86845")]
pub fn into_locked(self) -> StdoutLock<'static> {
self.lock_any()
}
/// Ok(())
/// }
/// ```
-#[unstable(feature = "stdio_locked", issue = "none")]
+#[unstable(feature = "stdio_locked", issue = "86845")]
pub fn stderr_locked() -> StderrLock<'static> {
stderr().into_locked()
}
/// Ok(())
/// }
/// ```
- #[unstable(feature = "stdio_locked", issue = "none")]
+ #[unstable(feature = "stdio_locked", issue = "86845")]
pub fn into_locked(self) -> StderrLock<'static> {
self.lock_any()
}
install!((self, builder, _config),
Docs, "src/doc", _config.docs, only_hosts: false, {
- let tarball = builder.ensure(dist::Docs { host: self.target }).expect("missing docs");
- install_sh(builder, "docs", self.compiler.stage, Some(self.target), &tarball);
+ if let Some(tarball) = builder.ensure(dist::Docs { host: self.target }) {
+ install_sh(builder, "docs", self.compiler.stage, Some(self.target), &tarball);
+ } else {
+ panic!("docs are not available to install, \
+ check that `build.docs` is true in `config.toml`");
+ }
};
Std, "library/std", true, only_hosts: false, {
for target in &builder.targets {
+ // `expect` should be safe, only None when host != build, but this
+ // only runs when host == build
let tarball = builder.ensure(dist::Std {
compiler: self.compiler,
target: *target
}
};
RustAnalyzer, "rust-analyzer", Self::should_build(_config), only_hosts: true, {
- let tarball = builder
- .ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
- .expect("missing rust-analyzer");
- install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball);
+ if let Some(tarball) =
+ builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
+ {
+ install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball);
+ } else {
+ builder.info(
+ &format!("skipping Install rust-analyzer stage{} ({})", self.compiler.stage, self.target),
+ );
+ }
};
Clippy, "clippy", Self::should_build(_config), only_hosts: true, {
let tarball = builder.ensure(dist::Clippy { compiler: self.compiler, target: self.target });
}
};
Analysis, "analysis", Self::should_build(_config), only_hosts: false, {
+ // `expect` should be safe, only None with host != build, but this
+ // only uses the `build` compiler
let tarball = builder.ensure(dist::Analysis {
// Find the actual compiler (handling the full bootstrap option) which
// produced the save-analysis data because that data isn't copied
t!(std::fs::read_dir(dir)).next().is_none()
}
+ if !build.config.submodules {
+ return;
+ }
+
// NOTE: The check for the empty directory is here because when running x.py
// the first time, the llvm submodule won't be checked out. Check it out
// now so we can build it.
// We remove existing folder to be sure there won't be artifacts remaining.
let _ = fs::remove_dir_all(&out_dir);
- let mut nb_generated = 0;
+ let src_path = "src/test/rustdoc-gui/src";
// We generate docs for the libraries present in the rustdoc-gui's src folder.
- let libs_dir = builder.build.src.join("src/test/rustdoc-gui/src");
- for entry in libs_dir.read_dir().expect("read_dir call failed") {
- let entry = entry.expect("invalid entry");
- let path = entry.path();
- if path.extension().map(|e| e == "rs").unwrap_or(false) {
- let mut command = builder.rustdoc_cmd(self.compiler);
- command.arg(path).arg("-o").arg(&out_dir);
- builder.run(&mut command);
- nb_generated += 1;
- }
- }
- assert!(nb_generated > 0, "no documentation was generated...");
+ let mut cargo = Command::new(&builder.initial_cargo);
+ cargo
+ .arg("doc")
+ .arg("--workspace")
+ .arg("--target-dir")
+ .arg(&out_dir)
+ .env("RUSTDOC", builder.rustdoc(self.compiler))
+ .env("RUSTC", builder.rustc(self.compiler))
+ .current_dir(&builder.build.src.join(src_path));
+ builder.run(&mut cargo);
// We now run GUI tests.
let mut command = Command::new(&nodejs);
command
.arg(builder.build.src.join("src/tools/rustdoc-gui/tester.js"))
.arg("--doc-folder")
- .arg(out_dir)
+ .arg(out_dir.join("doc"))
.arg("--tests-folder")
.arg(builder.build.src.join("src/test/rustdoc-gui"));
for path in &builder.paths {
RUN ./build-gcc.sh && apt-get remove -y gcc g++
COPY host-x86_64/dist-x86_64-linux/build-python.sh /tmp/
-# Build Python 2.7 needed for Clang 10.
-RUN ./build-python.sh 2.7.12
# Build Python 3 needed for LLVM 12.
RUN ./build-python.sh 3.9.1
--build=i686-unknown-linux-gnu \
--set llvm.ninja=false \
--set rust.jemalloc
-ENV SCRIPT python2.7 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS
+ENV SCRIPT python3 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS
ENV CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang
# This was added when we switched from gcc to clang. It's not clear why this is
RUN ./build-gcc.sh && apt-get remove -y gcc g++
COPY host-x86_64/dist-x86_64-linux/build-python.sh /tmp/
-# Build Python 2.7 needed for Clang 10.
-RUN ./build-python.sh 2.7.12
# Build Python 3 needed for LLVM 12.
RUN ./build-python.sh 3.9.1
--set llvm.thin-lto=true \
--set llvm.ninja=false \
--set rust.jemalloc
-ENV SCRIPT ../src/ci/pgo.sh python2.7 ../x.py dist \
+ENV SCRIPT ../src/ci/pgo.sh python3 ../x.py dist \
--host $HOSTS --target $HOSTS \
--include-default-paths \
src/tools/build-manifest
source shared.sh
-curl https://ftp.gnu.org/gnu/binutils/binutils-2.25.1.tar.bz2 | tar xfj -
+VERSION=2.26.1
+
+curl https://ftp.gnu.org/gnu/binutils/binutils-$VERSION.tar.bz2 | tar xfj -
mkdir binutils-build
cd binutils-build
-hide_output ../binutils-2.25.1/configure --prefix=/rustroot
-hide_output make -j10
+hide_output ../binutils-$VERSION/configure --prefix=/rustroot
+hide_output make -j$(nproc)
hide_output make install
cd ..
rm -rf binutils-build
-rm -rf binutils-2.25.1
+rm -rf binutils-$VERSION
source shared.sh
-LLVM=llvmorg-10.0.0
+LLVM=llvmorg-12.0.1
mkdir llvm-project
cd llvm-project
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DC_INCLUDE_DIRS="$INC"
-hide_output make -j10
+hide_output make -j$(nproc)
hide_output make install
cd ../..
mkdir cmake-build
cd cmake-build
hide_output ../cmake-$CMAKE/configure --prefix=/rustroot
-hide_output make -j10
+hide_output make -j$(nproc)
hide_output make install
cd ..
--disable-rtsp \
--disable-ldaps \
--disable-ldap
-hide_output make -j10
+hide_output make -j$(nproc)
hide_output make install
cd ..
--prefix=/rustroot \
--enable-languages=c,c++ \
--disable-gnu-unique-object
-hide_output make -j10
+hide_output make -j$(nproc)
hide_output make install
ln -s gcc /rustroot/bin/cc
cd openssl-$VERSION
hide_output ./config --prefix=/rustroot shared -fPIC
-hide_output make -j10
+hide_output make -j$(nproc)
hide_output make install
cd ..
rm -rf openssl-$VERSION
# than that fairly normal.
CFLAGS='-I /rustroot/include' LDFLAGS='-L /rustroot/lib -L /rustroot/lib64' \
hide_output ../Python-$VERSION/configure --prefix=/rustroot
-hide_output make -j10
+hide_output make -j$(nproc)
hide_output make install
cd ..
rm -rf /tmp/rustc-pgo
-python2.7 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \
+python3 ../x.py build --target=$PGO_HOST --host=$PGO_HOST \
--stage 2 library/std --rust-profile-generate=/tmp/rustc-pgo
RUSTC_BOOTSTRAP=1 ./build/$PGO_HOST/stage2/bin/rustc --edition=2018 \
% The Rust Reference has moved
We've split up the reference into chapters. Please find it at its new
-home [here](reference/index.html).
+home [here](https://doc.rust-lang.org/stable/reference/introduction.html).
visibility: Inherited,
def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
kind: box ImplItem(Impl {
- span: self.cx.tcx.def_span(impl_def_id).clean(self.cx),
+ span: Span::from_rustc_span(self.cx.tcx.def_span(impl_def_id)),
unsafety: hir::Unsafety::Normal,
generics: (
self.cx.tcx.generics_of(impl_def_id),
crate fn try_inline(
cx: &mut DocContext<'_>,
parent_module: DefId,
+ import_def_id: Option<DefId>,
res: Res,
name: Symbol,
attrs: Option<Attrs<'_>>,
clean::ConstantItem(build_const(cx, did))
}
Res::Def(DefKind::Macro(kind), did) => {
- let mac = build_macro(cx, did, name);
+ let mac = build_macro(cx, did, name, import_def_id);
let type_kind = match kind {
MacroKind::Bang => ItemType::Macro,
let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs_clone);
cx.inlined.insert(did.into());
- ret.push(clean::Item::from_def_id_and_attrs_and_parts(
- did,
- Some(name),
- kind,
- box attrs,
- cx,
- cfg,
- ));
+ let mut item =
+ clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, box attrs, cx, cfg);
+ if let Some(import_def_id) = import_def_id {
+ // The visibility needs to reflect the one from the reexport and not from the "source" DefId.
+ item.visibility = cx.tcx.visibility(import_def_id).clean(cx);
+ }
+ ret.push(item);
Some(ret)
}
)),
cfg: None,
});
- } else if let Some(i) = try_inline(cx, did, item.res, item.ident.name, None, visited) {
+ } else if let Some(i) =
+ try_inline(cx, did, None, item.res, item.ident.name, None, visited)
+ {
items.extend(i)
}
}
}
}
-fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind {
- let imported_from = cx.tcx.crate_name(did.krate);
- match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
- LoadedMacro::MacroDef(def, _) => {
- if let ast::ItemKind::MacroDef(ref def) = def.kind {
- let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
- let matchers = tts.chunks(4).map(|arm| &arm[0]);
-
- let source = format!(
- "macro_rules! {} {{\n{}}}",
- name,
- utils::render_macro_arms(matchers, ";")
- );
-
- clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) })
+fn build_macro(
+ cx: &mut DocContext<'_>,
+ def_id: DefId,
+ name: Symbol,
+ import_def_id: Option<DefId>,
+) -> clean::ItemKind {
+ let imported_from = cx.tcx.crate_name(def_id.krate);
+ match cx.enter_resolver(|r| r.cstore().load_macro_untracked(def_id, cx.sess())) {
+ LoadedMacro::MacroDef(item_def, _) => {
+ if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
+ clean::MacroItem(clean::Macro {
+ source: utils::display_macro_source(
+ cx,
+ name,
+ def,
+ def_id,
+ cx.tcx.visibility(import_def_id.unwrap_or(def_id)),
+ ),
+ imported_from: Some(imported_from),
+ })
} else {
unreachable!()
}
}
}
-impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> {
- fn clean(&self, cx: &mut DocContext<'_>) -> Option<Vec<GenericBound>> {
- let mut v = Vec::new();
- v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives));
- v.extend(self.types().map(|t| {
- GenericBound::TraitBound(
- PolyTrait { trait_: t.clean(cx), generic_params: Vec::new() },
- hir::TraitBoundModifier::None,
- )
- }));
- if !v.is_empty() { Some(v) } else { None }
- }
-}
-
impl Clean<Lifetime> for hir::Lifetime {
fn clean(&self, cx: &mut DocContext<'_>) -> Lifetime {
let def = cx.tcx.named_region(self.hir_id);
}
}
-impl Clean<Lifetime> for ty::GenericParamDef {
- fn clean(&self, _cx: &mut DocContext<'_>) -> Lifetime {
- Lifetime(self.name)
- }
-}
-
impl Clean<Option<Lifetime>> for ty::RegionKind {
fn clean(&self, _cx: &mut DocContext<'_>) -> Option<Lifetime> {
match *self {
}
}
-impl Clean<Span> for rustc_span::Span {
- fn clean(&self, _cx: &mut DocContext<'_>) -> Span {
- Span::from_rustc_span(*self)
- }
-}
-
impl Clean<Path> for hir::Path<'_> {
fn clean(&self, cx: &mut DocContext<'_>) -> Path {
Path {
if let Some(items) = inline::try_inline(
cx,
cx.tcx.parent_module(krate.hir_id()).to_def_id(),
+ Some(krate.def_id.to_def_id()),
res,
name,
Some(attrs),
// forcefully don't inline if this is not public or if the
// #[doc(no_inline)] attribute is present.
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
- let mut denied = !import.vis.node.is_pub()
+ let mut denied = !(import.vis.node.is_pub()
+ || (cx.render_options.document_private && import.vis.node.is_pub_restricted()))
|| pub_underscore
|| attrs.iter().any(|a| {
a.has_name(sym::doc)
}
if !denied {
let mut visited = FxHashSet::default();
+ let import_def_id = import.def_id.to_def_id();
if let Some(mut items) = inline::try_inline(
cx,
cx.tcx.parent_module(import.hir_id()).to_def_id(),
+ Some(import_def_id),
path.res,
name,
Some(attrs),
&mut visited,
) {
items.push(Item::from_def_id_and_parts(
- import.def_id.to_def_id(),
+ import_def_id,
None,
ImportItem(Import::new_simple(name, resolve_use_source(cx, path), false)),
cx,
fn clean(&self, cx: &mut DocContext<'_>) -> Item {
let (item, renamed) = self;
let name = renamed.unwrap_or(item.ident.name);
- let tts = item.ast.body.inner_tokens().trees().collect::<Vec<_>>();
- // Extract the macro's matchers. They represent the "interface" of the macro.
- let matchers = tts.chunks(4).map(|arm| &arm[0]);
-
- let source = if item.ast.macro_rules {
- format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
- } else {
- let vis = item.vis.clean(cx);
- let def_id = item.def_id.to_def_id();
-
- if matchers.len() <= 1 {
- format!(
- "{}macro {}{} {{\n ...\n}}",
- vis.to_src_with_space(cx.tcx, def_id),
- name,
- matchers.map(render_macro_matcher).collect::<String>(),
- )
- } else {
- format!(
- "{}macro {} {{\n{}}}",
- vis.to_src_with_space(cx.tcx, def_id),
- name,
- render_macro_arms(matchers, ","),
- )
- }
- };
+ let def_id = item.def_id.to_def_id();
Item::from_hir_id_and_parts(
item.hir_id(),
Some(name),
- MacroItem(Macro { source, imported_from: None }),
+ MacroItem(Macro {
+ source: display_macro_source(cx, name, &item.ast, def_id, &item.vis),
+ imported_from: None,
+ }),
cx,
)
}
}
}
}
-
-enum SimpleBound {
- TraitBound(Vec<PathSegment>, Vec<SimpleBound>, Vec<GenericParamDef>, hir::TraitBoundModifier),
- Outlives(Lifetime),
-}
-
-impl From<GenericBound> for SimpleBound {
- fn from(bound: GenericBound) -> Self {
- match bound.clone() {
- GenericBound::Outlives(l) => SimpleBound::Outlives(l),
- GenericBound::TraitBound(t, mod_) => match t.trait_ {
- Type::ResolvedPath { path, .. } => {
- SimpleBound::TraitBound(path.segments, Vec::new(), t.generic_params, mod_)
- }
- _ => panic!("Unexpected bound {:?}", bound),
- },
- }
- }
-}
use crate::clean::{
inline, Clean, Crate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime,
Path, PathSegment, PolyTrait, Primitive, PrimitiveType, ResolvedPath, Type, TypeBinding,
+ Visibility,
};
use crate::core::DocContext;
use crate::formats::item_type::ItemType;
+use rustc_ast as ast;
use rustc_ast::tokenstream::TokenTree;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
pub(super) fn render_macro_matcher(matcher: &TokenTree) -> String {
rustc_ast_pretty::pprust::tt_to_string(matcher)
}
+
+pub(super) fn display_macro_source(
+ cx: &mut DocContext<'_>,
+ name: Symbol,
+ def: &ast::MacroDef,
+ def_id: DefId,
+ vis: impl Clean<Visibility>,
+) -> String {
+ let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
+ // Extract the spans of all matchers. They represent the "interface" of the macro.
+ let matchers = tts.chunks(4).map(|arm| &arm[0]);
+
+ if def.macro_rules {
+ format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
+ } else {
+ let vis = vis.clean(cx);
+
+ if matchers.len() <= 1 {
+ format!(
+ "{}macro {}{} {{\n ...\n}}",
+ vis.to_src_with_space(cx.tcx, def_id),
+ name,
+ matchers.map(render_macro_matcher).collect::<String>(),
+ )
+ } else {
+ format!(
+ "{}macro {} {{\n{}}}",
+ vis.to_src_with_space(cx.tcx, def_id),
+ name,
+ render_macro_arms(matchers, ","),
+ )
+ }
+ }
+}
clean::StructItem(ref s) => item_struct(buf, cx, item, s),
clean::UnionItem(ref s) => item_union(buf, cx, item, s),
clean::EnumItem(ref e) => item_enum(buf, cx, item, e),
- clean::TypedefItem(ref t, _) => item_typedef(buf, cx, item, t),
+ clean::TypedefItem(ref t, is_associated) => item_typedef(buf, cx, item, t, is_associated),
clean::MacroItem(ref m) => item_macro(buf, cx, item, m),
clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m),
clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All)
}
-fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
+fn item_typedef(
+ w: &mut Buffer,
+ cx: &Context<'_>,
+ it: &clean::Item,
+ t: &clean::Typedef,
+ is_associated: bool,
+) {
w.write_str("<pre class=\"rust typedef\">");
render_attributes_in_pre(w, it, "");
+ if !is_associated {
+ write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
+ }
write!(
w,
"type {}{}{where_clause} = {type_};</pre>",
});
}
+ var currentNbImpls = implementors.getElementsByClassName("impl").length;
+ var traitName = document.querySelector("h1.fqn > .in-band > .trait").textContent;
+ var baseIdName = "impl-" + traitName + "-";
var libs = Object.getOwnPropertyNames(imp);
for (var i = 0, llength = libs.length; i < llength; ++i) {
if (libs[i] === window.currentCrate) { continue; }
var code = document.createElement("code");
code.innerHTML = struct.text;
+ addClass(code, "in-band");
onEachLazy(code.getElementsByTagName("a"), function(elem) {
var href = elem.getAttribute("href");
}
});
- var display = document.createElement("h3");
+ var currentId = baseIdName + currentNbImpls;
+ var anchor = document.createElement("a");
+ anchor.href = "#" + currentId;
+ addClass(anchor, "anchor");
+
+ var display = document.createElement("div");
+ display.id = currentId;
addClass(display, "impl");
- display.innerHTML = "<span class=\"in-band\"><table class=\"table-display\">" +
- "<tbody><tr><td><code>" + code.outerHTML + "</code></td><td></td></tr>" +
- "</tbody></table></span>";
+ display.appendChild(anchor);
+ display.appendChild(code);
list.appendChild(display);
+ currentNbImpls += 1;
}
}
};
};
}
- function getObjectNameFromId(id) {
- if (typeof id === "number") {
- return searchIndex[id].name;
- }
- return id;
- }
-
function checkGenerics(obj, val) {
// The names match, but we need to be sure that all generics kinda
// match as well.
var elems = Object.create(null);
var elength = obj[GENERICS_DATA].length;
for (var x = 0; x < elength; ++x) {
- if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) {
- elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0;
+ if (!elems[obj[GENERICS_DATA][x]]) {
+ elems[obj[GENERICS_DATA][x]] = 0;
}
- elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1;
+ elems[obj[GENERICS_DATA][x]] += 1;
}
var total = 0;
var done = 0;
var vlength = val.generics.length;
for (x = 0; x < vlength; ++x) {
var lev = MAX_LEV_DISTANCE + 1;
- var firstGeneric = getObjectNameFromId(val.generics[x]);
+ var firstGeneric = val.generics[x];
var match = null;
if (elems[firstGeneric]) {
match = firstGeneric;
var elems = Object.create(null);
len = obj[GENERICS_DATA].length;
for (x = 0; x < len; ++x) {
- if (!elems[getObjectNameFromId(obj[GENERICS_DATA][x])]) {
- elems[getObjectNameFromId(obj[GENERICS_DATA][x])] = 0;
+ if (!elems[obj[GENERICS_DATA][x]]) {
+ elems[obj[GENERICS_DATA][x]] = 0;
}
- elems[getObjectNameFromId(obj[GENERICS_DATA][x])] += 1;
+ elems[obj[GENERICS_DATA][x]] += 1;
}
var allFound = true;
len = val.generics.length;
for (x = 0; x < len; ++x) {
- firstGeneric = getObjectNameFromId(val.generics[x]);
+ firstGeneric = val.generics[x];
if (elems[firstGeneric]) {
elems[firstGeneric] -= 1;
} else {
let stable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::stable;
let unstable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::unstable;
vec![
- stable("h", |o| o.optflag("h", "help", "show this help message")),
- stable("V", |o| o.optflag("V", "version", "print rustdoc's version")),
- stable("v", |o| o.optflag("v", "verbose", "use verbose output")),
+ stable("h", |o| o.optflagmulti("h", "help", "show this help message")),
+ stable("V", |o| o.optflagmulti("V", "version", "print rustdoc's version")),
+ stable("v", |o| o.optflagmulti("v", "verbose", "use verbose output")),
stable("r", |o| {
o.optopt("r", "input-format", "the input type of the specified file", "[rust]")
}),
)
}),
stable("plugins", |o| o.optmulti("", "plugins", "removed", "PLUGINS")),
- stable("no-default", |o| o.optflag("", "no-defaults", "don't run the default passes")),
+ stable("no-default", |o| o.optflagmulti("", "no-defaults", "don't run the default passes")),
stable("document-private-items", |o| {
- o.optflag("", "document-private-items", "document private items")
+ o.optflagmulti("", "document-private-items", "document private items")
}),
unstable("document-hidden-items", |o| {
- o.optflag("", "document-hidden-items", "document items that have doc(hidden)")
+ o.optflagmulti("", "document-hidden-items", "document items that have doc(hidden)")
}),
- stable("test", |o| o.optflag("", "test", "run code examples as tests")),
+ stable("test", |o| o.optflagmulti("", "test", "run code examples as tests")),
stable("test-args", |o| {
o.optmulti("", "test-args", "arguments to pass to the test runner", "ARGS")
}),
o.optopt("", "markdown-playground-url", "URL to send code snippets to", "URL")
}),
stable("markdown-no-toc", |o| {
- o.optflag("", "markdown-no-toc", "don't include table of contents")
+ o.optflagmulti("", "markdown-no-toc", "don't include table of contents")
}),
stable("e", |o| {
o.optopt(
)
}),
unstable("display-warnings", |o| {
- o.optflag("", "display-warnings", "to print code warnings when testing doc")
+ o.optflagmulti("", "display-warnings", "to print code warnings when testing doc")
}),
stable("crate-version", |o| {
o.optopt("", "crate-version", "crate version to print into documentation", "VERSION")
}),
unstable("sort-modules-by-appearance", |o| {
- o.optflag(
+ o.optflagmulti(
"",
"sort-modules-by-appearance",
"sort modules by where they appear in the program, rather than alphabetically",
o.optopt("", "json", "Configure the structure of JSON diagnostics", "CONFIG")
}),
unstable("disable-minification", |o| {
- o.optflag("", "disable-minification", "Disable minification applied on JS files")
+ o.optflagmulti("", "disable-minification", "Disable minification applied on JS files")
}),
stable("warn", |o| o.optmulti("W", "warn", "Set lint warnings", "OPT")),
stable("allow", |o| o.optmulti("A", "allow", "Set lint allowed", "OPT")),
o.optopt("", "index-page", "Markdown file to be used as index page", "PATH")
}),
unstable("enable-index-page", |o| {
- o.optflag("", "enable-index-page", "To enable generation of the index page")
+ o.optflagmulti("", "enable-index-page", "To enable generation of the index page")
}),
unstable("static-root-path", |o| {
o.optopt(
)
}),
unstable("disable-per-crate-search", |o| {
- o.optflag(
+ o.optflagmulti(
"",
"disable-per-crate-search",
"disables generating the crate selector on the search box",
)
}),
unstable("show-coverage", |o| {
- o.optflag(
+ o.optflagmulti(
"",
"show-coverage",
"calculate percentage of public items with documentation",
)
}),
unstable("enable-per-target-ignores", |o| {
- o.optflag(
+ o.optflagmulti(
"",
"enable-per-target-ignores",
"parse ignore-foo for ignoring doctests on a per-target basis",
unstable("test-builder", |o| {
o.optopt("", "test-builder", "The rustc-like binary to use as the test builder", "PATH")
}),
- unstable("check", |o| o.optflag("", "check", "Run rustdoc checks")),
+ unstable("check", |o| o.optflagmulti("", "check", "Run rustdoc checks")),
unstable("generate-redirect-map", |o| {
- o.optflag(
+ o.optflagmulti(
"",
"generate-redirect-map",
"Generate JSON file at the top level instead of generating HTML redirection files",
"[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]",
)
}),
- unstable("no-run", |o| o.optflag("", "no-run", "Compile doctests without running them")),
+ unstable("no-run", |o| {
+ o.optflagmulti("", "no-run", "Compile doctests without running them")
+ }),
unstable("show-type-layout", |o| {
- o.optflag("", "show-type-layout", "Include the memory layout of types in the docs")
+ o.optflagmulti("", "show-type-layout", "Include the memory layout of types in the docs")
}),
]
}
return Suggestion::Macro;
} else if kind == DefKind::Fn || kind == DefKind::AssocFn {
return Suggestion::Function;
+ } else if kind == DefKind::Field {
+ return Suggestion::RemoveDisambiguator;
}
let prefix = match kind {
Function,
/// `m!`
Macro,
+ /// `foo` without any disambiguator
+ RemoveDisambiguator,
}
impl Suggestion {
Self::Prefix(x) => format!("prefix with `{}@`", x).into(),
Self::Function => "add parentheses".into(),
Self::Macro => "add an exclamation mark".into(),
+ Self::RemoveDisambiguator => "remove the disambiguator".into(),
}
}
Self::Prefix(prefix) => format!("{}@{}", prefix, path_str),
Self::Function => format!("{}()", path_str),
Self::Macro => format!("{}!", path_str),
+ Self::RemoveDisambiguator => path_str.into(),
}
}
}
-Subproject commit 39c5555872cc5d379cc3535a31dc0cdac969466f
+Subproject commit bdb386270f55cb8e95793daa296f27a95a6d4834
$(RUSTC) --target i686-pc-windows-msvc --print cfg | $(CGREP) msvc
$(RUSTC) --target i686-apple-darwin --print cfg | $(CGREP) macos
$(RUSTC) --target i686-unknown-linux-gnu --print cfg | $(CGREP) gnu
+ $(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) target_abi=
+ $(RUSTC) --target arm-unknown-linux-gnueabihf --print cfg | $(CGREP) eabihf
ifdef IS_WINDOWS
default:
--- /dev/null
+// The goal of this test is to check that the external trait implementors, generated with JS,
+// have the same display than the "local" ones.
+goto: file://|DOC_PATH|/implementors/trait.Whatever.html
+assert: "#implementors-list"
+// There are supposed to be two implementors listed.
+assert-count: ("#implementors-list > .impl", 2)
+// Now we check that both implementors have an anchor, an ID and a similar DOM.
+assert: ("#implementors-list > .impl:nth-child(1) > a.anchor")
+assert-attribute: ("#implementors-list > .impl:nth-child(1)", {"id": "impl-Whatever"})
+assert-attribute: ("#implementors-list > .impl:nth-child(1) > a.anchor", {"href": "#impl-Whatever"})
+assert: "#implementors-list > .impl:nth-child(1) > code.in-band"
+
+assert: ("#implementors-list > .impl:nth-child(2) > a.anchor")
+assert-attribute: ("#implementors-list > .impl:nth-child(2)", {"id": "impl-Whatever-1"})
+assert-attribute: ("#implementors-list > .impl:nth-child(2) > a.anchor", {"href": "#impl-Whatever-1"})
+assert: "#implementors-list > .impl:nth-child(2) > code.in-band"
--- /dev/null
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "implementors"
+version = "0.1.0"
+
+[[package]]
+name = "lib2"
+version = "0.1.0"
+dependencies = [
+ "implementors",
+]
+
+[[package]]
+name = "test_docs"
+version = "0.1.0"
--- /dev/null
+[workspace]
+members = [
+ "test_docs",
+ "lib2",
+ "implementors",
+]
--- /dev/null
+[package]
+name = "implementors"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
--- /dev/null
+pub trait Whatever {
+ fn method() {}
+}
+
+pub struct Struct;
+
+impl Whatever for Struct {}
+++ /dev/null
-//! The point of this crate is to be able to have enough different "kinds" of
-//! documentation generated so we can test each different features.
-
-#![crate_name = "test_docs"]
-#![feature(doc_keyword)]
-#![feature(doc_cfg)]
-
-use std::fmt;
-
-/// Basic function with some code examples:
-///
-/// ```
-/// println!("nothing fancy");
-/// ```
-///
-/// A failing to compile one:
-///
-/// ```compile_fail
-/// println!("where did my argument {} go? :'(");
-/// ```
-///
-/// An ignored one:
-///
-/// ```ignore (it's a test)
-/// Let's say I'm just some text will ya?
-/// ```
-pub fn foo() {}
-
-/// Just a normal struct.
-pub struct Foo;
-
-impl Foo {
- #[must_use]
- pub fn must_use(&self) -> bool {
- true
- }
-}
-
-/// Just a normal enum.
-#[doc(alias = "ThisIsAnAlias")]
-pub enum WhoLetTheDogOut {
- /// Woof!
- Woof,
- /// Meoooooooow...
- Meow,
-}
-
-/// Who doesn't love to wrap a `format!` call?
-pub fn some_more_function<T: fmt::Debug>(t: &T) -> String {
- format!("{:?}", t)
-}
-
-/// Woohoo! A trait!
-pub trait AnotherOne {
- /// Some func 3.
- fn func3();
-
- /// Some func 1.
- fn func1();
-
- fn another();
- fn why_not();
-
- /// Some func 2.
- fn func2();
-
- fn hello();
-}
-
-/// ```compile_fail
-/// whatever
-/// ```
-///
-/// Check for "i" signs in lists!
-///
-/// 1. elem 1
-/// 2. test 1
-/// ```compile_fail
-/// fn foo() {}
-/// ```
-/// 3. elem 3
-/// 4. ```ignore (it's a test)
-/// fn foo() {}
-/// ```
-/// 5. elem 5
-///
-/// Final one:
-///
-/// ```ignore (still a test)
-/// let x = 12;
-/// ```
-pub fn check_list_code_block() {}
-
-/// a thing with a label
-#[deprecated(since = "1.0.0", note = "text why this deprecated")]
-#[doc(cfg(unix))]
-pub fn replaced_function() {}
-
-pub enum AnEnum {
- WithVariants { and: usize, sub: usize, variants: usize },
-}
-
-#[doc(keyword = "CookieMonster")]
-pub mod keyword {}
-
-/// Just some type alias.
-pub type SomeType = u32;
+++ /dev/null
-pub mod module {
- pub mod sub_module {
- pub mod sub_sub_module {
- pub fn foo() {}
- }
- pub fn bar() {}
- }
- pub fn whatever() {}
-}
-
-pub fn foobar() {}
-
-pub type Alias = u32;
-
-pub struct Foo {
- pub x: Alias,
-}
-
-impl Foo {
- pub fn a_method(&self) {}
-}
-
-pub trait Trait {
- type X;
- const Y: u32;
-
- fn foo() {}
-}
-
-impl Trait for Foo {
- type X = u32;
- const Y: u32 = 0;
-}
--- /dev/null
+[package]
+name = "lib2"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
+
+[dependencies]
+implementors = { path = "../implementors" }
--- /dev/null
+pub mod module {
+ pub mod sub_module {
+ pub mod sub_sub_module {
+ pub fn foo() {}
+ }
+ pub fn bar() {}
+ }
+ pub fn whatever() {}
+}
+
+pub fn foobar() {}
+
+pub type Alias = u32;
+
+pub struct Foo {
+ pub x: Alias,
+}
+
+impl Foo {
+ pub fn a_method(&self) {}
+}
+
+pub trait Trait {
+ type X;
+ const Y: u32;
+
+ fn foo() {}
+}
+
+impl Trait for Foo {
+ type X = u32;
+ const Y: u32 = 0;
+}
+
+impl implementors::Whatever for Foo {}
--- /dev/null
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn it_works() {
+ assert_eq!(2 + 2, 4);
+ }
+}
--- /dev/null
+[package]
+name = "test_docs"
+version = "0.1.0"
+edition = "2018"
+
+[lib]
+path = "lib.rs"
--- /dev/null
+//! The point of this crate is to be able to have enough different "kinds" of
+//! documentation generated so we can test each different features.
+
+#![crate_name = "test_docs"]
+#![feature(doc_keyword)]
+#![feature(doc_cfg)]
+
+use std::fmt;
+
+/// Basic function with some code examples:
+///
+/// ```
+/// println!("nothing fancy");
+/// ```
+///
+/// A failing to compile one:
+///
+/// ```compile_fail
+/// println!("where did my argument {} go? :'(");
+/// ```
+///
+/// An ignored one:
+///
+/// ```ignore (it's a test)
+/// Let's say I'm just some text will ya?
+/// ```
+pub fn foo() {}
+
+/// Just a normal struct.
+pub struct Foo;
+
+impl Foo {
+ #[must_use]
+ pub fn must_use(&self) -> bool {
+ true
+ }
+}
+
+/// Just a normal enum.
+#[doc(alias = "ThisIsAnAlias")]
+pub enum WhoLetTheDogOut {
+ /// Woof!
+ Woof,
+ /// Meoooooooow...
+ Meow,
+}
+
+/// Who doesn't love to wrap a `format!` call?
+pub fn some_more_function<T: fmt::Debug>(t: &T) -> String {
+ format!("{:?}", t)
+}
+
+/// Woohoo! A trait!
+pub trait AnotherOne {
+ /// Some func 3.
+ fn func3();
+
+ /// Some func 1.
+ fn func1();
+
+ fn another();
+ fn why_not();
+
+ /// Some func 2.
+ fn func2();
+
+ fn hello();
+}
+
+/// ```compile_fail
+/// whatever
+/// ```
+///
+/// Check for "i" signs in lists!
+///
+/// 1. elem 1
+/// 2. test 1
+/// ```compile_fail
+/// fn foo() {}
+/// ```
+/// 3. elem 3
+/// 4. ```ignore (it's a test)
+/// fn foo() {}
+/// ```
+/// 5. elem 5
+///
+/// Final one:
+///
+/// ```ignore (still a test)
+/// let x = 12;
+/// ```
+pub fn check_list_code_block() {}
+
+/// a thing with a label
+#[deprecated(since = "1.0.0", note = "text why this deprecated")]
+#[doc(cfg(unix))]
+pub fn replaced_function() {}
+
+pub enum AnEnum {
+ WithVariants { and: usize, sub: usize, variants: usize },
+}
+
+#[doc(keyword = "CookieMonster")]
+pub mod keyword {}
+
+/// Just some type alias.
+pub type SomeType = u32;
--- /dev/null
+#![deny(rustdoc::broken_intra_doc_links)]
+//~^NOTE the lint level is defined here
+
+/// [`Foo::bar`]
+/// [`Foo::bar()`]
+//~^ERROR incompatible link kind for `Foo::bar`
+//~|HELP to link to the field, remove the disambiguator
+//~|NOTE this link resolved to a field, which is not a function
+pub struct Foo {
+ pub bar: u8
+}
--- /dev/null
+error: incompatible link kind for `Foo::bar`
+ --> $DIR/field-ice.rs:5:6
+ |
+LL | /// [`Foo::bar()`]
+ | ^^^^^^^^^^^^ help: to link to the field, remove the disambiguator: ``Foo::bar``
+ |
+note: the lint level is defined here
+ --> $DIR/field-ice.rs:1:9
+ |
+LL | #![deny(rustdoc::broken_intra_doc_links)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: this link resolved to a field, which is not a function
+
+error: aborting due to previous error
+
--- /dev/null
+#![feature(decl_macro)]
+
+pub macro addr_of($place:expr) {
+ &raw const $place
+}
+
+pub macro addr_of_self($place:expr) {
+ &raw const $place
+}
+
+pub macro addr_of_crate($place:expr) {
+ &raw const $place
+}
+
+pub struct Foo;
+pub struct FooSelf;
+pub struct FooCrate;
+
+pub enum Bar { Foo, }
+pub enum BarSelf { Foo, }
+pub enum BarCrate { Foo, }
+
+pub fn foo() {}
+pub fn foo_self() {}
+pub fn foo_crate() {}
+
+pub type Type = i32;
+pub type TypeSelf = i32;
+pub type TypeCrate = i32;
+
+pub union Union {
+ a: i8,
+ b: i8,
+}
+pub union UnionSelf {
+ a: i8,
+ b: i8,
+}
+pub union UnionCrate {
+ a: i8,
+ b: i8,
+}
--- /dev/null
+// compile-flags: --document-private-items --document-private-items
+
+// @has duplicate_flags/struct.Private.html
+struct Private;
--- /dev/null
+// aux-build: reexports.rs
+// compile-flags: --document-private-items
+
+#![crate_name = "foo"]
+
+extern crate reexports;
+
+// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
+pub use reexports::addr_of;
+// @has 'foo/macro.addr_of_crate.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_crate($place : expr) {'
+pub(crate) use reexports::addr_of_crate;
+// @has 'foo/macro.addr_of_self.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_self($place : expr) {'
+pub(self) use reexports::addr_of_self;
+
+// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
+pub use reexports::Foo;
+// @has 'foo/struct.FooCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooCrate;'
+pub(crate) use reexports::FooCrate;
+// @has 'foo/struct.FooSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooSelf;'
+pub(self) use reexports::FooSelf;
+
+// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
+pub use reexports::Bar;
+// @has 'foo/enum.BarCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarCrate {'
+pub(crate) use reexports::BarCrate;
+// @has 'foo/enum.BarSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarSelf {'
+pub(self) use reexports::BarSelf;
+
+// @has 'foo/fn.foo.html' '//*[@class="rust fn"]' 'pub fn foo()'
+pub use reexports::foo;
+// @has 'foo/fn.foo_crate.html' '//*[@class="rust fn"]' 'pub(crate) fn foo_crate()'
+pub(crate) use reexports::foo_crate;
+// @has 'foo/fn.foo_self.html' '//*[@class="rust fn"]' 'pub(crate) fn foo_self()'
+pub(self) use reexports::foo_self;
+
+// @has 'foo/type.Type.html' '//*[@class="rust typedef"]' 'pub type Type ='
+pub use reexports::Type;
+// @has 'foo/type.TypeCrate.html' '//*[@class="rust typedef"]' 'pub(crate) type TypeCrate ='
+pub(crate) use reexports::TypeCrate;
+// @has 'foo/type.TypeSelf.html' '//*[@class="rust typedef"]' 'pub(crate) type TypeSelf ='
+pub(self) use reexports::TypeSelf;
+
+// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
+pub use reexports::Union;
+// @has 'foo/union.UnionCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionCrate {'
+pub(crate) use reexports::UnionCrate;
+// @has 'foo/union.UnionSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionSelf {'
+pub(self) use reexports::UnionSelf;
+
+pub mod foo {
+ // @!has 'foo/foo/union.Union.html'
+ use crate::reexports::Union;
+}
--- /dev/null
+// aux-build: reexports.rs
+
+#![crate_name = "foo"]
+
+extern crate reexports;
+
+// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
+pub use reexports::addr_of;
+// @!has 'foo/macro.addr_of_crate.html'
+pub(crate) use reexports::addr_of_crate;
+// @!has 'foo/macro.addr_of_self.html'
+pub(self) use reexports::addr_of_self;
+
+// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
+pub use reexports::Foo;
+// @!has 'foo/struct.FooCrate.html'
+pub(crate) use reexports::FooCrate;
+// @!has 'foo/struct.FooSelf.html'
+pub(self) use reexports::FooSelf;
+
+// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
+pub use reexports::Bar;
+// @!has 'foo/enum.BarCrate.html'
+pub(crate) use reexports::BarCrate;
+// @!has 'foo/enum.BarSelf.html'
+pub(self) use reexports::BarSelf;
+
+// @has 'foo/fn.foo.html' '//*[@class="rust fn"]' 'pub fn foo()'
+pub use reexports::foo;
+// @!has 'foo/fn.foo_crate.html'
+pub(crate) use reexports::foo_crate;
+// @!has 'foo/fn.foo_self.html'
+pub(self) use reexports::foo_self;
+
+// @has 'foo/type.Type.html' '//*[@class="rust typedef"]' 'pub type Type ='
+pub use reexports::Type;
+// @!has 'foo/type.TypeCrate.html'
+pub(crate) use reexports::TypeCrate;
+// @!has 'foo/type.TypeSelf.html'
+pub(self) use reexports::TypeSelf;
+
+// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
+pub use reexports::Union;
+// @!has 'foo/union.UnionCrate.html'
+pub(crate) use reexports::UnionCrate;
+// @!has 'foo/union.UnionSelf.html'
+pub(self) use reexports::UnionSelf;
// compile-flags: -Z unstable-options
#![feature(rustc_private)]
+#![deny(rustc::default_hash_types)]
extern crate rustc_data_structures;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use std::collections::{HashMap, HashSet};
-#[deny(rustc::default_hash_types)]
+mod foo {
+ pub struct HashMap;
+}
+
fn main() {
let _map: HashMap<String, String> = HashMap::default();
- //~^ ERROR Prefer FxHashMap over HashMap, it has better performance
- //~^^ ERROR Prefer FxHashMap over HashMap, it has better performance
+ //~^ ERROR prefer `FxHashMap` over `HashMap`, it has better performance
+ //~^^ ERROR prefer `FxHashMap` over `HashMap`, it has better performance
let _set: HashSet<String> = HashSet::default();
- //~^ ERROR Prefer FxHashSet over HashSet, it has better performance
- //~^^ ERROR Prefer FxHashSet over HashSet, it has better performance
+ //~^ ERROR prefer `FxHashSet` over `HashSet`, it has better performance
+ //~^^ ERROR prefer `FxHashSet` over `HashSet`, it has better performance
// test that the lint doesn't also match the Fx variants themselves
let _fx_map: FxHashMap<String, String> = FxHashMap::default();
let _fx_set: FxHashSet<String> = FxHashSet::default();
+
+ // test another struct of the same name
+ let _ = foo::HashMap;
}
-error: Prefer FxHashMap over HashMap, it has better performance
- --> $DIR/default_hash_types.rs:12:15
+error: prefer `FxHashMap` over `HashMap`, it has better performance
+ --> $DIR/default_hash_types.rs:16:41
|
LL | let _map: HashMap<String, String> = HashMap::default();
- | ^^^^^^^ help: use: `FxHashMap`
+ | ^^^^^^^
|
note: the lint level is defined here
- --> $DIR/default_hash_types.rs:10:8
+ --> $DIR/default_hash_types.rs:4:9
|
-LL | #[deny(rustc::default_hash_types)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | #![deny(rustc::default_hash_types)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
= note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
-error: Prefer FxHashMap over HashMap, it has better performance
- --> $DIR/default_hash_types.rs:12:41
+error: prefer `FxHashMap` over `HashMap`, it has better performance
+ --> $DIR/default_hash_types.rs:16:15
|
LL | let _map: HashMap<String, String> = HashMap::default();
- | ^^^^^^^ help: use: `FxHashMap`
+ | ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: a `use rustc_data_structures::fx::FxHashMap` may be necessary
-error: Prefer FxHashSet over HashSet, it has better performance
- --> $DIR/default_hash_types.rs:15:15
+error: prefer `FxHashSet` over `HashSet`, it has better performance
+ --> $DIR/default_hash_types.rs:19:33
|
LL | let _set: HashSet<String> = HashSet::default();
- | ^^^^^^^ help: use: `FxHashSet`
+ | ^^^^^^^
|
= note: a `use rustc_data_structures::fx::FxHashSet` may be necessary
-error: Prefer FxHashSet over HashSet, it has better performance
- --> $DIR/default_hash_types.rs:15:33
+error: prefer `FxHashSet` over `HashSet`, it has better performance
+ --> $DIR/default_hash_types.rs:19:15
|
LL | let _set: HashSet<String> = HashSet::default();
- | ^^^^^^^ help: use: `FxHashSet`
+ | ^^^^^^^^^^^^^^^
|
= note: a `use rustc_data_structures::fx::FxHashSet` may be necessary
-error[E0594]: cannot assign to `*s.pointer` which is behind a `&` reference
+error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
--> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:9:5
|
LL | fn a(s: &S) {
LL | *s.pointer += 1;
| ^^^^^^^^^^^^^^^ `s` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*s.pointer` which is behind a `&` reference
+error[E0594]: cannot assign to `*s.pointer`, which is behind a `&` reference
--> $DIR/borrowck-assign-to-andmut-in-aliasable-loc.rs:17:5
|
LL | fn c(s: & &mut S) {
-error[E0594]: cannot assign to `**t1` which is behind a `&` reference
+error[E0594]: cannot assign to `**t1`, which is behind a `&` reference
--> $DIR/borrowck-borrow-mut-base-ptr-in-aliasable-loc.rs:9:5
|
LL | let t1 = t0;
-error[E0594]: cannot assign to `***p` which is behind a `&` reference
+error[E0594]: cannot assign to `***p`, which is behind a `&` reference
--> $DIR/borrowck-issue-14498.rs:16:5
|
LL | let p = &y;
-error[E0594]: cannot assign to `*item` which is behind a `&` reference
+error[E0594]: cannot assign to `*item`, which is behind a `&` reference
--> $DIR/issue-69789-iterator-mut-suggestion.rs:7:9
|
LL | for item in &mut std::iter::empty::<&'static ()>() {
for v in Query.iter_mut() {
//~^ NOTE this iterator yields `&` references
*v -= 1;
- //~^ ERROR cannot assign to `*v` which is behind a `&` reference
+ //~^ ERROR cannot assign to `*v`, which is behind a `&` reference
//~| NOTE `v` is a `&` reference, so the data it refers to cannot be written
}
}
-error[E0594]: cannot assign to `*v` which is behind a `&` reference
+error[E0594]: cannot assign to `*v`, which is behind a `&` reference
--> $DIR/issue-83309-ice-immut-in-for-loop.rs:11:9
|
LL | for v in Query.iter_mut() {
rofl.push(Vec::new());
//~^ ERROR cannot borrow `*rofl` as mutable, as it is behind a `&` reference
//~| NOTE `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
+
+ let mut mutvar = 42;
+ let r = &mutvar;
+ //~^ HELP consider changing this to be a mutable reference
+ *r = 0;
+ //~^ ERROR cannot assign to `*r`, which is behind a `&` reference
+ //~| NOTE `r` is a `&` reference, so the data it refers to cannot be written
}
LL | rofl.push(Vec::new());
| ^^^^ `rofl` is a `&` reference, so the data it refers to cannot be borrowed as mutable
-error: aborting due to previous error
+error[E0594]: cannot assign to `*r`, which is behind a `&` reference
+ --> $DIR/issue-85765.rs:12:5
+ |
+LL | let r = &mutvar;
+ | ------- help: consider changing this to be a mutable reference: `&mut mutvar`
+LL |
+LL | *r = 0;
+ | ^^^^^^ `r` is a `&` reference, so the data it refers to cannot be written
+
+error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0596`.
+Some errors have detailed explanations: E0594, E0596.
+For more information about an error, try `rustc --explain E0594`.
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
--> $DIR/mutability-errors.rs:9:5
|
LL | fn named_ref(x: &(i32,)) {
LL | *x = (1,);
| ^^^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `x.0` which is behind a `&` reference
+error[E0594]: cannot assign to `x.0`, which is behind a `&` reference
--> $DIR/mutability-errors.rs:10:5
|
LL | fn named_ref(x: &(i32,)) {
LL | &mut f().0;
| ^^^^^^^^^^ cannot borrow as mutable
-error[E0594]: cannot assign to `*x` which is behind a `*const` pointer
+error[E0594]: cannot assign to `*x`, which is behind a `*const` pointer
--> $DIR/mutability-errors.rs:23:5
|
LL | unsafe fn named_ptr(x: *const (i32,)) {
LL | *x = (1,);
| ^^^^^^^^^ `x` is a `*const` pointer, so the data it refers to cannot be written
-error[E0594]: cannot assign to `x.0` which is behind a `*const` pointer
+error[E0594]: cannot assign to `x.0`, which is behind a `*const` pointer
--> $DIR/mutability-errors.rs:24:5
|
LL | unsafe fn named_ptr(x: *const (i32,)) {
--- /dev/null
+// run-pass
+#![feature(cfg_target_abi)]
+
+#[cfg(target_abi = "eabihf")]
+pub fn main() {
+}
+
+#[cfg(not(target_abi = "eabihf"))]
+pub fn main() {
+}
--- /dev/null
+// Regression test for the ICE described in #87046.
+
+#![crate_type="lib"]
+#![allow(unreachable_patterns)]
+#![feature(const_fn_union)]
+
+#[derive(PartialEq, Eq)]
+#[repr(transparent)]
+pub struct Username(str);
+
+pub const ROOT_USER: &Username = Username::from_str("root");
+
+impl Username {
+ pub const fn from_str(raw: &str) -> &Self {
+ union Transmute<'a> {
+ raw: &'a str,
+ typed: &'a Username,
+ }
+
+ unsafe { Transmute { raw }.typed }
+ }
+
+ pub const fn as_str(&self) -> &str {
+ &self.0
+ }
+
+ pub fn is_root(&self) -> bool {
+ match self {
+ ROOT_USER => true,
+ //~^ ERROR: cannot use unsized non-slice type `Username` in constant patterns
+ _ => false,
+ }
+ }
+}
--- /dev/null
+error: cannot use unsized non-slice type `Username` in constant patterns
+ --> $DIR/issue-87046.rs:29:13
+ |
+LL | ROOT_USER => true,
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
error: use of deprecated function `deprecation_lint::deprecated_text`: text
- --> $DIR/deprecation-lint-3.rs:13:5
+ --> $DIR/deprecation-lint-3.rs:13:28
|
LL | macro_test_arg_nested!(deprecated_text);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/deprecation-lint-3.rs:4:9
|
LL | #![deny(deprecated)]
| ^^^^^^^^^^
- = note: this error originates in the macro `macro_test_arg_nested` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
| ^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:21:9
+ --> $DIR/deprecation-lint.rs:21:16
|
LL | Trait::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:23:9
+ --> $DIR/deprecation-lint.rs:23:25
|
LL | <Foo as Trait>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated function `deprecation_lint::deprecated_text`: text
--> $DIR/deprecation-lint.rs:25:9
| ^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:30:9
+ --> $DIR/deprecation-lint.rs:30:16
|
LL | ... Trait::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:32:9
+ --> $DIR/deprecation-lint.rs:32:25
|
LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated struct `deprecation_lint::DeprecatedStruct`: text
--> $DIR/deprecation-lint.rs:34:17
| ^^^^^^^^^^^^^^^^^^^^
error: use of deprecated variant `deprecation_lint::Enum::DeprecatedVariant`: text
- --> $DIR/deprecation-lint.rs:40:17
+ --> $DIR/deprecation-lint.rs:40:23
|
LL | let _ = Enum::DeprecatedVariant;
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
error: use of deprecated struct `deprecation_lint::DeprecatedTupleStruct`: text
--> $DIR/deprecation-lint.rs:42:17
| ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated struct `deprecation_lint::nested::DeprecatedStruct`: text
- --> $DIR/deprecation-lint.rs:44:17
+ --> $DIR/deprecation-lint.rs:44:25
|
LL | let _ = nested::DeprecatedStruct {
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated struct `deprecation_lint::nested::DeprecatedUnitStruct`: text
- --> $DIR/deprecation-lint.rs:48:17
+ --> $DIR/deprecation-lint.rs:48:25
|
LL | let _ = nested::DeprecatedUnitStruct;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^
error: use of deprecated variant `deprecation_lint::nested::Enum::DeprecatedVariant`: text
- --> $DIR/deprecation-lint.rs:50:17
+ --> $DIR/deprecation-lint.rs:50:31
|
LL | ... let _ = nested::Enum::DeprecatedVariant;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
error: use of deprecated struct `deprecation_lint::nested::DeprecatedTupleStruct`: text
- --> $DIR/deprecation-lint.rs:52:17
+ --> $DIR/deprecation-lint.rs:52:25
|
LL | ... let _ = nested::DeprecatedTupleStruct (1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated function `deprecation_lint::deprecated_text`: text
--> $DIR/deprecation-lint.rs:59:25
| ^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:65:9
+ --> $DIR/deprecation-lint.rs:65:16
|
LL | Trait::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:67:9
+ --> $DIR/deprecation-lint.rs:67:25
|
LL | <Foo as Trait>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:69:9
+ --> $DIR/deprecation-lint.rs:69:16
|
LL | ... Trait::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:71:9
+ --> $DIR/deprecation-lint.rs:71:25
|
LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated trait `deprecation_lint::DeprecatedTrait`: text
--> $DIR/deprecation-lint.rs:81:10
| ^^^^^^^^^^^
error: use of deprecated function `deprecation_lint::deprecated_mod::deprecated`: text
- --> $DIR/deprecation-lint.rs:162:9
+ --> $DIR/deprecation-lint.rs:162:25
|
LL | deprecated_mod::deprecated();
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^
error: use of deprecated function `this_crate::deprecated`: text
--> $DIR/deprecation-lint.rs:245:9
| ^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:250:9
+ --> $DIR/deprecation-lint.rs:250:16
|
LL | Trait::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:252:9
+ --> $DIR/deprecation-lint.rs:252:25
|
LL | <Foo as Trait>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated function `this_crate::deprecated_text`: text
--> $DIR/deprecation-lint.rs:254:9
| ^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:259:9
+ --> $DIR/deprecation-lint.rs:259:16
|
LL | Trait::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:261:9
+ --> $DIR/deprecation-lint.rs:261:25
|
LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated function `this_crate::deprecated_future`: text
--> $DIR/deprecation-lint.rs:264:9
| ^^^^^^^^^^^^^^^^^^^^
error: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text
- --> $DIR/deprecation-lint.rs:274:17
+ --> $DIR/deprecation-lint.rs:274:23
|
LL | let _ = Enum::DeprecatedVariant;
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
error: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text
--> $DIR/deprecation-lint.rs:276:17
| ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated struct `this_crate::nested::DeprecatedStruct`: text
- --> $DIR/deprecation-lint.rs:278:17
+ --> $DIR/deprecation-lint.rs:278:25
|
LL | let _ = nested::DeprecatedStruct {
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated unit struct `this_crate::nested::DeprecatedUnitStruct`: text
- --> $DIR/deprecation-lint.rs:283:17
+ --> $DIR/deprecation-lint.rs:283:25
|
LL | let _ = nested::DeprecatedUnitStruct;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^
error: use of deprecated unit variant `this_crate::nested::Enum::DeprecatedVariant`: text
- --> $DIR/deprecation-lint.rs:285:17
+ --> $DIR/deprecation-lint.rs:285:31
|
LL | ... let _ = nested::Enum::DeprecatedVariant;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
error: use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct`: text
- --> $DIR/deprecation-lint.rs:287:17
+ --> $DIR/deprecation-lint.rs:287:25
|
LL | ... let _ = nested::DeprecatedTupleStruct (1);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:292:9
+ --> $DIR/deprecation-lint.rs:292:16
|
LL | Trait::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/deprecation-lint.rs:294:9
+ --> $DIR/deprecation-lint.rs:294:25
|
LL | <Foo as Trait>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:296:9
+ --> $DIR/deprecation-lint.rs:296:16
|
LL | Trait::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/deprecation-lint.rs:298:9
+ --> $DIR/deprecation-lint.rs:298:25
|
LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
error: use of deprecated function `this_crate::test_fn_closure_body::{closure#0}::bar`
--> $DIR/deprecation-lint.rs:316:13
fn replacement(&self) {}
}
+mod bar {
+ #[rustc_deprecated(
+ since = "1.0.0",
+ reason = "replaced by `replacement`",
+ suggestion = "replacement",
+ )]
+ #[stable(since = "1.0.0", feature = "test")]
+ pub fn deprecated() {}
+
+ pub fn replacement() {}
+}
+
fn main() {
let foo = Foo;
foo.replacement(); //~ ERROR use of deprecated
+
+ bar::replacement(); //~ ERROR use of deprecated
}
fn replacement(&self) {}
}
+mod bar {
+ #[rustc_deprecated(
+ since = "1.0.0",
+ reason = "replaced by `replacement`",
+ suggestion = "replacement",
+ )]
+ #[stable(since = "1.0.0", feature = "test")]
+ pub fn deprecated() {}
+
+ pub fn replacement() {}
+}
+
fn main() {
let foo = Foo;
foo.deprecated(); //~ ERROR use of deprecated
+
+ bar::deprecated(); //~ ERROR use of deprecated
}
-error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement`
- --> $DIR/suggestion.rs:27:9
+error: use of deprecated function `bar::deprecated`: replaced by `replacement`
+ --> $DIR/suggestion.rs:41:10
|
-LL | foo.deprecated();
- | ^^^^^^^^^^ help: replace the use of the deprecated associated function: `replacement`
+LL | bar::deprecated();
+ | ^^^^^^^^^^ help: replace the use of the deprecated function: `replacement`
|
note: the lint level is defined here
--> $DIR/suggestion.rs:7:9
LL | #![deny(deprecated)]
| ^^^^^^^^^^
-error: aborting due to previous error
+error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement`
+ --> $DIR/suggestion.rs:39:9
+ |
+LL | foo.deprecated();
+ | ^^^^^^^^^^ help: replace the use of the deprecated associated function: `replacement`
+
+error: aborting due to 2 previous errors
let mut y = 0;
let x = (&y,);
*x.0 = 1;
- //~^ ERROR cannot assign to `*x.0` which is behind a `&` reference
+ //~^ ERROR cannot assign to `*x.0`, which is behind a `&` reference
}
LL | let _ = &mut w.x;
| ^^^^^^^^ `w` is a `&` reference, so the data it refers to cannot be borrowed as mutable
-error[E0594]: cannot assign to `*x.0` which is behind a `&` reference
+error[E0594]: cannot assign to `*x.0`, which is behind a `&` reference
--> $DIR/issue-39544.rs:48:5
|
LL | *x.0 = 1;
fn main() {
let mut fancy = FancyNum{ num: 5 };
let fancy_ref = &(&mut fancy);
- fancy_ref.num = 6; //~ ERROR cannot assign to `fancy_ref.num` which is behind a `&` reference
+ fancy_ref.num = 6; //~ ERROR cannot assign to `fancy_ref.num`, which is behind a `&` reference
println!("{}", fancy_ref.num);
}
-error[E0594]: cannot assign to `fancy_ref.num` which is behind a `&` reference
+error[E0594]: cannot assign to `fancy_ref.num`, which is behind a `&` reference
--> $DIR/E0389.rs:8:5
|
LL | let fancy_ref = &(&mut fancy);
--- /dev/null
+#[cfg(target_abi = "x")] //~ ERROR `cfg(target_abi)` is experimental
+#[cfg_attr(target_abi = "x", x)] //~ ERROR `cfg(target_abi)` is experimental
+struct Foo(u64, u64);
+
+#[cfg(not(any(all(target_abi = "x"))))] //~ ERROR `cfg(target_abi)` is experimental
+fn foo() {}
+
+fn main() {
+ cfg!(target_abi = "x");
+ //~^ ERROR `cfg(target_abi)` is experimental and subject to change
+}
--- /dev/null
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+ --> $DIR/feature-gate-cfg-target-abi.rs:2:12
+ |
+LL | #[cfg_attr(target_abi = "x", x)]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+ = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+ --> $DIR/feature-gate-cfg-target-abi.rs:1:7
+ |
+LL | #[cfg(target_abi = "x")]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+ = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+ --> $DIR/feature-gate-cfg-target-abi.rs:5:19
+ |
+LL | #[cfg(not(any(all(target_abi = "x"))))]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+ = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error[E0658]: `cfg(target_abi)` is experimental and subject to change
+ --> $DIR/feature-gate-cfg-target-abi.rs:9:10
+ |
+LL | cfg!(target_abi = "x");
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: see issue #80970 <https://github.com/rust-lang/rust/issues/80970> for more information
+ = help: add `#![feature(cfg_target_abi)]` to the crate attributes to enable
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
fn main() {
let ref my_ref @ _ = 0;
- *my_ref = 0; //~ ERROR cannot assign to `*my_ref` which is behind a `&` reference [E0594]
+ *my_ref = 0; //~ ERROR cannot assign to `*my_ref`, which is behind a `&` reference [E0594]
}
-error[E0594]: cannot assign to `*my_ref` which is behind a `&` reference
+error[E0594]: cannot assign to `*my_ref`, which is behind a `&` reference
--> $DIR/issue-51244.rs:3:5
|
LL | let ref my_ref @ _ = 0;
//~^ HELP consider changing this to be a mutable reference
//~| SUGGESTION &mut 16
*foo = 32;
- //~^ ERROR cannot assign to `*foo` which is behind a `&` reference
+ //~^ ERROR cannot assign to `*foo`, which is behind a `&` reference
let bar = foo;
//~^ HELP consider changing this to be a mutable reference
//~| SUGGESTION &mut i32
*bar = 64;
- //~^ ERROR cannot assign to `*bar` which is behind a `&` reference
+ //~^ ERROR cannot assign to `*bar`, which is behind a `&` reference
}
-error[E0594]: cannot assign to `*foo` which is behind a `&` reference
+error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
--> $DIR/issue-51515.rs:5:5
|
LL | let foo = &16;
LL | *foo = 32;
| ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*bar` which is behind a `&` reference
+error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
--> $DIR/issue-51515.rs:10:5
|
LL | let bar = foo;
--- /dev/null
+// Regression test for the ICE described in issue #86238.
+
+#![feature(lang_items)]
+#![feature(no_core)]
+
+#![no_core]
+fn main() {
+ let one = || {};
+ one()
+ //~^ ERROR: failed to find an overloaded call trait for closure call
+ //~| HELP: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined
+}
+#[lang = "sized"]
+trait Sized {}
+#[lang = "copy"]
+trait Copy {}
--- /dev/null
+error: failed to find an overloaded call trait for closure call
+ --> $DIR/issue-86238.rs:9:5
+ |
+LL | one()
+ | ^^^^^
+ |
+ = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions
+
+error: aborting due to previous error
+
//~| SUGGESTION rustc::default_hash_types
fn main() {
let _ = std::collections::HashMap::<String, String>::new();
- //~^ WARN Prefer FxHashMap over HashMap, it has better performance
- //~| HELP use
+ //~^ WARN prefer `FxHashMap` over `HashMap`, it has better performance
}
LL | #[allow(rustc::foo::default_hash_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `rustc::default_hash_types`
-warning: Prefer FxHashMap over HashMap, it has better performance
- --> $DIR/issue-83477.rs:14:31
+warning: prefer `FxHashMap` over `HashMap`, it has better performance
+ --> $DIR/issue-83477.rs:14:13
|
LL | let _ = std::collections::HashMap::<String, String>::new();
- | ^^^^^^^ help: use: `FxHashMap`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/issue-83477.rs:3:9
| ^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:29:9
+ --> $DIR/lint-stability-deprecated.rs:29:16
|
LL | Trait::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:31:9
+ --> $DIR/lint-stability-deprecated.rs:31:25
|
LL | <Foo as Trait>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated function `lint_stability::deprecated_text`: text
--> $DIR/lint-stability-deprecated.rs:33:9
| ^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:38:9
+ --> $DIR/lint-stability-deprecated.rs:38:16
|
LL | ... Trait::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:40:9
+ --> $DIR/lint-stability-deprecated.rs:40:25
|
LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated function `lint_stability::deprecated_unstable`: text
--> $DIR/lint-stability-deprecated.rs:42:9
| ^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
- --> $DIR/lint-stability-deprecated.rs:47:9
+ --> $DIR/lint-stability-deprecated.rs:47:16
|
LL | ... Trait::trait_deprecated_unstable(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
- --> $DIR/lint-stability-deprecated.rs:49:9
+ --> $DIR/lint-stability-deprecated.rs:49:25
|
LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text
--> $DIR/lint-stability-deprecated.rs:51:9
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
- --> $DIR/lint-stability-deprecated.rs:56:9
+ --> $DIR/lint-stability-deprecated.rs:56:16
|
LL | ... Trait::trait_deprecated_unstable_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
- --> $DIR/lint-stability-deprecated.rs:58:9
+ --> $DIR/lint-stability-deprecated.rs:58:25
|
LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated struct `lint_stability::DeprecatedStruct`: text
--> $DIR/lint-stability-deprecated.rs:108:17
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated variant `lint_stability::Enum::DeprecatedVariant`: text
- --> $DIR/lint-stability-deprecated.rs:123:17
+ --> $DIR/lint-stability-deprecated.rs:123:23
|
LL | let _ = Enum::DeprecatedVariant;
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
warning: use of deprecated variant `lint_stability::Enum::DeprecatedUnstableVariant`: text
- --> $DIR/lint-stability-deprecated.rs:124:17
+ --> $DIR/lint-stability-deprecated.rs:124:23
|
LL | let _ = Enum::DeprecatedUnstableVariant;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated struct `lint_stability::DeprecatedTupleStruct`: text
--> $DIR/lint-stability-deprecated.rs:128:17
| ^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:145:9
+ --> $DIR/lint-stability-deprecated.rs:145:16
|
LL | Trait::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:147:9
+ --> $DIR/lint-stability-deprecated.rs:147:25
|
LL | <Foo as Trait>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:149:9
+ --> $DIR/lint-stability-deprecated.rs:149:16
|
LL | ... Trait::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:151:9
+ --> $DIR/lint-stability-deprecated.rs:151:25
|
LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
- --> $DIR/lint-stability-deprecated.rs:153:9
+ --> $DIR/lint-stability-deprecated.rs:153:16
|
LL | ... Trait::trait_deprecated_unstable(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text
- --> $DIR/lint-stability-deprecated.rs:155:9
+ --> $DIR/lint-stability-deprecated.rs:155:25
|
LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
- --> $DIR/lint-stability-deprecated.rs:157:9
+ --> $DIR/lint-stability-deprecated.rs:157:16
|
LL | ... Trait::trait_deprecated_unstable_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text
- --> $DIR/lint-stability-deprecated.rs:159:9
+ --> $DIR/lint-stability-deprecated.rs:159:25
|
LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text
--> $DIR/lint-stability-deprecated.rs:187:10
| ^^^^^^^^^^^^^^^
warning: use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:208:9
+ --> $DIR/lint-stability-deprecated.rs:208:23
|
LL | unstable_mod::deprecated();
- | ^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^
warning: use of deprecated function `this_crate::deprecated`: text
--> $DIR/lint-stability-deprecated.rs:330:9
| ^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:335:9
+ --> $DIR/lint-stability-deprecated.rs:335:16
|
LL | Trait::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:337:9
+ --> $DIR/lint-stability-deprecated.rs:337:25
|
LL | <Foo as Trait>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated function `this_crate::deprecated_text`: text
--> $DIR/lint-stability-deprecated.rs:339:9
| ^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:344:9
+ --> $DIR/lint-stability-deprecated.rs:344:16
|
LL | Trait::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:346:9
+ --> $DIR/lint-stability-deprecated.rs:346:25
|
LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated struct `this_crate::DeprecatedStruct`: text
--> $DIR/lint-stability-deprecated.rs:384:17
| ^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text
- --> $DIR/lint-stability-deprecated.rs:395:17
+ --> $DIR/lint-stability-deprecated.rs:395:23
|
LL | let _ = Enum::DeprecatedVariant;
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^
warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text
--> $DIR/lint-stability-deprecated.rs:399:17
| ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:406:9
+ --> $DIR/lint-stability-deprecated.rs:406:16
|
LL | Trait::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text
- --> $DIR/lint-stability-deprecated.rs:408:9
+ --> $DIR/lint-stability-deprecated.rs:408:25
|
LL | <Foo as Trait>::trait_deprecated(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:410:9
+ --> $DIR/lint-stability-deprecated.rs:410:16
|
LL | Trait::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text
- --> $DIR/lint-stability-deprecated.rs:412:9
+ --> $DIR/lint-stability-deprecated.rs:412:25
|
LL | ... <Foo as Trait>::trait_deprecated_text(&foo);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^^^^^^^
warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text
--> $DIR/lint-stability-deprecated.rs:439:9
error: use of deprecated function `lint_stability::deprecated_text`: text
- --> $DIR/lint-stability3.rs:13:5
+ --> $DIR/lint-stability3.rs:13:28
|
LL | macro_test_arg_nested!(deprecated_text);
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/lint-stability3.rs:4:9
|
LL | #![deny(deprecated)]
| ^^^^^^^^^^
- = note: this error originates in the macro `macro_test_arg_nested` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
-error[E0594]: cannot assign to `self.how_hungry` which is behind a `&` reference
+error[E0594]: cannot assign to `self.how_hungry`, which is behind a `&` reference
--> $DIR/mutable-class-fields-2.rs:9:5
|
LL | pub fn eat(&self) {
-error[E0594]: cannot assign to `fancy_ref.num` which is behind a `&` reference
+error[E0594]: cannot assign to `fancy_ref.num`, which is behind a `&` reference
--> $DIR/issue-47388.rs:8:5
|
LL | let fancy_ref = &(&mut fancy);
fn main() {
let ref my_ref @ _ = 0;
*my_ref = 0;
- //~^ ERROR cannot assign to `*my_ref` which is behind a `&` reference [E0594]
+ //~^ ERROR cannot assign to `*my_ref`, which is behind a `&` reference [E0594]
}
-error[E0594]: cannot assign to `*my_ref` which is behind a `&` reference
+error[E0594]: cannot assign to `*my_ref`, which is behind a `&` reference
--> $DIR/issue-51244.rs:3:5
|
LL | let ref my_ref @ _ = 0;
fn f(x: &i32) {
let g = &x;
- *x = 0; //~ ERROR cannot assign to `*x` which is behind a `&` reference
+ *x = 0; //~ ERROR cannot assign to `*x`, which is behind a `&` reference
//~| ERROR cannot assign to `*x` because it is borrowed
g;
}
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
--> $DIR/issue-57989.rs:5:5
|
LL | fn f(x: &i32) {
_x1 = U; //~ ERROR cannot assign twice to immutable variable
let _x0_hold = &mut tup.0; //~ ERROR cannot borrow `tup.0` as mutable because it is also
let (ref mut _x0_hold, ..) = tup; //~ ERROR cannot borrow `tup.0` as mutable because it is also
- *_x0 = U; //~ ERROR cannot assign to `*_x0` which is behind a `&` reference
- *_x2 = U; //~ ERROR cannot assign to `*_x2` which is behind a `&` reference
+ *_x0 = U; //~ ERROR cannot assign to `*_x0`, which is behind a `&` reference
+ *_x2 = U; //~ ERROR cannot assign to `*_x2`, which is behind a `&` reference
drop(tup.1); //~ ERROR use of moved value: `tup.1`
let _x1_hold = &tup.1; //~ ERROR borrow of moved value: `tup.1`
let (.., ref mut _x3) = tup;
LL | *_x0 = U;
| -------- immutable borrow later used here
-error[E0594]: cannot assign to `*_x0` which is behind a `&` reference
+error[E0594]: cannot assign to `*_x0`, which is behind a `&` reference
--> $DIR/borrowck-move-ref-pattern.rs:26:5
|
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
LL | *_x0 = U;
| ^^^^^^^^ `_x0` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*_x2` which is behind a `&` reference
+error[E0594]: cannot assign to `*_x2`, which is behind a `&` reference
--> $DIR/borrowck-move-ref-pattern.rs:27:5
|
LL | let (ref _x0, _x1, ref _x2, ..) = tup;
pub fn main() {
let Wrap(x) = &Wrap(3);
- *x += 1; //~ ERROR cannot assign to `*x` which is behind a `&` reference
+ *x += 1; //~ ERROR cannot assign to `*x`, which is behind a `&` reference
if let Some(x) = &Some(3) {
- *x += 1; //~ ERROR cannot assign to `*x` which is behind a `&` reference
+ *x += 1; //~ ERROR cannot assign to `*x`, which is behind a `&` reference
} else {
panic!();
}
while let Some(x) = &Some(3) {
- *x += 1; //~ ERROR cannot assign to `*x` which is behind a `&` reference
+ *x += 1; //~ ERROR cannot assign to `*x`, which is behind a `&` reference
break;
}
}
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
--> $DIR/enum.rs:9:5
|
LL | *x += 1;
| ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
--> $DIR/enum.rs:13:9
|
LL | *x += 1;
| ^^^^^^^ `x` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*x` which is behind a `&` reference
+error[E0594]: cannot assign to `*x`, which is behind a `&` reference
--> $DIR/enum.rs:19:9
|
LL | *x += 1;
fn main() {
match &&Some(5i32) {
Some(n) => {
- *n += 1; //~ ERROR cannot assign to `*n` which is behind a `&` reference
+ *n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference
let _ = n;
}
None => {},
match &mut &Some(5i32) {
Some(n) => {
- *n += 1; //~ ERROR cannot assign to `*n` which is behind a `&` reference
+ *n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference
let _ = n;
}
None => {},
match &&mut Some(5i32) {
Some(n) => {
- *n += 1; //~ ERROR cannot assign to `*n` which is behind a `&` reference
+ *n += 1; //~ ERROR cannot assign to `*n`, which is behind a `&` reference
let _ = n;
}
None => {},
-error[E0594]: cannot assign to `*n` which is behind a `&` reference
+error[E0594]: cannot assign to `*n`, which is behind a `&` reference
--> $DIR/explicit-mut.rs:7:13
|
LL | *n += 1;
| ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*n` which is behind a `&` reference
+error[E0594]: cannot assign to `*n`, which is behind a `&` reference
--> $DIR/explicit-mut.rs:15:13
|
LL | *n += 1;
| ^^^^^^^ `n` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*n` which is behind a `&` reference
+error[E0594]: cannot assign to `*n`, which is behind a `&` reference
--> $DIR/explicit-mut.rs:23:13
|
LL | *n += 1;
+++ /dev/null
-// only-i686-pc-windows-msvc
-// compile-flags: --crate-type lib --emit link
-#![allow(clashing_extern_declarations)]
-#![feature(raw_dylib)]
-//~^ WARN the feature `raw_dylib` is incomplete
-#[link(name = "foo", kind = "raw-dylib")]
-extern "C" {
- fn f(x: i32);
- //~^ ERROR multiple definitions of external function `f` from library `foo.dll` have different calling conventions
-}
-
-pub fn lib_main() {
- #[link(name = "foo", kind = "raw-dylib")]
- extern "stdcall" {
- fn f(x: i32);
- }
-
- unsafe { f(42); }
-}
+++ /dev/null
-warning: the feature `raw_dylib` is incomplete and may not be safe to use and/or cause compiler crashes
- --> $DIR/multiple-definitions.rs:4:12
- |
-LL | #![feature(raw_dylib)]
- | ^^^^^^^^^
- |
- = note: `#[warn(incomplete_features)]` on by default
- = note: see issue #58713 <https://github.com/rust-lang/rust/issues/58713> for more information
-
-error: multiple definitions of external function `f` from library `foo.dll` have different calling conventions
- --> $DIR/multiple-definitions.rs:8:5
- |
-LL | fn f(x: i32);
- | ^^^^^^^^^^^^^
-
-error: aborting due to previous error; 1 warning emitted
-
--- /dev/null
+#![feature(const_trait_impl)]
+#![allow(incomplete_features)]
+
+#[default_method_body_is_const] //~ ERROR attribute should be applied
+trait A {
+ #[default_method_body_is_const] //~ ERROR attribute should be applied
+ fn no_body(self);
+
+ #[default_method_body_is_const]
+ fn correct_use(&self) {}
+}
+
+#[default_method_body_is_const] //~ ERROR attribute should be applied
+fn main() {}
--- /dev/null
+error: attribute should be applied to a trait method with body
+ --> $DIR/attr-misuse.rs:4:1
+ |
+LL | #[default_method_body_is_const]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / trait A {
+LL | | #[default_method_body_is_const]
+LL | | fn no_body(self);
+LL | |
+LL | | #[default_method_body_is_const]
+LL | | fn correct_use(&self) {}
+LL | | }
+ | |_- not a trait method or missing a body
+
+error: attribute should be applied to a trait method with body
+ --> $DIR/attr-misuse.rs:13:1
+ |
+LL | #[default_method_body_is_const]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn main() {}
+ | ------------ not a trait method or missing a body
+
+error: attribute should be applied to a trait method with body
+ --> $DIR/attr-misuse.rs:6:5
+ |
+LL | #[default_method_body_is_const]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn no_body(self);
+ | ----------------- not a trait method or missing a body
+
+error: aborting due to 3 previous errors
+
--- /dev/null
+#![feature(const_trait_impl)]
+#![feature(const_fn_trait_bound)] // FIXME is this needed?
+#![allow(incomplete_features)]
+
+trait ConstDefaultFn: Sized {
+ fn b(self);
+
+ #[default_method_body_is_const]
+ fn a(self) {
+ self.b();
+ }
+}
+
+struct NonConstImpl;
+struct ConstImpl;
+
+impl ConstDefaultFn for NonConstImpl {
+ fn b(self) {}
+}
+
+impl const ConstDefaultFn for ConstImpl {
+ fn b(self) {}
+}
+
+const fn test() {
+ NonConstImpl.a();
+ //~^ ERROR calls in constant functions are limited to constant functions, tuple structs and tuple variants
+ ConstImpl.a();
+}
+
+fn main() {}
--- /dev/null
+error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+ --> $DIR/const-default-method-bodies.rs:26:5
+ |
+LL | NonConstImpl.a();
+ | ^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0015`.
println!("lul");
self.req();
}
+
+ #[default_method_body_is_const]
+ fn default() {}
}
struct S;
impl const Tr for S {
fn req(&self) {}
+} //~^^ ERROR const trait implementations may not use non-const default functions
+
+impl const Tr for u8 {
+ fn req(&self) {}
+ fn prov(&self) {}
}
-//~^^^ ERROR const trait implementations may not use default functions
+
+impl const Tr for u16 {
+ fn prov(&self) {}
+ fn default() {}
+} //~^^^ ERROR not all trait items implemented
+
+
+impl const Tr for u32 {
+ fn req(&self) {}
+ fn default() {}
+} //~^^^ ERROR const trait implementations may not use non-const default functions
fn main() {}
-error: const trait implementations may not use default functions
- --> $DIR/impl-with-default-fn.rs:15:1
+error: const trait implementations may not use non-const default functions
+ --> $DIR/impl-with-default-fn.rs:18:1
|
LL | / impl const Tr for S {
LL | | fn req(&self) {}
LL | | }
| |_^
+ |
+ = note: `prov` not implemented
+
+error: const trait implementations may not use non-const default functions
+ --> $DIR/impl-with-default-fn.rs:33:1
+ |
+LL | / impl const Tr for u32 {
+LL | | fn req(&self) {}
+LL | | fn default() {}
+LL | | }
+ | |_^
+ |
+ = note: `prov` not implemented
+
+error[E0046]: not all trait items implemented, missing: `req`
+ --> $DIR/impl-with-default-fn.rs:27:1
+ |
+LL | fn req(&self);
+ | -------------- `req` from trait
+...
+LL | impl const Tr for u16 {
+ | ^^^^^^^^^^^^^^^^^^^^^ missing `req` in implementation
-error: aborting due to previous error
+error: aborting due to 3 previous errors
+For more information about this error, try `rustc --explain E0046`.
--> $DIR/generics-default-stability.rs:83:12
|
LL | let _: Struct4<isize> = Struct4 { field: 1 };
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^
warning: use of deprecated struct `unstable_generic_param::Struct4`: test
--> $DIR/generics-default-stability.rs:88:12
--> $DIR/generics-default-stability.rs:89:12
|
LL | let _: Struct4<usize> = STRUCT4;
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^
warning: use of deprecated struct `unstable_generic_param::Struct4`: test
--> $DIR/generics-default-stability.rs:90:29
--> $DIR/generics-default-stability.rs:90:12
|
LL | let _: Struct4<isize> = Struct4 { field: 0 };
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^
warning: use of deprecated struct `unstable_generic_param::Struct5`: test
--> $DIR/generics-default-stability.rs:96:29
--> $DIR/generics-default-stability.rs:96:12
|
LL | let _: Struct5<isize> = Struct5 { field: 1 };
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^
warning: use of deprecated struct `unstable_generic_param::Struct5`: test
--> $DIR/generics-default-stability.rs:101:12
--> $DIR/generics-default-stability.rs:102:12
|
LL | let _: Struct5<usize> = STRUCT5;
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^
warning: use of deprecated struct `unstable_generic_param::Struct5`: test
--> $DIR/generics-default-stability.rs:104:29
--> $DIR/generics-default-stability.rs:104:12
|
LL | let _: Struct5<isize> = Struct5 { field: 0 };
- | ^^^^^^^^^^^^^^
+ | ^^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $DIR/generics-default-stability.rs:159:28
--> $DIR/generics-default-stability.rs:159:12
|
LL | let _: Alias4<isize> = Alias4::Some(1);
- | ^^^^^^^^^^^^^
+ | ^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $DIR/generics-default-stability.rs:163:12
--> $DIR/generics-default-stability.rs:164:12
|
LL | let _: Alias4<usize> = ALIAS4;
- | ^^^^^^^^^^^^^
+ | ^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias4`: test
--> $DIR/generics-default-stability.rs:165:28
--> $DIR/generics-default-stability.rs:165:12
|
LL | let _: Alias4<isize> = Alias4::Some(0);
- | ^^^^^^^^^^^^^
+ | ^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
--> $DIR/generics-default-stability.rs:170:28
--> $DIR/generics-default-stability.rs:170:12
|
LL | let _: Alias5<isize> = Alias5::Some(1);
- | ^^^^^^^^^^^^^
+ | ^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
--> $DIR/generics-default-stability.rs:174:12
--> $DIR/generics-default-stability.rs:175:12
|
LL | let _: Alias5<usize> = ALIAS5;
- | ^^^^^^^^^^^^^
+ | ^^^^^^
warning: use of deprecated type alias `unstable_generic_param::Alias5`: test
--> $DIR/generics-default-stability.rs:177:28
--> $DIR/generics-default-stability.rs:177:12
|
LL | let _: Alias5<isize> = Alias5::Some(0);
- | ^^^^^^^^^^^^^
+ | ^^^^^^
warning: use of deprecated variant `unstable_generic_param::Enum4::Some`: test
- --> $DIR/generics-default-stability.rs:231:27
+ --> $DIR/generics-default-stability.rs:231:34
|
LL | let _: Enum4<isize> = Enum4::Some(1);
- | ^^^^^^^^^^^
+ | ^^^^
warning: use of deprecated enum `unstable_generic_param::Enum4`: test
--> $DIR/generics-default-stability.rs:231:12
|
LL | let _: Enum4<isize> = Enum4::Some(1);
- | ^^^^^^^^^^^^
+ | ^^^^^
warning: use of deprecated enum `unstable_generic_param::Enum4`: test
--> $DIR/generics-default-stability.rs:235:12
--> $DIR/generics-default-stability.rs:236:12
|
LL | let _: Enum4<usize> = ENUM4;
- | ^^^^^^^^^^^^
+ | ^^^^^
warning: use of deprecated variant `unstable_generic_param::Enum4::Some`: test
- --> $DIR/generics-default-stability.rs:237:27
+ --> $DIR/generics-default-stability.rs:237:34
|
LL | let _: Enum4<isize> = Enum4::Some(0);
- | ^^^^^^^^^^^
+ | ^^^^
warning: use of deprecated enum `unstable_generic_param::Enum4`: test
--> $DIR/generics-default-stability.rs:237:12
|
LL | let _: Enum4<isize> = Enum4::Some(0);
- | ^^^^^^^^^^^^
+ | ^^^^^
warning: use of deprecated variant `unstable_generic_param::Enum5::Some`: test
- --> $DIR/generics-default-stability.rs:242:27
+ --> $DIR/generics-default-stability.rs:242:34
|
LL | let _: Enum5<isize> = Enum5::Some(1);
- | ^^^^^^^^^^^
+ | ^^^^
warning: use of deprecated enum `unstable_generic_param::Enum5`: test
--> $DIR/generics-default-stability.rs:242:12
|
LL | let _: Enum5<isize> = Enum5::Some(1);
- | ^^^^^^^^^^^^
+ | ^^^^^
warning: use of deprecated enum `unstable_generic_param::Enum5`: test
--> $DIR/generics-default-stability.rs:246:12
--> $DIR/generics-default-stability.rs:247:12
|
LL | let _: Enum5<usize> = ENUM5;
- | ^^^^^^^^^^^^
+ | ^^^^^
warning: use of deprecated variant `unstable_generic_param::Enum5::Some`: test
- --> $DIR/generics-default-stability.rs:249:27
+ --> $DIR/generics-default-stability.rs:249:34
|
LL | let _: Enum5<isize> = Enum5::Some(0);
- | ^^^^^^^^^^^
+ | ^^^^
warning: use of deprecated enum `unstable_generic_param::Enum5`: test
--> $DIR/generics-default-stability.rs:249:12
|
LL | let _: Enum5<isize> = Enum5::Some(0);
- | ^^^^^^^^^^^^
+ | ^^^^^
error[E0658]: use of unstable library feature 'unstable_default'
--> $DIR/generics-default-stability.rs:35:20
-error[E0594]: cannot assign to `self.0` which is behind a `&` reference
+error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
--> $DIR/issue-68049-1.rs:7:9
|
LL | self.0 += 1;
-error[E0594]: cannot assign to `*input` which is behind a `&` reference
+error[E0594]: cannot assign to `*input`, which is behind a `&` reference
--> $DIR/issue-68049-2.rs:9:7
|
LL | fn example(&self, input: &i32); // should suggest here
LL | *input = self.0;
| ^^^^^^^^^^^^^^^ `input` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `self.0` which is behind a `&` reference
+error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
--> $DIR/issue-68049-2.rs:17:5
|
LL | fn example(&self, input: &i32); // should suggest here
-error[E0594]: cannot assign to `t.v` which is behind a `&` reference
+error[E0594]: cannot assign to `t.v`, which is behind a `&` reference
--> $DIR/suggest-mut-method-for-loop.rs:14:9
|
LL | for mut t in buzz.values() {
-error[E0594]: cannot assign to `self.0` which is behind a `&` reference
+error[E0594]: cannot assign to `self.0`, which is behind a `&` reference
--> $DIR/suggest-ref-mut.rs:7:9
|
LL | fn zap(&self) {
LL | self.0 = 32;
| ^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*foo` which is behind a `&` reference
+error[E0594]: cannot assign to `*foo`, which is behind a `&` reference
--> $DIR/suggest-ref-mut.rs:16:5
|
LL | let ref foo = 16;
LL | *foo = 32;
| ^^^^^^^^^ `foo` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*bar` which is behind a `&` reference
+error[E0594]: cannot assign to `*bar`, which is behind a `&` reference
--> $DIR/suggest-ref-mut.rs:21:9
|
LL | if let Some(ref bar) = Some(16) {
LL | *bar = 32;
| ^^^^^^^^^ `bar` is a `&` reference, so the data it refers to cannot be written
-error[E0594]: cannot assign to `*quo` which is behind a `&` reference
+error[E0594]: cannot assign to `*quo`, which is behind a `&` reference
--> $DIR/suggest-ref-mut.rs:25:22
|
LL | ref quo => { *quo = 32; },
--- /dev/null
+// Regression test for #87051, where a double semicolon was erroneously
+// suggested after a `?` operator.
+
+fn main() -> Result<(), ()> {
+ a(|| {
+ b()
+ //~^ ERROR: mismatched types [E0308]
+ //~| NOTE: expected `()`, found `i32`
+ //~| HELP: consider using a semicolon here
+ })?;
+
+ // Here, we do want to suggest a semicolon:
+ let x = Ok(42);
+ if true {
+ //~^ NOTE: expected this to be `()`
+ x?
+ //~^ ERROR: mismatched types [E0308]
+ //~| NOTE: expected `()`, found integer
+ //~| HELP: consider using a semicolon here
+ }
+ //~^ HELP: consider using a semicolon here
+
+ Ok(())
+}
+
+fn a<F>(f: F) -> Result<(), ()> where F: FnMut() { Ok(()) }
+fn b() -> i32 { 42 }
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/try-operator-dont-suggest-semicolon.rs:6:9
+ |
+LL | b()
+ | ^^^- help: consider using a semicolon here: `;`
+ | |
+ | expected `()`, found `i32`
+
+error[E0308]: mismatched types
+ --> $DIR/try-operator-dont-suggest-semicolon.rs:16:9
+ |
+LL | / if true {
+LL | |
+LL | | x?
+ | | ^^ expected `()`, found integer
+LL | |
+LL | |
+LL | |
+LL | | }
+ | |_____- expected this to be `()`
+ |
+help: consider using a semicolon here
+ |
+LL | x?;
+ | ^
+help: consider using a semicolon here
+ |
+LL | };
+ | ^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints2.rs:11:13
+ |
+LL | let y = &mut x.0;
+ | ^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
#![feature(rustc_attrs)]
#[rustc_layout_scalar_valid_range_start(1)]
+++ /dev/null
-error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
- --> $DIR/ranged_ints2.rs:8:13
- |
-LL | let y = &mut x.0;
- | ^^^^^^^^ mutation of layout constrained field
- |
- = note: mutating layout constrained fields cannot statically be checked for valid values
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints2.rs:11:13
+ |
+LL | let y = &mut x.0;
+ | ^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0658]: mutable references are not allowed in constant functions
+ --> $DIR/ranged_ints2_const.rs:14:13
+ |
+LL | let y = &mut x.0;
+ | ^^^^^^^^
+ |
+ = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+ = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+ --> $DIR/ranged_ints2_const.rs:21:22
+ |
+LL | let y = unsafe { &mut x.0 };
+ | ^^^^^^^^
+ |
+ = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+ = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+ --> $DIR/ranged_ints2_const.rs:27:22
+ |
+LL | unsafe { let y = &mut x.0; }
+ | ^^^^^^^^
+ |
+ = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+ = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints2_const.rs:14:13
+ |
+LL | let y = &mut x.0;
+ | ^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
#![feature(rustc_attrs)]
#[rustc_layout_scalar_valid_range_start(1)]
+++ /dev/null
-error[E0658]: mutable references are not allowed in constant functions
- --> $DIR/ranged_ints2_const.rs:11:13
- |
-LL | let y = &mut x.0;
- | ^^^^^^^^
- |
- = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
- = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error[E0658]: mutable references are not allowed in constant functions
- --> $DIR/ranged_ints2_const.rs:18:22
- |
-LL | let y = unsafe { &mut x.0 };
- | ^^^^^^^^
- |
- = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
- = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error[E0658]: mutable references are not allowed in constant functions
- --> $DIR/ranged_ints2_const.rs:24:22
- |
-LL | unsafe { let y = &mut x.0; }
- | ^^^^^^^^
- |
- = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
- = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
-
-error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
- --> $DIR/ranged_ints2_const.rs:11:13
- |
-LL | let y = &mut x.0;
- | ^^^^^^^^ mutation of layout constrained field
- |
- = note: mutating layout constrained fields cannot statically be checked for valid values
-
-error: aborting due to 4 previous errors
-
-Some errors have detailed explanations: E0133, E0658.
-For more information about an error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints2_const.rs:14:13
+ |
+LL | let y = &mut x.0;
+ | ^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0658]: mutable references are not allowed in constant functions
+ --> $DIR/ranged_ints2_const.rs:14:13
+ |
+LL | let y = &mut x.0;
+ | ^^^^^^^^
+ |
+ = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+ = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+ --> $DIR/ranged_ints2_const.rs:21:22
+ |
+LL | let y = unsafe { &mut x.0 };
+ | ^^^^^^^^
+ |
+ = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+ = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constant functions
+ --> $DIR/ranged_ints2_const.rs:27:22
+ |
+LL | unsafe { let y = &mut x.0; }
+ | ^^^^^^^^
+ |
+ = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+ = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints3.rs:13:13
+ |
+LL | let y = &x.0;
+ | ^^^^ borrow of layout constrained field with interior mutability
+ |
+ = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
#![feature(rustc_attrs)]
use std::cell::Cell;
+++ /dev/null
-error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
- --> $DIR/ranged_ints3.rs:10:13
- |
-LL | let y = &x.0;
- | ^^^^ borrow of layout constrained field with interior mutability
- |
- = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints3.rs:13:13
+ |
+LL | let y = &x.0;
+ | ^^^^ borrow of layout constrained field with interior mutability
+ |
+ = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
+ --> $DIR/ranged_ints3_const.rs:15:13
+ |
+LL | let y = &x.0;
+ | ^^^^
+ |
+ = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
+ = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
+
+error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
+ --> $DIR/ranged_ints3_const.rs:22:22
+ |
+LL | let y = unsafe { &x.0 };
+ | ^^^^
+ |
+ = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
+ = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
+
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints3_const.rs:15:13
+ |
+LL | let y = &x.0;
+ | ^^^^ borrow of layout constrained field with interior mutability
+ |
+ = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
#![feature(rustc_attrs)]
use std::cell::Cell;
+++ /dev/null
-error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
- --> $DIR/ranged_ints3_const.rs:12:13
- |
-LL | let y = &x.0;
- | ^^^^
- |
- = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
- = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
-
-error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
- --> $DIR/ranged_ints3_const.rs:19:22
- |
-LL | let y = unsafe { &x.0 };
- | ^^^^
- |
- = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
- = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
-
-error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
- --> $DIR/ranged_ints3_const.rs:12:13
- |
-LL | let y = &x.0;
- | ^^^^ borrow of layout constrained field with interior mutability
- |
- = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0133, E0658.
-For more information about an error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints3_const.rs:15:13
+ |
+LL | let y = &x.0;
+ | ^^^^ borrow of layout constrained field with interior mutability
+ |
+ = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
+ --> $DIR/ranged_ints3_const.rs:15:13
+ |
+LL | let y = &x.0;
+ | ^^^^
+ |
+ = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
+ = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
+
+error[E0658]: cannot borrow here, since the borrowed element may contain interior mutability
+ --> $DIR/ranged_ints3_const.rs:22:22
+ |
+LL | let y = unsafe { &x.0 };
+ | ^^^^
+ |
+ = note: see issue #80384 <https://github.com/rust-lang/rust/issues/80384> for more information
+ = help: add `#![feature(const_refs_to_cell)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints3_match.rs:14:17
+ |
+LL | NonZero(ref x) => { x }
+ | ^^^^^ borrow of layout constrained field with interior mutability
+ |
+ = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints3_match.rs:20:23
+ |
+LL | match y { NonZero(ref mut y) => { y } };
+ | ^^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![feature(rustc_attrs)]
+
+use std::cell::Cell;
+
+#[rustc_layout_scalar_valid_range_start(1)]
+#[repr(transparent)]
+pub(crate) struct NonZero<T>(pub(crate) T);
+fn main() {
+ let mut x = unsafe { NonZero(Cell::new(1)) };
+ match x {
+ NonZero(ref x) => { x }
+ //~^ ERROR borrow of layout constrained field with interior mutability
+ };
+
+ let mut y = unsafe { NonZero(42) };
+ match y { NonZero(ref y) => { y } }; // OK, type of `y` is freeze
+ match y { NonZero(ref mut y) => { y } };
+ //~^ ERROR mutation of layout constrained field
+}
--- /dev/null
+error[E0133]: borrow of layout constrained field with interior mutability is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints3_match.rs:14:17
+ |
+LL | NonZero(ref x) => { x }
+ | ^^^^^ borrow of layout constrained field with interior mutability
+ |
+ = note: references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints3_match.rs:20:23
+ |
+LL | match y { NonZero(ref mut y) => { y } };
+ | ^^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints4.rs:11:5
+ |
+LL | x.0 = 0;
+ | ^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
#![feature(rustc_attrs)]
#[rustc_layout_scalar_valid_range_start(1)]
+++ /dev/null
-error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
- --> $DIR/ranged_ints4.rs:8:5
- |
-LL | x.0 = 0;
- | ^^^^^^^ mutation of layout constrained field
- |
- = note: mutating layout constrained fields cannot statically be checked for valid values
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints4.rs:11:5
+ |
+LL | x.0 = 0;
+ | ^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints4_const.rs:13:5
+ |
+LL | x.0 = 0;
+ | ^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
#![feature(rustc_attrs)]
#[rustc_layout_scalar_valid_range_start(1)]
+++ /dev/null
-error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
- --> $DIR/ranged_ints4_const.rs:10:5
- |
-LL | x.0 = 0;
- | ^^^^^^^ mutation of layout constrained field
- |
- = note: mutating layout constrained fields cannot statically be checked for valid values
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/ranged_ints4_const.rs:13:5
+ |
+LL | x.0 = 0;
+ | ^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-assign.rs:12:5
+ |
+LL | foo.0.0 = 0;
+ | ^^^^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![feature(rustc_attrs)]
+#![allow(unused,dead_code)]
+
+fn nested_field() {
+ #[rustc_layout_scalar_valid_range_start(1)]
+ struct NonZero<T>(T);
+
+ let mut foo = unsafe { NonZero((1,)) };
+ foo.0.0 = 0;
+ //~^ ERROR: mutation of layout constrained field is unsafe
+}
+
+fn block() {
+ #[rustc_layout_scalar_valid_range_start(1)]
+ struct NonZero<T>(T);
+
+ let mut foo = unsafe { NonZero((1,)) };
+ { foo.0 }.0 = 0;
+ // ^ not unsafe because the result of the block expression is a new place
+}
+
+fn main() {}
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-assign.rs:12:5
+ |
+LL | foo.0.0 = 0;
+ | ^^^^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-borrow.rs:12:13
+ |
+LL | let a = &mut foo.0.0;
+ | ^^^^^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-borrow.rs:32:13
+ |
+LL | let a = &mut foo.0[2];
+ | ^^^^^^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-borrow.rs:51:18
+ |
+LL | NonZero((a,)) => *a = 0,
+ | ^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
--- /dev/null
+// revisions: mirunsafeck thirunsafeck
+// [thirunsafeck]compile-flags: -Z thir-unsafeck
+
+#![feature(rustc_attrs)]
+#![allow(unused,dead_code)]
+
+fn tuple_struct() {
+ #[rustc_layout_scalar_valid_range_start(1)]
+ struct NonZero<T>(T);
+
+ let mut foo = unsafe { NonZero((1,)) };
+ let a = &mut foo.0.0;
+ //~^ ERROR: mutation of layout constrained field is unsafe
+}
+
+fn slice() {
+ #[rustc_layout_scalar_valid_range_start(1)]
+ struct NonZero<'a, T>(&'a mut [T]);
+
+ let mut nums = [1, 2, 3, 4];
+ let mut foo = unsafe { NonZero(&mut nums[..]) };
+ let a = &mut foo.0[2];
+ // ^ not unsafe because there is an implicit dereference here
+}
+
+fn array() {
+ #[rustc_layout_scalar_valid_range_start(1)]
+ struct NonZero<T>([T; 4]);
+
+ let nums = [1, 2, 3, 4];
+ let mut foo = unsafe { NonZero(nums) };
+ let a = &mut foo.0[2];
+ //~^ ERROR: mutation of layout constrained field is unsafe
+}
+
+fn block() {
+ #[rustc_layout_scalar_valid_range_start(1)]
+ struct NonZero<T>(T);
+
+ let foo = unsafe { NonZero((1,)) };
+ &mut { foo.0 }.0;
+ // ^ not unsafe because the result of the block expression is a new place
+}
+
+fn mtch() {
+ #[rustc_layout_scalar_valid_range_start(1)]
+ struct NonZero<T>(T);
+
+ let mut foo = unsafe { NonZero((1,)) };
+ match &mut foo {
+ NonZero((a,)) => *a = 0,
+ //~^ ERROR: mutation of layout constrained field is unsafe
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-borrow.rs:12:13
+ |
+LL | let a = &mut foo.0.0;
+ | ^^^^^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-borrow.rs:32:13
+ |
+LL | let a = &mut foo.0[2];
+ | ^^^^^^^^^^^^^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error[E0133]: mutation of layout constrained field is unsafe and requires unsafe function or block
+ --> $DIR/unsafe-borrow.rs:51:18
+ |
+LL | NonZero((a,)) => *a = 0,
+ | ^ mutation of layout constrained field
+ |
+ = note: mutating layout constrained fields cannot statically be checked for valid values
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
-#![allow(rustc::default_hash_types)]
+#![cfg_attr(bootstrap, allow(rustc::default_hash_types))]
use std::borrow::Cow;
use std::collections::BTreeMap;
-Subproject commit e5c1c8cf2fcfae3e15c8bcf5256e84cad3bd3436
+Subproject commit fe00358888a24c64878abc15f09b0e60e16db9d6
let contains_platform_specific_cfg = cfg.contains("target_os")
|| cfg.contains("target_env")
+ || cfg.contains("target_abi")
|| cfg.contains("target_vendor")
|| cfg.contains("unix")
|| cfg.contains("windows");