diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs index 0b5b6cd55d720..ad108c34992e3 100644 --- a/compiler/rustc_codegen_cranelift/example/std_example.rs +++ b/compiler/rustc_codegen_cranelift/example/std_example.rs @@ -1,4 +1,4 @@ -#![feature(core_intrinsics, generators, generator_trait, is_sorted, bench_black_box)] +#![feature(core_intrinsics, generators, generator_trait, is_sorted)] #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; diff --git a/compiler/rustc_codegen_gcc/tests/run/int.rs b/compiler/rustc_codegen_gcc/tests/run/int.rs index 2b90e4ae8d82b..75779622b54cd 100644 --- a/compiler/rustc_codegen_gcc/tests/run/int.rs +++ b/compiler/rustc_codegen_gcc/tests/run/int.rs @@ -3,7 +3,7 @@ // Run-time: // status: 0 -#![feature(bench_black_box, const_black_box, core_intrinsics, start)] +#![feature(const_black_box, core_intrinsics, start)] #![no_std] diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 854625579ee7b..1e86d159668ff 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -159,6 +159,7 @@ E0307: include_str!("./error_codes/E0307.md"), E0308: include_str!("./error_codes/E0308.md"), E0309: include_str!("./error_codes/E0309.md"), E0310: include_str!("./error_codes/E0310.md"), +E0311: include_str!("./error_codes/E0311.md"), E0312: include_str!("./error_codes/E0312.md"), E0316: include_str!("./error_codes/E0316.md"), E0317: include_str!("./error_codes/E0317.md"), @@ -568,7 +569,6 @@ E0790: include_str!("./error_codes/E0790.md"), // E0300, // unexpanded macro // E0304, // expected signed integer constant // E0305, // expected constant - E0311, // thing may not live long enough E0313, // lifetime of borrowed pointer outlives lifetime of captured // variable // E0314, // closure outlives stack frame diff --git a/compiler/rustc_error_codes/src/error_codes/E0311.md b/compiler/rustc_error_codes/src/error_codes/E0311.md new file mode 100644 index 0000000000000..08159d3f469ac --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0311.md @@ -0,0 +1,42 @@ +This error occurs when there is an unsatisfied outlives bound involving an +elided region and a generic type parameter or associated type. + +Erroneous code example: + +```compile_fail,E0311 +fn no_restriction(x: &()) -> &() { + with_restriction::(x) +} + +fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () { + x +} +``` + +Why doesn't this code compile? It helps to look at the lifetime bounds that are +automatically added by the compiler. For more details see the documentation for +[lifetime elision]( https://doc.rust-lang.org/reference/lifetime-elision.html). + +The compiler elides the lifetime of `x` and the return type to some arbitrary +lifetime `'anon` in `no_restriction()`. The only information available to the +compiler is that `'anon` is valid for the duration of the function. When +calling `with_restriction()`, the compiler requires the completely unrelated +type parameter `T` to outlive `'anon` because of the `T: 'a` bound in +`with_restriction()`. This causes an error because `T` is not required to +outlive `'anon` in `no_restriction()`. + +If `no_restriction()` were to use `&T` instead of `&()` as an argument, the +compiler would have added an implied bound, causing this to compile. + +This error can be resolved by explicitly naming the elided lifetime for `x` and +then explicily requiring that the generic parameter `T` outlives that lifetime: + +``` +fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () { + with_restriction::(x) +} + +fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () { + x +} +``` diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index b3cbb606c728d..244018ebbeb74 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -595,7 +595,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "create_substs_for_associated_item(span: {:?}, item_def_id: {:?}, item_segment: {:?}", span, item_def_id, item_segment ); - self.create_substs_for_ast_path( + let (args, _) = self.create_substs_for_ast_path( span, item_def_id, parent_substs, @@ -603,8 +603,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { item_segment.args(), item_segment.infer_args, None, - ) - .0 + ); + + let assoc_bindings = self.create_assoc_bindings_for_generic_args(item_segment.args()); + if let Some(b) = assoc_bindings.first() { + Self::prohibit_assoc_ty_binding(self.tcx(), b.span); + } + + args } /// Instantiates the path for the given trait reference, assuming that it's diff --git a/compiler/rustc_hir_analysis/src/check/method/suggest.rs b/compiler/rustc_hir_analysis/src/check/method/suggest.rs index 0e77ed0a4fe28..0e82e4956c7c1 100644 --- a/compiler/rustc_hir_analysis/src/check/method/suggest.rs +++ b/compiler/rustc_hir_analysis/src/check/method/suggest.rs @@ -2,6 +2,7 @@ //! found or is otherwise invalid. use crate::check::FnCtxt; +use rustc_ast::ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ pluralize, struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, @@ -30,7 +31,7 @@ use rustc_trait_selection::traits::{ use std::cmp::Ordering; use std::iter; -use super::probe::{IsSuggestion, Mode, ProbeScope}; +use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope}; use super::{CandidateSource, MethodError, NoMatchData}; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -983,7 +984,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.check_for_field_method(&mut err, source, span, actual, item_name); } - self.check_for_unwrap_self(&mut err, source, span, actual, item_name); + self.check_for_inner_self(&mut err, source, span, actual, item_name); bound_spans.sort(); bound_spans.dedup(); @@ -1395,7 +1396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn check_for_unwrap_self( + fn check_for_inner_self( &self, err: &mut Diagnostic, source: SelfSource<'tcx>, @@ -1408,81 +1409,168 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let call_expr = tcx.hir().expect_expr(tcx.hir().get_parent_node(expr.hir_id)); let ty::Adt(kind, substs) = actual.kind() else { return; }; - if !kind.is_enum() { - return; - } + match kind.adt_kind() { + ty::AdtKind::Enum => { + let matching_variants: Vec<_> = kind + .variants() + .iter() + .flat_map(|variant| { + let [field] = &variant.fields[..] else { return None; }; + let field_ty = field.ty(tcx, substs); + + // Skip `_`, since that'll just lead to ambiguity. + if self.resolve_vars_if_possible(field_ty).is_ty_var() { + return None; + } - let matching_variants: Vec<_> = kind - .variants() - .iter() - .flat_map(|variant| { - let [field] = &variant.fields[..] else { return None; }; - let field_ty = field.ty(tcx, substs); + self.lookup_probe( + span, + item_name, + field_ty, + call_expr, + ProbeScope::TraitsInScope, + ) + .ok() + .map(|pick| (variant, field, pick)) + }) + .collect(); + + let ret_ty_matches = |diagnostic_item| { + if let Some(ret_ty) = self + .ret_coercion + .as_ref() + .map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty())) + && let ty::Adt(kind, _) = ret_ty.kind() + && tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did()) + { + true + } else { + false + } + }; - // Skip `_`, since that'll just lead to ambiguity. - if self.resolve_vars_if_possible(field_ty).is_ty_var() { - return None; + match &matching_variants[..] { + [(_, field, pick)] => { + let self_ty = field.ty(tcx, substs); + err.span_note( + tcx.def_span(pick.item.def_id), + &format!("the method `{item_name}` exists on the type `{self_ty}`"), + ); + let (article, kind, variant, question) = + if tcx.is_diagnostic_item(sym::Result, kind.did()) { + ("a", "Result", "Err", ret_ty_matches(sym::Result)) + } else if tcx.is_diagnostic_item(sym::Option, kind.did()) { + ("an", "Option", "None", ret_ty_matches(sym::Option)) + } else { + return; + }; + if question { + err.span_suggestion_verbose( + expr.span.shrink_to_hi(), + format!( + "use the `?` operator to extract the `{self_ty}` value, propagating \ + {article} `{kind}::{variant}` value to the caller" + ), + "?", + Applicability::MachineApplicable, + ); + } else { + err.span_suggestion_verbose( + expr.span.shrink_to_hi(), + format!( + "consider using `{kind}::expect` to unwrap the `{self_ty}` value, \ + panicking if the value is {article} `{kind}::{variant}`" + ), + ".expect(\"REASON\")", + Applicability::HasPlaceholders, + ); + } + } + // FIXME(compiler-errors): Support suggestions for other matching enum variants + _ => {} } - - self.lookup_probe(span, item_name, field_ty, call_expr, ProbeScope::AllTraits) - .ok() - .map(|pick| (variant, field, pick)) - }) - .collect(); - - let ret_ty_matches = |diagnostic_item| { - if let Some(ret_ty) = self - .ret_coercion - .as_ref() - .map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty())) - && let ty::Adt(kind, _) = ret_ty.kind() - && tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did()) - { - true - } else { - false } - }; + // Target wrapper types - types that wrap or pretend to wrap another type, + // perhaps this inner type is meant to be called? + ty::AdtKind::Struct | ty::AdtKind::Union => { + let [first] = ***substs else { return; }; + let ty::GenericArgKind::Type(ty) = first.unpack() else { return; }; + let Ok(pick) = self.lookup_probe( + span, + item_name, + ty, + call_expr, + ProbeScope::TraitsInScope, + ) else { return; }; - match &matching_variants[..] { - [(_, field, pick)] => { - let self_ty = field.ty(tcx, substs); - err.span_note( - tcx.def_span(pick.item.def_id), - &format!("the method `{item_name}` exists on the type `{self_ty}`"), - ); - let (article, kind, variant, question) = - if Some(kind.did()) == tcx.get_diagnostic_item(sym::Result) { - ("a", "Result", "Err", ret_ty_matches(sym::Result)) - } else if Some(kind.did()) == tcx.get_diagnostic_item(sym::Option) { - ("an", "Option", "None", ret_ty_matches(sym::Option)) - } else { - return; + let name = self.ty_to_value_string(actual); + let inner_id = kind.did(); + let mutable = if let Some(AutorefOrPtrAdjustment::Autoref { mutbl, .. }) = + pick.autoref_or_ptr_adjustment + { + Some(mutbl) + } else { + None + }; + + if tcx.is_diagnostic_item(sym::LocalKey, inner_id) { + err.help("use `with` or `try_with` to access thread local storage"); + } else if Some(kind.did()) == tcx.lang_items().maybe_uninit() { + err.help(format!( + "if this `{name}` has been initialized, \ + use one of the `assume_init` methods to access the inner value" + )); + } else if tcx.is_diagnostic_item(sym::RefCell, inner_id) { + let (suggestion, borrow_kind, panic_if) = match mutable { + Some(Mutability::Not) => (".borrow()", "borrow", "a mutable borrow exists"), + Some(Mutability::Mut) => { + (".borrow_mut()", "mutably borrow", "any borrows exist") + } + None => return, }; - if question { err.span_suggestion_verbose( expr.span.shrink_to_hi(), format!( - "use the `?` operator to extract the `{self_ty}` value, propagating \ - {article} `{kind}::{variant}` value to the caller" + "use `{suggestion}` to {borrow_kind} the `{ty}`, \ + panicking if {panic_if}" ), - "?", - Applicability::MachineApplicable, + suggestion, + Applicability::MaybeIncorrect, ); - } else { + } else if tcx.is_diagnostic_item(sym::Mutex, inner_id) { err.span_suggestion_verbose( expr.span.shrink_to_hi(), format!( - "consider using `{kind}::expect` to unwrap the `{self_ty}` value, \ - panicking if the value is {article} `{kind}::{variant}`" + "use `.lock().unwrap()` to borrow the `{ty}`, \ + blocking the current thread until it can be acquired" ), - ".expect(\"REASON\")", - Applicability::HasPlaceholders, + ".lock().unwrap()", + Applicability::MaybeIncorrect, ); - } + } else if tcx.is_diagnostic_item(sym::RwLock, inner_id) { + let (suggestion, borrow_kind) = match mutable { + Some(Mutability::Not) => (".read().unwrap()", "borrow"), + Some(Mutability::Mut) => (".write().unwrap()", "mutably borrow"), + None => return, + }; + err.span_suggestion_verbose( + expr.span.shrink_to_hi(), + format!( + "use `{suggestion}` to {borrow_kind} the `{ty}`, \ + blocking the current thread until it can be acquired" + ), + suggestion, + Applicability::MaybeIncorrect, + ); + } else { + return; + }; + + err.span_note( + tcx.def_span(pick.item.def_id), + &format!("the method `{item_name}` exists on the type `{ty}`"), + ); } - // FIXME(compiler-errors): Support suggestions for other matching enum variants - _ => {} } } diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 9753fb355308c..23a4c1f069662 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -1,7 +1,6 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] #![feature(allow_internal_unstable)] -#![feature(bench_black_box)] #![feature(extend_one)] #![feature(min_specialization)] #![feature(new_uninit)] diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs index 3da6bc14622a0..8f64b5f5158e4 100644 --- a/compiler/rustc_lexer/src/unescape.rs +++ b/compiler/rustc_lexer/src/unescape.rs @@ -93,7 +93,7 @@ where // NOTE: Raw strings do not perform any explicit character escaping, here we // only translate CRLF to LF and produce errors on bare CR. Mode::RawStr | Mode::RawByteStr => { - unescape_raw_str_or_byte_str(literal_text, mode, callback) + unescape_raw_str_or_raw_byte_str(literal_text, mode, callback) } } } @@ -105,7 +105,7 @@ pub fn unescape_byte_literal(literal_text: &str, mode: Mode, callback: &mut F where F: FnMut(Range, Result), { - assert!(mode.is_bytes()); + debug_assert!(mode.is_bytes()); unescape_literal(literal_text, mode, &mut |range, result| { callback(range, result.map(byte_from_char)); }) @@ -129,7 +129,7 @@ pub fn unescape_byte(literal_text: &str) -> Result { } /// What kind of literal do we parse. -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum Mode { Char, Str, @@ -140,17 +140,13 @@ pub enum Mode { } impl Mode { - pub fn in_single_quotes(self) -> bool { + pub fn in_double_quotes(self) -> bool { match self { - Mode::Char | Mode::Byte => true, - Mode::Str | Mode::ByteStr | Mode::RawStr | Mode::RawByteStr => false, + Mode::Str | Mode::ByteStr | Mode::RawStr | Mode::RawByteStr => true, + Mode::Char | Mode::Byte => false, } } - pub fn in_double_quotes(self) -> bool { - !self.in_single_quotes() - } - pub fn is_bytes(self) -> bool { match self { Mode::Byte | Mode::ByteStr | Mode::RawByteStr => true, @@ -184,7 +180,7 @@ fn scan_escape(chars: &mut Chars<'_>, mode: Mode) -> Result { let value = hi * 16 + lo; - // For a byte literal verify that it is within ASCII range. + // For a non-byte literal verify that it is within ASCII range. if !mode.is_bytes() && !is_ascii(value) { return Err(EscapeError::OutOfRangeHexEscape); } @@ -263,6 +259,7 @@ fn ascii_check(first_char: char, mode: Mode) -> Result { } fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result { + debug_assert!(mode == Mode::Char || mode == Mode::Byte); let first_char = chars.next().ok_or(EscapeError::ZeroChars)?; let res = match first_char { '\\' => scan_escape(chars, mode), @@ -282,7 +279,7 @@ fn unescape_str_or_byte_str(src: &str, mode: Mode, callback: &mut F) where F: FnMut(Range, Result), { - assert!(mode.in_double_quotes()); + debug_assert!(mode == Mode::Str || mode == Mode::ByteStr); let initial_len = src.len(); let mut chars = src.chars(); while let Some(first_char) = chars.next() { @@ -344,11 +341,11 @@ where /// sequence of characters or errors. /// NOTE: Raw strings do not perform any explicit character escaping, here we /// only translate CRLF to LF and produce errors on bare CR. -fn unescape_raw_str_or_byte_str(literal_text: &str, mode: Mode, callback: &mut F) +fn unescape_raw_str_or_raw_byte_str(literal_text: &str, mode: Mode, callback: &mut F) where F: FnMut(Range, Result), { - assert!(mode.in_double_quotes()); + debug_assert!(mode == Mode::RawStr || mode == Mode::RawByteStr); let initial_len = literal_text.len(); let mut chars = literal_text.chars(); @@ -368,7 +365,7 @@ where fn byte_from_char(c: char) -> u8 { let res = c as u32; - assert!(res <= u8::MAX as u32, "guaranteed because of Mode::ByteStr"); + debug_assert!(res <= u8::MAX as u32, "guaranteed because of Mode::ByteStr"); res as u8 } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 7657f9486c227..07f3656d086b8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -224,6 +224,7 @@ symbols! { Left, LinkedList, LintPass, + LocalKey, Mutex, MutexGuard, N, @@ -266,6 +267,7 @@ symbols! { Rc, Ready, Receiver, + RefCell, Relaxed, Release, Result, @@ -274,6 +276,7 @@ symbols! { Rust, RustcDecodable, RustcEncodable, + RwLock, RwLockReadGuard, RwLockWriteGuard, Send, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 6f3a9412dde7a..f13736a76b214 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -102,7 +102,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { } /// Attempts to select obligations using `selcx`. - fn select(&mut self, selcx: &mut SelectionContext<'a, 'tcx>) -> Vec> { + fn select(&mut self, selcx: SelectionContext<'a, 'tcx>) -> Vec> { let span = debug_span!("select", obligation_forest_size = ?self.predicates.len()); let _enter = span.enter(); @@ -197,8 +197,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { &mut self, infcx: &InferCtxt<'_, 'tcx>, ) -> Vec> { - let mut selcx = SelectionContext::new(infcx); - self.select(&mut selcx) + let selcx = SelectionContext::new(infcx); + self.select(selcx) } fn pending_obligations(&self) -> Vec> { @@ -210,8 +210,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { } } -struct FulfillProcessor<'a, 'b, 'tcx> { - selcx: &'a mut SelectionContext<'b, 'tcx>, +struct FulfillProcessor<'a, 'tcx> { + selcx: SelectionContext<'a, 'tcx>, } fn mk_pending(os: Vec>) -> Vec> { @@ -220,7 +220,7 @@ fn mk_pending(os: Vec>) -> Vec ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { +impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { type Obligation = PendingPredicateObligation<'tcx>; type Error = FulfillmentErrorCode<'tcx>; type OUT = Outcome; @@ -291,7 +291,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { if obligation.predicate.has_projections() { let mut obligations = Vec::new(); let predicate = crate::traits::project::try_normalize_with_depth_to( - self.selcx, + &mut self.selcx, obligation.param_env, obligation.cause.clone(), obligation.recursion_depth + 1, @@ -608,7 +608,7 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> { } } -impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { +impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { #[instrument(level = "debug", skip(self, obligation, stalled_on))] fn process_trait_obligation( &mut self, @@ -643,7 +643,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { // information about the types in the trait. stalled_on.clear(); stalled_on.extend(substs_infer_vars( - self.selcx, + &self.selcx, trait_obligation.predicate.map_bound(|pred| pred.trait_ref.substs), )); @@ -695,12 +695,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { } } - match project::poly_project_and_unify_type(self.selcx, &project_obligation) { + match project::poly_project_and_unify_type(&mut self.selcx, &project_obligation) { ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)), ProjectAndUnifyResult::FailedNormalization => { stalled_on.clear(); stalled_on.extend(substs_infer_vars( - self.selcx, + &self.selcx, project_obligation.predicate.map_bound(|pred| pred.projection_ty.substs), )); ProcessResult::Unchanged @@ -718,7 +718,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> { /// Returns the set of inference variables contained in `substs`. fn substs_infer_vars<'a, 'tcx>( - selcx: &mut SelectionContext<'a, 'tcx>, + selcx: &SelectionContext<'a, 'tcx>, substs: ty::Binder<'tcx, SubstsRef<'tcx>>, ) -> impl Iterator> { selcx diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 27fbfb6dd21fb..dd49dcecf77e3 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -626,7 +626,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // the signature, as evidenced by how we treat it during projection. // The safe thing to do here is to liberate it, though, which should // have no worse effect than skipping the binder here. - let liberated_fn_ty = self.infcx.replace_bound_vars_with_placeholders(obligation.self_ty()); + let liberated_fn_ty = + self.infcx.replace_bound_vars_with_placeholders(obligation.predicate.rebind(self_ty)); let output_ty = self .infcx .replace_bound_vars_with_placeholders(liberated_fn_ty.fn_sig(self.tcx()).output()); diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 55aced5106c94..f30ebd77e2466 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -41,7 +41,6 @@ #![feature(pointer_is_aligned)] #![feature(slice_flatten)] #![feature(thin_box)] -#![feature(bench_black_box)] #![feature(strict_provenance)] #![feature(once_cell)] #![feature(drain_keep_rest)] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 1abbb39497a0f..288cab1ef3994 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -614,6 +614,7 @@ impl Cell<[T; N]> { /// A mutable memory location with dynamically checked borrow rules /// /// See the [module-level documentation](self) for more. +#[cfg_attr(not(test), rustc_diagnostic_item = "RefCell")] #[stable(feature = "rust1", since = "1.0.0")] pub struct RefCell { borrow: Cell, diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 764e2796202c9..f9267371aa745 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -217,7 +217,7 @@ pub fn spin_loop() { /// /// [`std::convert::identity`]: crate::convert::identity #[inline] -#[unstable(feature = "bench_black_box", issue = "64102")] +#[stable(feature = "bench_black_box", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_black_box", issue = "none")] pub const fn black_box(dummy: T) -> T { crate::intrinsics::black_box(dummy) diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 46f603eaebaca..6d58ed9743d6a 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -2,7 +2,6 @@ #![feature(array_chunks)] #![feature(array_methods)] #![feature(array_windows)] -#![feature(bench_black_box)] #![feature(bigint_helper_methods)] #![feature(cell_update)] #![feature(const_assume)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index ac5d0384d43dc..64b62fd3bba4f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -348,7 +348,6 @@ #![feature(trace_macros)] // // Only used in tests/benchmarks: -#![feature(bench_black_box)] // // Only for const-ness: #![feature(const_io_structs)] diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index 9ab781561e9b1..ee2c79b6669b8 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -76,6 +76,7 @@ use crate::sys_common::rwlock as sys; /// /// [`Mutex`]: super::Mutex #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "RwLock")] pub struct RwLock { inner: sys::MovableRwLock, poison: poison::Flag, diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index 8aedfc4a6b819..ffd17dc99093a 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -95,6 +95,7 @@ use crate::fmt; /// [loader lock]: https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-best-practices /// [`JoinHandle::join`]: crate::thread::JoinHandle::join /// [`with`]: LocalKey::with +#[cfg_attr(not(test), rustc_diagnostic_item = "LocalKey")] #[stable(feature = "rust1", since = "1.0.0")] pub struct LocalKey { // This outer `LocalKey` type is what's going to be stored in statics, diff --git a/library/test/src/lib.rs b/library/test/src/lib.rs index 3b7193adcc758..33c6ea5853227 100644 --- a/library/test/src/lib.rs +++ b/library/test/src/lib.rs @@ -15,7 +15,6 @@ #![unstable(feature = "test", issue = "50297")] #![doc(test(attr(deny(warnings))))] -#![feature(bench_black_box)] #![feature(internal_output_capture)] #![feature(staged_api)] #![feature(process_exitcode_internals)] diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index c8ea5bef37a55..0ea6d9c38b69f 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1776,9 +1776,6 @@ in storage.js plus the media query with (min-width: 701px) } .rustdoc.source > .sidebar { - position: fixed; - margin: 0; - z-index: 11; width: 0; } diff --git a/src/test/incremental/spans_significant_w_panic.rs b/src/test/incremental/spans_significant_w_panic.rs index e9e35791aa158..6f51c9729e370 100644 --- a/src/test/incremental/spans_significant_w_panic.rs +++ b/src/test/incremental/spans_significant_w_panic.rs @@ -8,7 +8,6 @@ // compile-flags: -C overflow-checks=on -Z query-dep-graph #![feature(rustc_attrs)] -#![feature(bench_black_box)] #![rustc_partition_codegened(module = "spans_significant_w_panic", cfg = "rpass2")] #![rustc_partition_codegened(module = "spans_significant_w_panic", cfg = "rpass4")] diff --git a/src/test/ui/associated-consts/issue-102335-const.rs b/src/test/ui/associated-consts/issue-102335-const.rs new file mode 100644 index 0000000000000..f60cb92da7f6b --- /dev/null +++ b/src/test/ui/associated-consts/issue-102335-const.rs @@ -0,0 +1,12 @@ +#![feature(associated_const_equality)] + +trait T { + type A: S = 34>; + //~^ ERROR associated type bindings are not allowed here +} + +trait S { + const C: i32; +} + +fn main() {} diff --git a/src/test/ui/associated-consts/issue-102335-const.stderr b/src/test/ui/associated-consts/issue-102335-const.stderr new file mode 100644 index 0000000000000..531d15c5900c5 --- /dev/null +++ b/src/test/ui/associated-consts/issue-102335-const.stderr @@ -0,0 +1,9 @@ +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-102335-const.rs:4:17 + | +LL | type A: S = 34>; + | ^^^^^^^^ associated type not allowed here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0229`. diff --git a/src/test/ui/associated-type-bounds/issue-102335-ty.rs b/src/test/ui/associated-type-bounds/issue-102335-ty.rs new file mode 100644 index 0000000000000..363df73c1ffd7 --- /dev/null +++ b/src/test/ui/associated-type-bounds/issue-102335-ty.rs @@ -0,0 +1,12 @@ +trait T { + type A: S = ()>; + //~^ ERROR associated type bindings are not allowed here +} + +trait Q {} + +trait S { + type C: Q; +} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/issue-102335-ty.stderr b/src/test/ui/associated-type-bounds/issue-102335-ty.stderr new file mode 100644 index 0000000000000..8777b2965153a --- /dev/null +++ b/src/test/ui/associated-type-bounds/issue-102335-ty.stderr @@ -0,0 +1,9 @@ +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-102335-ty.rs:2:17 + | +LL | type A: S = ()>; + | ^^^^^^^^^ associated type not allowed here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0229`. diff --git a/src/test/ui/box/issue-95036.rs b/src/test/ui/box/issue-95036.rs index c2d4275aa49d3..0611fabc15c08 100644 --- a/src/test/ui/box/issue-95036.rs +++ b/src/test/ui/box/issue-95036.rs @@ -1,7 +1,7 @@ // compile-flags: -O // build-pass -#![feature(allocator_api, bench_black_box)] +#![feature(allocator_api)] #[inline(never)] pub fn by_ref(node: &mut Box<[u8; 1], &std::alloc::Global>) { diff --git a/src/test/ui/consts/cast-discriminant-zst-enum.rs b/src/test/ui/consts/cast-discriminant-zst-enum.rs index e59ae297da1a7..2767f178fb664 100644 --- a/src/test/ui/consts/cast-discriminant-zst-enum.rs +++ b/src/test/ui/consts/cast-discriminant-zst-enum.rs @@ -1,6 +1,5 @@ // run-pass // Test a ZST enum whose dicriminant is ~0i128. This caused an ICE when casting to an i32. -#![feature(bench_black_box)] use std::hint::black_box; #[derive(Copy, Clone)] diff --git a/src/test/ui/consts/const_discriminant.rs b/src/test/ui/consts/const_discriminant.rs index f623c5101f4cd..79e68590e85d4 100644 --- a/src/test/ui/consts/const_discriminant.rs +++ b/src/test/ui/consts/const_discriminant.rs @@ -1,6 +1,5 @@ // run-pass #![feature(const_discriminant)] -#![feature(bench_black_box)] #![allow(dead_code)] use std::mem::{discriminant, Discriminant}; diff --git a/src/test/ui/error-codes/E0311.rs b/src/test/ui/error-codes/E0311.rs new file mode 100644 index 0000000000000..566b518b4331d --- /dev/null +++ b/src/test/ui/error-codes/E0311.rs @@ -0,0 +1,9 @@ +fn no_restriction(x: &()) -> &() { + with_restriction::(x) //~ ERROR E0311 +} + +fn with_restriction<'a, T: 'a>(x: &'a ()) -> &'a () { + x +} + +fn main() {} diff --git a/src/test/ui/error-codes/E0311.stderr b/src/test/ui/error-codes/E0311.stderr new file mode 100644 index 0000000000000..9873b5ae6ff13 --- /dev/null +++ b/src/test/ui/error-codes/E0311.stderr @@ -0,0 +1,24 @@ +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/E0311.rs:2:5 + | +LL | with_restriction::(x) + | ^^^^^^^^^^^^^^^^^^^^^ + | +note: the parameter type `T` must be valid for the anonymous lifetime defined here... + --> $DIR/E0311.rs:1:25 + | +LL | fn no_restriction(x: &()) -> &() { + | ^^^ +note: ...so that the type `T` will meet its required lifetime bounds + --> $DIR/E0311.rs:2:5 + | +LL | with_restriction::(x) + | ^^^^^^^^^^^^^^^^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() { + | +++ ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0311`. diff --git a/src/test/ui/function-pointer/issue-102289.rs b/src/test/ui/function-pointer/issue-102289.rs new file mode 100644 index 0000000000000..de394ca9ad6d4 --- /dev/null +++ b/src/test/ui/function-pointer/issue-102289.rs @@ -0,0 +1,54 @@ +// check-pass + +pub(crate) trait Parser: Sized { + type Output; + fn parse(&mut self, _input: &str) -> Result<(), ()> { + loop {} + } + fn map(self, _f: F) -> Map + where + F: FnMut(Self::Output) -> B, + { + todo!() + } +} + +pub(crate) struct Chainl1(P, Op); +impl Parser for Chainl1 +where + P: Parser, + Op: Parser, + Op::Output: FnOnce(P::Output, P::Output) -> P::Output, +{ + type Output = P::Output; +} +pub(crate) fn chainl1(_parser: P, _op: Op) -> Chainl1 +where + P: Parser, + Op: Parser, + Op::Output: FnOnce(P::Output, P::Output) -> P::Output, +{ + loop {} +} + +pub(crate) struct Map(P, F); +impl Parser for Map +where + P: Parser, + F: FnMut(A) -> B, +{ + type Output = B; +} + +impl Parser for u32 { + type Output = (); +} + +pub fn chainl1_error_consume() { + fn first(t: T, _: U) -> T { + t + } + let _ = chainl1(1, 1.map(|_| first)).parse(""); +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-102335-gat.rs b/src/test/ui/generic-associated-types/issue-102335-gat.rs new file mode 100644 index 0000000000000..a7255fdcbf5e1 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-102335-gat.rs @@ -0,0 +1,12 @@ +trait T { + type A: S = ()>; + //~^ ERROR associated type bindings are not allowed here +} + +trait Q {} + +trait S { + type C: Q; +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-102335-gat.stderr b/src/test/ui/generic-associated-types/issue-102335-gat.stderr new file mode 100644 index 0000000000000..7a7900a1e656a --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-102335-gat.stderr @@ -0,0 +1,9 @@ +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-102335-gat.rs:2:21 + | +LL | type A: S = ()>; + | ^^^^^^^^ associated type not allowed here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0229`. diff --git a/src/test/ui/issues/issue-99838.rs b/src/test/ui/issues/issue-99838.rs index eaeeac72b25e1..2e81d5e8221c4 100644 --- a/src/test/ui/issues/issue-99838.rs +++ b/src/test/ui/issues/issue-99838.rs @@ -1,5 +1,5 @@ // run-pass -#![feature(bench_black_box)] + use std::hint; struct U16(u16); diff --git a/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr b/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr index a8b0996d8b0c7..31fd8a4d633e9 100644 --- a/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr +++ b/src/test/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr @@ -21,3 +21,4 @@ LL | fn no_restriction<'a, T: 'a>(x: &()) -> &() { error: aborting due to previous error +For more information about this error, try `rustc --explain E0311`. diff --git a/src/test/ui/oom_unwind.rs b/src/test/ui/oom_unwind.rs index d036c817a0e83..21a8fb2b22bee 100644 --- a/src/test/ui/oom_unwind.rs +++ b/src/test/ui/oom_unwind.rs @@ -4,8 +4,6 @@ // needs-unwind // only-linux -#![feature(bench_black_box)] - use std::hint::black_box; use std::mem::forget; use std::panic::catch_unwind; diff --git a/src/test/ui/process/process-panic-after-fork.rs b/src/test/ui/process/process-panic-after-fork.rs index 1ccf6bb051c20..08b30b600e737 100644 --- a/src/test/ui/process/process-panic-after-fork.rs +++ b/src/test/ui/process/process-panic-after-fork.rs @@ -7,7 +7,6 @@ // ignore-sgx no processes // ignore-android: FIXME(#85261) -#![feature(bench_black_box)] #![feature(rustc_private)] #![feature(never_type)] #![feature(panic_always_abort)] diff --git a/src/test/ui/sanitize/address.rs b/src/test/ui/sanitize/address.rs index 9a26a351d992c..5b2cea87560fd 100644 --- a/src/test/ui/sanitize/address.rs +++ b/src/test/ui/sanitize/address.rs @@ -5,9 +5,7 @@ // // run-fail // error-pattern: AddressSanitizer: stack-buffer-overflow -// error-pattern: 'xs' (line 15) <== Memory access at offset - -#![feature(bench_black_box)] +// error-pattern: 'xs' (line 13) <== Memory access at offset use std::hint::black_box; diff --git a/src/test/ui/sanitize/hwaddress.rs b/src/test/ui/sanitize/hwaddress.rs index b988035f75e4c..f9b37a155aad7 100644 --- a/src/test/ui/sanitize/hwaddress.rs +++ b/src/test/ui/sanitize/hwaddress.rs @@ -10,8 +10,6 @@ // run-fail // error-pattern: HWAddressSanitizer: tag-mismatch -#![feature(bench_black_box)] - use std::hint::black_box; fn main() { diff --git a/src/test/ui/sanitize/leak.rs b/src/test/ui/sanitize/leak.rs index f63f81352dada..cbb44ae8acd60 100644 --- a/src/test/ui/sanitize/leak.rs +++ b/src/test/ui/sanitize/leak.rs @@ -6,8 +6,6 @@ // run-fail // error-pattern: LeakSanitizer: detected memory leaks -#![feature(bench_black_box)] - use std::hint::black_box; use std::mem; diff --git a/src/test/ui/sanitize/memory-eager.rs b/src/test/ui/sanitize/memory-eager.rs index cc0593ec07dcd..0018c2f758182 100644 --- a/src/test/ui/sanitize/memory-eager.rs +++ b/src/test/ui/sanitize/memory-eager.rs @@ -17,7 +17,6 @@ #![feature(core_intrinsics)] #![feature(start)] -#![feature(bench_black_box)] use std::hint::black_box; use std::mem::MaybeUninit; diff --git a/src/test/ui/sanitize/memory.rs b/src/test/ui/sanitize/memory.rs index 14d4de65dd378..1a9ac3a4f3c32 100644 --- a/src/test/ui/sanitize/memory.rs +++ b/src/test/ui/sanitize/memory.rs @@ -16,7 +16,6 @@ #![feature(core_intrinsics)] #![feature(start)] -#![feature(bench_black_box)] #![allow(invalid_value)] use std::hint::black_box; diff --git a/src/test/ui/suggestions/inner_type.fixed b/src/test/ui/suggestions/inner_type.fixed new file mode 100644 index 0000000000000..7af7391ca851d --- /dev/null +++ b/src/test/ui/suggestions/inner_type.fixed @@ -0,0 +1,40 @@ +// compile-flags: --edition=2021 +// run-rustfix + +pub struct Struct { + pub p: T, +} + +impl Struct { + pub fn method(&self) {} + + pub fn some_mutable_method(&mut self) {} +} + +fn main() { + let other_item = std::cell::RefCell::new(Struct { p: 42_u32 }); + + other_item.borrow().method(); + //~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599] + //~| HELP use `.borrow()` to borrow the `Struct`, panicking if a mutable borrow exists + + other_item.borrow_mut().some_mutable_method(); + //~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599] + //~| HELP .borrow_mut()` to mutably borrow the `Struct`, panicking if any borrows exist + + let another_item = std::sync::Mutex::new(Struct { p: 42_u32 }); + + another_item.lock().unwrap().method(); + //~^ ERROR no method named `method` found for struct `Mutex` in the current scope [E0599] + //~| HELP use `.lock().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired + + let another_item = std::sync::RwLock::new(Struct { p: 42_u32 }); + + another_item.read().unwrap().method(); + //~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599] + //~| HELP use `.read().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired + + another_item.write().unwrap().some_mutable_method(); + //~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599] + //~| HELP use `.write().unwrap()` to mutably borrow the `Struct`, blocking the current thread until it can be acquired +} diff --git a/src/test/ui/suggestions/inner_type.rs b/src/test/ui/suggestions/inner_type.rs new file mode 100644 index 0000000000000..4aca50716258a --- /dev/null +++ b/src/test/ui/suggestions/inner_type.rs @@ -0,0 +1,40 @@ +// compile-flags: --edition=2021 +// run-rustfix + +pub struct Struct { + pub p: T, +} + +impl Struct { + pub fn method(&self) {} + + pub fn some_mutable_method(&mut self) {} +} + +fn main() { + let other_item = std::cell::RefCell::new(Struct { p: 42_u32 }); + + other_item.method(); + //~^ ERROR no method named `method` found for struct `RefCell` in the current scope [E0599] + //~| HELP use `.borrow()` to borrow the `Struct`, panicking if a mutable borrow exists + + other_item.some_mutable_method(); + //~^ ERROR no method named `some_mutable_method` found for struct `RefCell` in the current scope [E0599] + //~| HELP .borrow_mut()` to mutably borrow the `Struct`, panicking if any borrows exist + + let another_item = std::sync::Mutex::new(Struct { p: 42_u32 }); + + another_item.method(); + //~^ ERROR no method named `method` found for struct `Mutex` in the current scope [E0599] + //~| HELP use `.lock().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired + + let another_item = std::sync::RwLock::new(Struct { p: 42_u32 }); + + another_item.method(); + //~^ ERROR no method named `method` found for struct `RwLock` in the current scope [E0599] + //~| HELP use `.read().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired + + another_item.some_mutable_method(); + //~^ ERROR no method named `some_mutable_method` found for struct `RwLock` in the current scope [E0599] + //~| HELP use `.write().unwrap()` to mutably borrow the `Struct`, blocking the current thread until it can be acquired +} diff --git a/src/test/ui/suggestions/inner_type.stderr b/src/test/ui/suggestions/inner_type.stderr new file mode 100644 index 0000000000000..5ac3d04f10414 --- /dev/null +++ b/src/test/ui/suggestions/inner_type.stderr @@ -0,0 +1,83 @@ +error[E0599]: no method named `method` found for struct `RefCell` in the current scope + --> $DIR/inner_type.rs:17:16 + | +LL | other_item.method(); + | ^^^^^^ method not found in `RefCell>` + | +note: the method `method` exists on the type `Struct` + --> $DIR/inner_type.rs:9:5 + | +LL | pub fn method(&self) {} + | ^^^^^^^^^^^^^^^^^^^^ +help: use `.borrow()` to borrow the `Struct`, panicking if a mutable borrow exists + | +LL | other_item.borrow().method(); + | +++++++++ + +error[E0599]: no method named `some_mutable_method` found for struct `RefCell` in the current scope + --> $DIR/inner_type.rs:21:16 + | +LL | other_item.some_mutable_method(); + | ^^^^^^^^^^^^^^^^^^^ method not found in `RefCell>` + | +note: the method `some_mutable_method` exists on the type `Struct` + --> $DIR/inner_type.rs:11:5 + | +LL | pub fn some_mutable_method(&mut self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use `.borrow_mut()` to mutably borrow the `Struct`, panicking if any borrows exist + | +LL | other_item.borrow_mut().some_mutable_method(); + | +++++++++++++ + +error[E0599]: no method named `method` found for struct `Mutex` in the current scope + --> $DIR/inner_type.rs:27:18 + | +LL | another_item.method(); + | ^^^^^^ method not found in `Mutex>` + | +note: the method `method` exists on the type `Struct` + --> $DIR/inner_type.rs:9:5 + | +LL | pub fn method(&self) {} + | ^^^^^^^^^^^^^^^^^^^^ +help: use `.lock().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired + | +LL | another_item.lock().unwrap().method(); + | ++++++++++++++++ + +error[E0599]: no method named `method` found for struct `RwLock` in the current scope + --> $DIR/inner_type.rs:33:18 + | +LL | another_item.method(); + | ^^^^^^ method not found in `RwLock>` + | +note: the method `method` exists on the type `Struct` + --> $DIR/inner_type.rs:9:5 + | +LL | pub fn method(&self) {} + | ^^^^^^^^^^^^^^^^^^^^ +help: use `.read().unwrap()` to borrow the `Struct`, blocking the current thread until it can be acquired + | +LL | another_item.read().unwrap().method(); + | ++++++++++++++++ + +error[E0599]: no method named `some_mutable_method` found for struct `RwLock` in the current scope + --> $DIR/inner_type.rs:37:18 + | +LL | another_item.some_mutable_method(); + | ^^^^^^^^^^^^^^^^^^^ method not found in `RwLock>` + | +note: the method `some_mutable_method` exists on the type `Struct` + --> $DIR/inner_type.rs:11:5 + | +LL | pub fn some_mutable_method(&mut self) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use `.write().unwrap()` to mutably borrow the `Struct`, blocking the current thread until it can be acquired + | +LL | another_item.write().unwrap().some_mutable_method(); + | +++++++++++++++++ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/inner_type2.rs b/src/test/ui/suggestions/inner_type2.rs new file mode 100644 index 0000000000000..c56ea7c030d8e --- /dev/null +++ b/src/test/ui/suggestions/inner_type2.rs @@ -0,0 +1,26 @@ +pub struct Struct { + pub p: T, +} + +impl Struct { + pub fn method(&self) {} + + pub fn some_mutable_method(&mut self) {} +} + +thread_local! { + static STRUCT: Struct = Struct { + p: 42_u32 + }; +} + +fn main() { + STRUCT.method(); + //~^ ERROR no method named `method` found for struct `LocalKey` in the current scope [E0599] + //~| HELP use `with` or `try_with` to access thread local storage + + let item = std::mem::MaybeUninit::new(Struct { p: 42_u32 }); + item.method(); + //~^ ERROR no method named `method` found for union `MaybeUninit` in the current scope [E0599] + //~| HELP if this `MaybeUninit::>` has been initialized, use one of the `assume_init` methods to access the inner value +} diff --git a/src/test/ui/suggestions/inner_type2.stderr b/src/test/ui/suggestions/inner_type2.stderr new file mode 100644 index 0000000000000..eddfd9d63409d --- /dev/null +++ b/src/test/ui/suggestions/inner_type2.stderr @@ -0,0 +1,29 @@ +error[E0599]: no method named `method` found for struct `LocalKey` in the current scope + --> $DIR/inner_type2.rs:18:12 + | +LL | STRUCT.method(); + | ^^^^^^ method not found in `LocalKey>` + | + = help: use `with` or `try_with` to access thread local storage +note: the method `method` exists on the type `Struct` + --> $DIR/inner_type2.rs:6:5 + | +LL | pub fn method(&self) {} + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0599]: no method named `method` found for union `MaybeUninit` in the current scope + --> $DIR/inner_type2.rs:23:10 + | +LL | item.method(); + | ^^^^^^ method not found in `MaybeUninit>` + | + = help: if this `MaybeUninit::>` has been initialized, use one of the `assume_init` methods to access the inner value +note: the method `method` exists on the type `Struct` + --> $DIR/inner_type2.rs:6:5 + | +LL | pub fn method(&self) {} + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/issue-85347.rs b/src/test/ui/suggestions/issue-85347.rs index dd52b3150551a..02b5fb61894e9 100644 --- a/src/test/ui/suggestions/issue-85347.rs +++ b/src/test/ui/suggestions/issue-85347.rs @@ -2,6 +2,7 @@ use std::ops::Deref; trait Foo { type Bar<'a>: Deref::Bar>; //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + //~| ERROR associated type bindings are not allowed here //~| HELP add missing } diff --git a/src/test/ui/suggestions/issue-85347.stderr b/src/test/ui/suggestions/issue-85347.stderr index de853de27e40e..17c1b7dc4cce9 100644 --- a/src/test/ui/suggestions/issue-85347.stderr +++ b/src/test/ui/suggestions/issue-85347.stderr @@ -14,6 +14,13 @@ help: add missing lifetime argument LL | type Bar<'a>: Deref::Bar<'a, Target = Self>>; | +++ -error: aborting due to previous error +error[E0229]: associated type bindings are not allowed here + --> $DIR/issue-85347.rs:3:46 + | +LL | type Bar<'a>: Deref::Bar>; + | ^^^^^^^^^^^^^ associated type not allowed here + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0107, E0229. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr index e5d2ead6ad67c..872263fd7311b 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr @@ -27,3 +27,4 @@ LL | fn func<'a, T: Test + 'a>(foo: &Foo, t: T) { error: aborting due to previous error +For more information about this error, try `rustc --explain E0311`. diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index ed1b91676a214..171f4b333db4e 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -164,5 +164,5 @@ LL | G: Get + 'a, error: aborting due to 8 previous errors -Some errors have detailed explanations: E0261, E0309, E0621, E0700. +Some errors have detailed explanations: E0261, E0309, E0311, E0621, E0700. For more information about an error, try `rustc --explain E0261`. diff --git a/src/tools/miri/tests/fail/invalid_bool.rs b/src/tools/miri/tests/fail/invalid_bool.rs index 525f8831c1c00..dde414f417740 100644 --- a/src/tools/miri/tests/fail/invalid_bool.rs +++ b/src/tools/miri/tests/fail/invalid_bool.rs @@ -1,7 +1,7 @@ // Validation makes this fail in the wrong place // Make sure we find these even with many checks disabled. //@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation -#![feature(bench_black_box)] + fn main() { let b = unsafe { std::mem::transmute::(2) }; diff --git a/src/tools/miri/tests/pass/float.rs b/src/tools/miri/tests/pass/float.rs index 48dd99441ebff..ce62fb0de04f8 100644 --- a/src/tools/miri/tests/pass/float.rs +++ b/src/tools/miri/tests/pass/float.rs @@ -1,4 +1,4 @@ -#![feature(stmt_expr_attributes, bench_black_box)] +#![feature(stmt_expr_attributes)] #![allow(arithmetic_overflow)] use std::fmt::Debug; use std::hint::black_box; diff --git a/src/tools/miri/tests/pass/u128.rs b/src/tools/miri/tests/pass/u128.rs index 0ef7a514cb653..6def529dbe7c3 100644 --- a/src/tools/miri/tests/pass/u128.rs +++ b/src/tools/miri/tests/pass/u128.rs @@ -1,4 +1,3 @@ -#![feature(bench_black_box)] use std::hint::black_box as b; fn main() {