diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 7b6abdf1ea99e..2e51753ede697 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -638,7 +638,7 @@ impl AddAssign for Size { #[cfg(feature = "nightly")] impl Step for Size { #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { + fn steps_between(start: &Self, end: &Self) -> (usize, Option) { u64::steps_between(&start.bytes(), &end.bytes()) } diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs index 1ac2c44e9dca1..67ec776113399 100644 --- a/compiler/rustc_index_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs @@ -122,7 +122,7 @@ impl Parse for Newtype { #gate_rustc_only impl ::std::iter::Step for #name { #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { + fn steps_between(start: &Self, end: &Self) -> (usize, Option) { ::steps_between( &Self::index(*start), &Self::index(*end), diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 26b345f5941c4..02cb9da6e9ab2 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3940,12 +3940,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } Res::SelfCtor(_) => { // We resolve `Self` in pattern position as an ident sometimes during recovery, - // so delay a bug instead of ICEing. (Note: is this no longer true? We now ICE. If - // this triggers, please convert to a delayed bug and add a test.) - self.r.dcx().span_bug( + // so delay a bug instead of ICEing. + self.r.dcx().span_delayed_bug( ident.span, "unexpected `SelfCtor` in pattern, expected identifier" ); + None } _ => span_bug!( ident.span, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index cbfe5d22f1dbc..edee7b4468cd0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -358,7 +358,7 @@ fn build_options( #[allow(non_upper_case_globals)] mod desc { - pub(crate) const parse_no_flag: &str = "no value"; + pub(crate) const parse_no_value: &str = "no value"; pub(crate) const parse_bool: &str = "one of: `y`, `yes`, `on`, `true`, `n`, `no`, `off` or `false`"; pub(crate) const parse_opt_bool: &str = parse_bool; @@ -462,14 +462,18 @@ pub mod parse { pub(crate) use super::*; pub(crate) const MAX_THREADS_CAP: usize = 256; - /// This is for boolean options that don't take a value and start with - /// `no-`. This style of option is deprecated. - pub(crate) fn parse_no_flag(slot: &mut bool, v: Option<&str>) -> bool { + /// This is for boolean options that don't take a value, and are true simply + /// by existing on the command-line. + /// + /// This style of option is deprecated, and is mainly used by old options + /// beginning with `no-`. + pub(crate) fn parse_no_value(slot: &mut bool, v: Option<&str>) -> bool { match v { None => { *slot = true; true } + // Trying to specify a value is always forbidden. Some(_) => false, } } @@ -1609,16 +1613,16 @@ options! { "perform LLVM link-time optimizations"), metadata: Vec = (Vec::new(), parse_list, [TRACKED], "metadata to mangle symbol names with"), - no_prepopulate_passes: bool = (false, parse_no_flag, [TRACKED], + no_prepopulate_passes: bool = (false, parse_no_value, [TRACKED], "give an empty list of passes to the pass manager"), no_redzone: Option = (None, parse_opt_bool, [TRACKED], "disable the use of the redzone"), #[rustc_lint_opt_deny_field_access("documented to do nothing")] - no_stack_check: bool = (false, parse_no_flag, [UNTRACKED], + no_stack_check: bool = (false, parse_no_value, [UNTRACKED], "this option is deprecated and does nothing"), - no_vectorize_loops: bool = (false, parse_no_flag, [TRACKED], + no_vectorize_loops: bool = (false, parse_no_value, [TRACKED], "disable loop vectorization optimization passes"), - no_vectorize_slp: bool = (false, parse_no_flag, [TRACKED], + no_vectorize_slp: bool = (false, parse_no_value, [TRACKED], "disable LLVM's SLP vectorization pass"), opt_level: String = ("0".to_string(), parse_string, [TRACKED], "optimization level (0-3, s, or z; default: 0)"), @@ -1915,25 +1919,25 @@ options! { "dump facts from NLL analysis into side files (default: no)"), nll_facts_dir: String = ("nll-facts".to_string(), parse_string, [UNTRACKED], "the directory the NLL facts are dumped into (default: `nll-facts`)"), - no_analysis: bool = (false, parse_no_flag, [UNTRACKED], + no_analysis: bool = (false, parse_no_value, [UNTRACKED], "parse and expand the source, but run no analysis"), - no_codegen: bool = (false, parse_no_flag, [TRACKED_NO_CRATE_HASH], + no_codegen: bool = (false, parse_no_value, [TRACKED_NO_CRATE_HASH], "run all passes except codegen; no output"), - no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED], + no_generate_arange_section: bool = (false, parse_no_value, [TRACKED], "omit DWARF address ranges that give faster lookups"), no_implied_bounds_compat: bool = (false, parse_bool, [TRACKED], "disable the compatibility version of the `implied_bounds_ty` query"), - no_jump_tables: bool = (false, parse_no_flag, [TRACKED], + no_jump_tables: bool = (false, parse_no_value, [TRACKED], "disable the jump tables and lookup tables that can be generated from a switch case lowering"), - no_leak_check: bool = (false, parse_no_flag, [UNTRACKED], + no_leak_check: bool = (false, parse_no_value, [UNTRACKED], "disable the 'leak check' for subtyping; unsound, but useful for tests"), - no_link: bool = (false, parse_no_flag, [TRACKED], + no_link: bool = (false, parse_no_value, [TRACKED], "compile without linking"), - no_parallel_backend: bool = (false, parse_no_flag, [UNTRACKED], + no_parallel_backend: bool = (false, parse_no_value, [UNTRACKED], "run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)"), - no_profiler_runtime: bool = (false, parse_no_flag, [TRACKED], + no_profiler_runtime: bool = (false, parse_no_value, [TRACKED], "prevent automatic injection of the profiler_builtins crate"), - no_trait_vptr: bool = (false, parse_no_flag, [TRACKED], + no_trait_vptr: bool = (false, parse_no_value, [TRACKED], "disable generation of trait vptr in vtable for upcasting"), no_unique_section_names: bool = (false, parse_bool, [TRACKED], "do not use unique names for text and data sections when -Z function-sections is used"), @@ -1991,7 +1995,7 @@ options! { proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread, parse_proc_macro_execution_strategy, [UNTRACKED], "how to run proc-macro code (default: same-thread)"), - profile_closures: bool = (false, parse_no_flag, [UNTRACKED], + profile_closures: bool = (false, parse_no_value, [UNTRACKED], "profile size of closures"), profile_sample_use: Option = (None, parse_opt_pathbuf, [TRACKED], "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"), @@ -2165,8 +2169,14 @@ written to standard error output)"), "enable unsound and buggy MIR optimizations (default: no)"), /// This name is kind of confusing: Most unstable options enable something themselves, while /// this just allows "normal" options to be feature-gated. + /// + /// The main check for `-Zunstable-options` takes place separately from the + /// usual parsing of `-Z` options (see [`crate::config::nightly_options`]), + /// so this boolean value is mostly used for enabling unstable _values_ of + /// stable options. That separate check doesn't handle boolean values, so + /// to avoid an inconsistent state we also forbid them here. #[rustc_lint_opt_deny_field_access("use `Session::unstable_options` instead of this field")] - unstable_options: bool = (false, parse_bool, [UNTRACKED], + unstable_options: bool = (false, parse_no_value, [UNTRACKED], "adds unstable command line options to rustc interface (default: no)"), use_ctors_section: Option = (None, parse_opt_bool, [TRACKED], "use legacy .ctors section for initializers rather than .init_array"), diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 345e1cc31f32b..41d430f06df4a 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -91,14 +91,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } else if tcx.is_lang_item(def_id, LangItem::Sized) { // Sized is never implementable by end-users, it is // always automatically computed. - - // FIXME: Consider moving this check to the top level as it - // may also be useful for predicates other than `Sized` - // Error type cannot possibly implement `Sized` (fixes #123154) - if let Err(e) = obligation.predicate.skip_binder().self_ty().error_reported() { - return Err(SelectionError::Overflow(e.into())); - } - let sized_conditions = self.sized_conditions(obligation); self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); } else if tcx.is_lang_item(def_id, LangItem::Unsize) { @@ -230,13 +222,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<(), SelectionError<'tcx>> { debug!(?stack.obligation); - // An error type will unify with anything. So, avoid - // matching an error type with `ParamCandidate`. - // This helps us avoid spurious errors like issue #121941. - if stack.obligation.predicate.references_error() { - return Ok(()); - } - let bounds = stack .obligation .param_env @@ -563,19 +548,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &PolyTraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - // Essentially any user-written impl will match with an error type, - // so creating `ImplCandidates` isn't useful. However, we might - // end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized`) - // This helps us avoid overflow: see issue #72839 - // Since compilation is already guaranteed to fail, this is just - // to try to show the 'nicest' possible errors to the user. - // We don't check for errors in the `ParamEnv` - in practice, - // it seems to cause us to be overly aggressive in deciding - // to give up searching for candidates, leading to spurious errors. - if obligation.predicate.references_error() { - return; - } - let drcx = DeepRejectCtxt::relate_rigid_infer(self.tcx()); let obligation_args = obligation.predicate.skip_binder().trait_ref.args; self.tcx().for_each_relevant_impl( diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 5b4e895189b0e..e0c862a81f341 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2487,10 +2487,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id); let trait_ref = impl_trait_header.trait_ref.instantiate(self.tcx(), impl_args); - if trait_ref.references_error() { - return Err(()); - } - debug!(?impl_trait_header); let Normalized { value: impl_trait_ref, obligations: mut nested_obligations } = diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 2127ba8a42321..292e777f28802 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -6,8 +6,7 @@ use rustc_index::bit_set::BitSet; use rustc_middle::bug; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, - TypeVisitor, Upcast, + self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Upcast, }; use rustc_span::DUMMY_SP; use rustc_span::def_id::{CRATE_DEF_ID, DefId, LocalDefId}; @@ -95,9 +94,6 @@ fn adt_sized_constraint<'tcx>( let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?; - if let Err(guar) = constraint_ty.error_reported() { - return Some(ty::EarlyBinder::bind(Ty::new_error(tcx, guar))); - } // perf hack: if there is a `constraint_ty: Sized` bound, then we know // that the type is sized and do not need to check it on the impl. diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index da4f68a0de4fb..4fa719de5ebf0 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -22,23 +22,21 @@ unsafe_impl_trusted_step![AsciiChar char i8 i16 i32 i64 i128 isize u8 u16 u32 u6 /// The *predecessor* operation moves towards values that compare lesser. #[unstable(feature = "step_trait", issue = "42168")] pub trait Step: Clone + PartialOrd + Sized { - /// Returns the number of *successor* steps required to get from `start` to `end`. + /// Returns the bounds on the number of *successor* steps required to get from `start` to `end` + /// like [`Iterator::size_hint()`][Iterator::size_hint()]. /// - /// Returns `None` if the number of steps would overflow `usize` - /// (or is infinite, or if `end` would never be reached). + /// Returns `(usize::MAX, None)` if the number of steps would overflow `usize`, or is infinite. /// /// # Invariants /// /// For any `a`, `b`, and `n`: /// - /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::forward_checked(&a, n) == Some(b)` - /// * `steps_between(&a, &b) == Some(n)` if and only if `Step::backward_checked(&b, n) == Some(a)` - /// * `steps_between(&a, &b) == Some(n)` only if `a <= b` - /// * Corollary: `steps_between(&a, &b) == Some(0)` if and only if `a == b` - /// * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`; - /// this is the case when it would require more than `usize::MAX` steps to get to `b` - /// * `steps_between(&a, &b) == None` if `a > b` - fn steps_between(start: &Self, end: &Self) -> Option; + /// * `steps_between(&a, &b) == (n, Some(n))` if and only if `Step::forward_checked(&a, n) == Some(b)` + /// * `steps_between(&a, &b) == (n, Some(n))` if and only if `Step::backward_checked(&b, n) == Some(a)` + /// * `steps_between(&a, &b) == (n, Some(n))` only if `a <= b` + /// * Corollary: `steps_between(&a, &b) == (0, Some(0))` if and only if `a == b` + /// * `steps_between(&a, &b) == (0, None)` if `a > b` + fn steps_between(start: &Self, end: &Self) -> (usize, Option); /// Returns the value that would be obtained by taking the *successor* /// of `self` `count` times. @@ -169,7 +167,7 @@ pub trait Step: Clone + PartialOrd + Sized { /// For any `a`: /// /// * if there exists `b` such that `b < a`, it is safe to call `Step::backward_unchecked(a, 1)` - /// * if there exists `b`, `n` such that `steps_between(&b, &a) == Some(n)`, + /// * if there exists `b`, `n` such that `steps_between(&b, &a) == (n, Some(n))`, /// it is safe to call `Step::backward_unchecked(a, m)` for any `m <= n`. /// * Corollary: `Step::backward_unchecked(a, 0)` is always safe. /// @@ -261,12 +259,13 @@ macro_rules! step_integer_impls { step_unsigned_methods!(); #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { + fn steps_between(start: &Self, end: &Self) -> (usize, Option) { if *start <= *end { // This relies on $u_narrower <= usize - Some((*end - *start) as usize) + let steps = (*end - *start) as usize; + (steps, Some(steps)) } else { - None + (0, None) } } @@ -294,16 +293,17 @@ macro_rules! step_integer_impls { step_signed_methods!($u_narrower); #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { + fn steps_between(start: &Self, end: &Self) -> (usize, Option) { if *start <= *end { // This relies on $i_narrower <= usize // // Casting to isize extends the width but preserves the sign. // Use wrapping_sub in isize space and cast to usize to compute // the difference that might not fit inside the range of isize. - Some((*end as isize).wrapping_sub(*start as isize) as usize) + let steps = (*end as isize).wrapping_sub(*start as isize) as usize; + (steps, Some(steps)) } else { - None + (0, None) } } @@ -359,11 +359,15 @@ macro_rules! step_integer_impls { step_unsigned_methods!(); #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { + fn steps_between(start: &Self, end: &Self) -> (usize, Option) { if *start <= *end { - usize::try_from(*end - *start).ok() + if let Ok(steps) = usize::try_from(*end - *start) { + (steps, Some(steps)) + } else { + (usize::MAX, None) + } } else { - None + (0, None) } } @@ -385,16 +389,22 @@ macro_rules! step_integer_impls { step_signed_methods!($u_wider); #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { + fn steps_between(start: &Self, end: &Self) -> (usize, Option) { if *start <= *end { match end.checked_sub(*start) { - Some(result) => usize::try_from(result).ok(), + Some(result) => { + if let Ok(steps) = usize::try_from(result) { + (steps, Some(steps)) + } else { + (usize::MAX, None) + } + } // If the difference is too big for e.g. i128, // it's also gonna be too big for usize with fewer bits. - None => None, + None => (usize::MAX, None), } } else { - None + (0, None) } } @@ -433,18 +443,26 @@ step_integer_impls! { #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] impl Step for char { #[inline] - fn steps_between(&start: &char, &end: &char) -> Option { + fn steps_between(&start: &char, &end: &char) -> (usize, Option) { let start = start as u32; let end = end as u32; if start <= end { let count = end - start; if start < 0xD800 && 0xE000 <= end { - usize::try_from(count - 0x800).ok() + if let Ok(steps) = usize::try_from(count - 0x800) { + (steps, Some(steps)) + } else { + (usize::MAX, None) + } } else { - usize::try_from(count).ok() + if let Ok(steps) = usize::try_from(count) { + (steps, Some(steps)) + } else { + (usize::MAX, None) + } } } else { - None + (0, None) } } @@ -512,7 +530,7 @@ impl Step for char { #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] impl Step for AsciiChar { #[inline] - fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> Option { + fn steps_between(&start: &AsciiChar, &end: &AsciiChar) -> (usize, Option) { Step::steps_between(&start.to_u8(), &end.to_u8()) } @@ -554,7 +572,7 @@ impl Step for AsciiChar { #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] impl Step for Ipv4Addr { #[inline] - fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> Option { + fn steps_between(&start: &Ipv4Addr, &end: &Ipv4Addr) -> (usize, Option) { u32::steps_between(&start.to_bits(), &end.to_bits()) } @@ -586,7 +604,7 @@ impl Step for Ipv4Addr { #[unstable(feature = "step_trait", reason = "recently redesigned", issue = "42168")] impl Step for Ipv6Addr { #[inline] - fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> Option { + fn steps_between(&start: &Ipv6Addr, &end: &Ipv6Addr) -> (usize, Option) { u128::steps_between(&start.to_bits(), &end.to_bits()) } @@ -690,11 +708,8 @@ impl RangeIteratorImpl for ops::Range { #[inline] default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero> { - let available = if self.start <= self.end { - Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) - } else { - 0 - }; + let steps = Step::steps_between(&self.start, &self.end); + let available = steps.1.unwrap_or(steps.0); let taken = available.min(n); @@ -731,11 +746,8 @@ impl RangeIteratorImpl for ops::Range { #[inline] default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { - let available = if self.start <= self.end { - Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) - } else { - 0 - }; + let steps = Step::steps_between(&self.start, &self.end); + let available = steps.1.unwrap_or(steps.0); let taken = available.min(n); @@ -775,11 +787,8 @@ impl RangeIteratorImpl for ops::Range { #[inline] fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZero> { - let available = if self.start <= self.end { - Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) - } else { - 0 - }; + let steps = Step::steps_between(&self.start, &self.end); + let available = steps.1.unwrap_or(steps.0); let taken = available.min(n); @@ -819,11 +828,8 @@ impl RangeIteratorImpl for ops::Range { #[inline] fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZero> { - let available = if self.start <= self.end { - Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) - } else { - 0 - }; + let steps = Step::steps_between(&self.start, &self.end); + let available = steps.1.unwrap_or(steps.0); let taken = available.min(n); @@ -846,8 +852,7 @@ impl Iterator for ops::Range { #[inline] fn size_hint(&self) -> (usize, Option) { if self.start < self.end { - let hint = Step::steps_between(&self.start, &self.end); - (hint.unwrap_or(usize::MAX), hint) + Step::steps_between(&self.start, &self.end) } else { (0, Some(0)) } @@ -856,7 +861,7 @@ impl Iterator for ops::Range { #[inline] fn count(self) -> usize { if self.start < self.end { - Step::steps_between(&self.start, &self.end).expect("count overflowed usize") + Step::steps_between(&self.start, &self.end).1.expect("count overflowed usize") } else { 0 } @@ -980,11 +985,11 @@ impl DoubleEndedIterator for ops::Range { // Safety: // The following invariants for `Step::steps_between` exist: // -// > * `steps_between(&a, &b) == Some(n)` only if `a <= b` -// > * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != None`; +// > * `steps_between(&a, &b) == (n, Some(n))` only if `a <= b` +// > * Note that `a <= b` does _not_ imply `steps_between(&a, &b) != (n, None)`; // > this is the case when it would require more than `usize::MAX` steps to // > get to `b` -// > * `steps_between(&a, &b) == None` if `a > b` +// > * `steps_between(&a, &b) == (0, None)` if `a > b` // // The first invariant is what is generally required for `TrustedLen` to be // sound. The note addendum satisfies an additional `TrustedLen` invariant. @@ -1253,10 +1258,8 @@ impl Iterator for ops::RangeInclusive { return (0, Some(0)); } - match Step::steps_between(&self.start, &self.end) { - Some(hint) => (hint.saturating_add(1), hint.checked_add(1)), - None => (usize::MAX, None), - } + let hint = Step::steps_between(&self.start, &self.end); + (hint.0.saturating_add(1), hint.1.and_then(|steps| steps.checked_add(1))) } #[inline] @@ -1266,6 +1269,7 @@ impl Iterator for ops::RangeInclusive { } Step::steps_between(&self.start, &self.end) + .1 .and_then(|steps| steps.checked_add(1)) .expect("count overflowed usize") } diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs index d3360c1820719..6746f0b2b316b 100644 --- a/library/core/src/net/ip_addr.rs +++ b/library/core/src/net/ip_addr.rs @@ -1594,16 +1594,15 @@ impl Ipv6Addr { /// # Examples /// /// ``` - /// #![feature(ip)] - /// /// use std::net::Ipv6Addr; /// /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff).is_unique_local(), false); /// assert_eq!(Ipv6Addr::new(0xfc02, 0, 0, 0, 0, 0, 0, 0).is_unique_local(), true); /// ``` - #[unstable(feature = "ip", issue = "27709")] #[must_use] #[inline] + #[stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] pub const fn is_unique_local(&self) -> bool { (self.segments()[0] & 0xfe00) == 0xfc00 } @@ -1665,8 +1664,6 @@ impl Ipv6Addr { /// # Examples /// /// ``` - /// #![feature(ip)] - /// /// use std::net::Ipv6Addr; /// /// // The loopback address (`::1`) does not actually have link-local scope. @@ -1680,9 +1677,10 @@ impl Ipv6Addr { /// assert_eq!(Ipv6Addr::new(0xfe80, 0, 0, 1, 0, 0, 0, 0).is_unicast_link_local(), true); /// assert_eq!(Ipv6Addr::new(0xfe81, 0, 0, 0, 0, 0, 0, 0).is_unicast_link_local(), true); /// ``` - #[unstable(feature = "ip", issue = "27709")] #[must_use] #[inline] + #[stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "ipv6_is_unique_local", since = "CURRENT_RUSTC_VERSION")] pub const fn is_unicast_link_local(&self) -> bool { (self.segments()[0] & 0xffc0) == 0xfe80 } diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 318bb8ee4cda2..8f3694de94884 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2101,6 +2101,7 @@ macro_rules! int_impl { /// /// ``` #[doc = concat!("assert_eq!(100", stringify!($SelfT), ".wrapping_neg(), -100);")] + #[doc = concat!("assert_eq!(-100", stringify!($SelfT), ".wrapping_neg(), 100);")] #[doc = concat!("assert_eq!(", stringify!($SelfT), "::MIN.wrapping_neg(), ", stringify!($SelfT), "::MIN);")] /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] diff --git a/library/core/tests/iter/traits/step.rs b/library/core/tests/iter/traits/step.rs index 3d82a40cd2941..bf935af397c71 100644 --- a/library/core/tests/iter/traits/step.rs +++ b/library/core/tests/iter/traits/step.rs @@ -2,26 +2,37 @@ use core::iter::*; #[test] fn test_steps_between() { - assert_eq!(Step::steps_between(&20_u8, &200_u8), Some(180_usize)); - assert_eq!(Step::steps_between(&-20_i8, &80_i8), Some(100_usize)); - assert_eq!(Step::steps_between(&-120_i8, &80_i8), Some(200_usize)); - assert_eq!(Step::steps_between(&20_u32, &4_000_100_u32), Some(4_000_080_usize)); - assert_eq!(Step::steps_between(&-20_i32, &80_i32), Some(100_usize)); - assert_eq!(Step::steps_between(&-2_000_030_i32, &2_000_050_i32), Some(4_000_080_usize)); + assert_eq!(Step::steps_between(&20_u8, &200_u8), (180_usize, Some(180_usize))); + assert_eq!(Step::steps_between(&-20_i8, &80_i8), (100_usize, Some(100_usize))); + assert_eq!(Step::steps_between(&-120_i8, &80_i8), (200_usize, Some(200_usize))); + assert_eq!( + Step::steps_between(&20_u32, &4_000_100_u32), + (4_000_080_usize, Some(4_000_080_usize)) + ); + assert_eq!(Step::steps_between(&-20_i32, &80_i32), (100_usize, Some(100_usize))); + assert_eq!( + Step::steps_between(&-2_000_030_i32, &2_000_050_i32), + (4_000_080_usize, Some(4_000_080_usize)) + ); // Skip u64/i64 to avoid differences with 32-bit vs 64-bit platforms - assert_eq!(Step::steps_between(&20_u128, &200_u128), Some(180_usize)); - assert_eq!(Step::steps_between(&-20_i128, &80_i128), Some(100_usize)); + assert_eq!(Step::steps_between(&20_u128, &200_u128), (180_usize, Some(180_usize))); + assert_eq!(Step::steps_between(&-20_i128, &80_i128), (100_usize, Some(100_usize))); if cfg!(target_pointer_width = "64") { - assert_eq!(Step::steps_between(&10_u128, &0x1_0000_0000_0000_0009_u128), Some(usize::MAX)); + assert_eq!( + Step::steps_between(&10_u128, &0x1_0000_0000_0000_0009_u128), + (usize::MAX, Some(usize::MAX)) + ); } - assert_eq!(Step::steps_between(&10_u128, &0x1_0000_0000_0000_000a_u128), None); - assert_eq!(Step::steps_between(&10_i128, &0x1_0000_0000_0000_000a_i128), None); + assert_eq!(Step::steps_between(&10_u128, &0x1_0000_0000_0000_000a_u128), (usize::MAX, None)); + assert_eq!(Step::steps_between(&10_i128, &0x1_0000_0000_0000_000a_i128), (usize::MAX, None)); assert_eq!( Step::steps_between(&-0x1_0000_0000_0000_0000_i128, &0x1_0000_0000_0000_0000_i128,), - None, + (usize::MAX, None), ); + + assert_eq!(Step::steps_between(&100_u32, &10_u32), (0, None)); } #[test] diff --git a/library/std/src/env.rs b/library/std/src/env.rs index d732a15117e9e..27f4daba44bf6 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -653,19 +653,28 @@ pub fn home_dir() -> Option { /// may result in "insecure temporary file" security vulnerabilities. Consider /// using a crate that securely creates temporary files or directories. /// +/// Note that the returned value may be a symbolic link, not a directory. +/// /// # Platform-specific behavior /// /// On Unix, returns the value of the `TMPDIR` environment variable if it is -/// set, otherwise for non-Android it returns `/tmp`. On Android, since there -/// is no global temporary folder (it is usually allocated per-app), it returns -/// `/data/local/tmp`. +/// set, otherwise the value is OS-specific: +/// - On Android, there is no global temporary folder (it is usually allocated +/// per-app), it returns `/data/local/tmp`. +/// - On Darwin-based OSes (macOS, iOS, etc) it returns the directory provided +/// by `confstr(_CS_DARWIN_USER_TEMP_DIR, ...)`, as recommended by [Apple's +/// security guidelines][appledoc]. +/// - On all other unix-based OSes, it returns `/tmp`. +/// /// On Windows, the behavior is equivalent to that of [`GetTempPath2`][GetTempPath2] / /// [`GetTempPath`][GetTempPath], which this function uses internally. +/// /// Note that, this [may change in the future][changes]. /// /// [changes]: io#platform-specific-behavior /// [GetTempPath2]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppath2a /// [GetTempPath]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha +/// [appledoc]: https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html#//apple_ref/doc/uid/TP40002585-SW10 /// /// ```no_run /// use std::env; diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs index f983d174ed61c..9b0b2500daf61 100644 --- a/library/std/src/sys/pal/unix/os.rs +++ b/library/std/src/sys/pal/unix/os.rs @@ -698,12 +698,81 @@ pub fn page_size() -> usize { unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } } +// Returns the value for [`confstr(key, ...)`][posix_confstr]. Currently only +// used on Darwin, but should work on any unix (in case we need to get +// `_CS_PATH` or `_CS_V[67]_ENV` in the future). +// +// [posix_confstr]: +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/confstr.html +#[cfg(target_vendor = "apple")] +fn confstr(key: c_int, size_hint: Option) -> io::Result { + let mut buf: Vec = Vec::with_capacity(0); + let mut bytes_needed_including_nul = size_hint + .unwrap_or_else(|| { + // Treat "None" as "do an extra call to get the length". In theory + // we could move this into the loop below, but it's hard to do given + // that it isn't 100% clear if it's legal to pass 0 for `len` when + // the buffer isn't null. + unsafe { libc::confstr(key, core::ptr::null_mut(), 0) } + }) + .max(1); + // If the value returned by `confstr` is greater than the len passed into + // it, then the value was truncated, meaning we need to retry. Note that + // while `confstr` results don't seem to change for a process, it's unclear + // if this is guaranteed anywhere, so looping does seem required. + while bytes_needed_including_nul > buf.capacity() { + // We write into the spare capacity of `buf`. This lets us avoid + // changing buf's `len`, which both simplifies `reserve` computation, + // allows working with `Vec` instead of `Vec>`, and + // may avoid a copy, since the Vec knows that none of the bytes are needed + // when reallocating (well, in theory anyway). + buf.reserve(bytes_needed_including_nul); + // `confstr` returns + // - 0 in the case of errors: we break and return an error. + // - The number of bytes written, iff the provided buffer is enough to + // hold the entire value: we break and return the data in `buf`. + // - Otherwise, the number of bytes needed (including nul): we go + // through the loop again. + bytes_needed_including_nul = + unsafe { libc::confstr(key, buf.as_mut_ptr().cast::(), buf.capacity()) }; + } + // `confstr` returns 0 in the case of an error. + if bytes_needed_including_nul == 0 { + return Err(io::Error::last_os_error()); + } + // Safety: `confstr(..., buf.as_mut_ptr(), buf.capacity())` returned a + // non-zero value, meaning `bytes_needed_including_nul` bytes were + // initialized. + unsafe { + buf.set_len(bytes_needed_including_nul); + // Remove the NUL-terminator. + let last_byte = buf.pop(); + // ... and smoke-check that it *was* a NUL-terminator. + assert_eq!(last_byte, Some(0), "`confstr` provided a string which wasn't nul-terminated"); + }; + Ok(OsString::from_vec(buf)) +} + +#[cfg(target_vendor = "apple")] +fn darwin_temp_dir() -> PathBuf { + confstr(libc::_CS_DARWIN_USER_TEMP_DIR, Some(64)).map(PathBuf::from).unwrap_or_else(|_| { + // It failed for whatever reason (there are several possible reasons), + // so return the global one. + PathBuf::from("/tmp") + }) +} + pub fn temp_dir() -> PathBuf { crate::env::var_os("TMPDIR").map(PathBuf::from).unwrap_or_else(|| { - if cfg!(target_os = "android") { - PathBuf::from("/data/local/tmp") - } else { - PathBuf::from("/tmp") + cfg_if::cfg_if! { + // FIXME: Support `confstr` in Miri. + if #[cfg(all(target_vendor = "apple", not(miri)))] { + darwin_temp_dir() + } else if #[cfg(target_os = "android")] { + PathBuf::from("/data/local/tmp") + } else { + PathBuf::from("/tmp") + } } }) } diff --git a/library/std/src/sys/pal/unix/os/tests.rs b/library/std/src/sys/pal/unix/os/tests.rs index efc29955b05fe..a84086037ce0b 100644 --- a/library/std/src/sys/pal/unix/os/tests.rs +++ b/library/std/src/sys/pal/unix/os/tests.rs @@ -21,3 +21,28 @@ fn test_parse_glibc_version() { assert_eq!(parsed, super::parse_glibc_version(version_str)); } } + +// Smoke check `confstr`, do it for several hint values, to ensure our resizing +// logic is correct. +#[test] +#[cfg(target_vendor = "apple")] +fn test_confstr() { + for key in [libc::_CS_DARWIN_USER_TEMP_DIR, libc::_CS_PATH] { + let value_nohint = super::confstr(key, None).unwrap_or_else(|e| { + panic!("confstr({key}, None) failed: {e:?}"); + }); + let end = (value_nohint.len() + 1) * 2; + for hint in 0..end { + assert_eq!( + super::confstr(key, Some(hint)).as_deref().ok(), + Some(&*value_nohint), + "confstr({key}, Some({hint})) failed", + ); + } + } + // Smoke check that we don't loop forever or something if the input was not valid. + for hint in [None, Some(0), Some(1)] { + let hopefully_invalid = 123456789_i32; + assert!(super::confstr(hopefully_invalid, hint).is_err()); + } +} diff --git a/library/std/src/sys/random/arc4random.rs b/library/std/src/sys/random/arc4random.rs index ffabaafbee803..32467e9ebaa64 100644 --- a/library/std/src/sys/random/arc4random.rs +++ b/library/std/src/sys/random/arc4random.rs @@ -12,7 +12,6 @@ #[cfg(not(any( target_os = "haiku", target_os = "illumos", - target_os = "rtems", target_os = "solaris", target_os = "vita", )))] @@ -22,7 +21,6 @@ use libc::arc4random_buf; #[cfg(any( target_os = "haiku", // See https://git.haiku-os.org/haiku/tree/headers/compatibility/bsd/stdlib.h target_os = "illumos", // See https://www.illumos.org/man/3C/arc4random - target_os = "rtems", // See https://docs.rtems.org/branches/master/bsp-howto/getentropy.html target_os = "solaris", // See https://docs.oracle.com/cd/E88353_01/html/E37843/arc4random-3c.html target_os = "vita", // See https://github.com/vitasdk/newlib/blob/b89e5bc183b516945f9ee07eef483ecb916e45ff/newlib/libc/include/stdlib.h#L74 ))] diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 0216ac811621c..a636c4a9ef131 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1023,7 +1023,7 @@ impl Step for PlainSourceTarball { let mut cmd = command(&builder.initial_cargo); cmd.arg("vendor").arg("--versioned-dirs"); - for p in default_paths_to_vendor(builder) { + for (p, _) in default_paths_to_vendor(builder) { cmd.arg("--sync").arg(p); } diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 82a6b4d4f28cb..ce044c4a4a7a4 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -4,24 +4,26 @@ use crate::core::build_steps::tool::SUBMODULES_FOR_RUSTBOOK; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::utils::exec::command; -/// List of default paths used for vendoring for `x vendor` and dist tarballs. -pub fn default_paths_to_vendor(builder: &Builder<'_>) -> Vec { - let mut paths = vec![]; - for p in [ - "src/tools/cargo/Cargo.toml", - "src/tools/rust-analyzer/Cargo.toml", - "compiler/rustc_codegen_cranelift/Cargo.toml", - "compiler/rustc_codegen_gcc/Cargo.toml", - "library/Cargo.toml", - "src/bootstrap/Cargo.toml", - "src/tools/rustbook/Cargo.toml", - "src/tools/rustc-perf/Cargo.toml", - "src/tools/opt-dist/Cargo.toml", - ] { - paths.push(builder.src.join(p)); - } - - paths +/// Returns the cargo workspaces to vendor for `x vendor` and dist tarballs. +/// +/// Returns a `Vec` of `(path_to_manifest, submodules_required)` where +/// `path_to_manifest` is the cargo workspace, and `submodules_required` is +/// the set of submodules that must be available. +pub fn default_paths_to_vendor(builder: &Builder<'_>) -> Vec<(PathBuf, Vec<&'static str>)> { + [ + ("src/tools/cargo/Cargo.toml", vec!["src/tools/cargo"]), + ("src/tools/rust-analyzer/Cargo.toml", vec![]), + ("compiler/rustc_codegen_cranelift/Cargo.toml", vec![]), + ("compiler/rustc_codegen_gcc/Cargo.toml", vec![]), + ("library/Cargo.toml", vec![]), + ("src/bootstrap/Cargo.toml", vec![]), + ("src/tools/rustbook/Cargo.toml", SUBMODULES_FOR_RUSTBOOK.into()), + ("src/tools/rustc-perf/Cargo.toml", vec!["src/tools/rustc-perf"]), + ("src/tools/opt-dist/Cargo.toml", vec![]), + ] + .into_iter() + .map(|(path, submodules)| (builder.src.join(path), submodules)) + .collect() } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -56,13 +58,16 @@ impl Step for Vendor { cmd.arg("--versioned-dirs"); } + let to_vendor = default_paths_to_vendor(builder); // These submodules must be present for `x vendor` to work. - for submodule in SUBMODULES_FOR_RUSTBOOK.iter().chain(["src/tools/cargo"].iter()) { - builder.build.require_submodule(submodule, None); + for (_, submodules) in &to_vendor { + for submodule in submodules { + builder.build.require_submodule(submodule, None); + } } // Sync these paths by default. - for p in default_paths_to_vendor(builder) { + for (p, _) in &to_vendor { cmd.arg("--sync").arg(p); } diff --git a/tests/crashes/124350.rs b/tests/crashes/124350.rs deleted file mode 100644 index d6038f280cf81..0000000000000 --- a/tests/crashes/124350.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #124350 - -struct Node {} - -impl Node -where - SmallVec<{ D * 2 }>:, -{ - fn new() -> Self { - let mut node = Node::new(); - (&a, 0)(); - - node - } -} - -struct SmallVec {} diff --git a/tests/crashes/125758.rs b/tests/crashes/125758.rs deleted file mode 100644 index 86c3b80abab9d..0000000000000 --- a/tests/crashes/125758.rs +++ /dev/null @@ -1,26 +0,0 @@ -//@ known-bug: rust-lang/rust#125758 -#![feature(impl_trait_in_assoc_type)] - -trait Trait: Sized { - type Assoc2; -} - -impl Trait for Bar { - type Assoc2 = impl std::fmt::Debug; -} - -struct Foo { - field: ::Assoc2, -} - -enum Bar { - C = 42, - D = 99, -} - -static BAR: u8 = 42; - -static FOO2: (&Foo, &::Assoc2) = - unsafe { (std::mem::transmute(&BAR), std::mem::transmute(&BAR)) }; - -fn main() {} diff --git a/tests/crashes/127351.rs b/tests/crashes/127351.rs deleted file mode 100644 index e3f415948852d..0000000000000 --- a/tests/crashes/127351.rs +++ /dev/null @@ -1,17 +0,0 @@ -//@ known-bug: #127351 -#![feature(lazy_type_alias)] -#![allow(incomplete_features)] - -struct Outer0<'a, T>(ExplicitTypeOutlives<'a, T>); -type ExplicitTypeOutlives<'a, T: 'a> = (&'a (), T); - -pub struct Warns { - _significant_drop: ExplicitTypeOutlives, - field: String, -} - -pub fn test(w: Warns) { - _ = || drop(w.field); -} - -fn main() {} diff --git a/tests/crashes/127353.rs b/tests/crashes/127353.rs deleted file mode 100644 index 9bcb90b5c57f8..0000000000000 --- a/tests/crashes/127353.rs +++ /dev/null @@ -1,18 +0,0 @@ -//@ known-bug: #127353 -#![feature(type_alias_impl_trait)] -trait Trait {} -type Alias<'a, U> = impl Trait; - -fn f<'a>() -> Alias<'a, ()> {} - -pub enum UninhabitedVariants { - Tuple(Alias), -} - -struct A; - -fn cannot_empty_match_on_enum_with_empty_variants_struct_to_anything(x: UninhabitedVariants) -> A { - match x {} -} - -fn main() {} diff --git a/tests/crashes/127742.rs b/tests/crashes/127742.rs deleted file mode 100644 index 24add45413566..0000000000000 --- a/tests/crashes/127742.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #127742 -struct Vtable(dyn Cap); // missing lifetime - -trait Cap<'a> {} - -union Transmute { - t: u64, // ICEs with u64, u128, or usize. Correctly errors with u32. - u: &'static Vtable, -} - -const G: &'static Vtable = unsafe { Transmute { t: 1 }.u }; diff --git a/tests/crashes/130521.rs b/tests/crashes/130521.rs index 7c078ab579094..ccc2b444b822a 100644 --- a/tests/crashes/130521.rs +++ b/tests/crashes/130521.rs @@ -6,7 +6,7 @@ struct Vtable(dyn Cap); trait Cap<'a> {} union Transmute { - t: u64, + t: u128, u: &'static Vtable, } diff --git a/tests/ui/codemap_tests/huge_multispan_highlight.rs b/tests/ui/codemap_tests/huge_multispan_highlight.rs index 7d7b757082350..6f6834b01bd61 100644 --- a/tests/ui/codemap_tests/huge_multispan_highlight.rs +++ b/tests/ui/codemap_tests/huge_multispan_highlight.rs @@ -1,7 +1,7 @@ //@ revisions: ascii unicode //@ compile-flags: --color=always //@[ascii] compile-flags: --error-format=human -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode //@ ignore-windows fn main() { let _ = match true { diff --git a/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs b/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs new file mode 100644 index 0000000000000..1af6d5742b1f6 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/bad-multiply.rs @@ -0,0 +1,18 @@ +// regression test for #124350 + +struct Node {} + +impl Node +where + SmallVec<{ D * 2 }>:, + //~^ ERROR generic parameters may not be used in const operations + //~| ERROR constant provided when a type was expected +{ + fn new() -> Self { + Node::new() + } +} + +struct SmallVec(T1); + +fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr new file mode 100644 index 0000000000000..a8d6cebabe718 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/bad-multiply.stderr @@ -0,0 +1,18 @@ +error: generic parameters may not be used in const operations + --> $DIR/bad-multiply.rs:7:16 + | +LL | SmallVec<{ D * 2 }>:, + | ^ cannot perform const operation using `D` + | + = help: const parameters may only be used as standalone arguments, i.e. `D` + = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions + +error[E0747]: constant provided when a type was expected + --> $DIR/bad-multiply.rs:7:14 + | +LL | SmallVec<{ D * 2 }>:, + | ^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/const-generics/kind_mismatch.rs b/tests/ui/const-generics/kind_mismatch.rs index bab58d5952a5f..ecdc01a5ef901 100644 --- a/tests/ui/const-generics/kind_mismatch.rs +++ b/tests/ui/const-generics/kind_mismatch.rs @@ -20,5 +20,4 @@ pub fn remove_key>() -> S { fn main() { let map: KeyHolder<0> = remove_key::<_, _>(); - //~^ ERROR: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied } diff --git a/tests/ui/const-generics/kind_mismatch.stderr b/tests/ui/const-generics/kind_mismatch.stderr index e13bc6ee058d0..1487b18961986 100644 --- a/tests/ui/const-generics/kind_mismatch.stderr +++ b/tests/ui/const-generics/kind_mismatch.stderr @@ -14,26 +14,6 @@ LL | impl ContainsKey for KeyHolder {} | | | help: consider changing this type parameter to a const parameter: `const K: u8` -error[E0277]: the trait bound `KeyHolder<0>: SubsetExcept<_>` is not satisfied - --> $DIR/kind_mismatch.rs:22:45 - | -LL | let map: KeyHolder<0> = remove_key::<_, _>(); - | ^ the trait `ContainsKey<0>` is not implemented for `KeyHolder<0>` - | -note: required for `KeyHolder<0>` to implement `SubsetExcept<_>` - --> $DIR/kind_mismatch.rs:15:28 - | -LL | impl> SubsetExcept

for T {} - | -------------- ^^^^^^^^^^^^^^^ ^ - | | - | unsatisfied trait bound introduced here -note: required by a bound in `remove_key` - --> $DIR/kind_mismatch.rs:17:25 - | -LL | pub fn remove_key>() -> S { - | ^^^^^^^^^^^^^^^ required by this bound in `remove_key` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0277, E0747. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs index ce41ad2952bc9..dedae4365e889 100644 --- a/tests/ui/diagnostic-width/E0271.rs +++ b/tests/ui/diagnostic-width/E0271.rs @@ -1,6 +1,6 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=40 -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=40 +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" trait Future { type Error; diff --git a/tests/ui/diagnostic-width/flag-human.rs b/tests/ui/diagnostic-width/flag-human.rs index 1af4165914164..8e656293b4102 100644 --- a/tests/ui/diagnostic-width/flag-human.rs +++ b/tests/ui/diagnostic-width/flag-human.rs @@ -1,6 +1,6 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=20 -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode --diagnostic-width=20 +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=20 // This test checks that `-Z output-width` effects the human error output by restricting it to an // arbitrarily low value so that the effect is visible. diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs index 73f81f5872a64..695852f83ac0a 100644 --- a/tests/ui/diagnostic-width/long-E0308.rs +++ b/tests/ui/diagnostic-width/long-E0308.rs @@ -1,6 +1,6 @@ //@ revisions: ascii unicode //@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes -//@[unicode] compile-flags: -Zunstable-options=yes --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes +//@[unicode] compile-flags: -Zunstable-options --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash" mod a { diff --git a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs index 61c4b31e03a62..e630db8ba42a2 100644 --- a/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs +++ b/tests/ui/diagnostic-width/non-1-width-unicode-multiline-label.rs @@ -1,5 +1,5 @@ //@ revisions: ascii unicode -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode // ignore-tidy-linelength fn main() { diff --git a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs index 283506bd6c90d..de2f42a4a7292 100644 --- a/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs +++ b/tests/ui/diagnostic-width/non-whitespace-trimming-2.rs @@ -1,5 +1,5 @@ //@ revisions: ascii unicode -//@[unicode] compile-flags: -Zunstable-options=yes --error-format=human-unicode +//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode // ignore-tidy-linelength fn main() { diff --git a/tests/ui/error-emitter/unicode-output.rs b/tests/ui/error-emitter/unicode-output.rs index ba6db37b66c22..5c083c4e57508 100644 --- a/tests/ui/error-emitter/unicode-output.rs +++ b/tests/ui/error-emitter/unicode-output.rs @@ -1,4 +1,4 @@ -//@ compile-flags: -Zunstable-options=yes --error-format=human-unicode --color=always +//@ compile-flags: -Zunstable-options --error-format=human-unicode --color=always //@ edition:2018 //@ only-linux diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs index b33fda8e15443..7fffe312f4b7b 100644 --- a/tests/ui/generic-associated-types/issue-71176.rs +++ b/tests/ui/generic-associated-types/issue-71176.rs @@ -16,6 +16,8 @@ struct Holder { fn main() { Holder { - inner: Box::new(()), //~ ERROR: the trait `Provider` cannot be made into an object + inner: Box::new(()), + //~^ ERROR: the trait `Provider` cannot be made into an object + //~| ERROR: the trait `Provider` cannot be made into an object }; } diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr index 15d5a3df6f276..1cd2ed0d313dc 100644 --- a/tests/ui/generic-associated-types/issue-71176.stderr +++ b/tests/ui/generic-associated-types/issue-71176.stderr @@ -80,7 +80,24 @@ LL | type A<'a>; = help: consider moving `A` to another trait = help: only type `()` implements the trait, consider using it directly instead -error: aborting due to 5 previous errors +error[E0038]: the trait `Provider` cannot be made into an object + --> $DIR/issue-71176.rs:19:16 + | +LL | inner: Box::new(()), + | ^^^^^^^^^^^^ `Provider` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-71176.rs:2:10 + | +LL | trait Provider { + | -------- this trait cannot be made into an object... +LL | type A<'a>; + | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait + = help: only type `()` implements the trait, consider using it directly instead + = note: required for the cast from `Box<()>` to `Box<(dyn Provider = _> + 'static), {type error}>` + +error: aborting due to 6 previous errors Some errors have detailed explanations: E0038, E0107. For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/impl-trait/example-calendar.rs b/tests/ui/impl-trait/example-calendar.rs index 1dadc5dfcb3ef..c3c01f0103669 100644 --- a/tests/ui/impl-trait/example-calendar.rs +++ b/tests/ui/impl-trait/example-calendar.rs @@ -156,7 +156,7 @@ impl<'a, 'b> std::ops::Add<&'b NaiveDate> for &'a NaiveDate { } impl std::iter::Step for NaiveDate { - fn steps_between(_: &Self, _: &Self) -> Option { + fn steps_between(_: &Self, _: &Self) -> (usize, Option) { unimplemented!() } diff --git a/tests/ui/issues/issue-48006.rs b/tests/ui/issues/issue-48006.rs index e48146d07bc14..1adc76f2a2641 100644 --- a/tests/ui/issues/issue-48006.rs +++ b/tests/ui/issues/issue-48006.rs @@ -6,10 +6,10 @@ use std::iter::Step; #[cfg(target_pointer_width = "16")] fn main() { - assert!(Step::steps_between(&0u32, &u32::MAX).is_none()); + assert!(Step::steps_between(&0u32, &u32::MAX).1.is_none()); } #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))] fn main() { - assert!(Step::steps_between(&0u32, &u32::MAX).is_some()); + assert!(Step::steps_between(&0u32, &u32::MAX).1.is_some()); } diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.rs b/tests/ui/layout/ice-type-error-in-tail-124031.rs index 0a2be11740358..ecd6f3d56f3f4 100644 --- a/tests/ui/layout/ice-type-error-in-tail-124031.rs +++ b/tests/ui/layout/ice-type-error-in-tail-124031.rs @@ -1,3 +1,5 @@ +//@ normalize-stderr-test: "\d+ bits" -> "$$BITS bits" + // Regression test for issue #124031 // Checks that we don't ICE when the tail // of an ADT has a type error @@ -16,5 +18,6 @@ struct Other { fn main() { unsafe { std::mem::transmute::, Option<&Other>>(None); + //~^ ERROR cannot transmute between types of different sizes } } diff --git a/tests/ui/layout/ice-type-error-in-tail-124031.stderr b/tests/ui/layout/ice-type-error-in-tail-124031.stderr index 57dc83f92dfda..a066e8574dc50 100644 --- a/tests/ui/layout/ice-type-error-in-tail-124031.stderr +++ b/tests/ui/layout/ice-type-error-in-tail-124031.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `RefTarget` - --> $DIR/ice-type-error-in-tail-124031.rs:9:1 + --> $DIR/ice-type-error-in-tail-124031.rs:11:1 | LL | type RefTarget; | -------------- `RefTarget` from trait @@ -7,6 +7,16 @@ LL | type RefTarget; LL | impl Trait for () {} | ^^^^^^^^^^^^^^^^^ missing `RefTarget` in implementation -error: aborting due to 1 previous error +error[E0512]: cannot transmute between types of different sizes, or dependently-sized types + --> $DIR/ice-type-error-in-tail-124031.rs:20:9 + | +LL | std::mem::transmute::, Option<&Other>>(None); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: source type: `Option<()>` ($BITS bits) + = note: target type: `Option<&Other>` ($BITS bits) + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0046`. +Some errors have detailed explanations: E0046, E0512. +For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs new file mode 100644 index 0000000000000..6ded9118700c0 --- /dev/null +++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.rs @@ -0,0 +1,18 @@ +// regression test for #127351 + +#![feature(lazy_type_alias)] +//~^ WARN the feature `lazy_type_alias` is incomplete + +type ExplicitTypeOutlives = T; + +pub struct Warns { + _significant_drop: ExplicitTypeOutlives, + //~^ ERROR missing generics for type alias `ExplicitTypeOutlives` + field: String, +} + +pub fn test(w: Warns) { + let _ = || drop(w.field); +} + +fn main() {} diff --git a/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr new file mode 100644 index 0000000000000..3a5ded60241b1 --- /dev/null +++ b/tests/ui/lazy-type-alias/bad-lazy-type-alias.stderr @@ -0,0 +1,28 @@ +warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-lazy-type-alias.rs:3:12 + | +LL | #![feature(lazy_type_alias)] + | ^^^^^^^^^^^^^^^ + | + = note: see issue #112792 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0107]: missing generics for type alias `ExplicitTypeOutlives` + --> $DIR/bad-lazy-type-alias.rs:9:24 + | +LL | _significant_drop: ExplicitTypeOutlives, + | ^^^^^^^^^^^^^^^^^^^^ expected 1 generic argument + | +note: type alias defined here, with 1 generic parameter: `T` + --> $DIR/bad-lazy-type-alias.rs:6:6 + | +LL | type ExplicitTypeOutlives = T; + | ^^^^^^^^^^^^^^^^^^^^ - +help: add missing generic argument + | +LL | _significant_drop: ExplicitTypeOutlives, + | +++ + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.rs b/tests/ui/nll/user-annotations/region-error-ice-109072.rs index bcdc6651cf5bb..3f2ad3ccbf582 100644 --- a/tests/ui/nll/user-annotations/region-error-ice-109072.rs +++ b/tests/ui/nll/user-annotations/region-error-ice-109072.rs @@ -11,5 +11,4 @@ impl Lt<'missing> for () { //~ ERROR undeclared lifetime fn main() { let _: <() as Lt<'_>>::T = &(); - //~^ ERROR the trait bound `(): Lt<'_>` is not satisfied } diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr index c187c17d98c68..d90971bed25ba 100644 --- a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr +++ b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr @@ -21,13 +21,6 @@ help: consider introducing lifetime `'missing` here LL | impl<'missing> Lt<'missing> for () { | ++++++++++ -error[E0277]: the trait bound `(): Lt<'_>` is not satisfied - --> $DIR/region-error-ice-109072.rs:13:13 - | -LL | let _: <() as Lt<'_>>::T = &(); - | ^^ the trait `Lt<'_>` is not implemented for `()` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0261, E0277. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/pattern/self-ctor-133272.rs b/tests/ui/pattern/self-ctor-133272.rs new file mode 100644 index 0000000000000..ad64d6b88cd91 --- /dev/null +++ b/tests/ui/pattern/self-ctor-133272.rs @@ -0,0 +1,21 @@ +//! Regression test for , where a `ref Self` ctor +//! makes it possible to hit a `delayed_bug` that was converted into a `span_bug` in +//! , and hitting this reveals that we did not have +//! test coverage for this specific code pattern (heh) previously. +//! +//! # References +//! +//! - ICE bug report: . +//! - Previous PR to change `delayed_bug` -> `span_bug`: +//! +#![crate_type = "lib"] + +struct Foo; + +impl Foo { + fn fun() { + let S { ref Self } = todo!(); + //~^ ERROR expected identifier, found keyword `Self` + //~| ERROR cannot find struct, variant or union type `S` in this scope + } +} diff --git a/tests/ui/pattern/self-ctor-133272.stderr b/tests/ui/pattern/self-ctor-133272.stderr new file mode 100644 index 0000000000000..bca55a43d9c08 --- /dev/null +++ b/tests/ui/pattern/self-ctor-133272.stderr @@ -0,0 +1,15 @@ +error: expected identifier, found keyword `Self` + --> $DIR/self-ctor-133272.rs:17:21 + | +LL | let S { ref Self } = todo!(); + | ^^^^ expected identifier, found keyword + +error[E0422]: cannot find struct, variant or union type `S` in this scope + --> $DIR/self-ctor-133272.rs:17:13 + | +LL | let S { ref Self } = todo!(); + | ^ not found in this scope + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0422`. diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs index a7487b8aecb9c..d11ec79833217 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.rs +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.rs @@ -17,7 +17,6 @@ impl MyTrait for D { } impl MyTrait for BadStruct { -//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` fn foo() {} } diff --git a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr index 13f6ae0805dad..0ecec03a023eb 100644 --- a/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr +++ b/tests/ui/specialization/issue-68830-spurious-diagnostics.stderr @@ -4,16 +4,6 @@ error[E0412]: cannot find type `MissingType` in this scope LL | err: MissingType | ^^^^^^^^^^^ not found in this scope -error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `BadStruct` - --> $DIR/issue-68830-spurious-diagnostics.rs:19:1 - | -LL | impl MyTrait for D { - | --------------------------- first implementation here -... -LL | impl MyTrait for BadStruct { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0119, E0412. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0412`. diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs index a08407683d8fe..85c70a21f6839 100644 --- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs +++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs @@ -1,5 +1,6 @@ fn function() { foo == 2; //~ ERROR cannot find value `foo` in this scope [E0425] + //~^ ERROR mismatched types } fn main() {} diff --git a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr index 2da731dcc4b14..8010c0842ba97 100644 --- a/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr +++ b/tests/ui/traits/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.stderr @@ -4,6 +4,18 @@ error[E0425]: cannot find value `foo` in this scope LL | foo == 2; | ^^^ not found in this scope -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/dont-match-error-ty-with-calller-supplied-obligation-issue-121941.rs:2:12 + | +LL | fn function() { + | - expected this type parameter +LL | foo == 2; + | ^ expected type parameter `T`, found integer + | + = note: expected type parameter `T` + found type `{integer}` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0425`. +Some errors have detailed explanations: E0308, E0425. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/traits/issue-78372.rs b/tests/ui/traits/issue-78372.rs index 82b13cc0b6238..f03baf2ceca36 100644 --- a/tests/ui/traits/issue-78372.rs +++ b/tests/ui/traits/issue-78372.rs @@ -10,5 +10,4 @@ trait X { } trait Marker {} impl Marker for dyn Foo {} -//~^ ERROR cannot be made into an object fn main() {} diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr index 4cc2c59fd8dc5..86234d15a5d4b 100644 --- a/tests/ui/traits/issue-78372.stderr +++ b/tests/ui/traits/issue-78372.stderr @@ -55,24 +55,6 @@ LL | impl DispatchFromDyn> for T {} = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/issue-78372.rs:12:17 - | -LL | fn foo(self: Smaht); - | -------------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self` -... -LL | impl Marker for dyn Foo {} - | ^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-78372.rs:9:18 - | -LL | trait Foo: X {} - | --- this trait cannot be made into an object... -LL | trait X { -LL | fn foo(self: Smaht); - | ^^^^^^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on - error[E0307]: invalid `self` parameter type: `Smaht` --> $DIR/issue-78372.rs:9:18 | @@ -88,7 +70,7 @@ error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion LL | impl DispatchFromDyn> for T {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors +error: aborting due to 7 previous errors -Some errors have detailed explanations: E0038, E0307, E0378, E0412, E0658. -For more information about an error, try `rustc --explain E0038`. +Some errors have detailed explanations: E0307, E0378, E0412, E0658. +For more information about an error, try `rustc --explain E0307`. diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs index 3af299e5b115a..4aadd45c49c1e 100644 --- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs +++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.rs @@ -10,6 +10,7 @@ fn w<'a, T: 'a, F: Fn(&'a T)>() { let b: &dyn FromResidual = &(); //~^ ERROR: the trait `FromResidual` cannot be made into an object //~| ERROR: the trait `FromResidual` cannot be made into an object + //~| ERROR: the trait `FromResidual` cannot be made into an object } fn main() {} diff --git a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr index 960802e2f8f82..c67a8c05379cd 100644 --- a/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr +++ b/tests/ui/traits/object/canonicalize-fresh-infer-vars-issue-103626.stderr @@ -6,6 +6,29 @@ LL | let b: &dyn FromResidual = &(); | = note: it cannot use `Self` as a type parameter in a supertrait or `where`-clause +error[E0038]: the trait `FromResidual` cannot be made into an object + --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:32 + | +LL | let b: &dyn FromResidual = &(); + | ^^^ `FromResidual` cannot be made into an object + | +note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:2:8 + | +LL | trait FromResidual::Residual> { + | ------------ this trait cannot be made into an object... +LL | fn from_residual(residual: R) -> Self; + | ^^^^^^^^^^^^^ ...because associated function `from_residual` has no `self` parameter + = note: required for the cast from `&()` to `&dyn FromResidual<{type error}>` +help: consider turning `from_residual` into a method by giving it a `&self` argument + | +LL | fn from_residual(&self, residual: R) -> Self; + | ++++++ +help: alternatively, consider constraining `from_residual` so it does not apply to trait objects + | +LL | fn from_residual(residual: R) -> Self where Self: Sized; + | +++++++++++++++++ + error[E0038]: the trait `FromResidual` cannot be made into an object --> $DIR/canonicalize-fresh-infer-vars-issue-103626.rs:10:12 | @@ -28,6 +51,6 @@ help: alternatively, consider constraining `from_residual` so it does not apply LL | fn from_residual(residual: R) -> Self where Self: Sized; | +++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/traits/span-bug-issue-121414.rs b/tests/ui/traits/span-bug-issue-121414.rs index ec38d8c2de6a6..2f4ad34f0c858 100644 --- a/tests/ui/traits/span-bug-issue-121414.rs +++ b/tests/ui/traits/span-bug-issue-121414.rs @@ -6,8 +6,7 @@ impl<'a> Bar for Foo<'f> { //~ ERROR undeclared lifetime type Type = u32; } -fn test() //~ ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied - //~| ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied +fn test() where for<'a> as Bar>::Type: Sized, { diff --git a/tests/ui/traits/span-bug-issue-121414.stderr b/tests/ui/traits/span-bug-issue-121414.stderr index e2ef6672cd57a..744806a341506 100644 --- a/tests/ui/traits/span-bug-issue-121414.stderr +++ b/tests/ui/traits/span-bug-issue-121414.stderr @@ -6,22 +6,6 @@ LL | impl<'a> Bar for Foo<'f> { | | | help: consider introducing lifetime `'f` here: `'f,` -error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied - --> $DIR/span-bug-issue-121414.rs:9:1 - | -LL | / fn test() -LL | | -LL | | where -LL | | for<'a> as Bar>::Type: Sized, - | |__________________________________________^ the trait `for<'a> Bar` is not implemented for `Foo<'a>` - -error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied - --> $DIR/span-bug-issue-121414.rs:9:4 - | -LL | fn test() - | ^^^^ the trait `for<'a> Bar` is not implemented for `Foo<'a>` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0261, E0277. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs new file mode 100644 index 0000000000000..18cfb1c1f93be --- /dev/null +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.rs @@ -0,0 +1,21 @@ +// regression test for #127353 + +#![feature(type_alias_impl_trait)] +trait Trait {} +type Alias<'a, U> = impl Trait; +//~^ ERROR unconstrained opaque type + +pub enum UninhabitedVariants { + Tuple(Alias), + //~^ ERROR missing lifetime specifier + //~| ERROR missing generics + //~| ERROR non-defining opaque type use in defining scope +} + +fn uwu(x: UninhabitedVariants) { + //~^ ERROR item does not constrain + match x {} + //~^ ERROR non-exhaustive patterns +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr new file mode 100644 index 0000000000000..cf366c55ea816 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/bad-tait-no-substs.stderr @@ -0,0 +1,86 @@ +error[E0106]: missing lifetime specifier + --> $DIR/bad-tait-no-substs.rs:9:11 + | +LL | Tuple(Alias), + | ^^^^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL ~ pub enum UninhabitedVariants<'a> { +LL ~ Tuple(Alias<'a>), + | + +error[E0107]: missing generics for type alias `Alias` + --> $DIR/bad-tait-no-substs.rs:9:11 + | +LL | Tuple(Alias), + | ^^^^^ expected 1 generic argument + | +note: type alias defined here, with 1 generic parameter: `U` + --> $DIR/bad-tait-no-substs.rs:5:6 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^ - +help: add missing generic argument + | +LL | Tuple(Alias), + | +++ + +error[E0792]: non-defining opaque type use in defining scope + --> $DIR/bad-tait-no-substs.rs:9:11 + | +LL | Tuple(Alias), + | ^^^^^ argument `'_` is not a generic parameter + | +note: for this opaque type + --> $DIR/bad-tait-no-substs.rs:5:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + +error: item does not constrain `Alias::{opaque#0}`, but has it in its signature + --> $DIR/bad-tait-no-substs.rs:15:4 + | +LL | fn uwu(x: UninhabitedVariants) { + | ^^^ + | + = note: consider moving the opaque type's declaration and defining uses into a separate module +note: this opaque type is in the signature + --> $DIR/bad-tait-no-substs.rs:5:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + +error: unconstrained opaque type + --> $DIR/bad-tait-no-substs.rs:5:21 + | +LL | type Alias<'a, U> = impl Trait; + | ^^^^^^^^^^^^^ + | + = note: `Alias` must be used in combination with a concrete type within the same module + +error[E0004]: non-exhaustive patterns: `UninhabitedVariants::Tuple(_)` not covered + --> $DIR/bad-tait-no-substs.rs:17:11 + | +LL | match x {} + | ^ pattern `UninhabitedVariants::Tuple(_)` not covered + | +note: `UninhabitedVariants` defined here + --> $DIR/bad-tait-no-substs.rs:8:10 + | +LL | pub enum UninhabitedVariants { + | ^^^^^^^^^^^^^^^^^^^ +LL | Tuple(Alias), + | ----- not covered + = note: the matched value is of type `UninhabitedVariants` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ match x { +LL + UninhabitedVariants::Tuple(_) => todo!(), +LL + } + | + +error: aborting due to 6 previous errors + +Some errors have detailed explanations: E0004, E0106, E0107, E0792. +For more information about an error, try `rustc --explain E0004`. diff --git a/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs new file mode 100644 index 0000000000000..8314b28eeac4b --- /dev/null +++ b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.rs @@ -0,0 +1,22 @@ +// regression test for rust-lang/rust#125758 + +#![feature(impl_trait_in_assoc_type)] + +trait Trait { + type Assoc2; +} + +struct Bar; +impl Trait for Bar { + type Assoc2 = impl std::fmt::Debug; + //~^ ERROR unconstrained opaque type +} + +struct Foo { + field: ::Assoc2, +} + +static BAR: u8 = 42; +static FOO2: &Foo = unsafe { std::mem::transmute(&BAR) }; + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr new file mode 100644 index 0000000000000..6cbf6c83ff4ce --- /dev/null +++ b/tests/ui/type-alias-impl-trait/bad-transmute-itiat.stderr @@ -0,0 +1,10 @@ +error: unconstrained opaque type + --> $DIR/bad-transmute-itiat.rs:11:19 + | +LL | type Assoc2 = impl std::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `Assoc2` must be used in combination with a concrete type within the same impl + +error: aborting due to 1 previous error + diff --git a/tests/crashes/130956.rs b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs similarity index 88% rename from tests/crashes/130956.rs rename to tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs index ebb986d123f91..4332f1264a80b 100644 --- a/tests/crashes/130956.rs +++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.rs @@ -1,8 +1,11 @@ -//@ known-bug: #130956 +// Regression test for #130956 + +#![feature(type_alias_impl_trait)] mod impl_trait_mod { use super::*; pub type OpaqueBlock = impl Trait; + //~^ ERROR unconstrained opaque type pub type OpaqueIf = impl Trait; pub struct BlockWrapper(OpaqueBlock); diff --git a/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr new file mode 100644 index 0000000000000..8e5838d5ddf55 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/drop-analysis-on-unconstrained-tait.stderr @@ -0,0 +1,10 @@ +error: unconstrained opaque type + --> $DIR/drop-analysis-on-unconstrained-tait.rs:7:28 + | +LL | pub type OpaqueBlock = impl Trait; + | ^^^^^^^^^^ + | + = note: `OpaqueBlock` must be used in combination with a concrete type within the same module + +error: aborting due to 1 previous error + diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs index e6d4e2ee01a27..0be5127dcc4da 100644 --- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs +++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs @@ -14,5 +14,4 @@ impl Trait for Ref {} //~ ERROR: implicit elided lifetime not allowed here extern "C" { pub fn repro(_: Wrapper); - //~^ ERROR the trait bound `Ref<'_>: Trait` is not satisfied } diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr index 59b55b2732d30..0af4ab022e1eb 100644 --- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr +++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr @@ -9,19 +9,6 @@ help: indicate the anonymous lifetime LL | impl Trait for Ref<'_> {} | ++++ -error[E0277]: the trait bound `Ref<'_>: Trait` is not satisfied - --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21 - | -LL | pub fn repro(_: Wrapper); - | ^^^^^^^^^^^^ the trait `Trait` is not implemented for `Ref<'_>` - | -note: required by a bound in `Wrapper` - --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23 - | -LL | pub struct Wrapper(T); - | ^^^^^ required by this bound in `Wrapper` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0726. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0726`.